@neuxnet/neux-cli 0.2.3

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 (73) hide show
  1. package/README.md +438 -0
  2. package/README.zh-CN.md +554 -0
  3. package/assets/container/assets/index.css +1 -0
  4. package/assets/container/assets/index.js +137 -0
  5. package/assets/container/assets/pageFrame.css +1 -0
  6. package/assets/container/assets/pageFrame.js +56 -0
  7. package/assets/container/assets/service.js +6 -0
  8. package/assets/container/assets/vconsole.js +931 -0
  9. package/assets/container/favicon.ico +0 -0
  10. package/assets/container/images/icon-arrow.png +0 -0
  11. package/assets/container/images/mini-action-white.png +0 -0
  12. package/assets/container/images/mini-action.png +0 -0
  13. package/assets/container/images/mini-arrow-left-white.png +0 -0
  14. package/assets/container/images/mini-arrow-left.jpg +0 -0
  15. package/assets/container/images/mini-arrow-left.png +0 -0
  16. package/assets/container/images/mini-close-white.png +0 -0
  17. package/assets/container/images/mini-close.png +0 -0
  18. package/assets/container/images/more.png +0 -0
  19. package/assets/container/images/search.jpg +0 -0
  20. package/assets/container/index.html +1 -0
  21. package/assets/container/pageFrame.html +1 -0
  22. package/assets/init/tabbar/home-active.png +0 -0
  23. package/assets/init/tabbar/home.png +0 -0
  24. package/assets/init/tabbar/list-active.png +0 -0
  25. package/assets/init/tabbar/list.png +0 -0
  26. package/assets/init/types/neux-api.d.ts +1402 -0
  27. package/package.json +68 -0
  28. package/scripts/generate-init-types.js +210 -0
  29. package/scripts/sync-compiler.js +22 -0
  30. package/scripts/sync-web-container.js +34 -0
  31. package/src/bin/cli.js +646 -0
  32. package/src/core/brand.js +11 -0
  33. package/src/core/compiler.js +305 -0
  34. package/src/core/defaults.js +12 -0
  35. package/src/core/dev.js +15 -0
  36. package/src/core/errors.js +17 -0
  37. package/src/core/fs.js +66 -0
  38. package/src/core/i18n.js +37 -0
  39. package/src/core/init.js +866 -0
  40. package/src/core/lifecycle.js +32 -0
  41. package/src/core/manifest.js +72 -0
  42. package/src/core/pack.js +156 -0
  43. package/src/core/package-info.js +27 -0
  44. package/src/core/preview-server.js +123 -0
  45. package/src/core/project.js +101 -0
  46. package/src/core/prompts.js +71 -0
  47. package/src/core/proxy-security.js +141 -0
  48. package/src/core/proxy.js +156 -0
  49. package/src/core/qr.js +41 -0
  50. package/src/core/terminal-qr.js +72 -0
  51. package/src/core/update.js +278 -0
  52. package/src/core/watch.js +113 -0
  53. package/src/core/web.js +649 -0
  54. package/src/core/zip.js +120 -0
  55. package/src/index.js +20 -0
  56. package/src/providers/service-client.js +149 -0
  57. package/src/providers/service-config.js +264 -0
  58. package/src/providers/service.js +146 -0
  59. package/src/providers/upload.js +112 -0
  60. package/vendor/dimina-compiler/bin/index.cjs +265 -0
  61. package/vendor/dimina-compiler/bin/index.js +263 -0
  62. package/vendor/dimina-compiler/compatibility-B-DoZtUX.cjs +395 -0
  63. package/vendor/dimina-compiler/compatibility-Cl3-DO6V.js +366 -0
  64. package/vendor/dimina-compiler/core/logic-compiler.cjs +378 -0
  65. package/vendor/dimina-compiler/core/logic-compiler.js +374 -0
  66. package/vendor/dimina-compiler/core/style-compiler.cjs +392 -0
  67. package/vendor/dimina-compiler/core/style-compiler.js +377 -0
  68. package/vendor/dimina-compiler/core/view-compiler.cjs +1601 -0
  69. package/vendor/dimina-compiler/core/view-compiler.js +1582 -0
  70. package/vendor/dimina-compiler/index.cjs +762 -0
  71. package/vendor/dimina-compiler/index.js +751 -0
  72. package/vendor/dimina-compiler/sourcemap-BgtIgqkC.cjs +1377 -0
  73. package/vendor/dimina-compiler/sourcemap-CKjhV9h7.js +1135 -0
@@ -0,0 +1,112 @@
1
+ import fsp from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import { pathToFileURL } from 'node:url'
4
+ import { DiminaCliError } from '../core/errors.js'
5
+ import { createServiceProvider } from './service.js'
6
+
7
+ function unsupported(command) {
8
+ throw new DiminaCliError(
9
+ 'DIMINA_PROVIDER_UNSUPPORTED',
10
+ `${command} is reserved for provider-backed integrations and is not implemented in v1.`,
11
+ { command },
12
+ )
13
+ }
14
+
15
+ function providerFunction(provider, command) {
16
+ if (command === 'submit') return provider.submit || provider.audit
17
+ if (command === 'audit') return provider.audit || provider.submit
18
+ if (command === 'login') return provider.login
19
+ if (command === 'debug-preview') return provider.debugPreview
20
+ if (command === 'service-preview') return provider.servicePreview || provider.preview
21
+ if (command === 'submit-audit') return provider.submitAudit || provider.submit || provider.audit
22
+ if (command === 'audit-status') return provider.auditStatus
23
+ return provider[command]
24
+ }
25
+
26
+ export function createUploadProvider(provider = {}) {
27
+ return {
28
+ login: provider.login || (async () => unsupported('login')),
29
+ upload: provider.upload || (async () => unsupported('upload')),
30
+ debugPreview: provider.debugPreview || (async () => unsupported('debug-preview')),
31
+ servicePreview: provider.servicePreview || provider.preview || (async () => unsupported('service-preview')),
32
+ version: provider.version || (async () => unsupported('version')),
33
+ auditStatus: provider.auditStatus || (async () => unsupported('audit-status')),
34
+ submitAudit: provider.submitAudit || provider.submit || provider.audit || (async () => unsupported('submit-audit')),
35
+ audit: provider.audit || provider.submit || (async () => unsupported('audit')),
36
+ submit: provider.submit || provider.audit || (async () => unsupported('submit')),
37
+ }
38
+ }
39
+
40
+ export function createLocalFileProvider(options = {}) {
41
+ const recordDir = path.resolve(options.providerOut || path.join(options.out || 'artifacts', 'provider-records'))
42
+
43
+ async function writeRecord(command, payload) {
44
+ const payloadOptions = payload.options || {}
45
+ await fsp.mkdir(recordDir, { recursive: true })
46
+ const record = {
47
+ ok: true,
48
+ command,
49
+ provider: 'local-file',
50
+ recordPath: path.join(recordDir, `${command}.json`),
51
+ artifact: payload.artifact,
52
+ project: payload.project,
53
+ versionCode: payloadOptions.versionCode,
54
+ versionName: payloadOptions.versionName,
55
+ }
56
+ await fsp.writeFile(record.recordPath, `${JSON.stringify(record, null, 2)}\n`)
57
+ return record
58
+ }
59
+
60
+ return createUploadProvider({
61
+ login: payload => writeRecord('login', payload),
62
+ upload: payload => writeRecord('upload', payload),
63
+ audit: payload => writeRecord('audit', payload),
64
+ submit: payload => writeRecord('submit', payload),
65
+ })
66
+ }
67
+
68
+ function resolveProviderModule(specifier) {
69
+ if (path.isAbsolute(specifier) || specifier.startsWith('.') || specifier.startsWith('..')) {
70
+ return pathToFileURL(path.resolve(process.cwd(), specifier)).href
71
+ }
72
+ return specifier
73
+ }
74
+
75
+ export async function loadUploadProvider(specifier, options = {}) {
76
+ if (!specifier || specifier === 'service') return createUploadProvider(createServiceProvider(options))
77
+ if (specifier === 'local-file') return createLocalFileProvider(options)
78
+
79
+ let mod
80
+ try {
81
+ mod = await import(resolveProviderModule(specifier))
82
+ }
83
+ catch (error) {
84
+ throw new DiminaCliError('DIMINA_PROVIDER_LOAD_FAILED', `Unable to load provider module: ${specifier}`, {
85
+ provider: specifier,
86
+ cause: error.message,
87
+ })
88
+ }
89
+
90
+ const factory = mod.createProvider || mod.default
91
+ const provider = typeof factory === 'function'
92
+ ? await factory(options)
93
+ : mod.provider || mod.default || mod
94
+ return createUploadProvider(provider)
95
+ }
96
+
97
+ export async function runProviderCommand(command, options, payload) {
98
+ const provider = await loadUploadProvider(options.provider, options)
99
+ const action = providerFunction(provider, command)
100
+ if (typeof action !== 'function') return await unsupported(command)
101
+ const result = await action({ command, ...payload, options })
102
+ return {
103
+ ok: true,
104
+ command,
105
+ provider: options.provider,
106
+ ...result,
107
+ }
108
+ }
109
+
110
+ export async function unsupportedProviderCommand(command) {
111
+ return await unsupported(command)
112
+ }
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env node
2
+ const require_sourcemap = require("../sourcemap-BgtIgqkC.cjs");
3
+ const require_index = require("../index.cjs");
4
+ let node_path = require("node:path");
5
+ node_path = require_sourcemap.__toESM(node_path, 1);
6
+ let node_process = require("node:process");
7
+ node_process = require_sourcemap.__toESM(node_process, 1);
8
+ let chokidar = require("chokidar");
9
+ chokidar = require_sourcemap.__toESM(chokidar, 1);
10
+ let commander = require("commander");
11
+ var package_default = {
12
+ name: "@dimina/compiler",
13
+ version: "1.1.0",
14
+ description: "星河编译工具",
15
+ main: "./dist/index.cjs",
16
+ module: "./dist/index.js",
17
+ type: "module",
18
+ files: ["dist"],
19
+ exports: {
20
+ ".": {
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ },
24
+ "./view-compiler": {
25
+ "import": "./dist/core/view-compiler.js",
26
+ "require": "./dist/core/view-compiler.cjs"
27
+ },
28
+ "./logic-compiler": {
29
+ "import": "./dist/core/logic-compiler.mjs",
30
+ "require": "./dist/core/logic-compiler.js"
31
+ },
32
+ "./style-compiler": {
33
+ "import": "./dist/core/style-compiler.js",
34
+ "require": "./dist/core/style-compiler.cjs"
35
+ }
36
+ },
37
+ bin: { "dmcc": "dist/bin/index.js" },
38
+ scripts: {
39
+ "prebuild": "node scripts/sync-compatibility-reference.js",
40
+ "build": "vite build",
41
+ "sync:compat": "node scripts/sync-compatibility-reference.js",
42
+ "pretest": "node scripts/sync-compatibility-reference.js",
43
+ "test": "vitest run",
44
+ "test:dev": "vitest",
45
+ "coverage": "vitest run --coverage",
46
+ "prepack": "npm run build",
47
+ "release:beta": "npm version prerelease --preid=beta && npm publish --tag beta",
48
+ "release": "npm version patch && npm publish"
49
+ },
50
+ author: "doslin",
51
+ license: "Apache-2.0",
52
+ engines: { "node": ">=20" },
53
+ keywords: [
54
+ "dimina",
55
+ "compiler",
56
+ "miniapp",
57
+ "小程序"
58
+ ],
59
+ dependencies: {
60
+ "@vue/compiler-sfc": "^3.5.39",
61
+ "@vue/shared": "^3.5.39",
62
+ "autoprefixer": "^10.5.3",
63
+ "cheerio": "^1.2.0",
64
+ "chokidar": "^4.0.3",
65
+ "commander": "^14.0.3",
66
+ "cssnano": "^8.0.2",
67
+ "esbuild": "^0.28.1",
68
+ "htmlparser2": "^12.0.0",
69
+ "less": "^4.6.7",
70
+ "listr2": "^9.0.5",
71
+ "magic-string": "^0.30.21",
72
+ "oxc-parser": "^0.140.0",
73
+ "oxc-walker": "^1.0.0",
74
+ "postcss": "^8.5.19",
75
+ "postcss-selector-parser": "^7.1.4",
76
+ "sass": "^1.101.0",
77
+ "source-map-js": "^1.2.1"
78
+ },
79
+ publishConfig: {
80
+ "registry": "https://registry.npmjs.org/",
81
+ "access": "public"
82
+ }
83
+ };
84
+ //#endregion
85
+ //#region src/common/compile-stages.js
86
+ var COMPILE_STAGE_ORDER = [
87
+ "view",
88
+ "logic",
89
+ "style"
90
+ ];
91
+ var COMPILE_STAGE_SET = new Set(COMPILE_STAGE_ORDER);
92
+ function getCompileStagesForFiles(dependencyGraph, filePaths) {
93
+ const selected = /* @__PURE__ */ new Set();
94
+ const unknownKinds = /* @__PURE__ */ new Set();
95
+ for (const filePath of filePaths) for (const kind of dependencyGraph.getFileKinds(filePath)) if (COMPILE_STAGE_SET.has(kind)) selected.add(kind);
96
+ else if (kind !== "config") unknownKinds.add(kind);
97
+ return {
98
+ stages: COMPILE_STAGE_ORDER.filter((stage) => selected.has(stage)),
99
+ unknownKinds: [...unknownKinds].sort()
100
+ };
101
+ }
102
+ //#endregion
103
+ //#region src/bin/watch.js
104
+ var WATCH_FILE_EVENTS = /* @__PURE__ */ new Set([
105
+ "add",
106
+ "change",
107
+ "unlink"
108
+ ]);
109
+ function createWatchRebuildScheduler({ rebuild, onRebuild = () => {}, onError = () => {} }) {
110
+ let pendingChange;
111
+ let running = false;
112
+ let idlePromise = Promise.resolve();
113
+ let resolveIdle;
114
+ const drain = async () => {
115
+ while (pendingChange) {
116
+ const change = pendingChange;
117
+ pendingChange = void 0;
118
+ try {
119
+ onRebuild(change);
120
+ await rebuild(change);
121
+ } catch (error) {
122
+ onError(error, change);
123
+ }
124
+ }
125
+ running = false;
126
+ resolveIdle?.();
127
+ resolveIdle = void 0;
128
+ };
129
+ return {
130
+ schedule(event, filePath) {
131
+ if (!WATCH_FILE_EVENTS.has(event)) return false;
132
+ pendingChange = {
133
+ event,
134
+ filePath,
135
+ count: (pendingChange?.count || 0) + 1
136
+ };
137
+ if (!running) {
138
+ running = true;
139
+ idlePromise = new Promise((resolve) => {
140
+ resolveIdle = resolve;
141
+ });
142
+ drain();
143
+ }
144
+ return true;
145
+ },
146
+ waitForIdle() {
147
+ return idlePromise;
148
+ }
149
+ };
150
+ }
151
+ function getPublishedOutputPath(targetPath, useAppIdDir, appId) {
152
+ return node_path.default.resolve(targetPath, useAppIdDir ? appId : ".");
153
+ }
154
+ function createWatchBuildPlan({ event, filePath, count = 1, dependencyGraph, publishedPath }) {
155
+ if (count > 1 || event !== "change" || node_path.default.extname(filePath).toLowerCase() === ".json") return {
156
+ skip: false,
157
+ incremental: false,
158
+ options: {}
159
+ };
160
+ if (!dependencyGraph.hasFile(filePath)) return {
161
+ skip: true,
162
+ incremental: false,
163
+ options: {}
164
+ };
165
+ const affectedEntries = dependencyGraph.getAffectedEntries(filePath);
166
+ if (affectedEntries.length === 0) return {
167
+ skip: true,
168
+ incremental: false,
169
+ options: {}
170
+ };
171
+ const { stages, unknownKinds } = getCompileStagesForFiles(dependencyGraph, [filePath]);
172
+ if (unknownKinds.length > 0) return {
173
+ skip: false,
174
+ incremental: false,
175
+ options: {}
176
+ };
177
+ return {
178
+ skip: false,
179
+ incremental: true,
180
+ options: {
181
+ affectedEntries,
182
+ stages,
183
+ seedPath: publishedPath,
184
+ dependencyGraph: dependencyGraph.toJSON()
185
+ }
186
+ };
187
+ }
188
+ function isSameOrDescendantPath(candidatePath, directoryPath) {
189
+ const relativePath = node_path.default.relative(directoryPath, candidatePath);
190
+ return relativePath === "" || !relativePath.startsWith(`..${node_path.default.sep}`) && relativePath !== ".." && !node_path.default.isAbsolute(relativePath);
191
+ }
192
+ function createIgnoredPathMatcher(ignoredPaths) {
193
+ return (watchedPath) => {
194
+ const absolutePath = node_path.default.resolve(watchedPath);
195
+ for (const ignoredPath of ignoredPaths) if (isSameOrDescendantPath(absolutePath, ignoredPath)) return true;
196
+ return false;
197
+ };
198
+ }
199
+ //#endregion
200
+ //#region src/bin/index.js
201
+ commander.program.command("build").option("-c, --work-path <path>", "编译工作目录").option("-s, --target-path <path>", "编译产物存放路径").option("-w, --watch", "启用监听文件改动").option("--no-app-id-dir", "产物根目录不包含appId").option("--sourcemap", "生成 sourcemap 文件用于调试").action(async (options) => {
202
+ const workPath = options.workPath ? node_path.default.resolve(options.workPath) : node_process.default.cwd();
203
+ const targetPath = options.targetPath ? node_path.default.resolve(options.targetPath) : node_process.default.cwd();
204
+ const useAppIdDir = options.appIdDir !== false;
205
+ const sourcemap = !!options.sourcemap;
206
+ let buildResult;
207
+ try {
208
+ buildResult = await require_index.default(targetPath, workPath, useAppIdDir, { sourcemap });
209
+ } catch (error) {
210
+ throw new Error(`${workPath} 编译出错: ${error.message}`, { cause: error });
211
+ }
212
+ if (options.watch) {
213
+ let dependencyGraph = new require_sourcemap.DependencyGraph(buildResult.dependencyGraph);
214
+ const ignoredOutputPaths = /* @__PURE__ */ new Set([getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId)]);
215
+ const eventLabels = {
216
+ add: "新增",
217
+ change: "改动",
218
+ unlink: "删除"
219
+ };
220
+ const scheduler = createWatchRebuildScheduler({
221
+ rebuild: async (change) => {
222
+ const publishedPath = getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId);
223
+ const plan = createWatchBuildPlan({
224
+ ...change,
225
+ dependencyGraph,
226
+ publishedPath
227
+ });
228
+ if (plan.skip) return;
229
+ const result = await require_index.default(targetPath, workPath, useAppIdDir, {
230
+ sourcemap,
231
+ ...plan.options
232
+ });
233
+ buildResult = result;
234
+ dependencyGraph = new require_sourcemap.DependencyGraph(result.dependencyGraph);
235
+ ignoredOutputPaths.add(getPublishedOutputPath(targetPath, useAppIdDir, result.appId));
236
+ },
237
+ onRebuild: ({ event, filePath, count }) => {
238
+ const merged = count > 1 ? `(合并 ${count} 个文件事件)` : "";
239
+ console.log(`${filePath} ${eventLabels[event]},重新编译${merged}`);
240
+ },
241
+ onError: (error) => {
242
+ console.error(`${workPath} 编译出错: ${error.message}`);
243
+ }
244
+ });
245
+ chokidar.default.watch(workPath, {
246
+ persistent: true,
247
+ ignoreInitial: true,
248
+ ignored: createIgnoredPathMatcher(ignoredOutputPaths)
249
+ }).on("all", (event, filePath) => {
250
+ if (createWatchBuildPlan({
251
+ event,
252
+ filePath,
253
+ dependencyGraph,
254
+ publishedPath: getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId)
255
+ }).skip) return;
256
+ scheduler.schedule(event, filePath);
257
+ });
258
+ }
259
+ });
260
+ commander.program.name("dmcc").version(package_default.version);
261
+ commander.program.parseAsync(node_process.default.argv).catch((error) => {
262
+ console.error(error.stack || error.message);
263
+ node_process.default.exitCode = 1;
264
+ });
265
+ //#endregion
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+ import { F as DependencyGraph } from "../sourcemap-CKjhV9h7.js";
3
+ import build from "../index.js";
4
+ import path from "node:path";
5
+ import process from "node:process";
6
+ import chokidar from "chokidar";
7
+ import { program } from "commander";
8
+ var package_default = {
9
+ name: "@dimina/compiler",
10
+ version: "1.1.0",
11
+ description: "星河编译工具",
12
+ main: "./dist/index.cjs",
13
+ module: "./dist/index.js",
14
+ type: "module",
15
+ files: ["dist"],
16
+ exports: {
17
+ ".": {
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.cjs"
20
+ },
21
+ "./view-compiler": {
22
+ "import": "./dist/core/view-compiler.js",
23
+ "require": "./dist/core/view-compiler.cjs"
24
+ },
25
+ "./logic-compiler": {
26
+ "import": "./dist/core/logic-compiler.mjs",
27
+ "require": "./dist/core/logic-compiler.js"
28
+ },
29
+ "./style-compiler": {
30
+ "import": "./dist/core/style-compiler.js",
31
+ "require": "./dist/core/style-compiler.cjs"
32
+ }
33
+ },
34
+ bin: { "dmcc": "dist/bin/index.js" },
35
+ scripts: {
36
+ "prebuild": "node scripts/sync-compatibility-reference.js",
37
+ "build": "vite build",
38
+ "sync:compat": "node scripts/sync-compatibility-reference.js",
39
+ "pretest": "node scripts/sync-compatibility-reference.js",
40
+ "test": "vitest run",
41
+ "test:dev": "vitest",
42
+ "coverage": "vitest run --coverage",
43
+ "prepack": "npm run build",
44
+ "release:beta": "npm version prerelease --preid=beta && npm publish --tag beta",
45
+ "release": "npm version patch && npm publish"
46
+ },
47
+ author: "doslin",
48
+ license: "Apache-2.0",
49
+ engines: { "node": ">=20" },
50
+ keywords: [
51
+ "dimina",
52
+ "compiler",
53
+ "miniapp",
54
+ "小程序"
55
+ ],
56
+ dependencies: {
57
+ "@vue/compiler-sfc": "^3.5.39",
58
+ "@vue/shared": "^3.5.39",
59
+ "autoprefixer": "^10.5.3",
60
+ "cheerio": "^1.2.0",
61
+ "chokidar": "^4.0.3",
62
+ "commander": "^14.0.3",
63
+ "cssnano": "^8.0.2",
64
+ "esbuild": "^0.28.1",
65
+ "htmlparser2": "^12.0.0",
66
+ "less": "^4.6.7",
67
+ "listr2": "^9.0.5",
68
+ "magic-string": "^0.30.21",
69
+ "oxc-parser": "^0.140.0",
70
+ "oxc-walker": "^1.0.0",
71
+ "postcss": "^8.5.19",
72
+ "postcss-selector-parser": "^7.1.4",
73
+ "sass": "^1.101.0",
74
+ "source-map-js": "^1.2.1"
75
+ },
76
+ publishConfig: {
77
+ "registry": "https://registry.npmjs.org/",
78
+ "access": "public"
79
+ }
80
+ };
81
+ //#endregion
82
+ //#region src/common/compile-stages.js
83
+ var COMPILE_STAGE_ORDER = [
84
+ "view",
85
+ "logic",
86
+ "style"
87
+ ];
88
+ var COMPILE_STAGE_SET = new Set(COMPILE_STAGE_ORDER);
89
+ function getCompileStagesForFiles(dependencyGraph, filePaths) {
90
+ const selected = /* @__PURE__ */ new Set();
91
+ const unknownKinds = /* @__PURE__ */ new Set();
92
+ for (const filePath of filePaths) for (const kind of dependencyGraph.getFileKinds(filePath)) if (COMPILE_STAGE_SET.has(kind)) selected.add(kind);
93
+ else if (kind !== "config") unknownKinds.add(kind);
94
+ return {
95
+ stages: COMPILE_STAGE_ORDER.filter((stage) => selected.has(stage)),
96
+ unknownKinds: [...unknownKinds].sort()
97
+ };
98
+ }
99
+ //#endregion
100
+ //#region src/bin/watch.js
101
+ var WATCH_FILE_EVENTS = /* @__PURE__ */ new Set([
102
+ "add",
103
+ "change",
104
+ "unlink"
105
+ ]);
106
+ function createWatchRebuildScheduler({ rebuild, onRebuild = () => {}, onError = () => {} }) {
107
+ let pendingChange;
108
+ let running = false;
109
+ let idlePromise = Promise.resolve();
110
+ let resolveIdle;
111
+ const drain = async () => {
112
+ while (pendingChange) {
113
+ const change = pendingChange;
114
+ pendingChange = void 0;
115
+ try {
116
+ onRebuild(change);
117
+ await rebuild(change);
118
+ } catch (error) {
119
+ onError(error, change);
120
+ }
121
+ }
122
+ running = false;
123
+ resolveIdle?.();
124
+ resolveIdle = void 0;
125
+ };
126
+ return {
127
+ schedule(event, filePath) {
128
+ if (!WATCH_FILE_EVENTS.has(event)) return false;
129
+ pendingChange = {
130
+ event,
131
+ filePath,
132
+ count: (pendingChange?.count || 0) + 1
133
+ };
134
+ if (!running) {
135
+ running = true;
136
+ idlePromise = new Promise((resolve) => {
137
+ resolveIdle = resolve;
138
+ });
139
+ drain();
140
+ }
141
+ return true;
142
+ },
143
+ waitForIdle() {
144
+ return idlePromise;
145
+ }
146
+ };
147
+ }
148
+ function getPublishedOutputPath(targetPath, useAppIdDir, appId) {
149
+ return path.resolve(targetPath, useAppIdDir ? appId : ".");
150
+ }
151
+ function createWatchBuildPlan({ event, filePath, count = 1, dependencyGraph, publishedPath }) {
152
+ if (count > 1 || event !== "change" || path.extname(filePath).toLowerCase() === ".json") return {
153
+ skip: false,
154
+ incremental: false,
155
+ options: {}
156
+ };
157
+ if (!dependencyGraph.hasFile(filePath)) return {
158
+ skip: true,
159
+ incremental: false,
160
+ options: {}
161
+ };
162
+ const affectedEntries = dependencyGraph.getAffectedEntries(filePath);
163
+ if (affectedEntries.length === 0) return {
164
+ skip: true,
165
+ incremental: false,
166
+ options: {}
167
+ };
168
+ const { stages, unknownKinds } = getCompileStagesForFiles(dependencyGraph, [filePath]);
169
+ if (unknownKinds.length > 0) return {
170
+ skip: false,
171
+ incremental: false,
172
+ options: {}
173
+ };
174
+ return {
175
+ skip: false,
176
+ incremental: true,
177
+ options: {
178
+ affectedEntries,
179
+ stages,
180
+ seedPath: publishedPath,
181
+ dependencyGraph: dependencyGraph.toJSON()
182
+ }
183
+ };
184
+ }
185
+ function isSameOrDescendantPath(candidatePath, directoryPath) {
186
+ const relativePath = path.relative(directoryPath, candidatePath);
187
+ return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
188
+ }
189
+ function createIgnoredPathMatcher(ignoredPaths) {
190
+ return (watchedPath) => {
191
+ const absolutePath = path.resolve(watchedPath);
192
+ for (const ignoredPath of ignoredPaths) if (isSameOrDescendantPath(absolutePath, ignoredPath)) return true;
193
+ return false;
194
+ };
195
+ }
196
+ //#endregion
197
+ //#region src/bin/index.js
198
+ program.command("build").option("-c, --work-path <path>", "编译工作目录").option("-s, --target-path <path>", "编译产物存放路径").option("-w, --watch", "启用监听文件改动").option("--no-app-id-dir", "产物根目录不包含appId").option("--sourcemap", "生成 sourcemap 文件用于调试").action(async (options) => {
199
+ const workPath = options.workPath ? path.resolve(options.workPath) : process.cwd();
200
+ const targetPath = options.targetPath ? path.resolve(options.targetPath) : process.cwd();
201
+ const useAppIdDir = options.appIdDir !== false;
202
+ const sourcemap = !!options.sourcemap;
203
+ let buildResult;
204
+ try {
205
+ buildResult = await build(targetPath, workPath, useAppIdDir, { sourcemap });
206
+ } catch (error) {
207
+ throw new Error(`${workPath} 编译出错: ${error.message}`, { cause: error });
208
+ }
209
+ if (options.watch) {
210
+ let dependencyGraph = new DependencyGraph(buildResult.dependencyGraph);
211
+ const ignoredOutputPaths = /* @__PURE__ */ new Set([getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId)]);
212
+ const eventLabels = {
213
+ add: "新增",
214
+ change: "改动",
215
+ unlink: "删除"
216
+ };
217
+ const scheduler = createWatchRebuildScheduler({
218
+ rebuild: async (change) => {
219
+ const publishedPath = getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId);
220
+ const plan = createWatchBuildPlan({
221
+ ...change,
222
+ dependencyGraph,
223
+ publishedPath
224
+ });
225
+ if (plan.skip) return;
226
+ const result = await build(targetPath, workPath, useAppIdDir, {
227
+ sourcemap,
228
+ ...plan.options
229
+ });
230
+ buildResult = result;
231
+ dependencyGraph = new DependencyGraph(result.dependencyGraph);
232
+ ignoredOutputPaths.add(getPublishedOutputPath(targetPath, useAppIdDir, result.appId));
233
+ },
234
+ onRebuild: ({ event, filePath, count }) => {
235
+ const merged = count > 1 ? `(合并 ${count} 个文件事件)` : "";
236
+ console.log(`${filePath} ${eventLabels[event]},重新编译${merged}`);
237
+ },
238
+ onError: (error) => {
239
+ console.error(`${workPath} 编译出错: ${error.message}`);
240
+ }
241
+ });
242
+ chokidar.watch(workPath, {
243
+ persistent: true,
244
+ ignoreInitial: true,
245
+ ignored: createIgnoredPathMatcher(ignoredOutputPaths)
246
+ }).on("all", (event, filePath) => {
247
+ if (createWatchBuildPlan({
248
+ event,
249
+ filePath,
250
+ dependencyGraph,
251
+ publishedPath: getPublishedOutputPath(targetPath, useAppIdDir, buildResult.appId)
252
+ }).skip) return;
253
+ scheduler.schedule(event, filePath);
254
+ });
255
+ }
256
+ });
257
+ program.name("dmcc").version(package_default.version);
258
+ program.parseAsync(process.argv).catch((error) => {
259
+ console.error(error.stack || error.message);
260
+ process.exitCode = 1;
261
+ });
262
+ //#endregion
263
+ export {};