create-yeow 0.2.105 → 0.2.106
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/package.json
CHANGED
|
Binary file
|
|
@@ -4,7 +4,7 @@ import { resolve, dirname } from 'path';
|
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import AdmZip from 'adm-zip';
|
|
6
6
|
import { execSync } from 'child_process';
|
|
7
|
-
import { makeAssetPlugin, makeDedupePlugin, assetsOutDirFor, readMergedPermissions } from './yeow-assets.mjs';
|
|
7
|
+
import { makeAssetPlugin, makeDedupePlugin, assetsOutDirFor, readMergedPermissions, prepareAssets, computeNativeManifest } from './yeow-assets.mjs';
|
|
8
8
|
|
|
9
9
|
const root = resolve(fileURLToPath(import.meta.url), '..', '..');
|
|
10
10
|
const cfg = JSON.parse(readFileSync(resolve(root, 'yeow.config.json'), 'utf-8'));
|
|
@@ -55,6 +55,16 @@ async function main() {
|
|
|
55
55
|
console.log(' \u2713 No permissions declared');
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// ── 资产准备(id 分配 + 部署;与插件共享,保证路径一致)──
|
|
59
|
+
const prepared = prepareAssets(root, pkgJson, outDir);
|
|
60
|
+
|
|
61
|
+
// ── 原生服务可信性声明(native manifest:打包后路径 → SHA-256)──
|
|
62
|
+
const nativeManifest = computeNativeManifest(prepared);
|
|
63
|
+
if (nativeManifest.length > 0) {
|
|
64
|
+
const fileCount = nativeManifest.reduce((n, e) => n + e.files.length, 0);
|
|
65
|
+
console.log(' \u2713 Native manifest (' + nativeManifest.length + ' services, ' + fileCount + ' files, SHA-256)');
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
// ── 打包 ──
|
|
59
69
|
await esbuild.build({
|
|
60
70
|
entryPoints: [resolve(root, entry)],
|
|
@@ -70,7 +80,7 @@ async function main() {
|
|
|
70
80
|
sourcemap: isDev ? 'linked' : false,
|
|
71
81
|
plugins: [
|
|
72
82
|
makeDedupePlugin(root),
|
|
73
|
-
makeAssetPlugin({ root, pkgJson, outDir }),
|
|
83
|
+
makeAssetPlugin({ root, pkgJson, outDir, prepared }),
|
|
74
84
|
],
|
|
75
85
|
});
|
|
76
86
|
console.log(' \u2713 Bundled (' + (statSync(resolve(outDir, 'main.js')).size / 1024).toFixed(1) + ' KB)');
|
|
@@ -106,7 +116,7 @@ async function main() {
|
|
|
106
116
|
console.log(' \u2713 Assets included (' + files.length + ' files)');
|
|
107
117
|
}
|
|
108
118
|
|
|
109
|
-
zip.addFile('yeow.json', Buffer.from(JSON.stringify({ ...cfg, computedPermissions: mergedPerms })));
|
|
119
|
+
zip.addFile('yeow.json', Buffer.from(JSON.stringify({ ...cfg, computedPermissions: mergedPerms, native: nativeManifest })));
|
|
110
120
|
const outJar = resolve(root, 'dist', isDev ? 'plugins' : '', name + '-' + version + '.jar');
|
|
111
121
|
mkdirSync(dirname(outJar), { recursive: true });
|
|
112
122
|
zip.writeZip(outJar);
|
|
@@ -128,7 +138,7 @@ async function main() {
|
|
|
128
138
|
pkgZip.addFile('assets/' + f.replace(/\\/g, '/'), readFileSync(resolve(assetsOut, f)));
|
|
129
139
|
}
|
|
130
140
|
}
|
|
131
|
-
pkgZip.addFile('yeow.json', Buffer.from(JSON.stringify({ ...cfg, computedPermissions: mergedPerms })));
|
|
141
|
+
pkgZip.addFile('yeow.json', Buffer.from(JSON.stringify({ ...cfg, computedPermissions: mergedPerms, native: nativeManifest })));
|
|
132
142
|
const outZip = resolve(root, 'dist', isDev ? 'plugins' : '', name + '-' + version + '.yeow.zip');
|
|
133
143
|
mkdirSync(dirname(outZip), { recursive: true });
|
|
134
144
|
pkgZip.writeZip(outZip);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, existsSync, statSync, mkdirSync, copyFileSync, realpathSync } from 'fs';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import { createRequire } from 'module';
|
|
4
|
-
import { randomBytes } from 'crypto';
|
|
4
|
+
import { randomBytes, createHash } from 'crypto';
|
|
5
5
|
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
7
|
|
|
@@ -17,6 +17,15 @@ function readPerms(configPath) {
|
|
|
17
17
|
return [];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/** 读取 yeow.config.json 的 native 可信性声明([{serviceId, files[], source}])。 */
|
|
21
|
+
function readNatives(configPath) {
|
|
22
|
+
try {
|
|
23
|
+
const j = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
24
|
+
if (Array.isArray(j.native)) return j.native;
|
|
25
|
+
} catch { /* 无声明 */ }
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
|
|
20
29
|
// ── 依赖项收集(node_modules 扫描)─────────────────────────────
|
|
21
30
|
// 规则:
|
|
22
31
|
// - 主项目无条件参与(始终分配 id,保证 getAssetsPath 恒可用;有 assets/ 才复制)
|
|
@@ -34,6 +43,7 @@ function collectCandidates(root, pkgJson) {
|
|
|
34
43
|
absSrc: ownAssets,
|
|
35
44
|
hasAssets: existsSync(ownAssets),
|
|
36
45
|
perms: readPerms(resolve(root, 'yeow.config.json')),
|
|
46
|
+
natives: readNatives(resolve(root, 'yeow.config.json')),
|
|
37
47
|
});
|
|
38
48
|
|
|
39
49
|
const nm = resolve(root, 'node_modules');
|
|
@@ -66,6 +76,7 @@ function collectCandidates(root, pkgJson) {
|
|
|
66
76
|
absSrc: pkgAssets,
|
|
67
77
|
hasAssets: true,
|
|
68
78
|
perms: readPerms(resolve(pkgDir, 'yeow.config.json')),
|
|
79
|
+
natives: readNatives(resolve(pkgDir, 'yeow.config.json')),
|
|
69
80
|
});
|
|
70
81
|
}
|
|
71
82
|
}
|
|
@@ -169,18 +180,68 @@ function deployAll(candidates, assetsOutDir) {
|
|
|
169
180
|
}
|
|
170
181
|
}
|
|
171
182
|
|
|
183
|
+
// ── 资产准备(收集 + id 分配 + 部署)──────────────────────────
|
|
184
|
+
// 供 build.js 与 esbuild 插件共享——id 分配一次,保证打包路径(assets/<id>/...)
|
|
185
|
+
// 在 yeow.json(native manifest)与插件内注入的 getAssetsPath 中一致。
|
|
186
|
+
export function prepareAssets(root, pkgJson, outDir) {
|
|
187
|
+
const candidates = collectCandidates(root, pkgJson);
|
|
188
|
+
const ids = assignIds(candidates);
|
|
189
|
+
const assetsOutDir = resolve(outDir, '.assets');
|
|
190
|
+
deployAll(candidates, assetsOutDir);
|
|
191
|
+
return { candidates, ids, rootId: ids.get(normKey(root)), assetsOutDir };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ── 原生服务可信性声明(native manifest)───────────────────────
|
|
195
|
+
// 依赖包 / 主项目在 yeow.config.json 声明 native:[{serviceId, files[], source}];
|
|
196
|
+
// 构建时把 files 映射为打包后路径(assets/<id>/...)并计算 SHA-256,
|
|
197
|
+
// 相同 serviceId 合并(files 归并到一项)。产物写入 yeow.json 的 native 字段:
|
|
198
|
+
// [{ "serviceId": "...", "files": [{ "<打包后路径>": "<sha256>" }, ...], "source": "..." }]
|
|
199
|
+
export function computeNativeManifest(prepared) {
|
|
200
|
+
const merged = new Map(); // serviceId → { files: Map<path, {abs, packaged}>, source }
|
|
201
|
+
for (const c of prepared.candidates) {
|
|
202
|
+
for (const n of c.natives || []) {
|
|
203
|
+
const sid = n.serviceId;
|
|
204
|
+
if (!sid) continue;
|
|
205
|
+
let e = merged.get(sid);
|
|
206
|
+
if (!e) { e = { files: new Map(), source: n.source || '' }; merged.set(sid, e); }
|
|
207
|
+
else if (!e.source && n.source) e.source = n.source;
|
|
208
|
+
for (const f of n.files || []) {
|
|
209
|
+
const raw = String(f).replace(/\\/g, '/').replace(/^\/+/, '');
|
|
210
|
+
const packaged = 'assets/' + c.id + '/' + raw;
|
|
211
|
+
if (!e.files.has(packaged)) {
|
|
212
|
+
e.files.set(packaged, resolve(prepared.assetsOutDir, c.id, raw));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const out = [];
|
|
218
|
+
for (const [sid, e] of merged) {
|
|
219
|
+
const files = [];
|
|
220
|
+
for (const [packaged, abs] of e.files) {
|
|
221
|
+
let hash = null;
|
|
222
|
+
try { hash = createHash('sha256').update(readFileSync(abs)).digest('hex'); }
|
|
223
|
+
catch (err) { console.warn(' ! native file not found (skipped from manifest): ' + packaged); }
|
|
224
|
+
if (hash) files.push({ [packaged]: hash });
|
|
225
|
+
}
|
|
226
|
+
if (files.length === 0) continue;
|
|
227
|
+
out.push({ serviceId: sid, files, ...(e.source ? { source: e.source } : {}) });
|
|
228
|
+
}
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
|
|
172
232
|
// ── esbuild 插件:yeow-dev 虚拟模块 ────────────────────────────
|
|
173
233
|
// yeow-dev 是构建期模块(发布为空包):getAssetsPath 由构建器按
|
|
174
234
|
// importer 所属依赖项注入对应命名空间 id,运行时无需任何改动。
|
|
175
|
-
export function makeAssetPlugin({ root, pkgJson, outDir }) {
|
|
235
|
+
export function makeAssetPlugin({ root, pkgJson, outDir, prepared }) {
|
|
176
236
|
const assetsOutDir = resolve(outDir, '.assets');
|
|
177
237
|
return {
|
|
178
238
|
name: 'yeow-assets',
|
|
179
239
|
setup(build) {
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
const
|
|
183
|
-
|
|
240
|
+
const p = prepared ?? prepareAssets(root, pkgJson, outDir);
|
|
241
|
+
const candidates = p.candidates;
|
|
242
|
+
const ids = p.ids;
|
|
243
|
+
const rootId = p.rootId;
|
|
244
|
+
if (!prepared) deployAll(candidates, assetsOutDir); // prepared 时已由 build.js 部署
|
|
184
245
|
|
|
185
246
|
// importer → 所属依赖项 id(最长路径前缀匹配;未匹配归主项目)
|
|
186
247
|
const idForImporter = importer => {
|