@pactor-app/module-pack 1.55.0 → 1.56.0
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.
- package/README.md +56 -10
- package/dist/index.cjs +508 -157
- package/dist/index.d.cts +122 -11
- package/dist/index.d.ts +122 -11
- package/dist/index.js +462 -124
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,18 +21,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
CLIENT_EXTERNALS: () => CLIENT_EXTERNALS,
|
|
24
|
+
CLIENT_STYLES_ENTRY: () => CLIENT_STYLES_ENTRY,
|
|
24
25
|
CONFIG_DEFAULTS: () => CONFIG_DEFAULTS,
|
|
25
26
|
CONFIG_FILE: () => CONFIG_FILE,
|
|
26
27
|
ConfigError: () => ConfigError,
|
|
27
28
|
DEFAULT_TARGET: () => DEFAULT_TARGET,
|
|
28
29
|
INCLUDE_KEY: () => INCLUDE_KEY,
|
|
29
30
|
IncludeError: () => IncludeError,
|
|
31
|
+
MODULE_ID_PREFIX: () => MODULE_ID_PREFIX,
|
|
30
32
|
ModuleBuildError: () => ModuleBuildError,
|
|
31
33
|
ProfileError: () => ProfileError,
|
|
34
|
+
SERVER_BUNDLE_FILE: () => SERVER_BUNDLE_FILE,
|
|
35
|
+
SERVER_ENTRY: () => SERVER_ENTRY,
|
|
36
|
+
SERVER_EXTERNALS: () => SERVER_EXTERNALS,
|
|
37
|
+
ServerBundleError: () => ServerBundleError,
|
|
32
38
|
buildModule: () => buildModule,
|
|
39
|
+
bumpPackageVersion: () => bumpPackageVersion,
|
|
40
|
+
bumpVersion: () => bumpVersion,
|
|
33
41
|
bundleClient: () => bundleClient,
|
|
42
|
+
bundleServer: () => bundleServer,
|
|
34
43
|
collectModuleSource: () => collectModuleSource,
|
|
35
44
|
compileTailwind: () => compileTailwind,
|
|
45
|
+
deriveApiPrefix: () => deriveApiPrefix,
|
|
36
46
|
deriveModuleId: () => deriveModuleId,
|
|
37
47
|
discoverActions: () => discoverActions,
|
|
38
48
|
discoverComponents: () => discoverComponents,
|
|
@@ -43,6 +53,7 @@ __export(index_exports, {
|
|
|
43
53
|
initModule: () => initModule,
|
|
44
54
|
innospotsWebShellV1: () => innospotsWebShellV1,
|
|
45
55
|
innospotsWebShellV2: () => innospotsWebShellV2,
|
|
56
|
+
innospotsWebShellV3: () => innospotsWebShellV3,
|
|
46
57
|
listProfiles: () => listProfiles,
|
|
47
58
|
loadModuleConfig: () => loadModuleConfig,
|
|
48
59
|
loadYamlExpanded: () => loadYamlExpanded,
|
|
@@ -51,6 +62,8 @@ __export(index_exports, {
|
|
|
51
62
|
parseYamlFile: () => parseYamlFile,
|
|
52
63
|
readProjectVersion: () => readProjectVersion,
|
|
53
64
|
renderClientEntry: () => renderClientEntry,
|
|
65
|
+
renderModuleStyles: () => renderModuleStyles,
|
|
66
|
+
renderServerEntry: () => renderServerEntry,
|
|
54
67
|
resolvePactorVersionRange: () => resolvePactorVersionRange,
|
|
55
68
|
rewriteDslUrls: () => rewriteDslUrls,
|
|
56
69
|
rewriteNavigationTo: () => rewriteNavigationTo,
|
|
@@ -62,8 +75,8 @@ __export(index_exports, {
|
|
|
62
75
|
module.exports = __toCommonJS(index_exports);
|
|
63
76
|
|
|
64
77
|
// src/build.ts
|
|
65
|
-
var
|
|
66
|
-
var
|
|
78
|
+
var import_node_fs10 = require("fs");
|
|
79
|
+
var import_node_path10 = require("path");
|
|
67
80
|
|
|
68
81
|
// src/bundle-client.ts
|
|
69
82
|
var import_node_fs = require("fs");
|
|
@@ -180,17 +193,68 @@ function parseJsonc(text) {
|
|
|
180
193
|
return JSON.parse(out.replace(/,(\s*[}\]])/g, "$1"));
|
|
181
194
|
}
|
|
182
195
|
|
|
183
|
-
// src/
|
|
196
|
+
// src/bundle-server.ts
|
|
184
197
|
var import_node_fs2 = require("fs");
|
|
185
198
|
var import_node_path2 = require("path");
|
|
199
|
+
var import_esbuild2 = require("esbuild");
|
|
200
|
+
var SERVER_EXTERNALS = [
|
|
201
|
+
"react",
|
|
202
|
+
"react-dom",
|
|
203
|
+
"react-dom/*",
|
|
204
|
+
"next",
|
|
205
|
+
"next/*",
|
|
206
|
+
"pactor-app",
|
|
207
|
+
"pactor-app/*",
|
|
208
|
+
"@pactor-app/*"
|
|
209
|
+
];
|
|
210
|
+
var SERVER_BUNDLE_FILE = "index.mjs";
|
|
211
|
+
var ServerBundleError = class extends Error {
|
|
212
|
+
};
|
|
213
|
+
function bundleServer(options) {
|
|
214
|
+
const projectRoot = (0, import_node_path2.resolve)(options.projectDir);
|
|
215
|
+
const entry = (0, import_node_path2.resolve)(projectRoot, options.serverEntry);
|
|
216
|
+
if (!entry.startsWith(`${projectRoot}${import_node_path2.sep}`)) {
|
|
217
|
+
throw new ServerBundleError(
|
|
218
|
+
`server \u5165\u53E3\u5FC5\u987B\u4F4D\u4E8E\u5DE5\u7A0B\u6839\u5185: ${options.serverEntry}`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
if (!(0, import_node_fs2.existsSync)(entry)) {
|
|
222
|
+
throw new ServerBundleError(`server \u5165\u53E3\u4E0D\u5B58\u5728: ${options.serverEntry}`);
|
|
223
|
+
}
|
|
224
|
+
(0, import_node_fs2.mkdirSync)(options.outDir, { recursive: true });
|
|
225
|
+
(0, import_esbuild2.buildSync)({
|
|
226
|
+
entryPoints: [entry],
|
|
227
|
+
bundle: true,
|
|
228
|
+
format: "esm",
|
|
229
|
+
platform: "node",
|
|
230
|
+
target: "node20",
|
|
231
|
+
outdir: options.outDir,
|
|
232
|
+
entryNames: "index",
|
|
233
|
+
outExtension: { ".js": ".mjs" },
|
|
234
|
+
sourcemap: true,
|
|
235
|
+
alias: tsconfigAliases(projectRoot),
|
|
236
|
+
external: [...SERVER_EXTERNALS],
|
|
237
|
+
logLevel: "silent"
|
|
238
|
+
});
|
|
239
|
+
if (!(0, import_node_fs2.existsSync)((0, import_node_path2.join)(options.outDir, SERVER_BUNDLE_FILE))) {
|
|
240
|
+
throw new ServerBundleError(
|
|
241
|
+
`server \u6253\u5305\u672A\u4EA7\u51FA ${SERVER_BUNDLE_FILE}\uFF08\u8BF7\u68C0\u67E5 serverEntry \u4E0E esbuild \u914D\u7F6E\uFF09`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
return { bundled: true, entry: SERVER_BUNDLE_FILE };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/collect.ts
|
|
248
|
+
var import_node_fs3 = require("fs");
|
|
249
|
+
var import_node_path3 = require("path");
|
|
186
250
|
function collectModuleSource(yamlRoot) {
|
|
187
251
|
const pages = /* @__PURE__ */ new Map();
|
|
188
252
|
const layouts = [];
|
|
189
253
|
const fragments = [];
|
|
190
254
|
const warnings = [];
|
|
191
255
|
const walk = (dir) => {
|
|
192
|
-
for (const entry of (0,
|
|
193
|
-
const full = (0,
|
|
256
|
+
for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
|
|
257
|
+
const full = (0, import_node_path3.join)(dir, entry.name);
|
|
194
258
|
if (entry.isDirectory()) {
|
|
195
259
|
walk(full);
|
|
196
260
|
continue;
|
|
@@ -198,7 +262,7 @@ function collectModuleSource(yamlRoot) {
|
|
|
198
262
|
if (!entry.name.endsWith(".yaml") || entry.name === "sitemap.yaml") {
|
|
199
263
|
continue;
|
|
200
264
|
}
|
|
201
|
-
const rel = (0,
|
|
265
|
+
const rel = (0, import_node_path3.relative)(yamlRoot, full);
|
|
202
266
|
if (entry.name.endsWith(".layout.yaml")) {
|
|
203
267
|
layouts.push(rel);
|
|
204
268
|
continue;
|
|
@@ -225,20 +289,20 @@ function collectModuleSource(yamlRoot) {
|
|
|
225
289
|
|
|
226
290
|
// src/compile-styles.ts
|
|
227
291
|
var import_node_child_process = require("child_process");
|
|
228
|
-
var
|
|
292
|
+
var import_node_fs4 = require("fs");
|
|
229
293
|
var import_node_os = require("os");
|
|
230
|
-
var
|
|
294
|
+
var import_node_path4 = require("path");
|
|
231
295
|
function compileTailwind(options) {
|
|
232
296
|
const warnings = [];
|
|
233
297
|
if (!options.tailwind.enabled) {
|
|
234
298
|
return { compiled: false, warnings };
|
|
235
299
|
}
|
|
236
|
-
const work = (0,
|
|
300
|
+
const work = (0, import_node_fs4.mkdtempSync)((0, import_node_path4.join)((0, import_node_os.tmpdir)(), "pactor-tailwind-"));
|
|
237
301
|
try {
|
|
238
302
|
let input;
|
|
239
303
|
if (options.tailwind.input !== void 0) {
|
|
240
|
-
input = (0,
|
|
241
|
-
if (!(0,
|
|
304
|
+
input = (0, import_node_path4.join)(options.projectDir, options.tailwind.input);
|
|
305
|
+
if (!(0, import_node_fs4.existsSync)(input)) {
|
|
242
306
|
warnings.push(`tailwind.input \u4E0D\u5B58\u5728: ${options.tailwind.input}\uFF0C\u8DF3\u8FC7\u9884\u7F16\u8BD1`);
|
|
243
307
|
return { compiled: false, warnings };
|
|
244
308
|
}
|
|
@@ -246,22 +310,22 @@ function compileTailwind(options) {
|
|
|
246
310
|
const scan = (options.tailwind.scan ?? options.scanDirs).map(
|
|
247
311
|
(dir) => `@source "${dir.replace(/\\/g, "/")}";`
|
|
248
312
|
);
|
|
249
|
-
input = (0,
|
|
250
|
-
(0,
|
|
313
|
+
input = (0, import_node_path4.join)(work, "input.css");
|
|
314
|
+
(0, import_node_fs4.writeFileSync)(input, `@import "tailwindcss";
|
|
251
315
|
${scan.join("\n")}
|
|
252
316
|
`, "utf8");
|
|
253
317
|
}
|
|
254
|
-
const out = (0,
|
|
318
|
+
const out = (0, import_node_path4.join)(work, "tailwind.css");
|
|
255
319
|
(0, import_node_child_process.execFileSync)(
|
|
256
320
|
"npx",
|
|
257
321
|
["--no-install", "tailwindcss", "--input", input, "--output", out],
|
|
258
322
|
{ cwd: options.projectDir, stdio: "pipe" }
|
|
259
323
|
);
|
|
260
|
-
if ((0,
|
|
261
|
-
const css = (0,
|
|
324
|
+
if ((0, import_node_fs4.existsSync)(out)) {
|
|
325
|
+
const css = (0, import_node_fs4.readFileSync)(out, "utf8");
|
|
262
326
|
if (css.trim().length > 0) {
|
|
263
|
-
(0,
|
|
264
|
-
(0,
|
|
327
|
+
(0, import_node_fs4.mkdirSync)((0, import_node_path4.dirname)(options.cssFile), { recursive: true });
|
|
328
|
+
(0, import_node_fs4.appendFileSync)(
|
|
265
329
|
options.cssFile,
|
|
266
330
|
`
|
|
267
331
|
/* tailwind utilities\uFF08pactor module build \u9884\u7F16\u8BD1\uFF09 */
|
|
@@ -278,13 +342,13 @@ ${css}`,
|
|
|
278
342
|
warnings.push(`tailwind \u4E0D\u53EF\u7528\u6216\u7F16\u8BD1\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u8DF3\u8FC7\u9884\u7F16\u8BD1\uFF08${firstLine}\uFF09`);
|
|
279
343
|
return { compiled: false, warnings };
|
|
280
344
|
} finally {
|
|
281
|
-
(0,
|
|
345
|
+
(0, import_node_fs4.rmSync)(work, { recursive: true, force: true });
|
|
282
346
|
}
|
|
283
347
|
}
|
|
284
348
|
|
|
285
349
|
// src/config.ts
|
|
286
|
-
var
|
|
287
|
-
var
|
|
350
|
+
var import_node_fs5 = require("fs");
|
|
351
|
+
var import_node_path5 = require("path");
|
|
288
352
|
|
|
289
353
|
// src/profiles/innospots-web-shell.ts
|
|
290
354
|
var base = {
|
|
@@ -293,7 +357,8 @@ var base = {
|
|
|
293
357
|
stripMenuPaths: true,
|
|
294
358
|
rewriteNavigation: { basePath: true, excludeApiUrls: true },
|
|
295
359
|
rewriteAssetUrls: (id, version) => `/modules/${id}/${version}/`,
|
|
296
|
-
forbidRootBasePath: true
|
|
360
|
+
forbidRootBasePath: true,
|
|
361
|
+
moduleServerApi: false
|
|
297
362
|
};
|
|
298
363
|
var innospotsWebShellV1 = {
|
|
299
364
|
...base,
|
|
@@ -305,15 +370,22 @@ var innospotsWebShellV2 = {
|
|
|
305
370
|
version: 2,
|
|
306
371
|
forceInlinePages: false
|
|
307
372
|
};
|
|
373
|
+
var innospotsWebShellV3 = {
|
|
374
|
+
...base,
|
|
375
|
+
version: 3,
|
|
376
|
+
forceInlinePages: false,
|
|
377
|
+
moduleServerApi: true
|
|
378
|
+
};
|
|
308
379
|
|
|
309
380
|
// src/profiles/index.ts
|
|
310
381
|
var ProfileError = class extends Error {
|
|
311
382
|
};
|
|
312
383
|
var registry = /* @__PURE__ */ new Map([
|
|
313
384
|
[`${innospotsWebShellV1.name}@${innospotsWebShellV1.version}`, innospotsWebShellV1],
|
|
314
|
-
[`${innospotsWebShellV2.name}@${innospotsWebShellV2.version}`, innospotsWebShellV2]
|
|
385
|
+
[`${innospotsWebShellV2.name}@${innospotsWebShellV2.version}`, innospotsWebShellV2],
|
|
386
|
+
[`${innospotsWebShellV3.name}@${innospotsWebShellV3.version}`, innospotsWebShellV3]
|
|
315
387
|
]);
|
|
316
|
-
var DEFAULT_TARGET = `${
|
|
388
|
+
var DEFAULT_TARGET = `${innospotsWebShellV3.name}@${innospotsWebShellV3.version}`;
|
|
317
389
|
function listProfiles() {
|
|
318
390
|
return [...registry.keys()];
|
|
319
391
|
}
|
|
@@ -337,13 +409,13 @@ var CONFIG_DEFAULTS = {
|
|
|
337
409
|
outDir: "dist-module"
|
|
338
410
|
};
|
|
339
411
|
function loadModuleConfig(projectDir, configPath) {
|
|
340
|
-
const file = configPath ? (0,
|
|
341
|
-
if (!(0,
|
|
412
|
+
const file = configPath ? (0, import_node_path5.resolve)(projectDir, configPath) : (0, import_node_path5.join)(projectDir, CONFIG_FILE);
|
|
413
|
+
if (!(0, import_node_fs5.existsSync)(file)) {
|
|
342
414
|
throw new ConfigError(`\u7F3A\u5C11\u914D\u7F6E\u6587\u4EF6: ${file}\uFF08\u53EF\u5148\u6267\u884C pactor module init \u751F\u6210\uFF09`);
|
|
343
415
|
}
|
|
344
416
|
let raw;
|
|
345
417
|
try {
|
|
346
|
-
raw = JSON.parse((0,
|
|
418
|
+
raw = JSON.parse((0, import_node_fs5.readFileSync)(file, "utf8"));
|
|
347
419
|
} catch (error) {
|
|
348
420
|
throw new ConfigError(`\u914D\u7F6E\u89E3\u6790\u5931\u8D25: ${file}: ${error.message}`);
|
|
349
421
|
}
|
|
@@ -359,19 +431,32 @@ function loadModuleConfig(projectDir, configPath) {
|
|
|
359
431
|
if (!basePath.startsWith("/")) basePath = `/${basePath}`;
|
|
360
432
|
if (basePath.length > 1 && basePath.endsWith("/")) basePath = basePath.slice(0, -1);
|
|
361
433
|
const actions = raw.actions === void 0 ? [] : readStringArray(raw.actions, "actions", file);
|
|
362
|
-
|
|
434
|
+
if (raw.demo !== void 0) {
|
|
435
|
+
throw new ConfigError(
|
|
436
|
+
`${file}: demo.public \u5DF2\u79FB\u9664\uFF0C\u8BF7\u6539\u7528 "access": { "default": "public" }\uFF08\u7F3A\u7701\u586B\u5145\u8BED\u4E49\uFF0C\u4E0D\u8986\u76D6\u663E\u5F0F permission\uFF09`
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
const access = isRecord(raw.access) ? raw.access : {};
|
|
440
|
+
const accessDefault = readString(access, "default", file, "access") ?? "authenticated";
|
|
441
|
+
if (accessDefault !== "public" && accessDefault !== "authenticated") {
|
|
442
|
+
throw new ConfigError(`${file}: access.default \u53EA\u652F\u6301 "public" | "authenticated"`);
|
|
443
|
+
}
|
|
363
444
|
const tailwind = isRecord(raw.tailwind) ? raw.tailwind : {};
|
|
364
445
|
const rewrite = isRecord(raw.rewrite) ? raw.rewrite : {};
|
|
446
|
+
const serverEntry = readString(raw, "serverEntry", file);
|
|
447
|
+
const apiPrefixes = raw.apiPrefixes === void 0 ? void 0 : readStringArray(raw.apiPrefixes, "apiPrefixes", file);
|
|
448
|
+
validateServerConfig({ id, serverEntry, apiPrefixes, file });
|
|
365
449
|
return {
|
|
366
450
|
id,
|
|
367
451
|
name,
|
|
368
452
|
basePath,
|
|
369
453
|
yamlRoot: readString(raw, "yamlRoot", file) ?? CONFIG_DEFAULTS.yamlRoot,
|
|
370
454
|
clientEntry: readString(raw, "clientEntry", file) ?? CONFIG_DEFAULTS.clientEntry,
|
|
455
|
+
...serverEntry !== void 0 ? { serverEntry, apiPrefixes } : {},
|
|
371
456
|
actions,
|
|
372
457
|
publicDir: readString(raw, "publicDir", file) ?? CONFIG_DEFAULTS.publicDir,
|
|
373
458
|
target: readString(raw, "target", file) ?? CONFIG_DEFAULTS.target,
|
|
374
|
-
|
|
459
|
+
access: { default: accessDefault },
|
|
375
460
|
tailwind: {
|
|
376
461
|
enabled: readBoolean(tailwind, "enabled", file, "tailwind") ?? false,
|
|
377
462
|
input: readString(tailwind, "input", file, "tailwind"),
|
|
@@ -409,12 +494,59 @@ function readStringArray(value, label, file) {
|
|
|
409
494
|
}
|
|
410
495
|
return value;
|
|
411
496
|
}
|
|
497
|
+
var URL_SAFE_MODULE_ID_RE = /^[A-Za-z0-9._~-]+$/;
|
|
498
|
+
var API_PREFIX_RE = /^\/api\/[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)*$/;
|
|
499
|
+
var RESERVED_API_PREFIXES = ["/api/modules", "/api/runtime"];
|
|
500
|
+
function validateServerConfig(input) {
|
|
501
|
+
const { id, serverEntry, apiPrefixes, file } = input;
|
|
502
|
+
if (serverEntry === void 0 && apiPrefixes === void 0) return;
|
|
503
|
+
if (serverEntry === void 0 || apiPrefixes === void 0) {
|
|
504
|
+
throw new ConfigError(`${file}: serverEntry \u4E0E apiPrefixes \u5FC5\u987B\u540C\u65F6\u914D\u7F6E\uFF08\u7F3A\u4E00\u4E0D\u53EF\uFF09`);
|
|
505
|
+
}
|
|
506
|
+
if (apiPrefixes.length === 0) {
|
|
507
|
+
throw new ConfigError(`${file}: \u914D\u7F6E serverEntry \u65F6 apiPrefixes \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4`);
|
|
508
|
+
}
|
|
509
|
+
if (!URL_SAFE_MODULE_ID_RE.test(id)) {
|
|
510
|
+
throw new ConfigError(
|
|
511
|
+
`${file}: \u542F\u7528 serverEntry \u65F6 id \u53EA\u80FD\u5305\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u3001. _ ~ -\uFF08\u5F53\u524D: ${JSON.stringify(id)}\uFF09`
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
for (const prefix of apiPrefixes) {
|
|
515
|
+
if (!API_PREFIX_RE.test(prefix)) {
|
|
516
|
+
throw new ConfigError(
|
|
517
|
+
`${file}: apiPrefixes \u542B\u975E\u6CD5\u524D\u7F00 ${JSON.stringify(prefix)}\uFF08\u8981\u6C42\u5F62\u5982 /api/risk-analysis\uFF0C\u4E0D\u80FD\u542B query / hash / \u5C3E\u659C\u6760 / \u901A\u914D / :param\uFF09`
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
const reserved = RESERVED_API_PREFIXES.find(
|
|
521
|
+
(item) => prefix === item || prefix.startsWith(`${item}/`)
|
|
522
|
+
);
|
|
523
|
+
if (reserved) {
|
|
524
|
+
throw new ConfigError(
|
|
525
|
+
`${file}: apiPrefixes \u4E0D\u80FD\u4F7F\u7528\u4FDD\u7559\u524D\u7F00 ${reserved}\uFF08Shell \u81EA\u5E26\u8DEF\u7531\uFF09: ${prefix}`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
for (let i = 0; i < apiPrefixes.length; i += 1) {
|
|
530
|
+
for (let j = i + 1; j < apiPrefixes.length; j += 1) {
|
|
531
|
+
const a = apiPrefixes[i];
|
|
532
|
+
const b = apiPrefixes[j];
|
|
533
|
+
if (a === b) {
|
|
534
|
+
throw new ConfigError(`${file}: apiPrefixes \u5B58\u5728\u91CD\u590D\u524D\u7F00: ${a}`);
|
|
535
|
+
}
|
|
536
|
+
if (a.startsWith(`${b}/`) || b.startsWith(`${a}/`)) {
|
|
537
|
+
throw new ConfigError(
|
|
538
|
+
`${file}: apiPrefixes \u524D\u7F00\u4E92\u76F8\u5305\u542B\uFF08\u540C\u4E00\u6A21\u5757\u5185\u65E0\u6CD5\u786E\u5B9A\u5F52\u5C5E\uFF09: ${a} / ${b}`
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
412
544
|
|
|
413
545
|
// src/emit-manifest.ts
|
|
414
546
|
var import_node_crypto = require("crypto");
|
|
415
|
-
var
|
|
547
|
+
var import_node_fs6 = require("fs");
|
|
416
548
|
var import_node_module = require("module");
|
|
417
|
-
var
|
|
549
|
+
var import_node_path6 = require("path");
|
|
418
550
|
var import_yaml = require("yaml");
|
|
419
551
|
function emitModule(input) {
|
|
420
552
|
const dslResult = emitDsl(input);
|
|
@@ -423,22 +555,22 @@ function emitModule(input) {
|
|
|
423
555
|
}
|
|
424
556
|
function emitDsl(input) {
|
|
425
557
|
const { config, projectDir, outDir, site, pages } = input;
|
|
426
|
-
const dslDir = (0,
|
|
427
|
-
(0,
|
|
428
|
-
(0,
|
|
558
|
+
const dslDir = (0, import_node_path6.join)(outDir, "dsl");
|
|
559
|
+
(0, import_node_fs6.mkdirSync)(dslDir, { recursive: true });
|
|
560
|
+
(0, import_node_fs6.writeFileSync)((0, import_node_path6.join)(dslDir, "sitemap.yaml"), (0, import_yaml.stringify)(site, { lineWidth: 0 }), "utf8");
|
|
429
561
|
for (const [id, dsl] of pages) {
|
|
430
|
-
(0,
|
|
562
|
+
(0, import_node_fs6.writeFileSync)((0, import_node_path6.join)(dslDir, `${id}.yaml`), (0, import_yaml.stringify)(dsl, { lineWidth: 0 }), "utf8");
|
|
431
563
|
}
|
|
432
|
-
const publicDir = (0,
|
|
433
|
-
const assetsDir = (0,
|
|
434
|
-
if ((0,
|
|
435
|
-
(0,
|
|
564
|
+
const publicDir = (0, import_node_path6.join)(projectDir, config.publicDir);
|
|
565
|
+
const assetsDir = (0, import_node_path6.join)(outDir, "assets");
|
|
566
|
+
if ((0, import_node_fs6.existsSync)(publicDir)) {
|
|
567
|
+
(0, import_node_fs6.cpSync)(publicDir, assetsDir, { recursive: true });
|
|
436
568
|
} else {
|
|
437
|
-
(0,
|
|
569
|
+
(0, import_node_fs6.mkdirSync)(assetsDir, { recursive: true });
|
|
438
570
|
}
|
|
439
571
|
const assets = hashAssets(assetsDir, assetsDir);
|
|
440
|
-
(0,
|
|
441
|
-
(0,
|
|
572
|
+
(0, import_node_fs6.writeFileSync)(
|
|
573
|
+
(0, import_node_path6.join)(outDir, "module-assets.json"),
|
|
442
574
|
`${JSON.stringify({ module: config.id, assets }, null, 2)}
|
|
443
575
|
`,
|
|
444
576
|
"utf8"
|
|
@@ -459,10 +591,12 @@ function writeManifest(input) {
|
|
|
459
591
|
dslRoot: "dsl",
|
|
460
592
|
assetsRoot: "assets",
|
|
461
593
|
...input.clientEntry ? { clientEntry: input.clientEntry } : {},
|
|
462
|
-
...input.styles ? { styles: input.styles } : {}
|
|
594
|
+
...input.styles ? { styles: input.styles } : {},
|
|
595
|
+
...input.serverEntry ? { serverEntry: input.serverEntry } : {},
|
|
596
|
+
...input.apiPrefixes && input.apiPrefixes.length > 0 ? { apiPrefixes: input.apiPrefixes } : {}
|
|
463
597
|
};
|
|
464
|
-
(0,
|
|
465
|
-
(0,
|
|
598
|
+
(0, import_node_fs6.writeFileSync)(
|
|
599
|
+
(0, import_node_path6.join)(outDir, "manifest.json"),
|
|
466
600
|
`${JSON.stringify(manifest, null, 2)}
|
|
467
601
|
`,
|
|
468
602
|
"utf8"
|
|
@@ -470,10 +604,10 @@ function writeManifest(input) {
|
|
|
470
604
|
return manifest;
|
|
471
605
|
}
|
|
472
606
|
function readProjectVersion(projectDir) {
|
|
473
|
-
const pkgFile = (0,
|
|
474
|
-
if (!(0,
|
|
607
|
+
const pkgFile = (0, import_node_path6.join)(projectDir, "package.json");
|
|
608
|
+
if (!(0, import_node_fs6.existsSync)(pkgFile)) return "0.0.0";
|
|
475
609
|
try {
|
|
476
|
-
const pkg = JSON.parse((0,
|
|
610
|
+
const pkg = JSON.parse((0, import_node_fs6.readFileSync)(pkgFile, "utf8"));
|
|
477
611
|
return typeof pkg.version === "string" && pkg.version.length > 0 ? pkg.version : "0.0.0";
|
|
478
612
|
} catch {
|
|
479
613
|
return "0.0.0";
|
|
@@ -481,18 +615,18 @@ function readProjectVersion(projectDir) {
|
|
|
481
615
|
}
|
|
482
616
|
function resolvePactorVersionRange(projectDir, warnings) {
|
|
483
617
|
try {
|
|
484
|
-
const require2 = (0, import_node_module.createRequire)((0,
|
|
618
|
+
const require2 = (0, import_node_module.createRequire)((0, import_node_path6.join)(projectDir, "package.json"));
|
|
485
619
|
for (const name of ["pactor-app/package.json", "@pactor-app/app/package.json"]) {
|
|
486
620
|
try {
|
|
487
621
|
const pkgFile = require2.resolve(name);
|
|
488
|
-
const pkg2 = JSON.parse((0,
|
|
622
|
+
const pkg2 = JSON.parse((0, import_node_fs6.readFileSync)(pkgFile, "utf8"));
|
|
489
623
|
if (typeof pkg2.version === "string" && pkg2.version.length > 0) {
|
|
490
624
|
return `^${pkg2.version}`;
|
|
491
625
|
}
|
|
492
626
|
} catch {
|
|
493
627
|
}
|
|
494
628
|
}
|
|
495
|
-
const pkg = JSON.parse((0,
|
|
629
|
+
const pkg = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path6.join)(projectDir, "package.json"), "utf8"));
|
|
496
630
|
for (const section of ["dependencies", "peerDependencies", "devDependencies"]) {
|
|
497
631
|
const range = pkg[section]?.["pactor-app"];
|
|
498
632
|
if (typeof range === "string" && range.length > 0) {
|
|
@@ -506,35 +640,35 @@ function resolvePactorVersionRange(projectDir, warnings) {
|
|
|
506
640
|
}
|
|
507
641
|
function hashAssets(dir, root) {
|
|
508
642
|
const entries = [];
|
|
509
|
-
if (!(0,
|
|
510
|
-
for (const entry of (0,
|
|
643
|
+
if (!(0, import_node_fs6.existsSync)(dir)) return entries;
|
|
644
|
+
for (const entry of (0, import_node_fs6.readdirSync)(dir, { withFileTypes: true }).sort(
|
|
511
645
|
(a, b) => a.name.localeCompare(b.name)
|
|
512
646
|
)) {
|
|
513
|
-
const full = (0,
|
|
647
|
+
const full = (0, import_node_path6.join)(dir, entry.name);
|
|
514
648
|
if (entry.isDirectory()) {
|
|
515
649
|
entries.push(...hashAssets(full, root));
|
|
516
650
|
continue;
|
|
517
651
|
}
|
|
518
652
|
if (!entry.isFile()) continue;
|
|
519
|
-
const content = (0,
|
|
653
|
+
const content = (0, import_node_fs6.readFileSync)(full);
|
|
520
654
|
entries.push({
|
|
521
655
|
path: full.slice(root.length + 1).split("\\").join("/"),
|
|
522
656
|
sha256: (0, import_node_crypto.createHash)("sha256").update(content).digest("hex"),
|
|
523
|
-
size: (0,
|
|
657
|
+
size: (0, import_node_fs6.statSync)(full).size
|
|
524
658
|
});
|
|
525
659
|
}
|
|
526
660
|
return entries;
|
|
527
661
|
}
|
|
528
662
|
|
|
529
663
|
// src/expand-include.ts
|
|
530
|
-
var
|
|
531
|
-
var
|
|
664
|
+
var import_node_fs7 = require("fs");
|
|
665
|
+
var import_node_path7 = require("path");
|
|
532
666
|
var import_yaml2 = require("yaml");
|
|
533
667
|
var INCLUDE_KEY = "$include";
|
|
534
668
|
var IncludeError = class extends Error {
|
|
535
669
|
};
|
|
536
670
|
function parseYamlFile(file) {
|
|
537
|
-
const doc = (0, import_yaml2.parseDocument)((0,
|
|
671
|
+
const doc = (0, import_yaml2.parseDocument)((0, import_node_fs7.readFileSync)(file, "utf8"));
|
|
538
672
|
if (doc.errors.length > 0) {
|
|
539
673
|
throw new IncludeError(
|
|
540
674
|
`${file}: ${doc.errors.map((error) => error.message).join("; ")}`
|
|
@@ -546,7 +680,7 @@ function loadYamlExpanded(yamlRoot, relPath, stack = []) {
|
|
|
546
680
|
if (stack.includes(relPath)) {
|
|
547
681
|
throw new IncludeError(`\u5FAA\u73AF\u5F15\u7528: ${[...stack, relPath].join(" -> ")}`);
|
|
548
682
|
}
|
|
549
|
-
const value = parseYamlFile((0,
|
|
683
|
+
const value = parseYamlFile((0, import_node_path7.join)(yamlRoot, relPath));
|
|
550
684
|
return expandIncludes(value, { yamlRoot, current: relPath, stack: [...stack, relPath] });
|
|
551
685
|
}
|
|
552
686
|
function expandIncludes(value, ctx) {
|
|
@@ -573,8 +707,8 @@ function expandIncludes(value, ctx) {
|
|
|
573
707
|
}
|
|
574
708
|
|
|
575
709
|
// src/rewrite-urls.ts
|
|
576
|
-
var
|
|
577
|
-
var
|
|
710
|
+
var import_node_fs8 = require("fs");
|
|
711
|
+
var import_node_path8 = require("path");
|
|
578
712
|
var NAVIGATION_ACTIONS = /* @__PURE__ */ new Set(["navigate", "app.reload"]);
|
|
579
713
|
var ABSOLUTE_API_RE = /^https?:\/\/[^/]+(\/api\/.+)$/;
|
|
580
714
|
function rewriteDslUrls(value, ctx) {
|
|
@@ -629,11 +763,14 @@ function matchPathPattern(pattern, value) {
|
|
|
629
763
|
function rewriteString(value, ctx, warnings) {
|
|
630
764
|
const absoluteApi = ABSOLUTE_API_RE.exec(value);
|
|
631
765
|
if (absoluteApi) {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
766
|
+
const relative3 = absoluteApi[1];
|
|
767
|
+
const namespaced2 = ctx.absoluteApiToRelative ? namespaceModuleApi(relative3, ctx) : void 0;
|
|
768
|
+
const action = ctx.absoluteApiToRelative ? namespaced2 !== void 0 ? "\uFF08\u5DF2\u91CD\u5199\u4E3A\u6A21\u5757 API \u76F8\u5BF9\u8DEF\u5F84\uFF09" : "\uFF08\u5DF2\u91CD\u5199\u4E3A\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u9700\u5E95\u5EA7 BFF/\u4EE3\u7406\u627F\u63A5\uFF09" : "\uFF08absoluteApiToRelative=false\uFF0C\u4FDD\u6301\u7EDD\u5BF9\u5730\u5740\uFF0C\u4E0D\u4F1A\u8D70\u6A21\u5757 API \u8DEF\u7531\uFF09";
|
|
769
|
+
warnings.push(`\u7EDD\u5BF9 API \u5730\u5740: ${value}${action}`);
|
|
770
|
+
return ctx.absoluteApiToRelative ? namespaced2 ?? relative3 : value;
|
|
636
771
|
}
|
|
772
|
+
const namespaced = namespaceModuleApi(value, ctx);
|
|
773
|
+
if (namespaced !== void 0) return namespaced;
|
|
637
774
|
if (!ctx.rewriteAssets) return value;
|
|
638
775
|
if (!value.startsWith("/") || value.startsWith("//")) return value;
|
|
639
776
|
if (value.startsWith("/api/")) return value;
|
|
@@ -645,10 +782,18 @@ function rewriteString(value, ctx, warnings) {
|
|
|
645
782
|
if (!isPublicFile(ctx.publicDir, value)) return value;
|
|
646
783
|
return `${ctx.assetPrefix}${value}`;
|
|
647
784
|
}
|
|
785
|
+
function namespaceModuleApi(value, ctx) {
|
|
786
|
+
const { moduleId, apiPrefixes } = ctx;
|
|
787
|
+
if (!moduleId || !apiPrefixes || apiPrefixes.length === 0) return void 0;
|
|
788
|
+
const pathOnly = value.split(/[?#]/, 1)[0];
|
|
789
|
+
const hit = [...apiPrefixes].sort((a, b) => b.length - a.length).some((prefix) => pathOnly === prefix || pathOnly.startsWith(`${prefix}/`));
|
|
790
|
+
if (!hit) return void 0;
|
|
791
|
+
return `/api/modules/${encodeURIComponent(moduleId)}${value.slice("/api".length)}`;
|
|
792
|
+
}
|
|
648
793
|
function isPublicFile(publicDir, urlPath) {
|
|
649
|
-
const file = (0,
|
|
794
|
+
const file = (0, import_node_path8.join)(publicDir, urlPath);
|
|
650
795
|
try {
|
|
651
|
-
return (0,
|
|
796
|
+
return (0, import_node_fs8.existsSync)(file) && (0, import_node_fs8.statSync)(file).isFile();
|
|
652
797
|
} catch {
|
|
653
798
|
return false;
|
|
654
799
|
}
|
|
@@ -659,7 +804,8 @@ function isRecord2(value) {
|
|
|
659
804
|
|
|
660
805
|
// src/transform-sitemap.ts
|
|
661
806
|
function transformSitemap(site, options) {
|
|
662
|
-
const { profile,
|
|
807
|
+
const { profile, accessDefault, loadLayout } = options;
|
|
808
|
+
const fillPublic = accessDefault === "public";
|
|
663
809
|
const next = { ...site };
|
|
664
810
|
const rawLayouts = isRecord3(site.layouts) ? site.layouts : {};
|
|
665
811
|
const layouts = {};
|
|
@@ -673,7 +819,7 @@ function transformSitemap(site, options) {
|
|
|
673
819
|
if (profile.forceInlinePages) {
|
|
674
820
|
delete nextPage.lazy;
|
|
675
821
|
}
|
|
676
|
-
if (
|
|
822
|
+
if (fillPublic && isAccessUndeclared(nextPage)) {
|
|
677
823
|
nextPage.public = true;
|
|
678
824
|
}
|
|
679
825
|
return nextPage;
|
|
@@ -684,7 +830,7 @@ function transformSitemap(site, options) {
|
|
|
684
830
|
if (profile.stripMenuPaths) {
|
|
685
831
|
delete nextMenu.path;
|
|
686
832
|
}
|
|
687
|
-
if (
|
|
833
|
+
if (fillPublic && isAccessUndeclared(nextMenu)) {
|
|
688
834
|
nextMenu.public = true;
|
|
689
835
|
}
|
|
690
836
|
if (Array.isArray(nextMenu.children)) {
|
|
@@ -705,10 +851,13 @@ function transformSitemap(site, options) {
|
|
|
705
851
|
function isRecord3(value) {
|
|
706
852
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
707
853
|
}
|
|
854
|
+
function isAccessUndeclared(entry) {
|
|
855
|
+
return entry.public === void 0 && entry.permission === void 0;
|
|
856
|
+
}
|
|
708
857
|
|
|
709
858
|
// src/validate.ts
|
|
710
|
-
var
|
|
711
|
-
var
|
|
859
|
+
var import_node_fs9 = require("fs");
|
|
860
|
+
var import_node_path9 = require("path");
|
|
712
861
|
var import_yaml3 = require("yaml");
|
|
713
862
|
var REQUIRED_MANIFEST_FIELDS = [
|
|
714
863
|
"schemaVersion",
|
|
@@ -722,7 +871,7 @@ var REQUIRED_MANIFEST_FIELDS = [
|
|
|
722
871
|
"assetsRoot"
|
|
723
872
|
];
|
|
724
873
|
function validateModule(options = {}) {
|
|
725
|
-
const projectDir = (0,
|
|
874
|
+
const projectDir = (0, import_node_path9.resolve)(options.dir ?? process.cwd());
|
|
726
875
|
const errors = [];
|
|
727
876
|
const warnings = [];
|
|
728
877
|
let config;
|
|
@@ -740,15 +889,15 @@ function validateModule(options = {}) {
|
|
|
740
889
|
config = void 0;
|
|
741
890
|
}
|
|
742
891
|
}
|
|
743
|
-
const moduleDir = options.moduleDir ?? (0,
|
|
744
|
-
const manifestFile = (0,
|
|
745
|
-
if (!(0,
|
|
892
|
+
const moduleDir = options.moduleDir ?? (0, import_node_path9.join)(projectDir, config?.outDir ?? CONFIG_DEFAULTS.outDir);
|
|
893
|
+
const manifestFile = (0, import_node_path9.join)(moduleDir, "manifest.json");
|
|
894
|
+
if (!(0, import_node_fs9.existsSync)(manifestFile)) {
|
|
746
895
|
errors.push(`\u4EA7\u7269\u4E0D\u5B58\u5728: ${manifestFile}\uFF08\u5148\u6267\u884C pactor module build\uFF09`);
|
|
747
896
|
return { ok: false, errors, warnings };
|
|
748
897
|
}
|
|
749
898
|
let manifest;
|
|
750
899
|
try {
|
|
751
|
-
manifest = JSON.parse((0,
|
|
900
|
+
manifest = JSON.parse((0, import_node_fs9.readFileSync)(manifestFile, "utf8"));
|
|
752
901
|
} catch (error) {
|
|
753
902
|
errors.push(`manifest.json \u89E3\u6790\u5931\u8D25: ${error.message}`);
|
|
754
903
|
return { ok: false, errors, warnings };
|
|
@@ -763,11 +912,11 @@ function validateModule(options = {}) {
|
|
|
763
912
|
}
|
|
764
913
|
const dslRoot = typeof manifest.dslRoot === "string" ? manifest.dslRoot : "dsl";
|
|
765
914
|
const sitemapRel = typeof manifest.sitemap === "string" ? manifest.sitemap : "dsl/sitemap.yaml";
|
|
766
|
-
const sitemapFile = (0,
|
|
767
|
-
if (!(0,
|
|
915
|
+
const sitemapFile = (0, import_node_path9.join)(moduleDir, sitemapRel);
|
|
916
|
+
if (!(0, import_node_fs9.existsSync)(sitemapFile)) {
|
|
768
917
|
errors.push(`sitemap \u4E0D\u5B58\u5728: ${sitemapRel}`);
|
|
769
918
|
} else {
|
|
770
|
-
const doc = (0, import_yaml3.parseDocument)((0,
|
|
919
|
+
const doc = (0, import_yaml3.parseDocument)((0, import_node_fs9.readFileSync)(sitemapFile, "utf8"));
|
|
771
920
|
if (doc.errors.length > 0) {
|
|
772
921
|
errors.push(`sitemap YAML \u89E3\u6790\u5931\u8D25: ${doc.errors.map((e) => e.message).join("; ")}`);
|
|
773
922
|
} else {
|
|
@@ -779,7 +928,7 @@ function validateModule(options = {}) {
|
|
|
779
928
|
errors.push("sitemap.pages \u5B58\u5728\u7F3A\u5C11 id \u7684\u9875\u9762\u9879");
|
|
780
929
|
continue;
|
|
781
930
|
}
|
|
782
|
-
if (findPageDslFile((0,
|
|
931
|
+
if (findPageDslFile((0, import_node_path9.join)(moduleDir, dslRoot), id) === null) {
|
|
783
932
|
errors.push(`\u9875\u9762 ${id} \u7F3A\u5C11 DSL \u6587\u4EF6\uFF08${dslRoot}/ \u4E0B\u672A\u627E\u5230 ${id}.yaml\uFF09`);
|
|
784
933
|
}
|
|
785
934
|
}
|
|
@@ -793,34 +942,60 @@ function validateModule(options = {}) {
|
|
|
793
942
|
}
|
|
794
943
|
}
|
|
795
944
|
}
|
|
796
|
-
const dslDir = (0,
|
|
945
|
+
const dslDir = (0, import_node_path9.join)(moduleDir, dslRoot);
|
|
797
946
|
for (const file of listFiles(dslDir)) {
|
|
798
|
-
if ((0,
|
|
799
|
-
errors.push(`$include \u6B8B\u7559: ${(0,
|
|
947
|
+
if ((0, import_node_fs9.readFileSync)(file, "utf8").includes(INCLUDE_KEY)) {
|
|
948
|
+
errors.push(`$include \u6B8B\u7559: ${(0, import_node_path9.relative)(moduleDir, file)}`);
|
|
800
949
|
}
|
|
801
950
|
}
|
|
802
951
|
if (typeof manifest.clientEntry === "string") {
|
|
803
|
-
const clientFile = (0,
|
|
804
|
-
if (!(0,
|
|
952
|
+
const clientFile = (0, import_node_path9.join)(moduleDir, manifest.clientEntry);
|
|
953
|
+
if (!(0, import_node_fs9.existsSync)(clientFile)) {
|
|
805
954
|
errors.push(`client bundle \u4E0D\u5B58\u5728: ${manifest.clientEntry}`);
|
|
806
955
|
} else {
|
|
807
|
-
const text = (0,
|
|
956
|
+
const text = (0, import_node_fs9.readFileSync)(clientFile, "utf8");
|
|
808
957
|
if (/\bvar React\b|react\.production\.min|__REACT_DEVTOOLS_GLOBAL_HOOK__/.test(text)) {
|
|
809
958
|
errors.push("client bundle \u7591\u4F3C\u5185\u5D4C react\uFF08react \u5FC5\u987B\u4FDD\u6301 external\uFF0C\u907F\u514D\u53CC\u5B9E\u4F8B\uFF09");
|
|
810
959
|
}
|
|
811
960
|
if (/node_modules\/@pactor-app\//.test(text) || /node_modules\/pactor-app\//.test(text)) {
|
|
812
961
|
errors.push("client bundle \u7591\u4F3C\u5185\u5D4C pactor \u8FD0\u884C\u65F6\u4EE3\u7801\uFF08@pactor-app/* \u5FC5\u987B\u4FDD\u6301 external\uFF09");
|
|
813
962
|
}
|
|
814
|
-
const sizeKb = Math.round((0,
|
|
963
|
+
const sizeKb = Math.round((0, import_node_fs9.statSync)(clientFile).size / 1024);
|
|
815
964
|
if (sizeKb > 512) {
|
|
816
965
|
warnings.push(`client bundle \u4F53\u79EF\u8F83\u5927\uFF08${sizeKb}KB\uFF09\uFF0C\u8BF7\u786E\u8BA4 react / pactor \u5DF2 external`);
|
|
817
966
|
}
|
|
818
967
|
}
|
|
819
968
|
}
|
|
820
|
-
const
|
|
821
|
-
|
|
969
|
+
const hasServerEntry = typeof manifest.serverEntry === "string";
|
|
970
|
+
const hasApiPrefixes = Array.isArray(manifest.apiPrefixes);
|
|
971
|
+
if (hasServerEntry !== hasApiPrefixes) {
|
|
972
|
+
errors.push("manifest.serverEntry \u4E0E apiPrefixes \u5FC5\u987B\u6210\u5BF9\u51FA\u73B0");
|
|
973
|
+
}
|
|
974
|
+
if (hasServerEntry) {
|
|
975
|
+
const serverRel = manifest.serverEntry;
|
|
976
|
+
const serverFile = (0, import_node_path9.resolve)(moduleDir, serverRel);
|
|
977
|
+
if (!isInsideDir(moduleDir, serverFile)) {
|
|
978
|
+
errors.push(`server bundle \u8DEF\u5F84\u8D8A\u754C: ${serverRel}`);
|
|
979
|
+
} else if (!(0, import_node_fs9.existsSync)(serverFile)) {
|
|
980
|
+
errors.push(`server bundle \u4E0D\u5B58\u5728: ${serverRel}`);
|
|
981
|
+
} else {
|
|
982
|
+
const text = (0, import_node_fs9.readFileSync)(serverFile, "utf8");
|
|
983
|
+
if (/node_modules\/(?:next|react|react-dom|@pactor-app|pactor-app)\//.test(text)) {
|
|
984
|
+
warnings.push(
|
|
985
|
+
"server bundle \u7591\u4F3C\u5185\u5D4C next / react / pactor\uFF08\u5E94\u4FDD\u6301 external\uFF0C\u7531\u5BBF\u4E3B\u63D0\u4F9B\uFF09"
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (!Array.isArray(manifest.apiPrefixes) || manifest.apiPrefixes.length === 0) {
|
|
990
|
+
errors.push("manifest.apiPrefixes \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4");
|
|
991
|
+
} else if (manifest.apiPrefixes.some((prefix) => typeof prefix !== "string")) {
|
|
992
|
+
errors.push("manifest.apiPrefixes \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6570\u7EC4");
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
const pkgFile = (0, import_node_path9.join)(projectDir, "package.json");
|
|
996
|
+
if ((0, import_node_fs9.existsSync)(pkgFile)) {
|
|
822
997
|
try {
|
|
823
|
-
const pkg = JSON.parse((0,
|
|
998
|
+
const pkg = JSON.parse((0, import_node_fs9.readFileSync)(pkgFile, "utf8"));
|
|
824
999
|
const exportsMap = pkg.exports ?? {};
|
|
825
1000
|
if (exportsMap["./manifest"] === void 0) {
|
|
826
1001
|
errors.push('package.json exports \u7F3A\u5C11 "./manifest"\uFF08Shell \u88C5\u914D\u5668\u7ECF require.resolve("<pkg>/manifest") \u5B9A\u4F4D\uFF09');
|
|
@@ -828,6 +1003,9 @@ function validateModule(options = {}) {
|
|
|
828
1003
|
if (typeof manifest.clientEntry === "string" && exportsMap["./client"] === void 0) {
|
|
829
1004
|
errors.push('package.json exports \u7F3A\u5C11 "./client"\uFF08client-registry \u9759\u6001 import "<pkg>/client"\uFF09');
|
|
830
1005
|
}
|
|
1006
|
+
if (typeof manifest.serverEntry === "string" && exportsMap["./server"] === void 0) {
|
|
1007
|
+
errors.push('package.json exports \u7F3A\u5C11 "./server"\uFF08Shell \u88C5\u914D\u5668\u7ECF require.resolve("<pkg>/server") \u5B9A\u4F4D\uFF09');
|
|
1008
|
+
}
|
|
831
1009
|
if (typeof pkg.version === "string" && typeof manifest.version === "string" && pkg.version !== manifest.version) {
|
|
832
1010
|
warnings.push(
|
|
833
1011
|
`manifest.version (${manifest.version}) \u4E0E package.json version (${pkg.version}) \u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0 build`
|
|
@@ -841,13 +1019,17 @@ function validateModule(options = {}) {
|
|
|
841
1019
|
}
|
|
842
1020
|
return { ok: errors.length === 0, errors, warnings };
|
|
843
1021
|
}
|
|
1022
|
+
function isInsideDir(dir, file) {
|
|
1023
|
+
const root = (0, import_node_path9.resolve)(dir);
|
|
1024
|
+
return file.startsWith(`${root}${import_node_path9.sep}`);
|
|
1025
|
+
}
|
|
844
1026
|
function findPageDslFile(dslRootDir, pageId) {
|
|
845
|
-
if (!(0,
|
|
1027
|
+
if (!(0, import_node_fs9.existsSync)(dslRootDir)) return null;
|
|
846
1028
|
const queue = [dslRootDir];
|
|
847
1029
|
while (queue.length > 0) {
|
|
848
1030
|
const dir = queue.pop();
|
|
849
|
-
for (const entry of (0,
|
|
850
|
-
const full = (0,
|
|
1031
|
+
for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true })) {
|
|
1032
|
+
const full = (0, import_node_path9.join)(dir, entry.name);
|
|
851
1033
|
if (entry.isDirectory()) {
|
|
852
1034
|
queue.push(full);
|
|
853
1035
|
continue;
|
|
@@ -858,11 +1040,11 @@ function findPageDslFile(dslRootDir, pageId) {
|
|
|
858
1040
|
return null;
|
|
859
1041
|
}
|
|
860
1042
|
function listFiles(dir) {
|
|
861
|
-
if (!(0,
|
|
1043
|
+
if (!(0, import_node_fs9.existsSync)(dir)) return [];
|
|
862
1044
|
const files = [];
|
|
863
1045
|
const walk = (target) => {
|
|
864
|
-
for (const entry of (0,
|
|
865
|
-
const full = (0,
|
|
1046
|
+
for (const entry of (0, import_node_fs9.readdirSync)(target, { withFileTypes: true })) {
|
|
1047
|
+
const full = (0, import_node_path9.join)(target, entry.name);
|
|
866
1048
|
if (entry.isDirectory()) {
|
|
867
1049
|
walk(full);
|
|
868
1050
|
} else if (entry.isFile()) {
|
|
@@ -882,7 +1064,7 @@ var ModuleBuildError = class extends Error {
|
|
|
882
1064
|
}
|
|
883
1065
|
};
|
|
884
1066
|
function buildModule(options = {}) {
|
|
885
|
-
const projectDir = (0,
|
|
1067
|
+
const projectDir = (0, import_node_path10.resolve)(options.dir ?? process.cwd());
|
|
886
1068
|
const config = loadModuleConfig(projectDir, options.config);
|
|
887
1069
|
const profile = getProfile(config.target);
|
|
888
1070
|
if (profile.forbidRootBasePath && config.basePath === "/") {
|
|
@@ -891,8 +1073,17 @@ function buildModule(options = {}) {
|
|
|
891
1073
|
[`basePath: "/" \u4E0E profile ${config.target} \u7684 forbidRootBasePath \u51B2\u7A81\uFF0C\u8BF7\u6539\u7528\u5982 /${config.id} \u7684\u524D\u7F00`]
|
|
892
1074
|
);
|
|
893
1075
|
}
|
|
894
|
-
|
|
895
|
-
|
|
1076
|
+
if (config.serverEntry !== void 0 && !profile.moduleServerApi) {
|
|
1077
|
+
throw new ModuleBuildError(
|
|
1078
|
+
`target ${config.target} \u4E0D\u652F\u6301\u6A21\u5757 server entry\uFF08\u9700\u8981 innospots-web-shell@3\uFF09`,
|
|
1079
|
+
[
|
|
1080
|
+
`\u914D\u7F6E\u4E86 serverEntry / apiPrefixes\uFF0C\u4F46 profile ${config.target} \u7684 moduleServerApi=false`,
|
|
1081
|
+
'\u8BF7\u628A pactor.module.json \u7684 target \u5347\u5230 "innospots-web-shell@3" \u540E\u91CD\u65B0\u6784\u5EFA'
|
|
1082
|
+
]
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
const yamlRoot = (0, import_node_path10.join)(projectDir, config.yamlRoot);
|
|
1086
|
+
if (!(0, import_node_fs10.existsSync)(yamlRoot)) {
|
|
896
1087
|
throw new ModuleBuildError(`yamlRoot \u4E0D\u5B58\u5728: ${config.yamlRoot}`, [
|
|
897
1088
|
`yamlRoot \u4E0D\u5B58\u5728: ${yamlRoot}`
|
|
898
1089
|
]);
|
|
@@ -932,7 +1123,7 @@ function buildModule(options = {}) {
|
|
|
932
1123
|
}
|
|
933
1124
|
const transformed = transformSitemap(site, {
|
|
934
1125
|
profile,
|
|
935
|
-
|
|
1126
|
+
accessDefault: config.access.default,
|
|
936
1127
|
loadLayout: (rel) => loadYamlExpanded(yamlRoot, rel)
|
|
937
1128
|
});
|
|
938
1129
|
const version = readProjectVersion(projectDir);
|
|
@@ -941,11 +1132,13 @@ function buildModule(options = {}) {
|
|
|
941
1132
|
basePath: config.basePath,
|
|
942
1133
|
pagePaths: sitePages.map((page) => page.path).filter((path) => typeof path === "string"),
|
|
943
1134
|
loginPath: typeof siteAuth.loginPath === "string" ? siteAuth.loginPath : "/login",
|
|
944
|
-
publicDir: (0,
|
|
1135
|
+
publicDir: (0, import_node_path10.join)(projectDir, config.publicDir),
|
|
945
1136
|
rewriteNavigation: profile.rewriteNavigation.basePath,
|
|
946
1137
|
rewriteAssets: true,
|
|
947
1138
|
assetPrefix: profile.rewriteAssetUrls(config.id, version).replace(/\/+$/, ""),
|
|
948
|
-
absoluteApiToRelative: config.rewrite.absoluteApiToRelative
|
|
1139
|
+
absoluteApiToRelative: config.rewrite.absoluteApiToRelative,
|
|
1140
|
+
moduleId: config.id,
|
|
1141
|
+
apiPrefixes: config.apiPrefixes
|
|
949
1142
|
};
|
|
950
1143
|
const sitemapRewrite = rewriteDslUrls(transformed.site, rewriteCtx);
|
|
951
1144
|
warnings.push(...sitemapRewrite.warnings);
|
|
@@ -955,17 +1148,22 @@ function buildModule(options = {}) {
|
|
|
955
1148
|
warnings.push(...result.warnings.map((warning) => `${id}: ${warning}`));
|
|
956
1149
|
rewrittenPages.set(id, result.value);
|
|
957
1150
|
}
|
|
958
|
-
const outDir = (0,
|
|
959
|
-
const temp = (0,
|
|
1151
|
+
const outDir = (0, import_node_path10.join)(projectDir, config.outDir);
|
|
1152
|
+
const temp = (0, import_node_fs10.mkdtempSync)((0, import_node_path10.join)(projectDir, ".module-pack-"));
|
|
960
1153
|
try {
|
|
961
1154
|
const bundle = bundleClient({
|
|
962
1155
|
projectDir,
|
|
963
1156
|
clientEntry: config.clientEntry,
|
|
964
|
-
outDir: (0,
|
|
1157
|
+
outDir: (0, import_node_path10.join)(temp, "client")
|
|
965
1158
|
});
|
|
966
1159
|
if (bundle.message !== void 0) {
|
|
967
1160
|
warnings.push(bundle.message);
|
|
968
1161
|
}
|
|
1162
|
+
const server = config.serverEntry ? bundleServer({
|
|
1163
|
+
projectDir,
|
|
1164
|
+
serverEntry: config.serverEntry,
|
|
1165
|
+
outDir: (0, import_node_path10.join)(temp, "server")
|
|
1166
|
+
}) : void 0;
|
|
969
1167
|
const emitted = emitDsl({
|
|
970
1168
|
config,
|
|
971
1169
|
projectDir,
|
|
@@ -977,18 +1175,20 @@ function buildModule(options = {}) {
|
|
|
977
1175
|
const tailwind = compileTailwind({
|
|
978
1176
|
projectDir,
|
|
979
1177
|
tailwind: config.tailwind,
|
|
980
|
-
scanDirs: [(0,
|
|
981
|
-
cssFile: (0,
|
|
1178
|
+
scanDirs: [(0, import_node_path10.join)(temp, "dsl"), (0, import_node_path10.dirname)((0, import_node_path10.join)(projectDir, config.clientEntry))],
|
|
1179
|
+
cssFile: (0, import_node_path10.join)(temp, "client", "index.css")
|
|
982
1180
|
});
|
|
983
1181
|
warnings.push(...tailwind.warnings);
|
|
984
1182
|
}
|
|
985
|
-
const hasCss = (0,
|
|
1183
|
+
const hasCss = (0, import_node_fs10.existsSync)((0, import_node_path10.join)(temp, "client", "index.css"));
|
|
986
1184
|
writeManifest({
|
|
987
1185
|
config,
|
|
988
1186
|
projectDir,
|
|
989
1187
|
outDir: temp,
|
|
990
1188
|
clientEntry: bundle.bundled ? "client/index.js" : void 0,
|
|
991
1189
|
styles: bundle.bundled && hasCss ? ["client/index.css"] : void 0,
|
|
1190
|
+
serverEntry: server ? "server/index.mjs" : void 0,
|
|
1191
|
+
apiPrefixes: server ? config.apiPrefixes : void 0,
|
|
992
1192
|
warnings
|
|
993
1193
|
});
|
|
994
1194
|
const validation = validateModule({ dir: projectDir, config: options.config, moduleDir: temp });
|
|
@@ -999,9 +1199,9 @@ function buildModule(options = {}) {
|
|
|
999
1199
|
validation.errors
|
|
1000
1200
|
);
|
|
1001
1201
|
}
|
|
1002
|
-
(0,
|
|
1003
|
-
(0,
|
|
1004
|
-
(0,
|
|
1202
|
+
(0, import_node_fs10.rmSync)(outDir, { recursive: true, force: true });
|
|
1203
|
+
(0, import_node_fs10.mkdirSync)((0, import_node_path10.dirname)(outDir), { recursive: true });
|
|
1204
|
+
(0, import_node_fs10.renameSync)(temp, outDir);
|
|
1005
1205
|
return {
|
|
1006
1206
|
outDir,
|
|
1007
1207
|
stats: {
|
|
@@ -1011,77 +1211,142 @@ function buildModule(options = {}) {
|
|
|
1011
1211
|
assets: emitted.assetCount
|
|
1012
1212
|
},
|
|
1013
1213
|
clientBundled: bundle.bundled,
|
|
1214
|
+
serverBundled: server !== void 0,
|
|
1014
1215
|
warnings
|
|
1015
1216
|
};
|
|
1016
1217
|
} catch (error) {
|
|
1017
|
-
(0,
|
|
1218
|
+
(0, import_node_fs10.rmSync)(temp, { recursive: true, force: true });
|
|
1018
1219
|
throw error;
|
|
1019
1220
|
}
|
|
1020
1221
|
}
|
|
1021
1222
|
|
|
1022
1223
|
// src/init.ts
|
|
1023
|
-
var
|
|
1024
|
-
var
|
|
1224
|
+
var import_node_fs11 = require("fs");
|
|
1225
|
+
var import_node_path11 = require("path");
|
|
1226
|
+
var CLIENT_STYLES_ENTRY = "module/module.css";
|
|
1227
|
+
var SERVER_ENTRY = "module/server.ts";
|
|
1025
1228
|
function initModule(options = {}) {
|
|
1026
|
-
const projectDir = (0,
|
|
1027
|
-
const
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1229
|
+
const projectDir = (0, import_node_path11.resolve)(options.dir ?? process.cwd());
|
|
1230
|
+
const overwrite = options.overwrite ?? false;
|
|
1231
|
+
const server = options.server ?? false;
|
|
1232
|
+
const result = { created: [], overwritten: [], skipped: [], warnings: [] };
|
|
1233
|
+
const pkgFile = (0, import_node_path11.join)(projectDir, "package.json");
|
|
1234
|
+
if (!(0, import_node_fs11.existsSync)(pkgFile)) {
|
|
1030
1235
|
throw new Error(`\u672A\u627E\u5230 package.json: ${projectDir}\uFF08\u8BF7\u5728\u76EE\u6807\u5DE5\u7A0B\u6839\u6267\u884C\uFF09`);
|
|
1031
1236
|
}
|
|
1032
|
-
const pkg = JSON.parse((0,
|
|
1237
|
+
const pkg = JSON.parse((0, import_node_fs11.readFileSync)(pkgFile, "utf8"));
|
|
1033
1238
|
const id = deriveModuleId(pkg.name);
|
|
1034
1239
|
const actions = discoverActions(projectDir);
|
|
1035
1240
|
const hasComponents = discoverComponents(projectDir);
|
|
1036
|
-
const configFile = (0,
|
|
1037
|
-
|
|
1241
|
+
const configFile = (0, import_node_path11.join)(projectDir, CONFIG_FILE);
|
|
1242
|
+
const renderConfig = () => ({
|
|
1243
|
+
id,
|
|
1244
|
+
name: typeof pkg.name === "string" ? pkg.name : id,
|
|
1245
|
+
basePath: `/${id}`,
|
|
1246
|
+
yamlRoot: CONFIG_DEFAULTS.yamlRoot,
|
|
1247
|
+
clientEntry: CONFIG_DEFAULTS.clientEntry,
|
|
1248
|
+
// 只有显式 --server 才写入,避免纯 DSL 模块被迫启用 server entry
|
|
1249
|
+
...server ? { serverEntry: SERVER_ENTRY, apiPrefixes: [deriveApiPrefix(id)] } : {},
|
|
1250
|
+
actions: actions.map((action) => action.specifier.replace(/^\.\.\//, "")),
|
|
1251
|
+
publicDir: CONFIG_DEFAULTS.publicDir,
|
|
1252
|
+
target: DEFAULT_TARGET
|
|
1253
|
+
});
|
|
1254
|
+
const configExisted = (0, import_node_fs11.existsSync)(configFile);
|
|
1255
|
+
if (configExisted && !overwrite) {
|
|
1038
1256
|
result.skipped.push(`${CONFIG_FILE}\uFF08\u5DF2\u5B58\u5728\uFF09`);
|
|
1039
1257
|
} else {
|
|
1040
|
-
|
|
1041
|
-
id,
|
|
1042
|
-
name: typeof pkg.name === "string" ? pkg.name : id,
|
|
1043
|
-
basePath: `/${id}`,
|
|
1044
|
-
yamlRoot: CONFIG_DEFAULTS.yamlRoot,
|
|
1045
|
-
clientEntry: CONFIG_DEFAULTS.clientEntry,
|
|
1046
|
-
actions: actions.map((action) => action.specifier.replace(/^\.\.\//, "")),
|
|
1047
|
-
publicDir: CONFIG_DEFAULTS.publicDir,
|
|
1048
|
-
target: DEFAULT_TARGET,
|
|
1049
|
-
demo: { public: false }
|
|
1050
|
-
};
|
|
1051
|
-
(0, import_node_fs10.writeFileSync)(configFile, `${JSON.stringify(config, null, 2)}
|
|
1258
|
+
(0, import_node_fs11.writeFileSync)(configFile, `${JSON.stringify(renderConfig(), null, 2)}
|
|
1052
1259
|
`, "utf8");
|
|
1053
|
-
|
|
1260
|
+
if (configExisted) {
|
|
1261
|
+
result.overwritten.push(CONFIG_FILE);
|
|
1262
|
+
} else {
|
|
1263
|
+
result.created.push(CONFIG_FILE);
|
|
1264
|
+
}
|
|
1054
1265
|
}
|
|
1055
|
-
const clientFile = (0,
|
|
1056
|
-
if ((0,
|
|
1266
|
+
const clientFile = (0, import_node_path11.join)(projectDir, CONFIG_DEFAULTS.clientEntry);
|
|
1267
|
+
if ((0, import_node_fs11.existsSync)(clientFile) && !overwrite) {
|
|
1057
1268
|
result.skipped.push(`${CONFIG_DEFAULTS.clientEntry}\uFF08\u5DF2\u5B58\u5728\uFF09`);
|
|
1058
1269
|
} else {
|
|
1059
|
-
|
|
1060
|
-
(0,
|
|
1061
|
-
|
|
1270
|
+
const clientExisted = (0, import_node_fs11.existsSync)(clientFile);
|
|
1271
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path11.dirname)(clientFile), { recursive: true });
|
|
1272
|
+
(0, import_node_fs11.writeFileSync)(clientFile, renderClientEntry(hasComponents, actions), "utf8");
|
|
1273
|
+
if (clientExisted) {
|
|
1274
|
+
result.overwritten.push(CONFIG_DEFAULTS.clientEntry);
|
|
1275
|
+
} else {
|
|
1276
|
+
result.created.push(CONFIG_DEFAULTS.clientEntry);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
const stylesFile = (0, import_node_path11.join)(projectDir, CLIENT_STYLES_ENTRY);
|
|
1280
|
+
if ((0, import_node_fs11.existsSync)(stylesFile) && !overwrite) {
|
|
1281
|
+
result.skipped.push(`${CLIENT_STYLES_ENTRY}\uFF08\u5DF2\u5B58\u5728\uFF09`);
|
|
1282
|
+
} else {
|
|
1283
|
+
const stylesExisted = (0, import_node_fs11.existsSync)(stylesFile);
|
|
1284
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path11.dirname)(stylesFile), { recursive: true });
|
|
1285
|
+
(0, import_node_fs11.writeFileSync)(stylesFile, renderModuleStyles(), "utf8");
|
|
1286
|
+
if (stylesExisted) {
|
|
1287
|
+
result.overwritten.push(CLIENT_STYLES_ENTRY);
|
|
1288
|
+
} else {
|
|
1289
|
+
result.created.push(CLIENT_STYLES_ENTRY);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
if (server) {
|
|
1293
|
+
const serverFile = (0, import_node_path11.join)(projectDir, SERVER_ENTRY);
|
|
1294
|
+
if ((0, import_node_fs11.existsSync)(serverFile) && !overwrite) {
|
|
1295
|
+
result.skipped.push(`${SERVER_ENTRY}\uFF08\u5DF2\u5B58\u5728\uFF09`);
|
|
1296
|
+
} else {
|
|
1297
|
+
const serverExisted = (0, import_node_fs11.existsSync)(serverFile);
|
|
1298
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path11.dirname)(serverFile), { recursive: true });
|
|
1299
|
+
(0, import_node_fs11.writeFileSync)(serverFile, renderServerEntry(id), "utf8");
|
|
1300
|
+
if (serverExisted) {
|
|
1301
|
+
result.overwritten.push(SERVER_ENTRY);
|
|
1302
|
+
} else {
|
|
1303
|
+
result.created.push(SERVER_ENTRY);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1062
1306
|
}
|
|
1063
|
-
|
|
1064
|
-
(
|
|
1307
|
+
const hasServerEntry = (0, import_node_fs11.existsSync)((0, import_node_path11.join)(projectDir, SERVER_ENTRY));
|
|
1308
|
+
injectPackageJson(pkg, result, hasServerEntry);
|
|
1309
|
+
if (hasServerEntry && !configDeclaresServerEntry(configFile)) {
|
|
1310
|
+
result.warnings.push(
|
|
1311
|
+
'\u68C0\u6D4B\u5230 module/server.ts\uFF1A\u5DF2\u6CE8\u5165 "./server" export\uFF1B\u8BF7\u5728 pactor.module.json \u4E2D\u540C\u65F6\u914D\u7F6E serverEntry \u4E0E apiPrefixes \u540E\u518D\u6784\u5EFA\uFF08\u7F3A\u4E00\u6784\u5EFA\u4F1A\u5931\u8D25\uFF09'
|
|
1312
|
+
);
|
|
1313
|
+
}
|
|
1314
|
+
(0, import_node_fs11.writeFileSync)(pkgFile, `${JSON.stringify(pkg, null, 2)}
|
|
1065
1315
|
`, "utf8");
|
|
1066
1316
|
result.created.push("package.json\uFF08\u6CE8\u5165 files / exports / scripts / peerDependencies\uFF09");
|
|
1067
1317
|
return result;
|
|
1068
1318
|
}
|
|
1319
|
+
function configDeclaresServerEntry(configFile) {
|
|
1320
|
+
if (!(0, import_node_fs11.existsSync)(configFile)) return false;
|
|
1321
|
+
try {
|
|
1322
|
+
const raw = JSON.parse((0, import_node_fs11.readFileSync)(configFile, "utf8"));
|
|
1323
|
+
return raw.serverEntry === SERVER_ENTRY;
|
|
1324
|
+
} catch {
|
|
1325
|
+
return false;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
var MODULE_ID_PREFIX = "pactor-app-";
|
|
1069
1329
|
function deriveModuleId(name) {
|
|
1070
1330
|
const base2 = typeof name === "string" && name.length > 0 ? name : "module";
|
|
1071
1331
|
const withoutScope = base2.startsWith("@") ? base2.slice(base2.indexOf("/") + 1) : base2;
|
|
1072
1332
|
const kebab = withoutScope.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1073
|
-
|
|
1333
|
+
const id = kebab.length > 0 ? kebab : "module";
|
|
1334
|
+
return id.startsWith(MODULE_ID_PREFIX) ? id : `${MODULE_ID_PREFIX}${id}`;
|
|
1335
|
+
}
|
|
1336
|
+
function deriveApiPrefix(moduleId) {
|
|
1337
|
+
const slug = moduleId.startsWith(MODULE_ID_PREFIX) ? moduleId.slice(MODULE_ID_PREFIX.length) : moduleId;
|
|
1338
|
+
return `/api/${slug.length > 0 ? slug : "module"}`;
|
|
1074
1339
|
}
|
|
1075
1340
|
function discoverActions(projectDir) {
|
|
1076
|
-
const dir = (0,
|
|
1077
|
-
if (!(0,
|
|
1341
|
+
const dir = (0, import_node_path11.join)(projectDir, "src/pactor");
|
|
1342
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return [];
|
|
1078
1343
|
const sources = [];
|
|
1079
|
-
for (const entry of (0,
|
|
1344
|
+
for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true }).sort(
|
|
1080
1345
|
(a, b) => a.name.localeCompare(b.name)
|
|
1081
1346
|
)) {
|
|
1082
1347
|
if (!entry.isFile() || !entry.name.endsWith("-actions.ts")) continue;
|
|
1083
|
-
const file = (0,
|
|
1084
|
-
const content = (0,
|
|
1348
|
+
const file = (0, import_node_path11.join)(dir, entry.name);
|
|
1349
|
+
const content = (0, import_node_fs11.readFileSync)(file, "utf8");
|
|
1085
1350
|
const exports2 = [...content.matchAll(/export\s+const\s+([A-Za-z_$][\w$]*)/g)].map(
|
|
1086
1351
|
(match) => match[1]
|
|
1087
1352
|
);
|
|
@@ -1094,9 +1359,9 @@ function discoverActions(projectDir) {
|
|
|
1094
1359
|
return sources;
|
|
1095
1360
|
}
|
|
1096
1361
|
function discoverComponents(projectDir) {
|
|
1097
|
-
const file = (0,
|
|
1098
|
-
if (!(0,
|
|
1099
|
-
return /export\s+(const|\{[^}]*)\s*pactorComponents/.test((0,
|
|
1362
|
+
const file = (0, import_node_path11.join)(projectDir, "src/pactor/components/index.ts");
|
|
1363
|
+
if (!(0, import_node_fs11.existsSync)(file)) return false;
|
|
1364
|
+
return /export\s+(const|\{[^}]*)\s*pactorComponents/.test((0, import_node_fs11.readFileSync)(file, "utf8"));
|
|
1100
1365
|
}
|
|
1101
1366
|
function renderClientEntry(hasComponents, actions) {
|
|
1102
1367
|
const imports = [];
|
|
@@ -1112,18 +1377,48 @@ function renderClientEntry(hasComponents, actions) {
|
|
|
1112
1377
|
}
|
|
1113
1378
|
const components = hasComponents ? "pactorComponents" : "{}";
|
|
1114
1379
|
const actionsExpr = spreads.length > 0 ? `{ ${spreads.join(", ")} }` : "{}";
|
|
1380
|
+
const importsBlock = imports.length > 0 ? `${imports.join("\n")}
|
|
1381
|
+
` : "";
|
|
1115
1382
|
return `// \u7531 \`pactor module init\` \u751F\u6210\uFF1A\u6A21\u5757 client \u5165\u53E3\u3002
|
|
1116
1383
|
// Shell \u88C5\u914D\u5668\u751F\u6210 client-registry.ts \u65F6\u9759\u6001 import "<pkg>/client"\uFF0C
|
|
1117
1384
|
// \u8981\u6C42\u6B64\u5904\u5177\u540D\u5BFC\u51FA extensions\uFF08components / actions \u6CE8\u518C\u8868\uFF09\u3002
|
|
1118
|
-
|
|
1119
|
-
|
|
1385
|
+
// module.css \u7531 esbuild \u62BD\u6210 client/index.css\uFF0CShell \u6309 manifest.styles \u52A0\u8F7D\u3002
|
|
1386
|
+
import './module.css';
|
|
1387
|
+
${importsBlock}
|
|
1120
1388
|
export const extensions = {
|
|
1121
1389
|
components: ${components},
|
|
1122
1390
|
actions: ${actionsExpr},
|
|
1123
1391
|
};
|
|
1124
1392
|
`;
|
|
1125
1393
|
}
|
|
1126
|
-
function
|
|
1394
|
+
function renderModuleStyles() {
|
|
1395
|
+
return `/**
|
|
1396
|
+
* \u6A21\u5757\u81EA\u5E26\u6837\u5F0F\uFF08\u7531 \`pactor module init\` \u751F\u6210\uFF09\u3002
|
|
1397
|
+
*
|
|
1398
|
+
* \u672C\u6587\u4EF6\u7531 module/client.ts import\uFF1Aesbuild \u6253\u5305\u65F6\u4F1A\u62BD\u53D6\u4E3A
|
|
1399
|
+
* dist-module/client/index.css \u5E76\u5199\u5165 manifest.styles\uFF0CShell \u636E\u6B64\u81EA\u52A8\u52A0\u8F7D\u3002
|
|
1400
|
+
* Tailwind \u57FA\u7840\u6837\u5F0F\u3001pactor-app \u805A\u5408\u6837\u5F0F\u4E0E\u4E3B\u9898\u53D8\u91CF\u7531 Shell \u7EDF\u4E00\u63D0\u4F9B\uFF0C
|
|
1401
|
+
* \u6A21\u5757\u5185\u4E0D\u8981\u91CD\u590D\u5F15\u5165\uFF0C\u907F\u514D\u4EA7\u751F\u7B2C\u4E8C\u4EFD reset / \u4EE4\u724C\u3002
|
|
1402
|
+
*/
|
|
1403
|
+
|
|
1404
|
+
/* \u6A21\u5757\u7EA7\u6837\u5F0F\u5199\u5728\u8FD9\u91CC\uFF1A\u5EFA\u8BAE\u4F7F\u7528\u5E26\u6A21\u5757\u524D\u7F00\u7684\u7C7B\u540D\uFF0C\u907F\u514D\u4E0E Shell \u5168\u5C40\u6837\u5F0F\u51B2\u7A81\u3002 */
|
|
1405
|
+
`;
|
|
1406
|
+
}
|
|
1407
|
+
function renderServerEntry(moduleId) {
|
|
1408
|
+
const prefix = deriveApiPrefix(moduleId);
|
|
1409
|
+
return `// \u7531 \`pactor module init --server\` \u751F\u6210\uFF1A\u6A21\u5757\u670D\u52A1\u7AEF\u5165\u53E3\u3002
|
|
1410
|
+
// \u5BFC\u51FA\u300C\u903B\u8F91\u8DEF\u5F84 \u2192 \u65B9\u6CD5\u5904\u7406\u51FD\u6570\u300D\u6620\u5C04\uFF1A\u8DEF\u5F84\u952E\u4F7F\u7528\u539F\u59CB /api/... \u903B\u8F91\u8DEF\u5F84\uFF0C
|
|
1411
|
+
// Shell \u901A\u8FC7 /api/modules/<moduleId>/* \u7EDF\u4E00\u5206\u53D1\uFF08\u89C1 pactor.module.json \u7684 apiPrefixes\uFF09\u3002
|
|
1412
|
+
// handler \u53EA\u4F9D\u8D56 Web \u6807\u51C6 Request / Response\uFF0Ccontext.url \u4E3A\u903B\u8F91 URL\uFF08\u542B query\uFF09\u3002
|
|
1413
|
+
|
|
1414
|
+
export const handlers = {
|
|
1415
|
+
// '${prefix}/hello': {
|
|
1416
|
+
// GET: () => Response.json({ code: 0, data: { ok: true }, message: 'ok' }),
|
|
1417
|
+
// },
|
|
1418
|
+
};
|
|
1419
|
+
`;
|
|
1420
|
+
}
|
|
1421
|
+
function injectPackageJson(pkg, result, hasServerEntry) {
|
|
1127
1422
|
const outDir = CONFIG_DEFAULTS.outDir;
|
|
1128
1423
|
const files = Array.isArray(pkg.files) ? pkg.files : [];
|
|
1129
1424
|
if (!files.includes(outDir)) {
|
|
@@ -1133,7 +1428,8 @@ function injectPackageJson(pkg, result) {
|
|
|
1133
1428
|
const wantedExports = {
|
|
1134
1429
|
"./manifest": `./${outDir}/manifest.json`,
|
|
1135
1430
|
"./client": `./${outDir}/client/index.js`,
|
|
1136
|
-
"./styles.css": `./${outDir}/client/index.css
|
|
1431
|
+
"./styles.css": `./${outDir}/client/index.css`,
|
|
1432
|
+
...hasServerEntry ? { "./server": `./${outDir}/server/index.mjs` } : {}
|
|
1137
1433
|
};
|
|
1138
1434
|
for (const [key, value] of Object.entries(wantedExports)) {
|
|
1139
1435
|
if (exportsMap[key] === void 0) {
|
|
@@ -1146,7 +1442,8 @@ function injectPackageJson(pkg, result) {
|
|
|
1146
1442
|
const scripts = isRecord4(pkg.scripts) ? { ...pkg.scripts } : {};
|
|
1147
1443
|
const wantedScripts = {
|
|
1148
1444
|
"build:module": "pactor module build",
|
|
1149
|
-
"pack:module": "pactor module pack"
|
|
1445
|
+
"pack:module": "pactor module pack",
|
|
1446
|
+
"publish:module": "pactor module publish"
|
|
1150
1447
|
};
|
|
1151
1448
|
for (const [key, value] of Object.entries(wantedScripts)) {
|
|
1152
1449
|
if (scripts[key] === void 0) {
|
|
@@ -1174,21 +1471,72 @@ function injectPackageJson(pkg, result) {
|
|
|
1174
1471
|
function isRecord4(value) {
|
|
1175
1472
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1176
1473
|
}
|
|
1474
|
+
|
|
1475
|
+
// src/version.ts
|
|
1476
|
+
var import_node_fs12 = require("fs");
|
|
1477
|
+
var import_node_path12 = require("path");
|
|
1478
|
+
var SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?$/;
|
|
1479
|
+
function bumpVersion(current, release) {
|
|
1480
|
+
if (release === "major" || release === "minor" || release === "patch") {
|
|
1481
|
+
const match = SEMVER_RE.exec(current);
|
|
1482
|
+
if (!match) {
|
|
1483
|
+
throw new ConfigError(`package.json \u7248\u672C\u53F7\u975E\u6CD5: ${current}\uFF08\u671F\u671B x.y.z\uFF09`);
|
|
1484
|
+
}
|
|
1485
|
+
const [, major, minor, patch] = match;
|
|
1486
|
+
if (release === "major") return `${Number(major) + 1}.0.0`;
|
|
1487
|
+
if (release === "minor") return `${major}.${Number(minor) + 1}.0`;
|
|
1488
|
+
return `${major}.${minor}.${Number(patch) + 1}`;
|
|
1489
|
+
}
|
|
1490
|
+
if (!SEMVER_RE.test(release)) {
|
|
1491
|
+
throw new ConfigError(
|
|
1492
|
+
`--bump \u53D6\u503C\u975E\u6CD5: ${release}\uFF08\u652F\u6301 patch | minor | major | \u663E\u5F0F\u7248\u672C\u53F7 x.y.z\uFF09`
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
return release;
|
|
1496
|
+
}
|
|
1497
|
+
function bumpPackageVersion(options) {
|
|
1498
|
+
const dir = (0, import_node_path12.resolve)(options.dir ?? process.cwd());
|
|
1499
|
+
const pkgFile = (0, import_node_path12.resolve)(dir, "package.json");
|
|
1500
|
+
if (!(0, import_node_fs12.existsSync)(pkgFile)) {
|
|
1501
|
+
throw new ConfigError(`\u672A\u627E\u5230 package.json: ${dir}\uFF08\u8BF7\u5728\u76EE\u6807\u5DE5\u7A0B\u6839\u6267\u884C\uFF09`);
|
|
1502
|
+
}
|
|
1503
|
+
const pkg = JSON.parse((0, import_node_fs12.readFileSync)(pkgFile, "utf8"));
|
|
1504
|
+
const name = typeof pkg.name === "string" ? pkg.name : "(\u672A\u547D\u540D)";
|
|
1505
|
+
if (typeof pkg.version !== "string" || pkg.version === "") {
|
|
1506
|
+
throw new ConfigError(`package.json \u7F3A\u5C11 version \u5B57\u6BB5: ${pkgFile}`);
|
|
1507
|
+
}
|
|
1508
|
+
const from = pkg.version;
|
|
1509
|
+
const to = bumpVersion(from, options.release);
|
|
1510
|
+
pkg.version = to;
|
|
1511
|
+
(0, import_node_fs12.writeFileSync)(pkgFile, `${JSON.stringify(pkg, null, 2)}
|
|
1512
|
+
`, "utf8");
|
|
1513
|
+
return { name, from, to };
|
|
1514
|
+
}
|
|
1177
1515
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1178
1516
|
0 && (module.exports = {
|
|
1179
1517
|
CLIENT_EXTERNALS,
|
|
1518
|
+
CLIENT_STYLES_ENTRY,
|
|
1180
1519
|
CONFIG_DEFAULTS,
|
|
1181
1520
|
CONFIG_FILE,
|
|
1182
1521
|
ConfigError,
|
|
1183
1522
|
DEFAULT_TARGET,
|
|
1184
1523
|
INCLUDE_KEY,
|
|
1185
1524
|
IncludeError,
|
|
1525
|
+
MODULE_ID_PREFIX,
|
|
1186
1526
|
ModuleBuildError,
|
|
1187
1527
|
ProfileError,
|
|
1528
|
+
SERVER_BUNDLE_FILE,
|
|
1529
|
+
SERVER_ENTRY,
|
|
1530
|
+
SERVER_EXTERNALS,
|
|
1531
|
+
ServerBundleError,
|
|
1188
1532
|
buildModule,
|
|
1533
|
+
bumpPackageVersion,
|
|
1534
|
+
bumpVersion,
|
|
1189
1535
|
bundleClient,
|
|
1536
|
+
bundleServer,
|
|
1190
1537
|
collectModuleSource,
|
|
1191
1538
|
compileTailwind,
|
|
1539
|
+
deriveApiPrefix,
|
|
1192
1540
|
deriveModuleId,
|
|
1193
1541
|
discoverActions,
|
|
1194
1542
|
discoverComponents,
|
|
@@ -1199,6 +1547,7 @@ function isRecord4(value) {
|
|
|
1199
1547
|
initModule,
|
|
1200
1548
|
innospotsWebShellV1,
|
|
1201
1549
|
innospotsWebShellV2,
|
|
1550
|
+
innospotsWebShellV3,
|
|
1202
1551
|
listProfiles,
|
|
1203
1552
|
loadModuleConfig,
|
|
1204
1553
|
loadYamlExpanded,
|
|
@@ -1207,6 +1556,8 @@ function isRecord4(value) {
|
|
|
1207
1556
|
parseYamlFile,
|
|
1208
1557
|
readProjectVersion,
|
|
1209
1558
|
renderClientEntry,
|
|
1559
|
+
renderModuleStyles,
|
|
1560
|
+
renderServerEntry,
|
|
1210
1561
|
resolvePactorVersionRange,
|
|
1211
1562
|
rewriteDslUrls,
|
|
1212
1563
|
rewriteNavigationTo,
|