@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 +14 -0
- package/bin.mjs.map +1 -0
- package/index.mjs +417 -0
- package/index.mjs.map +1 -0
- package/package.json +26 -0
- package/test.sh +2 -0
- package/types.d.mts +89 -0
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
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 };
|