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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-yeow",
3
- "version": "0.2.105",
3
+ "version": "0.2.106",
4
4
  "description": "Scaffold a Yeow plugin project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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 candidates = collectCandidates(root, pkgJson);
181
- const ids = assignIds(candidates);
182
- const rootId = ids.get(normKey(root));
183
- deployAll(candidates, assetsOutDir);
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 => {
@@ -8,7 +8,7 @@
8
8
  "permissions": "node .yeow/permissions.js"
9
9
  },
10
10
  "dependencies": {
11
- "yeow-api": "^0.2.100",
11
+ "yeow-api": "^0.2.102",
12
12
  "yeow-utils": "^0.1.14"
13
13
  },
14
14
  "devDependencies": {