@yongdall/assets 0.1.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/bin.mjs ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import configuration, { assetsRoot, boot, projectRoot } from "@yongdall/configuration";
3
+ import { assets, initAssets } from "#index";
4
+
5
+ //#region cli/assets/bin.mjs
6
+ const { pluginAssets, nodeModules } = await assets(projectRoot);
7
+ await initAssets(projectRoot, assetsRoot, pluginAssets, nodeModules, {
8
+ title: configuration.title || "",
9
+ bootModule: configuration.bootModule,
10
+ bootName: configuration.bootName
11
+ }, boot);
12
+
13
+ //#endregion
14
+ //# sourceMappingURL=bin.mjs.map
package/bin.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.mjs","names":[],"sources":["../../cli/assets/bin.mjs"],"sourcesContent":["#!/usr/bin/env node\nimport configuration, { assetsRoot, boot, projectRoot } from '@yongdall/configuration';\nimport { initAssets, assets } from '#index';\n\nconst {pluginAssets, nodeModules} = await assets(projectRoot);\n\n\nawait initAssets(projectRoot, assetsRoot, pluginAssets, nodeModules, {\n\ttitle: configuration.title || '',\n\tbootModule: configuration.bootModule,\n\tbootName: configuration.bootName,\n}, boot);\n"],"mappings":";;;;;AAIA,MAAM,EAAC,cAAc,gBAAe,MAAM,OAAO,YAAY;AAG7D,MAAM,WAAW,aAAa,YAAY,cAAc,aAAa;CACpE,OAAO,cAAc,SAAS;CAC9B,YAAY,cAAc;CAC1B,UAAU,cAAc;CACxB,EAAE,KAAK"}
package/index.mjs ADDED
@@ -0,0 +1,417 @@
1
+ import { loadCfg } from "@yongdall/configuration";
2
+ import { pluginIdRegex } from "@yongdall/common";
3
+ import * as pathPosix from "node:path/posix";
4
+ import * as pathFn from "node:path";
5
+ import * as fsPromises from "node:fs/promises";
6
+ import pluginRoots from "@yongdall/plugins";
7
+
8
+ //#region cli/assets/createImportmap.mjs
9
+ /** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */
10
+ /**
11
+ *
12
+ * @param {string} text
13
+ * @param {Record<string, string | undefined>} values
14
+ * @returns
15
+ */
16
+ function replace(text, values) {
17
+ const { index } = /#|\?/.exec(text) || { index: Infinity };
18
+ return text.replace(/\{%([^%]*)%\}/g, (_, k, no) => {
19
+ const v = k in values && values[k];
20
+ if (typeof v !== "string") return "";
21
+ const s = encodeURIComponent(v);
22
+ if (index < no) return s;
23
+ return s.replace(/%2F/gi, "/").replace(/%40/g, "@");
24
+ });
25
+ }
26
+ /**
27
+ *
28
+ * @param {Record<string, Record<string, string>>} scopes
29
+ * @param {string} scope
30
+ * @returns
31
+ */
32
+ function getScope(scopes, scope) {
33
+ if (!(scope in scopes)) scopes[scope] = {};
34
+ return scopes[scope];
35
+ }
36
+ /**
37
+ *
38
+ * @param {string} serverRoot
39
+ * @param {string} origin
40
+ * @param {string} version
41
+ * @param {Record<string, string>} scope
42
+ * @param {Record<string, string>} map
43
+ * @param {Record<string, string>} [values]
44
+ */
45
+ function replaceScope(serverRoot, origin, version, scope, map, values) {
46
+ const assetsRoot = `${serverRoot}/assets`;
47
+ const originRoot = `${assetsRoot}/plugins/${origin}/${version}`;
48
+ const value = {
49
+ ...values,
50
+ origin,
51
+ "root:server": serverRoot,
52
+ "root:assets": assetsRoot,
53
+ "root:origin": originRoot
54
+ };
55
+ for (const [path, url] of Object.entries(map)) scope[replace(path, { origin })] = replace(url, {
56
+ url: scope[path],
57
+ ...value
58
+ });
59
+ }
60
+ /**
61
+ *
62
+ * @param {string} root
63
+ * @param {Record<string, PluginAssets | undefined>} plugins
64
+ * @param {Record<string, NodeModuleAssets>} [nodeModules]
65
+ * @returns
66
+ */
67
+ function createImportmap(root, plugins, nodeModules = {}) {
68
+ /** @type {Record<string, string>} */
69
+ const imports = {};
70
+ /** @type {Record<string, Record<string, string>>} */
71
+ const scopes = {};
72
+ for (const [itemName, assets] of Object.entries(plugins)) {
73
+ if (!assets) continue;
74
+ const { dir, esm, alias, version } = assets;
75
+ const encodedPlugin = encodeURIComponent(itemName).replace(/%2F/gi, "/").replace(/%40/g, "@");
76
+ const assetsRoot = pathPosix.join(`${root}/assets/plugins/`, itemName, version);
77
+ /** @type {Record<string, string>} */
78
+ const scope = { "@/": pathPosix.join(assetsRoot, `./`) };
79
+ scopes[`${root}/assets/plugins/${encodedPlugin}/`] = scope;
80
+ if (!esm) continue;
81
+ const nameRoot = [...new Set([itemName, pathPosix.join(itemName, dir || "")])];
82
+ const indexEsm = alias?.["."];
83
+ if (indexEsm && Object.hasOwn(esm, indexEsm)) {
84
+ const indexFile = esm[indexEsm];
85
+ if (indexFile) {
86
+ const indexPath = pathPosix.join(assetsRoot, indexFile);
87
+ scope["@"] = indexPath;
88
+ for (const name of nameRoot) imports[name] = indexPath;
89
+ }
90
+ }
91
+ for (const name of nameRoot) {
92
+ const path = encodeURIComponent(name).replace(/%2F/gi, "/").replace(/%40/g, "@");
93
+ for (const [k, v] of Object.entries(esm)) {
94
+ const key = pathPosix.join(name, k);
95
+ if (nameRoot.includes(key)) continue;
96
+ imports[key] = pathPosix.join(`${root}/assets/plugins/`, path, version, v);
97
+ }
98
+ if (alias) for (const [k, ev] of Object.entries(alias)) {
99
+ const v = Object.hasOwn(esm, ev) && esm[ev];
100
+ if (!v) continue;
101
+ const key = pathPosix.join(name, k);
102
+ if (nameRoot.includes(key)) continue;
103
+ imports[key] = pathPosix.join(`${root}/assets/plugins/`, path, version, v);
104
+ }
105
+ }
106
+ }
107
+ for (const [itemName, { esm, version }] of Object.entries(nodeModules)) {
108
+ const exports = esm || {};
109
+ const encodedName = encodeURIComponent(pathPosix.join(itemName, version)).replace(/%2F/gi, "/").replace(/%40/g, "@");
110
+ imports[itemName + "/"] = pathPosix.join(`${root}/assets/node_modules/`, encodedName, "./");
111
+ for (const [k, v] of Object.entries(exports)) {
112
+ const key = pathPosix.join(itemName, k);
113
+ imports[key] = pathPosix.join(`${root}/assets/node_modules/`, encodedName, v);
114
+ }
115
+ }
116
+ for (const [origin, assets] of Object.entries(plugins)) {
117
+ if (!assets) continue;
118
+ const { importmap, esm, version } = assets;
119
+ /** @type {Record<string, string>} */
120
+ const esmValues = {};
121
+ for (const [k, v] of Object.entries(esm || {})) esmValues[`esm:${k}`] = v;
122
+ if (!importmap) continue;
123
+ for (const [id, map] of Object.entries(importmap)) {
124
+ if (!map) continue;
125
+ if (id === "/") {
126
+ replaceScope(root, origin, version, imports, map, esmValues);
127
+ continue;
128
+ }
129
+ if (id[0] === "/") {
130
+ replaceScope(root, origin, version, getScope(scopes, id), map, {
131
+ ...esmValues,
132
+ scope: id
133
+ });
134
+ continue;
135
+ }
136
+ if (id === ".") {
137
+ const scope = `${root}/assets/plugins/${origin}/`;
138
+ replaceScope(root, origin, version, getScope(scopes, scope), map, {
139
+ ...esmValues,
140
+ scope,
141
+ plugin: origin
142
+ });
143
+ continue;
144
+ }
145
+ if (id[0] === ".") continue;
146
+ if (id === "*") {
147
+ for (const plugin of Object.keys(plugins)) {
148
+ const scope = `${root}/assets/plugins/${plugin}/`;
149
+ replaceScope(root, origin, version, getScope(scopes, scope), map, {
150
+ ...esmValues,
151
+ scope,
152
+ plugin
153
+ });
154
+ }
155
+ continue;
156
+ }
157
+ if (!pluginIdRegex.test(id)) continue;
158
+ const scope = `${root}/assets/plugins/${id}/`;
159
+ replaceScope(root, origin, version, getScope(scopes, scope), map, {
160
+ ...esmValues,
161
+ scope,
162
+ plugin: id
163
+ });
164
+ }
165
+ }
166
+ return {
167
+ imports,
168
+ scopes
169
+ };
170
+ }
171
+
172
+ //#endregion
173
+ //#region cli/assets/assets.mjs
174
+ /** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */
175
+ /**
176
+ *
177
+ * @param {string} path
178
+ * @returns
179
+ */
180
+ async function importIfExist(path) {
181
+ if (!(await fsPromises.stat(path).catch(() => null))?.isFile()) return null;
182
+ return await import(path).catch((e) => {
183
+ console.error(e);
184
+ return null;
185
+ });
186
+ }
187
+ /**
188
+ *
189
+ * @param {string} path
190
+ */
191
+ async function readPluginPackageJSON(path) {
192
+ const file = pathFn.resolve(path, "package.json");
193
+ const version = (await fsPromises.readFile(file, "utf-8").then((v) => JSON.parse(v)).catch((e) => {
194
+ console.error(e);
195
+ return null;
196
+ }))?.version;
197
+ if (version && typeof version === "string") return { version };
198
+ return null;
199
+ }
200
+ /**
201
+ *
202
+ * @param {string} root
203
+ * @param {string} name
204
+ */
205
+ async function findNodeModule(root, name) {
206
+ for (let basepath = root;;) {
207
+ const path = pathFn.resolve(basepath, "node_modules", name);
208
+ const version = (await fsPromises.readFile(pathFn.resolve(path, "package.json"), "utf-8").then((v) => JSON.parse(v)).catch(() => null))?.version;
209
+ if (version && typeof version === "string") return {
210
+ path,
211
+ version
212
+ };
213
+ const parent = pathFn.dirname(basepath);
214
+ if (parent === basepath) break;
215
+ basepath = parent;
216
+ }
217
+ return null;
218
+ }
219
+ /**
220
+ *
221
+ * @param {string} projectRoot
222
+ */
223
+ async function assets(projectRoot) {
224
+ /** @type {Record<string, NodeModuleAssets & {path: string}>} */
225
+ const nodeModules = Object.create(null);
226
+ /** @type {Record<string, PluginAssets & {path: string}>} */
227
+ const pluginAssets = Object.create(null);
228
+ const now = `${Date.now()}`;
229
+ for (const [plugin, { root: pluginRoot, development }] of Object.entries(pluginRoots)) {
230
+ const assets = await importIfExist(pathFn.resolve(pluginRoot, "assets.yongdall.mjs"));
231
+ if (!assets) continue;
232
+ const assetPackage = await readPluginPackageJSON(pluginRoot);
233
+ pluginAssets[plugin] = {
234
+ ...assets,
235
+ path: pathFn.resolve(pluginRoot, assets.dir || ""),
236
+ version: !development && String(assets.version || assetPackage?.version || "").replace(/[^.\da-zA-Z_-]/g, "") || now
237
+ };
238
+ for (const [name, value] of Object.entries(assets?.nodeModules || {})) {
239
+ if (!value) continue;
240
+ const info = await findNodeModule(pluginRoot, name);
241
+ if (!info) continue;
242
+ nodeModules[name] = {
243
+ ...value,
244
+ ...info,
245
+ version: String(info.version || value.version || now).replace(/[^.\da-zA-Z_-]/g, "")
246
+ };
247
+ }
248
+ }
249
+ for (const [name, value] of Object.entries(await loadCfg("nodeModules") || {})) {
250
+ const info = await findNodeModule(projectRoot, name);
251
+ if (!info) continue;
252
+ nodeModules[name] = {
253
+ ...value,
254
+ ...info,
255
+ version: String(info.version || value.version || "VERSION").replace(/[^.\da-zA-Z_-]/g, "")
256
+ };
257
+ }
258
+ return {
259
+ pluginAssets,
260
+ nodeModules
261
+ };
262
+ }
263
+
264
+ //#endregion
265
+ //#region cli/assets/initAssets.mjs
266
+ /** @import { Plugin } from '@yongdall/common' */
267
+ /** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */
268
+ /**
269
+ *
270
+ * @param {string} path
271
+ * @returns {Promise<void>}
272
+ */
273
+ async function rm(path) {
274
+ const stat = await fsPromises.lstat(path).catch(() => {});
275
+ if (!stat) return;
276
+ if (!stat.isDirectory()) {
277
+ await fsPromises.unlink(path);
278
+ return;
279
+ }
280
+ const files = await fsPromises.readdir(path);
281
+ for (const file of files) await rm(pathFn.resolve(path, file));
282
+ await fsPromises.rmdir(path);
283
+ }
284
+ /**
285
+ *
286
+ * @param {string} pluginsRoot
287
+ * @param {Record<string, {path: string; version?: string;}>} plugins
288
+ * @param {string} [type]
289
+ * @returns {Promise<void>}
290
+ */
291
+ async function linkPluginAssets(pluginsRoot, plugins, type = "Plugin Assets") {
292
+ await fsPromises.mkdir(pluginsRoot, { recursive: true });
293
+ for (const [plugin, { path, version }] of Object.entries(plugins)) {
294
+ console.log(`Link ${type}: ${plugin}`);
295
+ await fsPromises.mkdir(pathFn.resolve(pluginsRoot, plugin), { recursive: true });
296
+ await fsPromises.symlink(path, pathFn.resolve(pluginsRoot, plugin, (version || `VERSION`).replace(/[^.\da-zA-Z_-]/g, "")));
297
+ }
298
+ }
299
+ /**
300
+ *
301
+ * @param {string} bootFileName
302
+ * @param {string} [root]
303
+ * @param {string} [title]
304
+ * @param {string} [boot]
305
+ * @param {string[]} [polyfill]
306
+ * @returns {string}
307
+ */
308
+ function getIndexHtml(bootFileName, root, title, boot, polyfill) {
309
+ return `<!DOCTYPE html>
310
+ <html>
311
+ <head>
312
+ <meta charset="UTF-8">
313
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
314
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
315
+ <title>${title || "拥道YongDall"}</title>
316
+ ${polyfill?.map((src) => `<script src="${root || ""}/assets/${src}"><\/script>`).join("\n") || ""}
317
+ <script src="${root || ""}/assets/${bootFileName}"${boot ? ` boot-module="${boot}"` : ""}><\/script>
318
+ </head>
319
+ <body></body>
320
+ </html>
321
+ `;
322
+ }
323
+ /**
324
+ *
325
+ * @param {ReturnType<typeof createImportmap>} importmap
326
+ * @param {Record<string, PluginAssets>} [plugins]
327
+ */
328
+ function getBootloaderJs(importmap, plugins) {
329
+ return `;(function() {
330
+ document.write('<script type="importmap">' + JSON.stringify(${JSON.stringify(importmap)}) + '<\/script>');
331
+ window.yongdallPlugins = ${JSON.stringify(getPluginConfig(typeof plugins === "object" && plugins || {}))};
332
+ const currentScript = document.currentScript;
333
+ if (!currentScript) { return; }
334
+ const boot = currentScript.getAttribute('boot-module');
335
+ if (boot) { import(boot); }
336
+ })();`;
337
+ }
338
+ /**
339
+ *
340
+ * @param {ReturnType<typeof createImportmap>} importmap
341
+ */
342
+ function getImportmapJs(importmap) {
343
+ return `document.write('<script type="importmap">' + JSON.stringify(${JSON.stringify(importmap)}) + '<\/script>');`;
344
+ }
345
+ /**
346
+ *
347
+ * @param {string} assetsDir
348
+ */
349
+ async function clearAssets(assetsDir) {
350
+ const stat = await fsPromises.lstat(assetsDir).catch(() => {});
351
+ if (!stat) return;
352
+ if (!stat.isDirectory()) {
353
+ await fsPromises.unlink(assetsDir);
354
+ return;
355
+ }
356
+ const files = await fsPromises.readdir(assetsDir);
357
+ for (const file of files) if ([
358
+ "index.html",
359
+ "plugins",
360
+ "node_modules"
361
+ ].includes(file) || /^(bootloader|importmap)(\.\d+)?\.js(on)?$/.test(file)) await rm(pathFn.resolve(assetsDir, file));
362
+ }
363
+ /**
364
+ *
365
+ * @param {Record<string, PluginAssets>} pluginAssetDefines
366
+ */
367
+ function getPluginConfig(pluginAssetDefines) {
368
+ /** @type {Record<string, Plugin>} */
369
+ const plugins = {};
370
+ for (const [plugin, assets] of Object.entries(pluginAssetDefines)) {
371
+ /** @type {Plugin} */
372
+ const pluginDef = {};
373
+ plugins[plugin] = pluginDef;
374
+ if (!assets) continue;
375
+ const { files, hooks, styles } = assets;
376
+ if (typeof hooks === "string" && hooks) pluginDef.hooks = hooks;
377
+ if (files && Object.keys(files).length) pluginDef.assets = files;
378
+ if (Array.isArray(styles) && styles.length) pluginDef.styles = styles;
379
+ pluginDef.version = assets.version;
380
+ }
381
+ return plugins;
382
+ }
383
+ /**
384
+ *
385
+ * @param {string} root
386
+ * @param {string} assetsDir
387
+ * @param {Record<string, PluginAssets & {path: string}>} pluginAssets
388
+ * @param {Record<string, NodeModuleAssets & {path: string}>} nodeModules
389
+ * @param {object} options
390
+ * @param {string} [options.serverRoot]
391
+ * @param {string} [options.bootModule]
392
+ * @param {string} [options.bootName]
393
+ * @param {string} [options.title]
394
+ * @param {object} bootConfig
395
+ */
396
+ async function initAssets(root, assetsDir, pluginAssets, nodeModules, { serverRoot, bootModule, bootName, title }, bootConfig) {
397
+ const sRoot = pathPosix.join("/", serverRoot || "", ".").replace(/\/$/, "");
398
+ const importmap = createImportmap(sRoot, pluginAssets, nodeModules);
399
+ await clearAssets(assetsDir);
400
+ await linkPluginAssets(pathFn.resolve(assetsDir, "plugins"), pluginAssets);
401
+ await linkPluginAssets(pathFn.resolve(assetsDir, "node_modules"), nodeModules, "Node Module");
402
+ await fsPromises.mkdir(pathFn.resolve(assetsDir), { recursive: true });
403
+ const polyfill = Object.values(pluginAssets).flatMap((v) => v.polyfill || []);
404
+ const date = Date.now();
405
+ await fsPromises.writeFile(pathFn.resolve(assetsDir, `importmap.${date}.js`), getImportmapJs(importmap));
406
+ await fsPromises.writeFile(pathFn.resolve(assetsDir, `importmap.${date}.json`), JSON.stringify(importmap));
407
+ await fsPromises.writeFile(pathFn.resolve(assetsDir, `bootloader.${date}.js`), getBootloaderJs(importmap, pluginAssets));
408
+ await fsPromises.writeFile(pathFn.resolve(assetsDir, "index.html"), getIndexHtml(`bootloader.${date}.js`, sRoot, title, bootModule, polyfill));
409
+ await fsPromises.symlink(pathFn.resolve(assetsDir, `bootloader.${date}.js`), pathFn.resolve(assetsDir, `bootloader.js`));
410
+ await fsPromises.symlink(pathFn.resolve(assetsDir, `importmap.${date}.js`), pathFn.resolve(assetsDir, `importmap.js`));
411
+ await fsPromises.symlink(pathFn.resolve(assetsDir, `importmap.${date}.json`), pathFn.resolve(assetsDir, `importmap.json`));
412
+ await fsPromises.symlink(pathFn.resolve(assetsDir, "index.html"), pathFn.resolve(root, "index.html")).catch(() => {});
413
+ }
414
+
415
+ //#endregion
416
+ export { assets, createImportmap, initAssets };
417
+ //# sourceMappingURL=index.mjs.map
package/index.mjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../cli/assets/createImportmap.mjs","../../cli/assets/assets.mjs","../../cli/assets/initAssets.mjs"],"sourcesContent":["/** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */\nimport { pluginIdRegex } from '@yongdall/common';\nimport * as pathPosix from 'node:path/posix';\n\n\n/**\n * \n * @param {string} text \n * @param {Record<string, string | undefined>} values \n * @returns \n */\nfunction replace(text, values) {\n\tconst { index } = /#|\\?/.exec(text) || { index: Infinity };\n\treturn text.replace(/\\{%([^%]*)%\\}/g, (_, k, no) => {\n\t\tconst v = k in values && values[k];\n\t\tif (typeof v !== 'string') { return ''; }\n\t\tconst s = encodeURIComponent(v);\n\t\tif (index < no) { return s; }\n\t\treturn s.replace(/%2F/ig, '/').replace(/%40/g, '@');\n\t});\n}\n/**\n * \n * @param {Record<string, Record<string, string>>} scopes \n * @param {string} scope \n * @returns \n */\nfunction getScope(scopes, scope) {\n\tif (!(scope in scopes)) {\n\t\tscopes[scope] = {};\n\t}\n\treturn scopes[scope];\n}\n\n/**\n * \n * @param {string} serverRoot \n * @param {string} origin \n * @param {string} version \n * @param {Record<string, string>} scope \n * @param {Record<string, string>} map \n * @param {Record<string, string>} [values] \n */\nfunction replaceScope(serverRoot, origin, version, scope, map, values) {\n\n\tconst assetsRoot = `${serverRoot}/assets`;\n\tconst originRoot = `${assetsRoot}/plugins/${origin}/${version}`;\n\tconst value = {\n\t\t...values,\n\t\torigin,\n\t\t'root:server': serverRoot,\n\t\t'root:assets': assetsRoot,\n\t\t'root:origin': originRoot,\n\t};\n\tfor (const [path, url] of Object.entries(map)) {\n\t\tscope[replace(path, { origin })] = replace(url, { url: scope[path], ...value });\n\t}\n}\n/**\n * \n * @param {string} root \n * @param {Record<string, PluginAssets | undefined>} plugins \n * @param {Record<string, NodeModuleAssets>} [nodeModules] \n * @returns \n */\nexport default function createImportmap(root, plugins, nodeModules = {}) {\n\t/** @type {Record<string, string>} */\n\tconst imports = {};\n\t/** @type {Record<string, Record<string, string>>} */\n\tconst scopes = {};\n\n\n\tfor (const [itemName, assets] of Object.entries(plugins)) {\n\t\tif (!assets) { continue; }\n\t\tconst { dir, esm, alias, version } = assets;\n\t\tconst encodedPlugin = encodeURIComponent(itemName).replace(/%2F/ig, '/').replace(/%40/g, '@');\n\n\t\tconst assetsRoot = pathPosix.join(`${root}/assets/plugins/`, itemName, version);\n\t\t/** @type {Record<string, string>} */\n\t\tconst scope = { '@/': pathPosix.join(assetsRoot, `./`) };\n\t\tscopes[`${root}/assets/plugins/${encodedPlugin}/`] = scope;\n\t\tif (!esm) { continue; }\n\t\tconst nameRoot = [...new Set([itemName, pathPosix.join(itemName, dir || '')])];\n\t\tconst indexEsm = alias?.['.'];\n\t\tif (indexEsm && Object.hasOwn(esm, indexEsm)) {\n\t\t\tconst indexFile = esm[indexEsm];\n\t\t\tif (indexFile) {\n\t\t\t\tconst indexPath = pathPosix.join(assetsRoot, indexFile);\n\t\t\t\tscope['@'] = indexPath;\n\t\t\t\tfor (const name of nameRoot) {\n\t\t\t\t\timports[name] = indexPath;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const name of nameRoot) {\n\t\t\tconst path = encodeURIComponent(name).replace(/%2F/ig, '/').replace(/%40/g, '@');\n\t\t\tfor (const [k, v] of Object.entries(esm)) {\n\t\t\t\tconst key = pathPosix.join(name, k);\n\t\t\t\tif (nameRoot.includes(key)) { continue; }\n\t\t\t\timports[key] = pathPosix.join(`${root}/assets/plugins/`, path, version, v);\n\t\t\t}\n\t\t\tif (alias) {\n\t\t\t\tfor (const [k, ev] of Object.entries(alias)) {\n\t\t\t\t\tconst v = Object.hasOwn(esm, ev) && esm[ev];\n\t\t\t\t\tif (!v) { continue; }\n\t\t\t\t\tconst key = pathPosix.join(name, k);\n\t\t\t\t\tif (nameRoot.includes(key)) { continue; }\n\t\t\t\t\timports[key] = pathPosix.join(`${root}/assets/plugins/`, path, version, v);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfor (const [itemName, { esm, version }] of Object.entries(nodeModules)) {\n\t\t// TODO: 从 package.json 中加载\n\t\tconst exports = esm || {};\n\t\tconst encodedName = encodeURIComponent(pathPosix.join(itemName, version)).replace(/%2F/ig, '/').replace(/%40/g, '@');\n\t\timports[itemName + '/'] = pathPosix.join(`${root}/assets/node_modules/`, encodedName, './');\n\t\tfor (const [k, v] of Object.entries(exports)) {\n\t\t\tconst key = pathPosix.join(itemName, k);\n\t\t\timports[key] = pathPosix.join(`${root}/assets/node_modules/`, encodedName, v);\n\t\t}\n\t}\n\tfor (const [origin, assets] of Object.entries(plugins)) {\n\t\tif (!assets) { continue; }\n\t\tconst { importmap, esm, version } = assets;\n\n\t\t/** @type {Record<string, string>} */\n\t\tconst esmValues = {};\n\t\tfor (const [k, v] of Object.entries(esm || {})) {\n\t\t\tesmValues[`esm:${k}`] = v;\n\t\t}\n\t\tif (!importmap) { continue; }\n\t\tfor (const [id, map] of Object.entries(importmap)) {\n\t\t\tif (!map) { continue; }\n\t\t\tif (id === '/') {\n\t\t\t\treplaceScope(root, origin, version, imports, map, esmValues);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (id[0] === '/') {\n\t\t\t\treplaceScope(root, origin, version, getScope(scopes, id), map, { ...esmValues, scope: id });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (id === '.') {\n\t\t\t\tconst scope = `${root}/assets/plugins/${origin}/`;\n\t\t\t\treplaceScope(root, origin, version, getScope(scopes, scope), map, { ...esmValues, scope, plugin: origin });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (id[0] === '.') { continue; }\n\t\t\tif (id === '*') {\n\t\t\t\tfor (const plugin of Object.keys(plugins)) {\n\t\t\t\t\tconst scope = `${root}/assets/plugins/${plugin}/`;\n\t\t\t\t\treplaceScope(root, origin, version, getScope(scopes, scope), map, { ...esmValues, scope, plugin });\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!pluginIdRegex.test(id)) { continue; }\n\t\t\tconst scope = `${root}/assets/plugins/${id}/`;\n\t\t\treplaceScope(root, origin, version, getScope(scopes, scope), map, { ...esmValues, scope, plugin: id });\n\t\t}\n\t}\n\n\treturn { imports, scopes };\n}\n","/** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */\nimport * as pathFn from 'node:path';\nimport * as fsPromises from 'node:fs/promises';\nimport { loadCfg } from '@yongdall/configuration';\nimport pluginRoots from '@yongdall/plugins';\n\n/**\n * \n * @param {string} path \n * @returns \n */\nasync function importIfExist(path) {\n\tconst r = await fsPromises.stat(path).catch(() => null);\n\tif (!r?.isFile()) { return null; }\n\treturn await import(path).catch(e => { console.error(e); return null; });\n}\n/**\n * \n * @param {string} path \n */\nasync function readPluginPackageJSON(path) {\n\tconst file = pathFn.resolve(path, 'package.json');\n\tconst packageJson = await fsPromises.readFile(file, 'utf-8')\n\t\t.then(v => JSON.parse(v))\n\t\t.catch(e => { console.error(e); return null; });\n\tconst version = packageJson?.version;\n\tif (version && typeof version === 'string') {\n\t\treturn { version };\n\t}\n\treturn null;\n}\n/**\n * \n * @param {string} root \n * @param {string} name \n */\nasync function findNodeModule(root, name) {\n\tfor (let basepath = root; ;) {\n\t\tconst path = pathFn.resolve(basepath, 'node_modules', name);\n\t\tconst packageJson = await fsPromises.readFile(pathFn.resolve(path, 'package.json'), 'utf-8').then(v => JSON.parse(v)).catch(() => null);\n\t\tconst version = packageJson?.version;\n\t\tif (version && typeof version === 'string') {\n\t\t\treturn { path, version };\n\t\t}\n\t\tconst parent = pathFn.dirname(basepath);\n\t\tif (parent === basepath) { break; }\n\t\tbasepath = parent;\n\t}\n\treturn null;\n}\n/**\n * \n * @param {string} projectRoot\n */\nexport default async function assets(projectRoot) {\n\n\n\t/** @type {Record<string, NodeModuleAssets & {path: string}>} */\n\tconst nodeModules = Object.create(null);\n\t/** @type {Record<string, PluginAssets & {path: string}>} */\n\tconst pluginAssets = Object.create(null);\n\n\tconst now = `${Date.now()}`;\n\n\tfor (const [plugin, { root: pluginRoot, development }] of Object.entries(pluginRoots)) {\n\n\t\tconst assets = await importIfExist(pathFn.resolve(pluginRoot, 'assets.yongdall.mjs'));\n\t\tif (!assets) { continue; }\n\t\tconst assetPackage = await readPluginPackageJSON(pluginRoot);\n\t\tpluginAssets[plugin] = {\n\t\t\t...assets, path: pathFn.resolve(pluginRoot, assets.dir || ''),\n\t\t\tversion: !development && String(assets.version || assetPackage?.version || '').replace(/[^.\\da-zA-Z_-]/g, '') || now,\n\t\t};\n\t\tfor (const [name, value] of Object.entries(assets?.nodeModules || {})) {\n\t\t\tif (!value) { continue; }\n\t\t\tconst info = await findNodeModule(pluginRoot, name);\n\t\t\tif (!info) { continue; }\n\t\t\tnodeModules[name] = {\n\t\t\t\t...value, ...info,\n\t\t\t\tversion: String(info.version || value.version || now).replace(/[^.\\da-zA-Z_-]/g, ''),\n\t\t\t};\n\t\t}\n\t}\n\n\tfor (const [name, value] of Object.entries(await loadCfg('nodeModules') || {})) {\n\t\tconst info = await findNodeModule(projectRoot, name);\n\t\tif (!info) { continue; }\n\t\tnodeModules[name] = {\n\t\t\t...value, ...info,\n\t\t\tversion: String(info.version || value.version || 'VERSION').replace(/[^.\\da-zA-Z_-]/g, ''),\n\t\t};\n\t}\n\n\treturn {\n\t\tpluginAssets, nodeModules,\n\t};\n}\n","/** @import { Plugin } from '@yongdall/common' */\n/** @import {NodeModuleAssets, PluginAssets} from './types.mjs' */\nimport * as pathFn from 'node:path';\nimport * as pathPosix from 'node:path/posix';\nimport * as fsPromises from 'node:fs/promises';\nimport createImportmap from './createImportmap.mjs';\n\n/**\n * \n * @param {string} path \n * @returns {Promise<void>}\n */\nexport async function rm(path) {\n const stat = await fsPromises.lstat(path).catch(() => {})\n\t\tif (!stat) { return }\n\t\tif (!stat.isDirectory()) {\n\t\t\tawait fsPromises.unlink(path);\n\t\t\treturn\n\t\t}\n\t\tconst files = await fsPromises.readdir(path);\n\t\tfor (const file of files) {\n\t\t\tawait rm(pathFn.resolve(path, file));\n\t\t}\n\t\tawait fsPromises.rmdir(path);\n}\n\n\n/**\n * \n * @param {string} pluginsRoot \n * @param {Record<string, {path: string; version?: string;}>} plugins \n * @param {string} [type] \n * @returns {Promise<void>}\n */\nexport async function linkPluginAssets(pluginsRoot, plugins, type = 'Plugin Assets') {\n\tawait fsPromises.mkdir(pluginsRoot, { recursive: true })\n\tfor (const [plugin, {path, version}] of Object.entries(plugins)) {\n\t\tconsole.log(`Link ${type}: ${plugin}`);\n\t\tawait fsPromises.mkdir(pathFn.resolve(pluginsRoot, plugin), { recursive: true });\n\t\tawait fsPromises.symlink(path, pathFn.resolve(pluginsRoot, plugin, (version || `VERSION`).replace(/[^.\\da-zA-Z_-]/g, '')));\n}\n\n}\n/**\n * \n * @param {string} bootFileName\n * @param {string} [root] \n * @param {string} [title] \n * @param {string} [boot] \n * @param {string[]} [polyfill] \n * @returns {string}\n */\nexport function getIndexHtml(bootFileName, root, title, boot, polyfill) {\n\treturn `<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"UTF-8\">\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>${title || '拥道YongDall'}</title>\n${polyfill?.map(src => `<script src=\"${root || ''}/assets/${src}\"></script>`).join('\\n') || ''}\n<script src=\"${root || ''}/assets/${bootFileName}\"${boot ? ` boot-module=\"${boot}\"` : ''}></script>\n</head>\n<body></body>\n</html>\n`\n}\n\n/**\n * \n * @param {ReturnType<typeof createImportmap>} importmap\n * @param {Record<string, PluginAssets>} [plugins] \n */\nexport function getBootloaderJs(importmap, plugins) {\n\treturn `;(function() {\ndocument.write('<script type=\"importmap\">' + JSON.stringify(${JSON.stringify(importmap)}) + '</script>');\nwindow.yongdallPlugins = ${JSON.stringify(getPluginConfig(typeof plugins === 'object' && plugins || {}))};\nconst currentScript = document.currentScript;\nif (!currentScript) { return; }\nconst boot = currentScript.getAttribute('boot-module');\nif (boot) { import(boot); }\n})();`\n}\n/**\n * \n * @param {ReturnType<typeof createImportmap>} importmap\n */\nfunction getImportmapJs(importmap) {\n\treturn `document.write('<script type=\"importmap\">' + JSON.stringify(${JSON.stringify(importmap)}) + '</script>');`\n}\n\n/**\n * \n * @param {string} assetsDir\n */\nexport async function clearAssets(assetsDir) {\n\tconst stat = await fsPromises.lstat(assetsDir).catch(() => {})\n\tif (!stat) { return }\n\tif (!stat.isDirectory()) {\n\t\tawait fsPromises.unlink(assetsDir);\n\t\treturn\n\t}\n\tconst files = await fsPromises.readdir(assetsDir);\n\tfor (const file of files) {\n\t\tif (['index.html', 'plugins', 'node_modules'].includes(file) || /^(bootloader|importmap)(\\.\\d+)?\\.js(on)?$/.test(file)) {\n\t\t\tawait rm(pathFn.resolve(assetsDir, file));\n\t\t}\n\t}\n}\n\n/**\n * \n * @param {Record<string, PluginAssets>} pluginAssetDefines\n */\nfunction getPluginConfig(pluginAssetDefines) {\n\t/** @type {Record<string, Plugin>} */\n\tconst plugins = {}\n\tfor (const [plugin, assets] of Object.entries(pluginAssetDefines)) {\n\t\t/** @type {Plugin} */\n\t\tconst pluginDef = {}\n\t\tplugins[plugin] = pluginDef;\n\t\tif (!assets) { continue; }\n\t\tconst { files, hooks, styles } = assets;\n\t\tif (typeof hooks === 'string' && hooks) { pluginDef.hooks = hooks; }\n\t\tif (files && Object.keys(files).length) { pluginDef.assets = files; }\n\t\tif (Array.isArray(styles) && styles.length) { pluginDef.styles = styles; }\n\t\tpluginDef.version = assets.version;\n\t}\n\treturn plugins;\n}\n\n/**\n * \n * @param {string} root \n * @param {string} assetsDir \n * @param {Record<string, PluginAssets & {path: string}>} pluginAssets\n * @param {Record<string, NodeModuleAssets & {path: string}>} nodeModules\n * @param {object} options \n * @param {string} [options.serverRoot] \n * @param {string} [options.bootModule] \n * @param {string} [options.bootName] \n * @param {string} [options.title] \n * @param {object} bootConfig \n */\nexport default async function initAssets(root, assetsDir, pluginAssets, nodeModules, {\n\tserverRoot, bootModule, bootName, title,\n}, bootConfig) {\n\tconst sRoot = pathPosix.join('/', serverRoot || '', '.').replace(/\\/$/, '')\n\tconst importmap = createImportmap(sRoot, pluginAssets, nodeModules);\n\tawait clearAssets(assetsDir);\n\tawait linkPluginAssets(pathFn.resolve(assetsDir, 'plugins'), pluginAssets)\n\tawait linkPluginAssets(pathFn.resolve(assetsDir, 'node_modules'), nodeModules, 'Node Module')\n\tawait fsPromises.mkdir(pathFn.resolve(assetsDir), { recursive: true })\n\tconst polyfill = Object.values(pluginAssets).flatMap(v => v.polyfill || []);\n\n\tconst date = Date.now();\n\tawait fsPromises.writeFile(\n\t\tpathFn.resolve(assetsDir, `importmap.${date}.js`),\n\t\tgetImportmapJs(importmap),\n\t);\n\tawait fsPromises.writeFile(\n\t\tpathFn.resolve(assetsDir, `importmap.${date}.json`),\n\t\tJSON.stringify(importmap),\n\t);\n\tawait fsPromises.writeFile(\n\t\tpathFn.resolve(assetsDir, `bootloader.${date}.js`),\n\t\tgetBootloaderJs(importmap, pluginAssets),\n\t);\n\tawait fsPromises.writeFile(\n\t\tpathFn.resolve(assetsDir, 'index.html'),\n\t\tgetIndexHtml(`bootloader.${date}.js`, sRoot, title, bootModule, polyfill),\n\t);\n\tawait fsPromises.symlink(\n\t\tpathFn.resolve(assetsDir, `bootloader.${date}.js`),\n\t\tpathFn.resolve(assetsDir, `bootloader.js`),\n\t);\n\tawait fsPromises.symlink(\n\t\tpathFn.resolve(assetsDir, `importmap.${date}.js`),\n\t\tpathFn.resolve(assetsDir, `importmap.js`),\n\t);\n\tawait fsPromises.symlink(\n\t\tpathFn.resolve(assetsDir, `importmap.${date}.json`),\n\t\tpathFn.resolve(assetsDir, `importmap.json`),\n\t);\n\tawait fsPromises.symlink(\n\t\tpathFn.resolve(assetsDir, 'index.html'),\n\t\tpathFn.resolve(root, 'index.html'),\n\t).catch(() => { });\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@yongdall/assets",
3
+ "type": "module",
4
+ "main": "./index.mjs",
5
+ "imports": {
6
+ "#index": "./index.mjs"
7
+ },
8
+ "exports": {
9
+ ".": "./index.mjs"
10
+ },
11
+ "version": "0.1.0",
12
+ "description": "",
13
+ "keywords": [],
14
+ "author": "",
15
+ "license": "ISC",
16
+ "bin": {
17
+ "assets.yongdall": "./bin.mjs",
18
+ "test.assets.yongdall": "./test.sh"
19
+ },
20
+ "dependencies": {
21
+ "@yongdall/plugins": "^0.1.0",
22
+ "@yongdall/common": "^0.1.0",
23
+ "@yongdall/configuration": "^0.1.0"
24
+ },
25
+ "devDependencies": {}
26
+ }
package/test.sh ADDED
@@ -0,0 +1,2 @@
1
+ #/bin/sh
2
+ node --watch "`dirname $0`/bin.mjs"
package/types.d.mts ADDED
@@ -0,0 +1,89 @@
1
+ //#region cli/assets/createImportmap.d.mts
2
+ /**
3
+ *
4
+ * @param {string} root
5
+ * @param {Record<string, PluginAssets | undefined>} plugins
6
+ * @param {Record<string, NodeModuleAssets>} [nodeModules]
7
+ * @returns
8
+ */
9
+ declare function createImportmap(root: string, plugins: Record<string, PluginAssets | undefined>, nodeModules?: Record<string, NodeModuleAssets>): {
10
+ imports: Record<string, string>;
11
+ scopes: Record<string, Record<string, string>>;
12
+ };
13
+ //#endregion
14
+ //#region cli/assets/assets.d.mts
15
+ /**
16
+ *
17
+ * @param {string} projectRoot
18
+ */
19
+ declare function assets(projectRoot: string): Promise<{
20
+ pluginAssets: Record<string, PluginAssets & {
21
+ path: string;
22
+ }>;
23
+ nodeModules: Record<string, NodeModuleAssets & {
24
+ path: string;
25
+ }>;
26
+ }>;
27
+ //#endregion
28
+ //#region cli/assets/initAssets.d.mts
29
+ /**
30
+ *
31
+ * @param {string} root
32
+ * @param {string} assetsDir
33
+ * @param {Record<string, PluginAssets & {path: string}>} pluginAssets
34
+ * @param {Record<string, NodeModuleAssets & {path: string}>} nodeModules
35
+ * @param {object} options
36
+ * @param {string} [options.serverRoot]
37
+ * @param {string} [options.bootModule]
38
+ * @param {string} [options.bootName]
39
+ * @param {string} [options.title]
40
+ * @param {object} bootConfig
41
+ */
42
+ declare function initAssets(root: string, assetsDir: string, pluginAssets: Record<string, PluginAssets & {
43
+ path: string;
44
+ }>, nodeModules: Record<string, NodeModuleAssets & {
45
+ path: string;
46
+ }>, {
47
+ serverRoot,
48
+ bootModule,
49
+ bootName,
50
+ title
51
+ }: {
52
+ serverRoot?: string | undefined;
53
+ bootModule?: string | undefined;
54
+ bootName?: string | undefined;
55
+ title?: string | undefined;
56
+ }, bootConfig: object): Promise<void>;
57
+ //#endregion
58
+ //#region cli/assets/types.d.mts
59
+ /** 应用静态文件 */
60
+ interface PluginAssets {
61
+ version: string;
62
+ /** 静态文件目录 */
63
+ dir: string;
64
+ /** 前端脚本 */
65
+ alias?: Record<string, string>;
66
+ /** 前端脚本 */
67
+ esm?: Record<string, string>;
68
+ hooks?: string;
69
+ files?: Record<string, string>;
70
+ styles?: string[];
71
+ /**
72
+ * - 斜线(`/`)表示全局
73
+ * - 斜线(`/`)开头表示作用域
74
+ * - 点(`.`)表示当前应用
75
+ * - 星号(`*`)表示任意应用
76
+ * - 合法应用名称表示特定应用
77
+ */
78
+ importmap?: Record<string, Record<string, string>>;
79
+ nodeModules?: Record<string, NodeModuleAssets>;
80
+ polyfill?: string[];
81
+ }
82
+ /** 应用静态文件 */
83
+ interface NodeModuleAssets {
84
+ version: string;
85
+ /** 前端脚本 */
86
+ esm?: Record<string, string>;
87
+ }
88
+ //#endregion
89
+ export { NodeModuleAssets, PluginAssets, assets, createImportmap, initAssets };