WIP (this commit will be re-written): update use native Node ESM for server code, update config files to specifically use .cjs (those tools don't support Node ESM files yet), use a single eslintrc file, all test code uses ESM import/export syntax instead of require (WIP)

This commit is contained in:
Joe Pea 2020-11-02 22:40:25 -08:00
parent c354bceb92
commit d72dd287c8
62 changed files with 1052 additions and 616 deletions

View File

@ -1,3 +1,20 @@
const deasync = require('deasync'); // powerful magic
const promiseSync = deasync((promise, cb) => {
promise.then((result) => cb(null, result)).catch((error) => cb(error));
});
const importSync = (name) => promiseSync(import(name));
// Look, no await needed here!
const jestConfig = importSync('./jest.config').default;
const testGlobals = {};
for (const key of Object.keys(jestConfig.globals)) {
testGlobals[key] = 'readonly';
}
module.exports = {
root: true,
parser: 'babel-eslint',
@ -39,6 +56,7 @@ module.exports = {
'no-var': ['error'],
'no-void': ['error'],
'no-with': ['error'],
'no-prototype-builtins': 'off',
radix: ['error'],
'spaced-comment': ['error', 'always'],
strict: ['error', 'global'],
@ -60,4 +78,16 @@ module.exports = {
$docsify: 'writable',
dom: 'writable',
},
overrides: [
{
files: ['test/**/*.js', '**/*.test.js'],
extends: ['plugin:jest/recommended', 'plugin:jest/style'],
globals: testGlobals,
},
{
files: ['test/e2e/**/*.test.js'],
extends: ['plugin:jest-playwright/recommended'],
},
],
};

View File

@ -1,4 +1,6 @@
module.exports = {
singleQuote: true,
trailingComma: 'es5',
useTabs: false,
tabWidth: 2,
};

12
babel.config.cjs Normal file
View File

@ -0,0 +1,12 @@
module.exports = {
// presets: [
// [
// '@babel/preset-env',
// {
// targets: {
// node: 'current',
// },
// },
// ],
// ],
};

View File

@ -1,12 +0,0 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};

View File

@ -1,22 +1,31 @@
const path = require('path');
const { globals: serverGlobals } = require('./test/config/server.js');
import path from 'path';
import server from './test/config/server';
const { globals: serverGlobals } = server;
const dirname = path.dirname(import.meta.url.replace('file://', ''));
const sharedConfig = {
errorOnDeprecated: true,
globals: {
...serverGlobals, // BLANK_URL, DOCS_URL, LIB_URL, NODE_MODULES_URL, TEST_HOST
DOCS_PATH: path.resolve(__dirname, 'docs'),
LIB_PATH: path.resolve(__dirname, 'lib'),
SRC_PATH: path.resolve(__dirname, 'src'),
DOCS_PATH: path.resolve(dirname, 'docs'),
LIB_PATH: path.resolve(dirname, 'lib'),
SRC_PATH: path.resolve(dirname, 'src'),
},
globalSetup: './test/config/jest.setup.js',
globalTeardown: './test/config/jest.teardown.js',
globalSetup: './test/config/jest.setup.cjs',
globalTeardown: './test/config/jest.teardown.cjs',
resetModules: true,
restoreMocks: true,
};
module.exports = {
// Adding globals to config root for easier importing into .eslint.js, but
// Jest configuration: https://jestjs.io/docs/en/configuration
export default {
// Disable transforms, we'll write plain JS. This is also needed for native
// ESM (see https://jestjs.io/docs/en/ecmascript-modules).
transform: {},
// Adding globals to config root for easier importing into .eslint.cjs, but
// as of Jest 26.4.2 these globals need to be added to each project config
// as well.
globals: sharedConfig.globals,

554
package-lock.json generated
View File

@ -2362,6 +2362,81 @@
"minimist": "^1.2.0"
}
},
"@eslint/eslintrc": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz",
"integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.1.1",
"espree": "^7.3.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
"js-yaml": "^3.13.1",
"lodash": "^4.17.19",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"import-fresh": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
"integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
"@evocateur/libnpmaccess": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz",
@ -5847,6 +5922,15 @@
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"blob": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
@ -8610,6 +8694,16 @@
"integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
"dev": true
},
"deasync": {
"version": "0.1.20",
"resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.20.tgz",
"integrity": "sha512-E1GI7jMI57hL30OX6Ht/hfQU8DO4AuB9m72WFm4c38GNbUD4Q03//XZaOIHZiY+H1xUaomcot5yk2q/qIZQkGQ==",
"dev": true,
"requires": {
"bindings": "^1.5.0",
"node-addon-api": "^1.7.1"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@ -9225,6 +9319,12 @@
"string.prototype.trimright": "^2.1.0"
}
},
"es-main": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/es-main/-/es-main-1.0.2.tgz",
"integrity": "sha512-LLgW8Cby/FiyQygrI23q2EswulHiDKoyjWlDRgTGXjQ3iRim2R26VfoehpxI5oKRXSNams3L/80KtggoUdxdDQ==",
"dev": true
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
@ -9288,76 +9388,166 @@
}
},
"eslint": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz",
"integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.9.1",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"@eslint/eslintrc": "^0.2.1",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.1",
"esquery": "^1.0.1",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.1",
"eslint-utils": "^2.1.0",
"eslint-visitor-keys": "^2.0.0",
"espree": "^7.3.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"globals": "^11.7.0",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
"js-yaml": "^3.13.0",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
"levn": "^0.4.1",
"lodash": "^4.17.19",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
"strip-ansi": "^4.0.0",
"strip-json-comments": "^2.0.1",
"regexpp": "^3.1.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
"table": "^5.2.3",
"text-table": "^0.2.0"
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"eslint-visitor-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz",
"integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==",
"dev": true
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"import-fresh": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
"integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
"integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.3"
}
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"resolve-from": {
@ -9367,34 +9557,43 @@
"dev": true
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"shebang-regex": "^1.0.0"
"ansi-regex": "^5.0.0"
}
},
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
@ -9599,22 +9798,22 @@
}
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
}
},
"eslint-utils": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
@ -9629,14 +9828,34 @@
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
},
"espree": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
"integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
"integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
"acorn": "^7.4.0",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.3.0"
},
"dependencies": {
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
"acorn-jsx": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
"integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
"dev": true
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
}
}
},
"esprima": {
@ -9645,21 +9864,37 @@
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
"integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
"dev": true,
"requires": {
"estraverse": "^4.0.0"
"estraverse": "^5.1.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"esrecurse": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"requires": {
"estraverse": "^4.1.0"
"estraverse": "^5.2.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"estraverse": {
@ -10001,6 +10236,29 @@
}
}
},
"extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"requires": {
"@types/yauzl": "^2.9.1",
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
}
}
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@ -10132,6 +10390,12 @@
"flat-cache": "^2.0.1"
}
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -10372,9 +10636,9 @@
}
},
"flatted": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
"dev": true
},
"flush-write-stream": {
@ -15695,7 +15959,11 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"glob-parent": {
"version": "3.1.0",
@ -16889,6 +17157,13 @@
"thenify-all": "^1.0.0"
}
},
"nan": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"dev": true,
"optional": true
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -16932,6 +17207,12 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
"node-addon-api": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
"dev": true
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
@ -18455,6 +18736,73 @@
}
}
},
"playwright-firefox": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/playwright-firefox/-/playwright-firefox-1.5.2.tgz",
"integrity": "sha512-9iWi357NwVrZIPpMa1Fl2rPJCDAfAeScFc2rdEeIEIY4S6pAiSiXX2cxnZKH6m4X9h8m5FuezINHoW57VqGiXw==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.0",
"jpeg-js": "^0.4.2",
"mime": "^2.4.6",
"pngjs": "^5.0.0",
"progress": "^2.0.3",
"proper-lockfile": "^4.1.1",
"proxy-from-env": "^1.1.0",
"rimraf": "^3.0.2",
"ws": "^7.3.1"
},
"dependencies": {
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
"requires": {
"debug": "4"
}
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dev": true,
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"mime": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
"dev": true
},
"pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"ws": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
"dev": true
}
}
},
"please-upgrade-node": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
@ -19029,9 +19377,9 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"prettier": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"dev": true
},
"prettier-linter-helpers": {
@ -19464,9 +19812,9 @@
}
},
"regexpp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
"regexpu-core": {
@ -21410,9 +21758,9 @@
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"strong-log-transformer": {
@ -22346,6 +22694,12 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
},
"v8-compile-cache": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
"dev": true
},
"v8-to-istanbul": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-6.0.1.tgz",
@ -22562,6 +22916,12 @@
"execa": "^1.0.0"
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",

View File

@ -22,28 +22,33 @@
],
"scripts": {
"bootstrap": "npm i && lerna bootstrap",
"serve": "node server",
"serve:ssr": "cross-env SSR=1 node --experimental-specifier-resolution=node server",
"serve": "npm run _node -- server",
"serve:ssr": "cross-env SSR=1 npm run _node -- server",
"dev": "run-p serve watch:*",
"dev:ssr": "run-p serve:ssr watch:*",
"lint": "eslint .",
"fixlint": "eslint . --fix",
"test": "jest --runInBand",
"test:e2e": "jest --selectProjects e2e",
"test:integration": "jest --selectProjects integration",
"test:unit": "jest --selectProjects unit",
"css": "node build/css",
"lint": "npm run _eslint -- .",
"fixlint": "npm run _eslint -- . --fix",
"test": "npm run _jest -- --runInBand",
"test:e2e": "npm run _jest -- --selectProjects e2e",
"test:integration": "npm run _jest -- --selectProjects integration",
"test:unit": "npm run _jest -- --selectProjects unit",
"css": "npm run _node -- build/css",
"watch:css": "npm run css -- -o themes -w",
"watch:js": "node build/build.js",
"build:css:min": "mkdirp lib/themes && npm run css -- -o lib/themes && node build/mincss.js",
"watch:js": "npm run _node -- build/build.js",
"build:css:min": "mkdirp lib/themes && npm run css -- -o lib/themes && npm run _node -- build/mincss.js",
"build:css": "mkdirp themes && npm run css -- -o themes",
"build:js": "cross-env NODE_ENV=production node build/build.js",
"build:cover": "node build/cover.js",
"build:js": "cross-env NODE_ENV=production npm run _node -- build/build.js",
"build:cover": "npm run _node -- build/cover.js",
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:cover",
"prepare": "npm run build",
"pub:next": "cross-env RELEASE_TAG=next sh build/release.sh",
"pub": "sh build/release.sh",
"postinstall": "opencollective-postinstall"
"postinstall": "opencollective-postinstall",
"_node": "node --experimental-specifier-resolution=node",
"_eslint": "DISABLE_V8_COMPILE_CACHE=1 npm run _node -- ./node_modules/.bin/eslint",
"// ^ _eslint comment": "The DISABLE_V8_COMPILE_CACHE=1 var enables ESM import() in .eslintrc.cjs. See https://github.com/eslint/eslint/issues/13684",
"_jest": "npm run _node -- --experimental-vm-modules ./node_modules/.bin/jest",
"// ^ _jest comment": "--experimental-vm-modules is needed in order to enable full native ESM support in Jest"
},
"husky-OFF": {
"hooks": {
@ -79,7 +84,9 @@
"copy-dir": "^1.2.0",
"cross-env": "^6.0.3",
"cssnano": "^4.1.10",
"eslint": "^5.16.0",
"deasync": "^0.1.20",
"es-main": "^1.0.2",
"eslint": "^7.12.1",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jest": "^24.0.2",
"eslint-plugin-jest-playwright": "^0.2.1",
@ -94,7 +101,8 @@
"mkdirp": "^0.5.1",
"npm-run-all": "^4.1.5",
"playwright": "^1.4.1",
"prettier": "^1.19.1",
"playwright-firefox": "^1.5.2",
"prettier": "^2.0.0",
"rimraf": "^3.0.0",
"rollup": "^1.23.1",
"rollup-plugin-async": "^1.2.0",

View File

@ -62,6 +62,10 @@ export default class Renderer {
return isAbsolutePath(file) ? file : cwd(`./${file}`);
}
/**
* @param {string} url
* @returns {Promise<string>}
*/
async renderToString(url) {
this.url = url = this.router.parse(url).path;
this.isRemoteUrl = isExternal(this.url);
@ -128,10 +132,10 @@ export default class Renderer {
html = this.compiler.cover(html);
break;
case 'main':
tokens = await new Promise(r => {
tokens = await new Promise((r) => {
prerenderEmbed(
{
fetch: url => this._loadFile(this._getPath(url)),
fetch: (url) => this._loadFile(this._getPath(url)),
compiler: this.compiler,
raw: html,
},

View File

@ -1,6 +1,6 @@
{
"name": "docsify-server-renderer",
"version": "4.11.2",
"version": "4.11.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -16,11 +16,11 @@
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz",
"integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==",
"requires": {
"ms": "^2.1.1"
"ms": "2.1.2"
}
},
"delegate": {
@ -30,23 +30,24 @@
"optional": true
},
"docsify": {
"version": "4.11.2",
"resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.2.tgz",
"integrity": "sha512-vQVg+ERdYgrlgLcwTX9FdjUn3xb7PSwaiYopIAmCLraHJCr1e0r8Uzi2vm6XEwTrSrdd6C5j3Eg+QctsOGA4Gg==",
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/docsify/-/docsify-4.11.6.tgz",
"integrity": "sha512-6h3hB2Ni7gpOeu1fl1sDOmufuplIDmeFHsps17Qbg9VOS3h2tJ63FiW2w5oAydGyzaLrqu58FV7Mg4b6p0z9mg==",
"requires": {
"marked": "^0.7.0",
"medium-zoom": "^1.0.5",
"dompurify": "^2.0.8",
"marked": "^1.1.1",
"medium-zoom": "^1.0.6",
"opencollective-postinstall": "^2.0.2",
"prismjs": "^1.19.0",
"strip-indent": "^3.0.0",
"tinydate": "^1.0.0",
"tinydate": "^1.3.0",
"tweezer.js": "^1.4.0"
}
},
"dompurify": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.8.tgz",
"integrity": "sha512-vIOSyOXkMx81ghEalh4MLBtDHMx1bhKlaqHDMqM2yeitJ996SLOk5mGdDpI9ifJAgokred8Rmu219fX4OltqXw=="
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.2.tgz",
"integrity": "sha512-BsGR4nDLaC5CNBnyT5I+d5pOeaoWvgVeg6Gq/aqmKYWMPR07131u60I80BvExLAJ0FQEIBQ1BTicw+C5+jOyrg=="
},
"good-listener": {
"version": "1.2.2",
@ -58,19 +59,19 @@
}
},
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
"integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg=="
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.3.tgz",
"integrity": "sha512-RQuL2i6I6Gn+9n81IDNGbL0VHnta4a+8ZhqvryXEniTb/hQNtf3i26hi1XWUhzb9BgVyWHKR3UO8MaHtKoYibw=="
},
"medium-zoom": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.5.tgz",
"integrity": "sha512-aLGa6WlTuFKWvH88bqTrY5ztJMN+D0hd8UX6BYc4YSoPayppzETjZUcdVcksgaoQEMg4cZSmXPg846fTp2rjRQ=="
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.6.tgz",
"integrity": "sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg=="
},
"min-indent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz",
"integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
},
"ms": {
"version": "2.1.2",
@ -83,14 +84,14 @@
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"opencollective-postinstall": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
"integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
},
"prismjs": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz",
"integrity": "sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==",
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.22.0.tgz",
"integrity": "sha512-lLJ/Wt9yy0AiSYBf212kK3mM5L8ycwlyTlSxHBAneXLR0nzFMlZ5y7riFPF3E33zXOF2IH95xdY5jIyZbM9z/w==",
"requires": {
"clipboard": "^2.0.0"
}
@ -121,9 +122,9 @@
"optional": true
},
"tinydate": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz",
"integrity": "sha512-3GwPk8VhDFnUZ2TrgkhXJs6hcMAIIw4x/xkz+ayK6dGoQmp2nUwKzBXK0WnMsqkh6vfUhpqQicQF3rbshfyJkg=="
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz",
"integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w=="
},
"tweezer.js": {
"version": "1.5.0",

View File

@ -1,25 +1,24 @@
// @ts-check
import { isExternal } from './utils';
// import { docsifyInit } from '../helpers/docsify-init';
describe('isExternal', () => {
test('detects whether links are external or not', async () => {
// initJSDOM('', {
// url: 'http://127.0.0.1:3000',
// runScripts: 'dangerously',
// resources: 'usable',
// });
// docsifyInit();
// Note, Jest tests operate under the origin "http://127.0.0.1:3001"
expect(isExternal).toBeInstanceOf(Function);
expect(isExternal('/foo.md')).toBe(false);
expect(isExternal('//foo.md')).toBe(true);
expect(isExternal('//127.0.0.1:3000/foo.md')).toBe(false);
expect(isExternal('http://127.0.0.1:3001/foo.md')).toBe(true);
expect(isExternal('foo.md')).toBe(false);
expect(isExternal('//127.0.0.1:3000/foo.md')).toBe(true);
expect(isExternal('//127.0.0.1:3001/foo.md')).toBe(false);
expect(isExternal('http://127.0.0.1:3000/foo.md')).toBe(true);
expect(isExternal('https://127.0.0.1:3000/foo.md')).toBe(true);
expect(isExternal('http://127.0.0.1:3001/foo.md')).toBe(false);
expect(isExternal('https://127.0.0.1:3001/foo.md')).toBe(true);
expect(isExternal('https://google.com/foo.md')).toBe(true);
expect(isExternal('//google.com/foo.md')).toBe(true);
expect(isExternal('/google.com/foo.md')).toBe(false);
expect(isExternal('google.com')).toBe(false);
expect(isExternal('google.com/foo.md')).toBe(false);
});
});

View File

@ -1,5 +1,5 @@
// const liveServer = require('live-server');
import liveServer from 'live-server';
const isSSR = !!process.env.SSR;
const middleware = [];
@ -12,13 +12,7 @@ async function main() {
// URL to operate under (it probably can be anything).
initJSDOM('', { url: 'https://127.0.0.1:3000' });
// const requireESM = require('esm')(module /* , options */);
// const { Renderer, getServerHTMLTemplate } = requireESM(
// './packages/docsify-server-renderer/index'
// );
const { Renderer, getServerHTMLTemplate } = await import(
// './packages/docsify-server-renderer/index.js'
'./packages/docsify-server-renderer/index'
);
@ -41,11 +35,11 @@ async function main() {
},
});
middleware.push(function(req, res, next) {
middleware.push(function (req, res, next) {
if (/\.(css|js)$/.test(req.url)) {
return next();
}
renderer.renderToString(req.url).then(html => res.end(html));
renderer.renderToString(req.url).then((html) => res.end(html));
});
}
@ -59,7 +53,6 @@ async function main() {
}
async function initJSDOM(markup, options) {
// const { JSDOM } = require('jsdom');
const { JSDOM } = (await import('jsdom')).default;
const dom = new JSDOM(markup, options);

View File

@ -2,7 +2,7 @@ import { merge, hyphenate, isPrimitive, hasOwn } from './util/core';
const currentScript = document.currentScript;
export default function(vm) {
export default function (vm) {
const config = merge(
{
el: '#app',

View File

@ -4,7 +4,7 @@ import * as sidebar from './sidebar';
import { scrollIntoView, scroll2Top } from './scroll';
export function eventMixin(proto) {
proto.$resetEvents = function(source) {
proto.$resetEvents = function (source) {
const { auto2top } = this.config;
(() => {

View File

@ -13,7 +13,7 @@ const cache = {};
*/
export function get(url, hasBar = false, headers = {}) {
const xhr = new XMLHttpRequest();
const on = function() {
const on = function () {
xhr.addEventListener.apply(xhr, arguments);
};
@ -33,7 +33,7 @@ export function get(url, hasBar = false, headers = {}) {
xhr.send();
return {
then: function(success, error = noop) {
then: function (success, error = noop) {
if (hasBar) {
const id = setInterval(
_ =>

View File

@ -60,7 +60,7 @@ export function fetchMixin(proto) {
return path404;
};
proto._loadSideAndNav = function(path, qs, loadSidebar, cb) {
proto._loadSideAndNav = function (path, qs, loadSidebar, cb) {
return () => {
if (!loadSidebar) {
return cb();
@ -76,7 +76,7 @@ export function fetchMixin(proto) {
};
};
proto._fetch = function(cb = noop) {
proto._fetch = function (cb = noop) {
const { path, query } = this.route;
const qs = stringifyQuery(query, ['id']);
const { loadNavbar, requestHeaders, loadSidebar } = this.config;
@ -114,7 +114,7 @@ export function fetchMixin(proto) {
);
};
proto._fetchCover = function() {
proto._fetchCover = function () {
const { coverpage, requestHeaders } = this.config;
const query = this.route.query;
const root = getParentPath(this.route.path);
@ -150,7 +150,7 @@ export function fetchMixin(proto) {
}
};
proto.$fetch = function(
proto.$fetch = function (
cb = noop,
$resetEvents = this.$resetEvents.bind(this)
) {
@ -171,7 +171,7 @@ export function fetchMixin(proto) {
}
};
proto._fetchFallbackPage = function(path, qs, cb = noop) {
proto._fetchFallbackPage = function (path, qs, cb = noop) {
const { requestHeaders, fallbackLanguages, loadSidebar } = this.config;
if (!fallbackLanguages) {
@ -210,7 +210,7 @@ export function fetchMixin(proto) {
* @returns {Boolean} True if the requested page is not found
* @private
*/
proto._fetch404 = function(path, qs, cb = noop) {
proto._fetch404 = function (path, qs, cb = noop) {
const { loadSidebar, requestHeaders, notFoundPage } = this.config;
const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb);

View File

@ -10,7 +10,7 @@ import { get } from './fetch/ajax';
// major release. We'll tell people to get everything from the DOCSIFY global
// when using the global build, but we'll highly recommend for them to import
// from the ESM build (f.e. lib/docsify.esm.js and lib/docsify.min.esm.js).
export default function() {
export default function () {
window.Docsify = {
util,
dom,

View File

@ -7,7 +7,7 @@ import { isFn } from '../util/core';
import { initLifecycle, callHook } from './lifecycle';
export function initMixin(proto) {
proto._init = function() {
proto._init = function () {
const vm = this;
vm.config = config(vm);

View File

@ -21,7 +21,7 @@ export function initLifecycle(vm) {
export function callHook(vm, hookName, data, next = noop) {
const queue = vm._hooks[hookName];
const step = function(index) {
const step = function (index) {
const hookFn = queue[index];
if (index >= queue.length) {

View File

@ -28,8 +28,9 @@ const compileMedia = {
},
iframe(url, title) {
return {
html: `<iframe src="${url}" ${title ||
'width=100% height=400'}></iframe>`,
html: `<iframe src="${url}" ${
title || 'width=100% height=400'
}></iframe>`,
};
},
video(url, title) {
@ -205,7 +206,7 @@ export class Compiler {
* @param {Number} level Type of heading (h<level> tag)
* @returns {String} Heading element
*/
origin.heading = renderer.heading = function(text, level) {
origin.heading = renderer.heading = function (text, level) {
let { str, config } = getAndRemoveConfig(text);
const nextToc = { level, title: removeAtag(str) };

View File

@ -3,7 +3,7 @@ import Prism from 'prismjs';
import 'prismjs/components/prism-markup-templating';
export const highlightCodeCompiler = ({ renderer }) =>
(renderer.code = function(code, lang = 'markup') {
(renderer.code = function (code, lang = 'markup') {
const langOrMarkup = Prism.languages[lang] || Prism.languages.markup;
const text = Prism.highlight(
code.replace(/@DOCSIFY_QM@/g, '`'),

View File

@ -15,7 +15,7 @@ function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
while ((token = embedTokens[step++])) {
// eslint-disable-next-line no-shadow
const next = (function(token) {
const next = (function (token) {
return text => {
let embedToken;
if (text) {

View File

@ -90,7 +90,7 @@ function renderMain(html) {
if (!isAlreadyVue) {
new window.Vue({
mounted: function() {
mounted: function () {
this.$destroy();
},
}).$mount(elm);
@ -121,14 +121,14 @@ function renderNameLink(vm) {
}
export function renderMixin(proto) {
proto._renderTo = function(el, content, replace) {
proto._renderTo = function (el, content, replace) {
const node = dom.getNode(el);
if (node) {
node[replace ? 'outerHTML' : 'innerHTML'] = content;
}
};
proto._renderSidebar = function(text) {
proto._renderSidebar = function (text) {
const { maxLevel, subMaxLevel, loadSidebar, hideSidebar } = this.config;
if (hideSidebar) {
@ -156,7 +156,7 @@ export function renderMixin(proto) {
this._bindEventOnRendered(activeEl);
};
proto._bindEventOnRendered = function(activeEl) {
proto._bindEventOnRendered = function (activeEl) {
const { autoHeader } = this.config;
scrollActiveSidebar(this.router);
@ -172,14 +172,14 @@ export function renderMixin(proto) {
}
};
proto._renderNav = function(text) {
proto._renderNav = function (text) {
text && this._renderTo('nav', this.compiler.compile(text));
if (this.config.loadNavbar) {
getAndActive(this.router, 'nav');
}
};
proto._renderMain = function(text, opt = {}, next) {
proto._renderMain = function (text, opt = {}, next) {
if (!text) {
return renderMain.call(this, text);
}
@ -217,7 +217,7 @@ export function renderMixin(proto) {
});
};
proto._renderCover = function(text, coverOnly) {
proto._renderCover = function (text, coverOnly) {
const el = dom.getNode('.cover');
dom.toggleClass(
@ -261,7 +261,7 @@ export function renderMixin(proto) {
sticky();
};
proto._updateRender = function() {
proto._updateRender = function () {
// Render name link
renderNameLink(this);
};

View File

@ -17,7 +17,7 @@ function init() {
/**
* Render progress bar
*/
export default function({ loaded, total, step }) {
export default function ({ loaded, total, step }) {
let num;
!barEl && init();

View File

@ -32,6 +32,6 @@ export function slugify(str) {
return slug;
}
slugify.clear = function() {
slugify.clear = function () {
cache = {};
};

View File

@ -13,7 +13,7 @@ export function parseQuery(query) {
}
// Simple parse
query.split('&').forEach(function(param) {
query.split('&').forEach(function (param) {
const parts = param.replace(/\+/g, ' ').split('=');
res[parts[0]] = parts[1] && decode(parts[1]);

View File

@ -6,7 +6,7 @@
export function cached(fn) {
const cache = Object.create(null);
return function(str) {
return function (str) {
const key = isPrimitive(str) ? str : JSON.stringify(str);
const hit = cache[key];
return hit || (cache[key] = fn(str));
@ -29,7 +29,7 @@ export const hasOwn = Object.prototype.hasOwnProperty;
*/
export const merge =
Object.assign ||
function(to) {
function (to) {
for (let i = 1; i < arguments.length; i++) {
const from = Object(arguments[i]);

View File

@ -7,7 +7,7 @@ export const isMobile = inBrowser && document.body.clientWidth <= 600;
*/
export const supportsPushState =
inBrowser &&
(function() {
(function () {
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
return (
window.history &&

View File

@ -8,7 +8,7 @@ function replaceVar(block, color) {
);
}
export default function(color) {
export default function (color) {
// Variable support
if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) {
return;

View File

@ -28,7 +28,7 @@ function install(hook, vm) {
dom.appendTo(dom.find('.content'), div);
// eslint-disable-next-line
window.disqus_config = function() {
window.disqus_config = function () {
this.page.url = location.origin + '/-' + vm.route.path;
this.page.identifier = vm.route.path;
this.page.title = document.title;
@ -39,7 +39,7 @@ function install(hook, vm) {
if (typeof window.DISQUS !== 'undefined') {
window.DISQUS.reset({
reload: true,
config: function() {
config: function () {
this.page.url = location.origin + '/-' + vm.route.path;
this.page.identifier = vm.route.path;
this.page.title = document.title;

View File

@ -1,7 +1,7 @@
/* eslint-disable camelcase */
const AllGithubEmoji = {
'100': 'unicode/1f4af',
'1234': 'unicode/1f522',
100: 'unicode/1f4af',
1234: 'unicode/1f522',
'+1': 'unicode/1f44d',
'-1': 'unicode/1f44e',
'1st_place_medal': 'unicode/1f947',
@ -1804,7 +1804,7 @@ const AllGithubEmoji = {
// Emoji from GitHub API
// https://api.github.com/emojis
window.emojify = function(match, $1) {
window.emojify = function (match, $1) {
return AllGithubEmoji.hasOwnProperty($1) === false
? match
: '<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' +

View File

@ -18,7 +18,7 @@ function handleExternalScript() {
}
}
const install = function(hook) {
const install = function (hook) {
hook.doneEach(handleExternalScript);
};

View File

@ -1,10 +1,10 @@
import parser from './parser';
const install = function(hook, vm) {
const install = function (hook, vm) {
// Used to remove front matter from embedded pages if installed.
vm.config.frontMatter = {};
vm.config.frontMatter.installed = true;
vm.config.frontMatter.parseMarkdown = function(content) {
vm.config.frontMatter.parseMarkdown = function (content) {
const { body } = parser(content);
return body;
};

View File

@ -2,9 +2,9 @@
* Fork https://github.com/egoist/docute/blob/master/src/utils/front-matter.js
*/
/* eslint-disable */
import parser from './yaml'
import parser from './yaml';
var optionalByteOrderMark = '\\ufeff?'
var optionalByteOrderMark = '\\ufeff?';
var pattern =
'^(' +
optionalByteOrderMark +
@ -13,43 +13,43 @@ var pattern =
'(?:\\2|\\.\\.\\.)' +
'$' +
'' +
'(?:\\n)?)'
'(?:\\n)?)';
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
// need to be moved down into the functions that use it.
var regex = new RegExp(pattern, 'm')
var regex = new RegExp(pattern, 'm');
function extractor(string) {
string = string || ''
string = string || '';
var lines = string.split(/(\r?\n)/)
var lines = string.split(/(\r?\n)/);
if (lines[0] && /= yaml =|---/.test(lines[0])) {
return parse(string)
return parse(string);
} else {
return { attributes: {}, body: string }
return { attributes: {}, body: string };
}
}
function parse(string) {
var match = regex.exec(string)
var match = regex.exec(string);
if (!match) {
return {
attributes: {},
body: string
}
body: string,
};
}
var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
var attributes = parser(yaml) || {}
var body = string.replace(match[0], '')
var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '');
var attributes = parser(yaml) || {};
var body = string.replace(match[0], '');
return { attributes: attributes, body: body, frontmatter: yaml }
return { attributes: attributes, body: body, frontmatter: yaml };
}
function test(string) {
string = string || ''
string = string || '';
return regex.test(string)
return regex.test(string);
}
export default extractor
export default extractor;

View File

@ -27,7 +27,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/**
* @name YAML
* @namespace
*/
*/
var errors = [],
reference_blocks = [],
@ -46,14 +46,16 @@ var errors = [],
key: new RegExp('([a-z0-9_-][ a-z0-9_-]+):( .+)?', 'i'),
item: new RegExp('^-\\s+'),
trim: new RegExp('^\\s+|\\s+$'),
comment: new RegExp('([^\\\'\\"#]+([\\\'\\"][^\\\'\\"]*[\\\'\\"])*)*(#.*)?')
}
comment: new RegExp(
'([^\\\'\\"#]+([\\\'\\"][^\\\'\\"]*[\\\'\\"])*)*(#.*)?'
),
};
/**
* @class A block of lines of a given level.
* @param {int} lvl The block's level.
* @private
*/
* @class A block of lines of a given level.
* @param {int} lvl The block's level.
* @private
*/
function Block(lvl) {
return {
/* The block's parent */
@ -67,21 +69,21 @@ function Block(lvl) {
/* Blocks with greater level */
children: [],
/* Add a block to the children collection */
addChild: function(obj) {
this.children.push(obj)
obj.parent = this
++this.length
}
}
addChild: function (obj) {
this.children.push(obj);
obj.parent = this;
++this.length;
},
};
}
// function to create an XMLHttpClient in a cross-browser manner
function createXMLHTTPRequest() {
var xmlhttp
var xmlhttp;
try {
// Mozilla / Safari / IE7
xmlhttp = new XMLHttpRequest()
xmlhttp = new XMLHttpRequest();
} catch (e) {
// IE
var XMLHTTP_IDS = new Array(
@ -90,347 +92,347 @@ function createXMLHTTPRequest() {
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'
)
var success = false
);
var success = false;
for (var i = 0; i < XMLHTTP_IDS.length && !success; i++) {
try {
xmlhttp = new ActiveXObject(XMLHTTP_IDS[i])
success = true
xmlhttp = new ActiveXObject(XMLHTTP_IDS[i]);
success = true;
} catch (e) {}
}
if (!success) {
throw new Error('Unable to create XMLHttpRequest.')
throw new Error('Unable to create XMLHttpRequest.');
}
}
return xmlhttp
return xmlhttp;
}
function parser(str) {
var regLevel = regex['regLevel']
var invalidLine = regex['invalidLine']
var lines = str.split('\n')
var m
var regLevel = regex['regLevel'];
var invalidLine = regex['invalidLine'];
var lines = str.split('\n');
var m;
var level = 0,
curLevel = 0
curLevel = 0;
var blocks = []
var blocks = [];
var result = new Block(-1)
var currentBlock = new Block(0)
result.addChild(currentBlock)
var levels = []
var line = ''
var result = new Block(-1);
var currentBlock = new Block(0);
result.addChild(currentBlock);
var levels = [];
var line = '';
blocks.push(currentBlock)
levels.push(level)
blocks.push(currentBlock);
levels.push(level);
for (var i = 0, len = lines.length; i < len; ++i) {
line = lines[i]
line = lines[i];
if (line.match(invalidLine)) {
continue
continue;
}
if ((m = regLevel.exec(line))) {
level = m[1].length
} else level = 0
level = m[1].length;
} else level = 0;
if (level > curLevel) {
var oldBlock = currentBlock
currentBlock = new Block(level)
oldBlock.addChild(currentBlock)
blocks.push(currentBlock)
levels.push(level)
var oldBlock = currentBlock;
currentBlock = new Block(level);
oldBlock.addChild(currentBlock);
blocks.push(currentBlock);
levels.push(level);
} else if (level < curLevel) {
var added = false
var added = false;
var k = levels.length - 1
var k = levels.length - 1;
for (; k >= 0; --k) {
if (levels[k] == level) {
currentBlock = new Block(level)
blocks.push(currentBlock)
levels.push(level)
if (blocks[k].parent != null) blocks[k].parent.addChild(currentBlock)
added = true
break
currentBlock = new Block(level);
blocks.push(currentBlock);
levels.push(level);
if (blocks[k].parent != null) blocks[k].parent.addChild(currentBlock);
added = true;
break;
}
}
if (!added) {
errors.push('Error: Invalid indentation at line ' + i + ': ' + line)
return
errors.push('Error: Invalid indentation at line ' + i + ': ' + line);
return;
}
}
currentBlock.lines.push(line.replace(regex['trim'], ''))
curLevel = level
currentBlock.lines.push(line.replace(regex['trim'], ''));
curLevel = level;
}
return result
return result;
}
function processValue(val) {
val = val.replace(regex['trim'], '')
var m = null
val = val.replace(regex['trim'], '');
var m = null;
if (val == 'true') {
return true
return true;
} else if (val == 'false') {
return false
return false;
} else if (val == '.NaN') {
return Number.NaN
return Number.NaN;
} else if (val == 'null') {
return null
return null;
} else if (val == '.inf') {
return Number.POSITIVE_INFINITY
return Number.POSITIVE_INFINITY;
} else if (val == '-.inf') {
return Number.NEGATIVE_INFINITY
return Number.NEGATIVE_INFINITY;
} else if ((m = val.match(regex['dashesString']))) {
return m[1]
return m[1];
} else if ((m = val.match(regex['quotesString']))) {
return m[1]
return m[1];
} else if ((m = val.match(regex['float']))) {
return parseFloat(m[0])
return parseFloat(m[0]);
} else if ((m = val.match(regex['integer']))) {
return parseInt(m[0])
return parseInt(m[0]);
} else if (!isNaN((m = Date.parse(val)))) {
return new Date(m)
return new Date(m);
} else if ((m = val.match(regex['single_key_value']))) {
var res = {}
res[m[1]] = processValue(m[2])
return res
var res = {};
res[m[1]] = processValue(m[2]);
return res;
} else if ((m = val.match(regex['array']))) {
var count = 0,
c = ' '
var res = []
var content = ''
var str = false
c = ' ';
var res = [];
var content = '';
var str = false;
for (var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j]
c = m[1][j];
if (c == "'" || c == '"') {
if (str === false) {
str = c
content += c
continue
str = c;
content += c;
continue;
} else if ((c == "'" && str == "'") || (c == '"' && str == '"')) {
str = false
content += c
continue
str = false;
content += c;
continue;
}
} else if (str === false && (c == '[' || c == '{')) {
++count
++count;
} else if (str === false && (c == ']' || c == '}')) {
--count
--count;
} else if (str === false && count == 0 && c == ',') {
res.push(processValue(content))
content = ''
continue
res.push(processValue(content));
content = '';
continue;
}
content += c
content += c;
}
if (content.length > 0) res.push(processValue(content))
return res
if (content.length > 0) res.push(processValue(content));
return res;
} else if ((m = val.match(regex['map']))) {
var count = 0,
c = ' '
var res = []
var content = ''
var str = false
c = ' ';
var res = [];
var content = '';
var str = false;
for (var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j]
c = m[1][j];
if (c == "'" || c == '"') {
if (str === false) {
str = c
content += c
continue
str = c;
content += c;
continue;
} else if ((c == "'" && str == "'") || (c == '"' && str == '"')) {
str = false
content += c
continue
str = false;
content += c;
continue;
}
} else if (str === false && (c == '[' || c == '{')) {
++count
++count;
} else if (str === false && (c == ']' || c == '}')) {
--count
--count;
} else if (str === false && count == 0 && c == ',') {
res.push(content)
content = ''
continue
res.push(content);
content = '';
continue;
}
content += c
content += c;
}
if (content.length > 0) res.push(content)
if (content.length > 0) res.push(content);
var newRes = {}
var newRes = {};
for (var j = 0, lenJ = res.length; j < lenJ; ++j) {
if ((m = res[j].match(regex['key_value']))) {
newRes[m[1]] = processValue(m[2])
newRes[m[1]] = processValue(m[2]);
}
}
return newRes
} else return val
return newRes;
} else return val;
}
function processFoldedBlock(block) {
var lines = block.lines
var children = block.children
var str = lines.join(' ')
var chunks = [str]
var lines = block.lines;
var children = block.children;
var str = lines.join(' ');
var chunks = [str];
for (var i = 0, len = children.length; i < len; ++i) {
chunks.push(processFoldedBlock(children[i]))
chunks.push(processFoldedBlock(children[i]));
}
return chunks.join('\n')
return chunks.join('\n');
}
function processLiteralBlock(block) {
var lines = block.lines
var children = block.children
var str = lines.join('\n')
var lines = block.lines;
var children = block.children;
var str = lines.join('\n');
for (var i = 0, len = children.length; i < len; ++i) {
str += processLiteralBlock(children[i])
str += processLiteralBlock(children[i]);
}
return str
return str;
}
function processBlock(blocks) {
var m = null
var res = {}
var lines = null
var children = null
var currentObj = null
var m = null;
var res = {};
var lines = null;
var children = null;
var currentObj = null;
var level = -1
var level = -1;
var processedBlocks = []
var processedBlocks = [];
var isMap = true
var isMap = true;
for (var j = 0, lenJ = blocks.length; j < lenJ; ++j) {
if (level != -1 && level != blocks[j].level) continue
if (level != -1 && level != blocks[j].level) continue;
processedBlocks.push(j)
processedBlocks.push(j);
level = blocks[j].level
lines = blocks[j].lines
children = blocks[j].children
currentObj = null
level = blocks[j].level;
lines = blocks[j].lines;
children = blocks[j].children;
currentObj = null;
for (var i = 0, len = lines.length; i < len; ++i) {
var line = lines[i]
var line = lines[i];
if ((m = line.match(regex['key']))) {
var key = m[1]
var key = m[1];
if (key[0] == '-') {
key = key.replace(regex['item'], '')
key = key.replace(regex['item'], '');
if (isMap) {
isMap = false
isMap = false;
if (typeof res.length === 'undefined') {
res = []
res = [];
}
}
if (currentObj != null) res.push(currentObj)
currentObj = {}
isMap = true
if (currentObj != null) res.push(currentObj);
currentObj = {};
isMap = true;
}
if (typeof m[2] != 'undefined') {
var value = m[2].replace(regex['trim'], '')
var value = m[2].replace(regex['trim'], '');
if (value[0] == '&') {
var nb = processBlock(children)
if (currentObj != null) currentObj[key] = nb
else res[key] = nb
reference_blocks[value.substr(1)] = nb
var nb = processBlock(children);
if (currentObj != null) currentObj[key] = nb;
else res[key] = nb;
reference_blocks[value.substr(1)] = nb;
} else if (value[0] == '|') {
if (currentObj != null)
currentObj[key] = processLiteralBlock(children.shift())
else res[key] = processLiteralBlock(children.shift())
currentObj[key] = processLiteralBlock(children.shift());
else res[key] = processLiteralBlock(children.shift());
} else if (value[0] == '*') {
var v = value.substr(1)
var no = {}
var v = value.substr(1);
var no = {};
if (typeof reference_blocks[v] == 'undefined') {
errors.push("Reference '" + v + "' not found!")
errors.push("Reference '" + v + "' not found!");
} else {
for (var k in reference_blocks[v]) {
no[k] = reference_blocks[v][k]
no[k] = reference_blocks[v][k];
}
if (currentObj != null) currentObj[key] = no
else res[key] = no
if (currentObj != null) currentObj[key] = no;
else res[key] = no;
}
} else if (value[0] == '>') {
if (currentObj != null)
currentObj[key] = processFoldedBlock(children.shift())
else res[key] = processFoldedBlock(children.shift())
currentObj[key] = processFoldedBlock(children.shift());
else res[key] = processFoldedBlock(children.shift());
} else {
if (currentObj != null) currentObj[key] = processValue(value)
else res[key] = processValue(value)
if (currentObj != null) currentObj[key] = processValue(value);
else res[key] = processValue(value);
}
} else {
if (currentObj != null) currentObj[key] = processBlock(children)
else res[key] = processBlock(children)
if (currentObj != null) currentObj[key] = processBlock(children);
else res[key] = processBlock(children);
}
} else if (line.match(/^-\s*$/)) {
if (isMap) {
isMap = false
isMap = false;
if (typeof res.length === 'undefined') {
res = []
res = [];
}
}
if (currentObj != null) res.push(currentObj)
currentObj = {}
isMap = true
continue
if (currentObj != null) res.push(currentObj);
currentObj = {};
isMap = true;
continue;
} else if ((m = line.match(/^-\s*(.*)/))) {
if (currentObj != null) currentObj.push(processValue(m[1]))
if (currentObj != null) currentObj.push(processValue(m[1]));
else {
if (isMap) {
isMap = false
isMap = false;
if (typeof res.length === 'undefined') {
res = []
res = [];
}
}
res.push(processValue(m[1]))
res.push(processValue(m[1]));
}
continue
continue;
}
}
if (currentObj != null) {
if (isMap) {
isMap = false
isMap = false;
if (typeof res.length === 'undefined') {
res = []
res = [];
}
}
res.push(currentObj)
res.push(currentObj);
}
}
for (var j = processedBlocks.length - 1; j >= 0; --j) {
blocks.splice.call(blocks, processedBlocks[j], 1)
blocks.splice.call(blocks, processedBlocks[j], 1);
}
return res
return res;
}
function semanticAnalysis(blocks) {
var res = processBlock(blocks.children)
return res
var res = processBlock(blocks.children);
return res;
}
function preProcess(src) {
var m
var lines = src.split('\n')
var m;
var lines = src.split('\n');
var r = regex['comment']
var r = regex['comment'];
for (var i in lines) {
if ((m = lines[i].match(r))) {
@ -443,24 +445,24 @@ function preProcess(src) {
lines[i] = "";
*/
if (typeof m[3] !== 'undefined') {
lines[i] = m[0].substr(0, m[0].length - m[3].length)
lines[i] = m[0].substr(0, m[0].length - m[3].length);
}
}
}
return lines.join('\n')
return lines.join('\n');
}
function load(str) {
errors = []
reference_blocks = []
processing_time = new Date().getTime()
var pre = preProcess(str)
var doc = parser(pre)
var res = semanticAnalysis(doc)
processing_time = new Date().getTime() - processing_time
errors = [];
reference_blocks = [];
processing_time = new Date().getTime();
var pre = preProcess(str);
var doc = parser(pre);
var res = semanticAnalysis(doc);
processing_time = new Date().getTime() - processing_time;
return res
return res;
}
export default load
export default load;

View File

@ -11,7 +11,7 @@ function init(id) {
appendScript();
window.ga =
window.ga ||
function() {
function () {
(window.ga.q = window.ga.q || []).push(arguments);
};
@ -28,7 +28,7 @@ function collect() {
window.ga('send', 'pageview');
}
const install = function(hook) {
const install = function (hook) {
if (!$docsify.ga) {
console.error('[Docsify] ga is required.');
return;

View File

@ -9,7 +9,7 @@ function init(options) {
window._paq = window._paq || [];
window._paq.push(['trackPageView']);
window._paq.push(['enableLinkTracking']);
setTimeout(function() {
setTimeout(function () {
appendScript(options);
window._paq.push(['setTrackerUrl', options.host + '/matomo.php']);
window._paq.push(['setSiteId', String(options.id)]);
@ -26,7 +26,7 @@ function collect() {
window._paq.push(['trackPageView']);
}
const install = function(hook) {
const install = function (hook) {
if (!$docsify.matomo) {
// eslint-disable-next-line no-console
console.error('[Docsify] matomo is required.');

View File

@ -13,7 +13,7 @@ const CONFIG = {
pathNamespaces: undefined,
};
const install = function(hook, vm) {
const install = function (hook, vm) {
const { util } = Docsify;
const opts = vm.config.search || CONFIG;

View File

@ -58,7 +58,7 @@ function getTableData(token) {
if (!token.text && token.type === 'table') {
token.cells.unshift(token.header);
token.text = token.cells
.map(function(rows) {
.map(function (rows) {
return rows.join(' | ');
})
.join(' |\n ');

View File

@ -1,12 +0,0 @@
const jestConfig = require('../jest.config.js');
module.exports = {
env: {
'jest/globals': true,
},
extends: ['plugin:jest/recommended', 'plugin:jest/style'],
globals: {
...jestConfig.globals,
},
plugins: ['jest'],
};

View File

@ -1,4 +1,4 @@
/* global browserName page */
/* global browserName page jestPlaywright */
const { configureToMatchImageSnapshot } = require('jest-image-snapshot');
// Lifecycle Hooks
@ -41,7 +41,7 @@ beforeAll(async () => {
});
beforeEach(async () => {
await global.jestPlaywright.resetPage();
await jestPlaywright.resetPage();
// Goto URL ()
// https://playwright.dev/#path=docs%2Fapi.md&q=pagegotourl-options

View File

@ -28,14 +28,14 @@ beforeEach(async () => {
'google_tag_data',
'marked',
'Prism',
].forEach(prop => {
if (global[prop]) {
delete global[prop];
].forEach((prop) => {
if (globalThis[prop]) {
delete globalThis[prop];
}
});
// Remove attributes
[...rootElm.attributes].forEach(attr => rootElm.removeAttribute(attr.name));
[...rootElm.attributes].forEach((attr) => rootElm.removeAttribute(attr.name));
// Restore base elements
rootElm.innerHTML = '<html><head></head><body></body></html>';

View File

@ -0,0 +1,9 @@
// This has to be a CommonJS file because Jest currently imports it using
// `require()` instead of `import` (to be continued)...
module.exports = async () => {
// ...(continued) but we can use import in here to transition back into ESM land.
const server = (await import('./server')).default;
await server.startAsync();
};

View File

@ -1,5 +0,0 @@
const server = require('./server.js');
module.exports = async () => {
await server.startAsync();
};

View File

@ -0,0 +1,4 @@
module.exports = async () => {
const server = (await import('./server')).default;
server.stop();
};

View File

@ -1,5 +0,0 @@
const server = require('./server.js');
module.exports = async () => {
server.stop();
};

View File

@ -1,7 +1,10 @@
const browserSync = require('browser-sync').create();
const path = require('path');
import path from 'path';
import browserSyncModule from 'browser-sync';
import esMain from 'es-main';
const browserSync = browserSyncModule.create();
const hasStartArg = process.argv.includes('--start');
const dirname = path.dirname(import.meta.url.replace('file://', ''));
const serverConfig = {
host: '127.0.0.1',
@ -14,7 +17,7 @@ function startServer(options = {}, cb = Function.prototype) {
middleware: [
{
route: '/_blank.html',
handle: function(req, res, next) {
handle: function (req, res, next) {
res.setHeader('Content-Type', 'text/html');
res.end('');
next();
@ -31,18 +34,18 @@ function startServer(options = {}, cb = Function.prototype) {
},
],
server: {
baseDir: path.resolve(__dirname, '../'),
baseDir: path.resolve(dirname, '../'),
routes: {
'/docs': path.resolve(__dirname, '../../docs'),
'/docs': path.resolve(dirname, '../../docs'),
'/docs/changelog.md': './CHANGELOG.md',
'/lib': path.resolve(__dirname, '../../lib'),
'/node_modules': path.resolve(__dirname, '../../node_modules'),
'/lib': path.resolve(dirname, '../../lib'),
'/node_modules': path.resolve(dirname, '../../node_modules'),
},
},
snippetOptions: {
rule: {
match: /<\/body>/i,
fn: function(snippet, match) {
fn: function (snippet, match) {
// Override changelog alias to load local changelog (see routes)
const injectJS = `
<script>
@ -77,7 +80,7 @@ function startServer(options = {}, cb = Function.prototype) {
}
async function startServerAsync() {
await new Promise((resolve, reject) => {
await new Promise((resolve) => {
startServer({}, () => {
console.log('\n');
resolve();
@ -89,6 +92,8 @@ function stopServer() {
browserSync.exit();
}
const isTopLevelModule = esMain(import.meta);
// Allow starting the test server from the CLI. Useful for viewing test content
// like fixtures (/index.html)) and local docs site (/docs) used for testing.
if (hasStartArg) {
@ -99,11 +104,11 @@ if (hasStartArg) {
});
}
// Display friendly message about manually starting a server instance
else if (require.main === module) {
console.info('Use --start argument to manually start server instance');
else if (isTopLevelModule) {
console.info('Use the --start argument to manually start server instance');
}
module.exports = {
export default {
globals: {
get BLANK_URL() {
return `${this.TEST_HOST}/_blank.html`;

View File

@ -1,3 +0,0 @@
module.exports = {
extends: ['plugin:jest-playwright/recommended'],
};

View File

@ -1,10 +1,8 @@
// Modules, constants, and variables
// -----------------------------------------------------------------------------
const docsifyInit = require('../helpers/docsify-init');
import docsifyInit from '../helpers/docsify-init';
// Suite
// -----------------------------------------------------------------------------
describe(`Example Tests`, function() {
describe(`Example Tests`, function () {
// Tests
// ---------------------------------------------------------------------------
test('dom manipulation', async () => {
@ -17,7 +15,7 @@ describe(`Example Tests`, function() {
// Add class to <body> element and test
// https://playwright.dev/#path=docs%2Fapi.md&q=pageevalselector-pagefunction-arg
await page.$eval('body', elm => elm.classList.add('foo'));
await page.$eval('body', (elm) => elm.classList.add('foo'));
expect(await page.getAttribute('body', 'class')).toEqual('foo');
// Test using helper methods from expect-playright (via jest-playwright)
@ -58,7 +56,7 @@ describe(`Example Tests`, function() {
// Get result of script executed in browser context
// https://playwright.dev/#path=docs%2Fapi.md&q=pageevaluatepagefunction-arg
const scriptResult = await page.evaluate(
numbers => {
(numbers) => {
const result = numbers.reduce(
(accumulator, currentValue) => accumulator + currentValue
);
@ -106,7 +104,7 @@ describe(`Example Tests`, function() {
// Add docsify target element
// https://playwright.dev/#path=docs%2Fapi.md&q=pageevalselector-pagefunction-arg
await page.$eval('body', elm => {
await page.$eval('body', (elm) => {
elm.innerHTML = '<div id="app"></div>';
});
@ -240,9 +238,9 @@ describe(`Example Tests`, function() {
// Verify docsifyInitConfig.script was added to the DOM
expect(
await page.evaluate(scriptText => {
await page.evaluate((scriptText) => {
return [...document.querySelectorAll('script')].some(
elm => elm.textContent.replace(/\s+/g, '') === scriptText
(elm) => elm.textContent.replace(/\s+/g, '') === scriptText
);
}, docsifyInitConfig.script.replace(/\s+/g, ''))
).toBe(true);
@ -262,9 +260,9 @@ describe(`Example Tests`, function() {
// Verify docsifyInitConfig.style was added to the DOM
expect(
await page.evaluate(styleText => {
await page.evaluate((styleText) => {
return [...document.querySelectorAll('style')].some(
elm => elm.textContent.replace(/\s+/g, '') === styleText
(elm) => elm.textContent.replace(/\s+/g, '') === styleText
);
}, docsifyInitConfig.style.replace(/\s+/g, ''))
).toBe(true);

View File

@ -1,8 +1,8 @@
const docsifyInit = require('../helpers/docsify-init');
import docsifyInit from '../helpers/docsify-init';
// Suite
// -----------------------------------------------------------------------------
describe('Search Plugin Tests', function() {
describe('Search Plugin Tests', function () {
// Tests
// ---------------------------------------------------------------------------
test('search readme', async () => {

View File

@ -1,6 +1,6 @@
const docsifyInit = require('../helpers/docsify-init');
import docsifyInit from '../helpers/docsify-init';
describe('Vue.js Rendering', function() {
describe('Vue.js Rendering', function () {
const vueURLs = [
`${NODE_MODULES_URL}/vue2/dist/vue.js`,
`${NODE_MODULES_URL}/vue3/dist/vue.global.js`,
@ -23,7 +23,7 @@ describe('Vue.js Rendering', function() {
await expect(page).toEqualText('#test', 'test{{ i }}');
});
describe('Basic rendering', function() {
describe('Basic rendering', function () {
for (const vueURL of vueURLs) {
const vueVersion = vueURL.match(/vue(\d+)/)[1]; // vue2|vue3
@ -52,7 +52,7 @@ describe('Vue.js Rendering', function() {
}
});
describe('Advanced usage', function() {
describe('Advanced usage', function () {
const testData = {
vue2: {
markdown: `

View File

@ -1,15 +1,14 @@
/* global jestPlaywright page */
import axios from 'axios';
import * as prettier from 'prettier';
import stripIndent from 'common-tags/lib/stripIndent';
import mock, { proxy } from 'xhr-mock';
import { waitForSelector } from './wait-for';
const axios = require('axios');
const prettier = require('prettier');
const stripIndent = require('common-tags/lib/stripIndent');
const docsifyPATH = `${LIB_PATH}/docsify.js`; // JSDOM
const docsifyURL = `${LIB_URL}/docsify.js`; // Playwright
const isJSDOM = 'window' in global;
const isPlaywright = 'page' in global;
const isJSDOM = 'window' in globalThis;
const isPlaywright = 'page' in globalThis;
/**
* Jest / Playwright helper for creating custom docsify test sites
@ -79,7 +78,7 @@ async function docsifyInit(options = {}) {
// Config as function
if (typeof options.config === 'function') {
return function(vm) {
return function (vm) {
return { ...sharedConfig, ...options.config(vm) };
};
}
@ -127,12 +126,12 @@ async function docsifyInit(options = {}) {
// Merge scripts and remove duplicates
scriptURLs: []
.concat(options.scriptURLs || '')
.filter(url => url)
.map(url => new URL(url, TEST_HOST).href),
.filter((url) => url)
.map((url) => new URL(url, TEST_HOST).href),
styleURLs: []
.concat(options.styleURLs || '')
.filter(url => url)
.map(url => new URL(url, TEST_HOST).href),
.filter((url) => url)
.map((url) => new URL(url, TEST_HOST).href),
};
// Routes
@ -175,7 +174,7 @@ async function docsifyInit(options = {}) {
.header('Content-Type', contentType);
});
} else {
await page.route(urlGlob, route => route.fulfill(response));
await page.route(urlGlob, (route) => route.fulfill(response));
}
}
@ -197,7 +196,7 @@ async function docsifyInit(options = {}) {
if (isJSDOM) {
window.$docsify = settings.config;
} else if (isPlaywright) {
await page.evaluate(config => {
await page.evaluate((config) => {
window.$docsify = config;
}, settings.config);
}
@ -213,7 +212,9 @@ async function docsifyInit(options = {}) {
document.head.appendChild(linkElm);
}
} else if (isPlaywright) {
await Promise.all(settings.styleURLs.map(url => page.addStyleTag({ url })));
await Promise.all(
settings.styleURLs.map((url) => page.addStyleTag({ url }))
);
}
// JavaScript URLs
@ -230,7 +231,8 @@ async function docsifyInit(options = {}) {
const isDocsifyLoaded = 'Docsify' in window;
if (!isDocsifyLoaded) {
require(docsifyPATH);
// require(docsifyPATH);
await import(docsifyPATH);
}
} else if (isPlaywright) {
for (const url of settings.scriptURLs) {
@ -253,7 +255,7 @@ async function docsifyInit(options = {}) {
styleElm.textContent = stripIndent`${settings.style}`;
headElm.appendChild(styleElm);
} else if (isPlaywright) {
await page.evaluate(data => {
await page.evaluate((data) => {
const headElm = document.querySelector('head');
const styleElm = document.createElement('style');
@ -310,4 +312,4 @@ async function docsifyInit(options = {}) {
return Promise.resolve();
}
module.exports = docsifyInit;
export default docsifyInit;

View File

@ -95,7 +95,7 @@ export function waitForText(cssSelector, text, options = {}) {
return new Promise((resolve, reject) => {
waitForSelector(cssSelector, settings)
.then(elm => {
.then((elm) => {
const isMatch = elm.textContent.includes(text);
if (isMatch) {

View File

@ -1,10 +1,13 @@
const fs = require('fs').promises;
const path = require('path');
const docsifyInit = require('../helpers/docsify-init');
import _fs from 'fs';
import path from 'path';
import { jest } from '@jest/globals';
import docsifyInit from '../helpers/docsify-init';
const fs = _fs.promises;
// Suite
// -----------------------------------------------------------------------------
describe('Docs Site', function() {
describe('Docs Site', function () {
// Tests
// ---------------------------------------------------------------------------
test('coverpage renders and is unchanged', async () => {

View File

@ -1,12 +1,13 @@
const docsifyInit = require('../helpers/docsify-init');
import { jest } from '@jest/globals';
import docsifyInit from '../helpers/docsify-init';
// Suite
// -----------------------------------------------------------------------------
describe('Docsify', function() {
describe('Docsify', function () {
// Tests
// ---------------------------------------------------------------------------
test('allows $docsify configuration to be a function', async () => {
const testConfig = jest.fn(vm => {
const testConfig = jest.fn((vm) => {
expect(vm).toBeInstanceOf(Object);
expect(vm.constructor.name).toEqual('Docsify');
expect(vm.$fetch).toBeInstanceOf(Function);
@ -23,12 +24,12 @@ describe('Docsify', function() {
});
test('provides the hooks and vm API to plugins', async () => {
const testConfig = jest.fn(vm => {
const testConfig = jest.fn((vm) => {
const vm1 = vm;
return {
plugins: [
function(hook, vm2) {
function (hook, vm2) {
expect(vm1).toEqual(vm2);
expect(hook.init).toBeInstanceOf(Function);

View File

@ -1,10 +1,9 @@
import { waitForFunction, waitForText } from '../helpers/wait-for';
const docsifyInit = require('../helpers/docsify-init');
import docsifyInit from '../helpers/docsify-init';
// Suite
// -----------------------------------------------------------------------------
describe('Example Tests', function() {
describe('Example Tests', function () {
// Tests
// ---------------------------------------------------------------------------
test('Docsify /docs/ site using docsifyInit()', async () => {
@ -114,7 +113,7 @@ describe('Example Tests', function() {
// Verify docsifyInitConfig.script was added to the DOM
expect(
[...document.querySelectorAll('script')].some(
elm =>
(elm) =>
elm.textContent.replace(/\s+/g, '') ===
docsifyInitConfig.script.replace(/\s+/g, '')
)
@ -134,7 +133,7 @@ describe('Example Tests', function() {
// Verify docsifyInitConfig.style was added to the DOM
expect(
[...document.querySelectorAll('style')].some(
elm =>
(elm) =>
elm.textContent.replace(/\s+/g, '') ===
docsifyInitConfig.style.replace(/\s+/g, '')
)

View File

@ -1,8 +1,8 @@
import initGlobalAPI from '../../src/core/global-api.js';
import initGlobalAPI from '../../src/core/global-api';
// Suite
// -----------------------------------------------------------------------------
describe('Global APIs', function() {
describe('Global APIs', function () {
// Tests
// ---------------------------------------------------------------------------
test('APIs are available', () => {

View File

@ -1,9 +1,9 @@
const stripIndent = require('common-tags/lib/stripIndent');
const docsifyInit = require('../helpers/docsify-init');
import stripIndent from 'common-tags/lib/stripIndent';
import docsifyInit from '../helpers/docsify-init';
// Suite
// -----------------------------------------------------------------------------
describe('render', function() {
describe('render', function () {
// Setup & Teardown
// -------------------------------------------------------------------------
beforeEach(async () => {
@ -32,8 +32,8 @@ describe('render', function() {
// Lists
// ---------------------------------------------------------------------------
describe('lists', function() {
test('as unordered task list', async function() {
describe('lists', function () {
test('as unordered task list', async function () {
const output = window.marked(stripIndent`
- [x] Task 1
- [ ] Task 2
@ -45,7 +45,7 @@ describe('render', function() {
);
});
test('as ordered task list', async function() {
test('as ordered task list', async function () {
const output = window.marked(stripIndent`
1. [ ] Task 1
2. [x] Task 2
@ -56,7 +56,7 @@ describe('render', function() {
);
});
test('normal unordered', async function() {
test('normal unordered', async function () {
const output = window.marked(stripIndent`
- [linktext](link)
- just text
@ -67,7 +67,7 @@ describe('render', function() {
);
});
test('unordered with custom start', async function() {
test('unordered with custom start', async function () {
const output = window.marked(stripIndent`
1. first
2. second
@ -82,7 +82,7 @@ describe('render', function() {
);
});
test('nested', async function() {
test('nested', async function () {
const output = window.marked(stripIndent`
- 1
- 2
@ -99,8 +99,8 @@ describe('render', function() {
// Images
// ---------------------------------------------------------------------------
describe('images', function() {
test('regular', async function() {
describe('images', function () {
test('regular', async function () {
const output = window.marked('![alt text](http://imageUrl)');
expect(output).toMatchInlineSnapshot(
@ -108,7 +108,7 @@ describe('render', function() {
);
});
test('class', async function() {
test('class', async function () {
const output = window.marked(
"![alt text](http://imageUrl ':class=someCssClass')"
);
@ -118,7 +118,7 @@ describe('render', function() {
);
});
test('id', async function() {
test('id', async function () {
const output = window.marked(
"![alt text](http://imageUrl ':id=someCssID')"
);
@ -128,7 +128,7 @@ describe('render', function() {
);
});
test('no-zoom', async function() {
test('no-zoom', async function () {
const output = window.marked("![alt text](http://imageUrl ':no-zoom')");
expect(output).toMatchInlineSnapshot(
@ -136,8 +136,8 @@ describe('render', function() {
);
});
describe('size', function() {
test('width and height', async function() {
describe('size', function () {
test('width and height', async function () {
const output = window.marked(
"![alt text](http://imageUrl ':size=WIDTHxHEIGHT')"
);
@ -147,7 +147,7 @@ describe('render', function() {
);
});
test('width', async function() {
test('width', async function () {
const output = window.marked("![alt text](http://imageUrl ':size=50')");
expect(output).toMatchInlineSnapshot(
@ -159,8 +159,8 @@ describe('render', function() {
// Headings
// ---------------------------------------------------------------------------
describe('headings', function() {
test('h1', async function() {
describe('headings', function () {
test('h1', async function () {
const output = window.marked('# h1 tag');
expect(output).toMatchInlineSnapshot(
@ -168,7 +168,7 @@ describe('render', function() {
);
});
test('h2', async function() {
test('h2', async function () {
const output = window.marked('## h2 tag');
expect(output).toMatchInlineSnapshot(
@ -176,7 +176,7 @@ describe('render', function() {
);
});
test('h3', async function() {
test('h3', async function () {
const output = window.marked('### h3 tag');
expect(output).toMatchInlineSnapshot(
@ -184,7 +184,7 @@ describe('render', function() {
);
});
test('h4', async function() {
test('h4', async function () {
const output = window.marked('#### h4 tag');
expect(output).toMatchInlineSnapshot(
@ -192,7 +192,7 @@ describe('render', function() {
);
});
test('h5', async function() {
test('h5', async function () {
const output = window.marked('##### h5 tag');
expect(output).toMatchInlineSnapshot(
@ -200,7 +200,7 @@ describe('render', function() {
);
});
test('h6', async function() {
test('h6', async function () {
const output = window.marked('###### h6 tag');
expect(output).toMatchInlineSnapshot(
@ -209,8 +209,8 @@ describe('render', function() {
});
});
describe('link', function() {
test('regular', async function() {
describe('link', function () {
test('regular', async function () {
const output = window.marked('[alt text](http://url)');
expect(output).toMatchInlineSnapshot(
@ -218,7 +218,7 @@ describe('render', function() {
);
});
test('linkrel', async function() {
test('linkrel', async function () {
// const { docsify } = await init('default', {
// externalLinkTarget: '_blank',
// externalLinkRel: 'noopener',
@ -230,7 +230,7 @@ describe('render', function() {
);
});
test('disabled', async function() {
test('disabled', async function () {
const output = window.marked("[alt text](http://url ':disabled')");
expect(output).toMatchInlineSnapshot(
@ -238,7 +238,7 @@ describe('render', function() {
);
});
test('target', async function() {
test('target', async function () {
const output = window.marked("[alt text](http://url ':target=_self')");
expect(output).toMatchInlineSnapshot(
@ -246,7 +246,7 @@ describe('render', function() {
);
});
test('class', async function() {
test('class', async function () {
const output = window.marked(
"[alt text](http://url ':class=someCssClass')"
);
@ -256,7 +256,7 @@ describe('render', function() {
);
});
test('id', async function() {
test('id', async function () {
const output = window.marked("[alt text](http://url ':id=someCssID')");
expect(output).toMatchInlineSnapshot(

View File

@ -1,13 +1,17 @@
import { greet } from './fixtures/greet.js';
import { getTimeOfDay } from './fixtures/get-time-of-day.js';
import * as getTimeOfDayModule from './fixtures/get-time-of-day.js';
import { jest } from '@jest/globals';
import { greet } from './fixtures/greet';
import { getTimeOfDay } from './fixtures/get-time-of-day';
import * as _getTimeOfDayModule from './fixtures/get-time-of-day';
// ES Modules are non-extensible objects, so clone this one into an extensible object.
const getTimeOfDayModule = { ..._getTimeOfDayModule };
// Suite
// -----------------------------------------------------------------------------
describe(`Example Tests`, function() {
describe(`Example Tests`, function () {
// Tests
// ---------------------------------------------------------------------------
describe('Jest & JSDOM basics', function() {
describe('Jest & JSDOM basics', function () {
test('dom manipulation (jsdom)', () => {
const testText = 'This is a test';
const testHTML = `<h1>Test</h1><p>${testText}</p>`;
@ -48,7 +52,7 @@ describe(`Example Tests`, function() {
});
});
describe('Fake Timers', function() {
describe('Fake Timers', function () {
test('data & time', () => {
const fakeDate = new Date().setHours(1);
@ -61,10 +65,14 @@ describe(`Example Tests`, function() {
});
});
describe('Mocks & Spys', function() {
test('mock import/require dependency using jest.fn()', () => {
const testModule = require('./fixtures/get-time-of-day.js');
const { greet: testGreet } = require('./fixtures/greet.js');
describe('Mocks & Spys', function () {
// It is not yet possible to mock/spy on ES Modules, but they're working on it (https://github.com/facebook/jest/issues/10025).
// For now, don't mock/spy on modules. The alternative is to mock/spy on objects exported from modules.
// {{{
test.skip('mock import/require dependency using jest.fn()', async () => {
const testModule = { ...(await import('./fixtures/get-time-of-day.js')) };
const { greet: testGreet } = await import('./fixtures/greet.js');
testModule.getTimeOfDay = jest.fn(() => 'day');
@ -75,7 +83,7 @@ describe(`Example Tests`, function() {
expect(greeting).toBe(`Good day, John!`);
});
test('mock import/require dependency using jest.doMock()', () => {
test.skip('mock import/require dependency using jest.doMock()', async () => {
const mockModulePath = './fixtures/get-time-of-day.js';
jest.doMock(mockModulePath, () => ({
@ -83,8 +91,8 @@ describe(`Example Tests`, function() {
getTimeOfDay: jest.fn(() => 'night'),
}));
const mockGetTimeOfDay = require(mockModulePath).getTimeOfDay;
const { greet: testGreet } = require('./fixtures/greet.js');
const mockGetTimeOfDay = (await import(mockModulePath)).getTimeOfDay;
const { greet: testGreet } = await import('./fixtures/greet.js');
const timeOfDay = mockGetTimeOfDay();
const greeting = testGreet('John');
@ -93,16 +101,7 @@ describe(`Example Tests`, function() {
expect(greeting).toBe(`Good night, John!`);
});
test('spy on native method using jest.spyOn()', () => {
// Replace Math.random() implementation to return fixed value
jest.spyOn(Math, 'random').mockImplementation(() => 0.1);
expect(Math.random()).toEqual(0.1);
expect(Math.random()).toEqual(0.1);
expect(Math.random()).toEqual(0.1);
});
test('spy on import/require dependency using jest.spyOn()', () => {
test.skip('spy on import/require dependency using jest.spyOn()', () => {
jest
.spyOn(getTimeOfDayModule, 'getTimeOfDay')
.mockImplementation(() => 'night');
@ -113,5 +112,16 @@ describe(`Example Tests`, function() {
expect(timeOfDay).toBe('night');
expect(greeting).toBe(`Good night, John!`);
});
// }}}
test('spy on native method using jest.spyOn()', () => {
// Replace Math.random() implementation to return fixed value
jest.spyOn(Math, 'random').mockImplementation(() => 0.1);
expect(Math.random()).toEqual(0.1);
expect(Math.random()).toEqual(0.1);
expect(Math.random()).toEqual(0.1);
});
});
});

View File

@ -1,4 +1,4 @@
const { removeAtag } = require(`${SRC_PATH}/core/render/utils`);
import { removeAtag } from '../../src/core/render/utils';
// Suite
// -----------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
const { History } = require(`${SRC_PATH}/core/router/history/base`);
import { History } from '../../src/core/router/history/base';
class MockHistory extends History {
parse(path) {

View File

@ -1,4 +1,4 @@
const { resolvePath } = require(`${SRC_PATH}/core/util`);
import { resolvePath } from '../../src/core/util';
// Suite
// -----------------------------------------------------------------------------

View File

@ -1,19 +1,36 @@
// @ts-check
// const { initJSDOM } = require('../_helper');
// const port = 9754;
// const docsifySite = 'http://127.0.0.1:' + port;
// initJSDOM();
import {
Renderer,
getServerHTMLTemplate,
} from '../../packages/docsify-server-renderer/index';
describe('pacakges/docsify-server-render', function() {
it('renders content', async function() {
describe('pacakges/docsify-server-render Renderer', function () {
it('renders content', async function () {
const renderer = new Renderer({
template: getServerHTMLTemplate(),
config: {
name: 'docsify',
repo: 'docsifyjs/docsify',
// basePath: 'https://docsify.js.org/',
loadNavbar: true,
loadSidebar: true,
subMaxLevel: 3,
auto2top: true,
},
});
expect(renderer).toBeInstanceOf(Renderer);
const result = await renderer.renderToString('/docs/ssr.md');
expect(typeof result).toBe('string');
expect(result.includes('<h1 id="server-side-rendering">')).toBe(true);
expect(result.includes('<span>Server-Side Rendering</span></a></h1>')).toBe(
true
);
});
it('renders aliases the same', async () => {
const renderer = new Renderer({
template: getServerHTMLTemplate(),
config: {
@ -27,14 +44,18 @@ describe('pacakges/docsify-server-render', function() {
alias: {
'/de-de/changelog': '/changelog',
'/zh-cn/changelog': '/changelog',
'/changelog':
'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG',
'/changelog': '/docs/changelog.md',
},
},
});
await renderer.renderToString('/changelog');
const [one, two, three] = await Promise.all([
await renderer.renderToString('/de-de/changelog'),
await renderer.renderToString('/zh-cn/changelog'),
await renderer.renderToString('/changelog'),
]);
expect(renderer).toBeInstanceOf(Renderer);
expect(one).toEqual(two);
expect(two).toEqual(three);
});
});