xhs-mp-compiler-cli 1.3.4 → 1.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/compiler.d.ts +15 -11
  2. package/dist/compiler.js +96 -40
  3. package/dist/compilerImpl.d.ts +1 -0
  4. package/dist/{compilerCP.js → compilerImpl.js} +29 -42
  5. package/dist/compilerImplChildProcess.js +33 -0
  6. package/dist/compilerImplThreadWorker.d.ts +1 -0
  7. package/dist/compilerImplThreadWorker.js +30 -0
  8. package/dist/compilerImplWebWorker.d.ts +6 -0
  9. package/dist/compilerImplWebWorker.js +25 -0
  10. package/dist/dev-server/compatibleAPI.d.ts +25 -0
  11. package/dist/dev-server/compatibleAPI.js +56 -0
  12. package/dist/dev-server/escapeHtml.d.ts +5 -0
  13. package/dist/dev-server/escapeHtml.js +50 -0
  14. package/dist/dev-server/etag.d.ts +10 -0
  15. package/dist/dev-server/etag.js +69 -0
  16. package/dist/dev-server/getFilenameFromUrl.d.ts +9 -0
  17. package/dist/dev-server/getFilenameFromUrl.js +102 -0
  18. package/dist/dev-server/getPaths.d.ts +6 -0
  19. package/dist/dev-server/getPaths.js +20 -0
  20. package/dist/dev-server/index.d.ts +98 -0
  21. package/dist/dev-server/index.js +90 -0
  22. package/dist/dev-server/memorize.d.ts +7 -0
  23. package/dist/dev-server/memorize.js +23 -0
  24. package/dist/dev-server/middleware.d.ts +2 -0
  25. package/dist/dev-server/middleware.js +477 -0
  26. package/dist/dev-server/ready.d.ts +4 -0
  27. package/dist/dev-server/ready.js +11 -0
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +5 -5
  30. package/dist/packs/mp-pack/index.js +0 -1
  31. package/dist/packs/webpack/dev-server/index.js +1 -0
  32. package/dist/packs/webpack/index.d.ts +1 -1
  33. package/dist/packs/webpack/index.js +3 -4
  34. package/dist/packs/webpack/webpack.d.ts +1 -1
  35. package/dist/packs/webpack/webpack.js +6 -2
  36. package/dist/presets/configs/miniprogram/render/index.d.ts +2 -3
  37. package/dist/presets/configs/miniprogram/render/index.js +2 -2
  38. package/dist/presets/configs/miniprogram/service/index.js +1 -0
  39. package/dist/sharedFs.d.ts +2 -0
  40. package/dist/sharedFs.js +4 -0
  41. package/dist/utils/workerPool.d.ts +29 -0
  42. package/dist/utils/workerPool.js +115 -0
  43. package/package.json +26 -12
  44. /package/dist/{compilerCP.d.ts → compilerImplChildProcess.d.ts} +0 -0
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const matchHtmlRegExp = /["'&<>]/;
4
+ /**
5
+ * Escapes a string for use in HTML.
6
+ */
7
+ function escapeHtml(string) {
8
+ const str = `${string}`;
9
+ const match = matchHtmlRegExp.exec(str);
10
+ if (!match) {
11
+ return str;
12
+ }
13
+ let escape;
14
+ let html = "";
15
+ let index = 0;
16
+ let lastIndex = 0;
17
+ for ({ index } = match; index < str.length; index++) {
18
+ switch (str.charCodeAt(index)) {
19
+ // "
20
+ case 34:
21
+ escape = "&quot;";
22
+ break;
23
+ // &
24
+ case 38:
25
+ escape = "&amp;";
26
+ break;
27
+ // '
28
+ case 39:
29
+ escape = "&#39;";
30
+ break;
31
+ // <
32
+ case 60:
33
+ escape = "&lt;";
34
+ break;
35
+ // >
36
+ case 62:
37
+ escape = "&gt;";
38
+ break;
39
+ default:
40
+ continue;
41
+ }
42
+ if (lastIndex !== index) {
43
+ html += str.substring(lastIndex, index);
44
+ }
45
+ lastIndex = index + 1;
46
+ html += escape;
47
+ }
48
+ return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
49
+ }
50
+ exports.default = escapeHtml;
@@ -0,0 +1,10 @@
1
+ /// <reference types="node/fs" />
2
+ import { Stats, ReadStream } from 'fs';
3
+ /**
4
+ * Create a simple ETag.
5
+ */
6
+ declare function etag(entity: Buffer | ReadStream | Stats): Promise<{
7
+ hash: string;
8
+ buffer?: Buffer;
9
+ }>;
10
+ export default etag;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const crypto_1 = require("crypto");
13
+ /**
14
+ * Generate a tag for a stat.
15
+ */
16
+ function statTag(stat) {
17
+ const mtime = stat.mtime.getTime().toString(16);
18
+ const size = stat.size.toString(16);
19
+ return { hash: `W/"${size}-${mtime}"` };
20
+ }
21
+ /**
22
+ * Generate an entity tag.
23
+ */
24
+ function entityTag(entity) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const sha1 = (0, crypto_1.createHash)('sha1');
27
+ if (!Buffer.isBuffer(entity)) {
28
+ let byteLength = 0;
29
+ const buffers = [];
30
+ yield new Promise((resolve, reject) => {
31
+ entity
32
+ .on('data', (chunk) => {
33
+ sha1.update(chunk);
34
+ buffers.push(chunk);
35
+ byteLength += chunk.byteLength;
36
+ })
37
+ .on('end', () => {
38
+ resolve(sha1);
39
+ })
40
+ .on('error', reject);
41
+ });
42
+ return {
43
+ buffer: Buffer.concat(buffers),
44
+ hash: `"${byteLength.toString(16)}-${sha1.digest('base64').substring(0, 27)}"`,
45
+ };
46
+ }
47
+ if (entity.byteLength === 0) {
48
+ // Fast-path empty
49
+ return { hash: '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"' };
50
+ }
51
+ // Compute hash of entity
52
+ const hash = sha1.update(entity).digest('base64').substring(0, 27);
53
+ // Compute length of entity
54
+ const { byteLength } = entity;
55
+ return { hash: `"${byteLength.toString(16)}-${hash}"` };
56
+ });
57
+ }
58
+ /**
59
+ * Create a simple ETag.
60
+ */
61
+ function etag(entity) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ const isStrong = Buffer.isBuffer(entity) || entity.pipe !== undefined;
64
+ return isStrong
65
+ ? entityTag(entity)
66
+ : statTag(entity);
67
+ });
68
+ }
69
+ exports.default = etag;
@@ -0,0 +1,9 @@
1
+ /// <reference types="node/fs" />
2
+ import { Stats } from 'fs';
3
+ import { FilledContext } from '.';
4
+ export interface Extra {
5
+ stats?: Stats;
6
+ errorCode?: number;
7
+ }
8
+ declare function getFilenameFromUrl(context: FilledContext, url: string, extra?: Extra): string | undefined;
9
+ export default getFilenameFromUrl;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const url_1 = require("url");
8
+ const querystring_1 = __importDefault(require("querystring"));
9
+ const fs_1 = require("fs");
10
+ const memorize_1 = __importDefault(require("./memorize"));
11
+ const getPaths_1 = __importDefault(require("./getPaths"));
12
+ // eslint-disable-next-line no-undefined
13
+ const memoizedParse = (0, memorize_1.default)(url_1.parse, undefined, (value) => {
14
+ if (value.pathname) {
15
+ // eslint-disable-next-line no-param-reassign
16
+ value.pathname = decode(value.pathname);
17
+ }
18
+ return value;
19
+ });
20
+ const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
21
+ /**
22
+ * decodeURIComponent.
23
+ *
24
+ * Allows V8 to only deoptimize this fn instead of all of send().
25
+ */
26
+ function decode(input) {
27
+ return querystring_1.default.unescape(input);
28
+ }
29
+ // TODO refactor me in the next major release, this function should return `{ filename, stats, error }`
30
+ // TODO fix redirect logic when `/` at the end, like https://github.com/pillarjs/send/blob/master/index.js#L586
31
+ function getFilenameFromUrl(context, url, extra = {}) {
32
+ const { options } = context;
33
+ const paths = (0, getPaths_1.default)(context);
34
+ let foundFilename;
35
+ let urlObject;
36
+ try {
37
+ // The `url` property of the `request` is contains only `pathname`, `search` and `hash`
38
+ urlObject = memoizedParse(url, false, true);
39
+ }
40
+ catch (_ignoreError) {
41
+ return;
42
+ }
43
+ for (const { publicPath, outputPath } of paths) {
44
+ let filename;
45
+ let publicPathObject;
46
+ try {
47
+ publicPathObject = memoizedParse(publicPath !== "auto" && publicPath ? publicPath : "/", false, true);
48
+ }
49
+ catch (_ignoreError) {
50
+ continue;
51
+ }
52
+ const { pathname } = urlObject;
53
+ const { pathname: publicPathPathname } = publicPathObject;
54
+ if (pathname && pathname.startsWith(publicPathPathname)) {
55
+ // Null byte(s)
56
+ if (pathname.includes("\0")) {
57
+ extra.errorCode = 400;
58
+ return;
59
+ }
60
+ // ".." is malicious
61
+ if (UP_PATH_REGEXP.test(path_1.default.normalize(`./${pathname}`))) {
62
+ extra.errorCode = 403;
63
+ return;
64
+ }
65
+ // Strip the `pathname` property from the `publicPath` option from the start of requested url
66
+ // `/complex/foo.js` => `foo.js`
67
+ // and add outputPath
68
+ // `foo.js` => `/home/user/my-project/dist/foo.js`
69
+ filename = path_1.default.join(outputPath, pathname.slice(publicPathPathname.length));
70
+ try {
71
+ extra.stats = (0, fs_1.statSync)(filename);
72
+ }
73
+ catch (_ignoreError) {
74
+ continue;
75
+ }
76
+ if (extra.stats.isFile()) {
77
+ foundFilename = filename;
78
+ break;
79
+ }
80
+ else if (extra.stats.isDirectory() &&
81
+ (typeof options.index === "undefined" || options.index)) {
82
+ const indexValue = typeof options.index === "undefined" ||
83
+ typeof options.index === "boolean"
84
+ ? "index.html"
85
+ : options.index;
86
+ filename = path_1.default.join(filename, indexValue);
87
+ try {
88
+ extra.stats = (0, fs_1.statSync)(filename);
89
+ }
90
+ catch (__ignoreError) {
91
+ continue;
92
+ }
93
+ if (extra.stats.isFile()) {
94
+ foundFilename = filename;
95
+ break;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ return foundFilename;
101
+ }
102
+ exports.default = getFilenameFromUrl;
@@ -0,0 +1,6 @@
1
+ import { FilledContext } from ".";
2
+ declare function getPaths(context: FilledContext): {
3
+ outputPath: string;
4
+ publicPath: string;
5
+ }[];
6
+ export = getPaths;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ function getPaths(context) {
3
+ const { stats, options } = context;
4
+ const childStats = stats.stats
5
+ ? stats.stats
6
+ : [stats];
7
+ const publicPaths = [];
8
+ for (const { compilation } of childStats) {
9
+ // The `output.path` is always present and always absolute
10
+ const outputPath = compilation.getPath(compilation.outputOptions.path || "");
11
+ const publicPath = options.publicPath
12
+ ? compilation.getPath(options.publicPath)
13
+ : compilation.outputOptions.publicPath
14
+ ? compilation.getPath(compilation.outputOptions.publicPath)
15
+ : "";
16
+ publicPaths.push({ outputPath, publicPath });
17
+ }
18
+ return publicPaths;
19
+ }
20
+ module.exports = getPaths;
@@ -0,0 +1,98 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node/http" />
3
+ /// <reference types="node/fs" />
4
+ import { MultiCompiler, Compiler, MultiStats, Stats } from 'xhs-mp-pack';
5
+ import { IncomingMessage, ServerResponse as NodeServerResponse } from "http";
6
+ import { ReadStream } from "fs";
7
+ import type { ExpectedResponse } from "./compatibleAPI";
8
+ import { Extra } from "./getFilenameFromUrl";
9
+ import { AbstractCompiler } from "../compiler";
10
+ export type ExtendedServerResponse = NodeServerResponse & {
11
+ locals?: {
12
+ mppack?: {
13
+ devMiddleware?: Context;
14
+ };
15
+ };
16
+ };
17
+ export type Response = ExtendedServerResponse & ExpectedResponse;
18
+ export type NextFunction = (err?: any) => void;
19
+ export type WatchOptions = NonNullable<any>;
20
+ export type Watching = Compiler["watching"];
21
+ export type MultiWatching = ReturnType<MultiCompiler["watch"]>;
22
+ export type OutputFileSystem = {
23
+ createReadStream?: typeof import("fs").createReadStream;
24
+ statSync?: typeof import("fs").statSync;
25
+ lstat?: typeof import("fs").lstat;
26
+ readFileSync?: typeof import("fs").readFileSync;
27
+ };
28
+ type Logger = ReturnType<Compiler["getInfrastructureLogger"]>;
29
+ interface ResponseData {
30
+ data: Buffer | ReadStream;
31
+ byteLength: number;
32
+ }
33
+ export { IncomingMessage };
34
+ type ModifyResponseData = (req: Request, res: Response, data: Buffer | ReadStream, byteLength: number) => ResponseData;
35
+ export interface Context {
36
+ state: boolean;
37
+ stats: Stats | MultiStats | undefined;
38
+ callbacks: Array<(stats?: Stats | MultiStats) => void>;
39
+ options: Options;
40
+ compiler: Compiler | MultiCompiler;
41
+ watching: Watching | MultiWatching | undefined;
42
+ logger: Logger;
43
+ outputFileSystem: OutputFileSystem;
44
+ }
45
+ export type FilledContext = Omit<Context, "watching"> & {
46
+ watching: Watching | MultiWatching;
47
+ };
48
+ type NormalizedHeaders = Record<string, string | number> | Array<{
49
+ key: string;
50
+ value: number | string;
51
+ }>;
52
+ type Headers = NormalizedHeaders | ((req: Request, res: Response, context: Context) => void | undefined | NormalizedHeaders) | undefined;
53
+ interface Options {
54
+ mimeTypes?: {
55
+ [key: string]: string;
56
+ };
57
+ mimeTypeDefault?: string;
58
+ writeToDisk?: boolean | ((targetPath: string) => boolean);
59
+ methods?: string[];
60
+ headers?: Headers;
61
+ publicPath?: NonNullable<any>["publicPath"];
62
+ stats?: Stats;
63
+ serverSideRender?: boolean;
64
+ outputFileSystem?: OutputFileSystem;
65
+ index?: boolean | string;
66
+ modifyResponseData?: ModifyResponseData;
67
+ etag?: "weak" | "strong";
68
+ lastModified?: boolean;
69
+ }
70
+ type Middleware = (req: Request, res: Response, next: NextFunction) => Promise<void>;
71
+ type GetFilenameFromUrl = (url: string, extra?: Extra) => string | undefined;
72
+ type WaitUntilValid = (callback: (stats?: Stats | MultiStats) => void) => void;
73
+ type Invalidate = (callback: (stats?: Stats | MultiStats) => void) => void;
74
+ type Close = (callback: (err: Error | null | undefined) => void) => void;
75
+ interface AdditionalMethods {
76
+ getFilenameFromUrl: GetFilenameFromUrl;
77
+ waitUntilValid: WaitUntilValid;
78
+ invalidate: Invalidate;
79
+ close: Close;
80
+ context: Context;
81
+ }
82
+ type API = Middleware & AdditionalMethods;
83
+ declare function MPPackMiddleware(compiler: AbstractCompiler, options?: Options): API;
84
+ declare namespace MPPackMiddleware {
85
+ var koaWrapper: (compiler: AbstractCompiler, options?: Options | undefined) => {
86
+ (ctx: {
87
+ req: Request;
88
+ res: Response;
89
+ status: number;
90
+ body: Buffer | ReadStream | {
91
+ message: string;
92
+ };
93
+ state: Object;
94
+ }, next: Function): Promise<unknown>;
95
+ devMiddleware: API;
96
+ };
97
+ }
98
+ export default MPPackMiddleware;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.IncomingMessage = void 0;
16
+ const mime_types_1 = __importDefault(require("mime-types"));
17
+ const middleware_1 = __importDefault(require("./middleware"));
18
+ const getFilenameFromUrl_1 = __importDefault(require("./getFilenameFromUrl"));
19
+ const ready_1 = __importDefault(require("./ready"));
20
+ const http_1 = require("http");
21
+ Object.defineProperty(exports, "IncomingMessage", { enumerable: true, get: function () { return http_1.IncomingMessage; } });
22
+ function MPPackMiddleware(compiler, options = {}) {
23
+ const { mimeTypes } = options;
24
+ if (mimeTypes) {
25
+ const { types } = mime_types_1.default;
26
+ mime_types_1.default.types = Object.assign(Object.assign({}, types), mimeTypes);
27
+ }
28
+ const context = {
29
+ state: false,
30
+ stats: undefined,
31
+ callbacks: [],
32
+ options,
33
+ compiler,
34
+ logger: console,
35
+ };
36
+ const filledContext = context;
37
+ const instance = (0, middleware_1.default)(filledContext);
38
+ instance.getFilenameFromUrl = (url, extra) => (0, getFilenameFromUrl_1.default)(filledContext, url, extra);
39
+ instance.waitUntilValid = (callback = () => { }) => {
40
+ (0, ready_1.default)(filledContext, callback);
41
+ };
42
+ instance.invalidate = (callback = () => { }) => {
43
+ (0, ready_1.default)(filledContext, callback);
44
+ filledContext.watching.invalidate();
45
+ };
46
+ instance.close = (callback = () => { }) => {
47
+ filledContext.watching.close(callback);
48
+ };
49
+ instance.context = filledContext;
50
+ return instance;
51
+ }
52
+ function koaWrapper(compiler, options) {
53
+ const devMiddleware = MPPackMiddleware(compiler, options);
54
+ const wrapper = function mppackDevMiddleware(ctx, next) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ return new Promise((resolve, reject) => {
57
+ const { req } = ctx;
58
+ const { res } = ctx;
59
+ res.locals = ctx.state;
60
+ res.status = (status) => {
61
+ ctx.status = status;
62
+ };
63
+ res.pipeInto = (stream) => {
64
+ ctx.body = stream;
65
+ resolve(null);
66
+ };
67
+ res.send = (content) => {
68
+ ctx.body = content;
69
+ resolve(null);
70
+ };
71
+ devMiddleware(req, res, (err) => {
72
+ if (err) {
73
+ reject(err);
74
+ return;
75
+ }
76
+ resolve(next());
77
+ }).catch((err) => {
78
+ ctx.status = err.statusCode || err.status || 500;
79
+ ctx.body = {
80
+ message: err.message,
81
+ };
82
+ });
83
+ });
84
+ });
85
+ };
86
+ wrapper.devMiddleware = devMiddleware;
87
+ return wrapper;
88
+ }
89
+ MPPackMiddleware.koaWrapper = koaWrapper;
90
+ exports.default = MPPackMiddleware;
@@ -0,0 +1,7 @@
1
+ type Callback<T> = (value: T) => T;
2
+ declare function memorize<T>(fn: Function, { cache }?: {
3
+ cache?: Map<string, {
4
+ data: T;
5
+ }>;
6
+ }, callback?: Callback<T>): (...args: any[]) => any;
7
+ export = memorize;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ const cacheStore = new WeakMap();
3
+ function memorize(fn, { cache = new Map() } = {}, callback) {
4
+ const memoized = (...arguments_) => {
5
+ const [key] = arguments_;
6
+ const cacheItem = cache.get(key);
7
+ if (cacheItem) {
8
+ return cacheItem.data;
9
+ }
10
+ // @ts-ignore
11
+ let result = fn.apply(this, arguments_);
12
+ if (callback) {
13
+ result = callback(result);
14
+ }
15
+ cache.set(key, {
16
+ data: result,
17
+ });
18
+ return result;
19
+ };
20
+ cacheStore.set(memoized, cache);
21
+ return memoized;
22
+ }
23
+ module.exports = memorize;
@@ -0,0 +1,2 @@
1
+ declare function wrapper(context: any): (req: any, res: any, next: any) => Promise<void>;
2
+ export default wrapper;