create-yeow 0.5.3 → 0.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-yeow",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "description": "Scaffold a Yeow plugin project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -88,10 +88,23 @@ async function main() {
88
88
  }
89
89
 
90
90
  // ── 原生服务可信性声明(native manifest:打包后路径 → SHA-256)──
91
+ // 合并来源:主项目 + 每个依赖包各自的 yeow.config.json(依赖包在自身 native 中声明)
91
92
  const nativeManifest = computeNativeManifest(prepared);
92
93
  if (nativeManifest.length > 0) {
93
94
  const fileCount = nativeManifest.reduce((n, e) => n + e.files.length, 0);
94
95
  console.log(' \u2713 Native manifest (' + nativeManifest.length + ' services, ' + fileCount + ' files, SHA-256)');
96
+ for (const e of nativeManifest) {
97
+ console.log(' - ' + e.serviceId + ' (' + e.files.length + ' file' + (e.files.length > 1 ? 's' : '') + ')');
98
+ }
99
+ }
100
+ // ── 强制声明:任一包申请了原生服务权限,合并后的 native 清单就不能为空(构建即失败,避免运行期拒绝加载)──
101
+ const wantsNative = mergedPerms.some(p => p === 'service:registerNative' || p === 'service:*');
102
+ if (wantsNative && nativeManifest.length === 0) {
103
+ console.error('\n \u2717 `service:registerNative` is declared (by the main project or a dependency package)');
104
+ console.error(' but the merged `native` manifest is empty.');
105
+ console.error(' Declare `native` in the declaring package\'s yeow.config.json (serviceId + binary');
106
+ console.error(' files) so every native binary is pinned by SHA-256, then rebuild.\n');
107
+ process.exit(1);
95
108
  }
96
109
 
97
110
  // ── 打包 ──
@@ -114,7 +127,7 @@ async function main() {
114
127
  console.log(' \u2713 Bundled (' + (statSync(resolve(outDir, 'main.js')).size / 1024).toFixed(1) + ' KB)');
115
128
 
116
129
  // ── 组装 JAR ──
117
- const zip = new AdmZip(resolve(root, '.yeow', 'assets', 'yeow-template-0.5.3.jar'));
130
+ const zip = new AdmZip(resolve(root, '.yeow', 'assets', 'yeow-template-0.6.0.jar'));
118
131
  zip.updateFile('plugin.yml', Buffer.from(
119
132
  'name: ' + name + '\n' +
120
133
  'version: ' + version + '\n' +
@@ -34,7 +34,7 @@ const HEADLESS = process.argv.includes('--eula') || process.argv.includes('--tim
34
34
  || process.argv.includes('--wait') || process.argv.includes('--outfile') || KEEP;
35
35
 
36
36
  const cfg = JSON.parse(readFileSync(resolve(ROOT, 'yeow.config.json'), 'utf-8'));
37
- const RUNTIME = resolve(ROOT, '.yeow', 'assets', 'yeow-runtime-0.5.3.jar');
37
+ const RUNTIME = resolve(ROOT, '.yeow', 'assets', 'yeow-runtime-0.6.0.jar');
38
38
 
39
39
  // Dev server config (optional, from yeow.config.json)
40
40
  const devCfg = cfg.dev || {};
@@ -29,9 +29,10 @@ function readNatives(configPath) {
29
29
  // ── 依赖项收集(node_modules 扫描)─────────────────────────────
30
30
  // 规则:
31
31
  // - 主项目无条件参与(始终分配 id,保证 getAssetsPath 恒可用;有 assets/ 才复制)
32
- // - 依赖包:node_modules 顶层目录(含 @scope/name 两级),要求
33
- // assets/ 目录存在 且 peerDependencies 含 yeow-api
34
- // - 每个候选同时读取其 yeow.config.json 的 permissions(依赖包可自行声明权限)
32
+ // - 依赖包:node_modules 顶层目录(含 @scope/name 两级),要求 assets/ 目录存在,
33
+ // 且满足以下之一:peerDependencies 含 yeow-api 键,或自带 yeow.config.json 的
34
+ // permissions/native 声明(纯原生/资源包可无 peer 依赖)
35
+ // - 每个候选同时读取其 yeow.config.json 的 permissions 与 native
35
36
  // 键:<name>-<version>。npm/pnpm 扁平布局支持良好;yarn 的 hoisting
36
37
  // 差异可能导致依赖不在预期位置(见文档说明)。
37
38
  function collectCandidates(root, pkgJson) {
@@ -67,16 +68,23 @@ function collectCandidates(root, pkgJson) {
67
68
  const pkgDir = resolve(nm, ...name.split('/'));
68
69
  let meta;
69
70
  try { meta = JSON.parse(readFileSync(resolve(pkgDir, 'package.json'), 'utf-8')); } catch { continue; }
70
- if (!meta.peerDependencies || !meta.peerDependencies['yeow-api']) continue;
71
71
  const pkgAssets = resolve(pkgDir, 'assets');
72
72
  if (!existsSync(pkgAssets)) continue;
73
+ const perms = readPerms(resolve(pkgDir, 'yeow.config.json'));
74
+ const natives = readNatives(resolve(pkgDir, 'yeow.config.json'));
75
+ // 识别条件:assets/ 目录 +(peerDependencies 含 yeow-api,或自带 yeow.config.json 的
76
+ // permissions/native 声明)——后者让「纯原生 / 资源包」即使未声明 yeow-api peer 也能被
77
+ // 识别,保证其 native 声明参与合并、其 assets 被部署。
78
+ const yeowAware = (meta.peerDependencies && meta.peerDependencies['yeow-api'])
79
+ || perms.length > 0 || natives.length > 0;
80
+ if (!yeowAware) continue;
73
81
  candidates.push({
74
82
  key: meta.name + '-' + (meta.version || '0.0.0'),
75
83
  pkgDir,
76
84
  absSrc: pkgAssets,
77
85
  hasAssets: true,
78
- perms: readPerms(resolve(pkgDir, 'yeow.config.json')),
79
- natives: readNatives(resolve(pkgDir, 'yeow.config.json')),
86
+ perms,
87
+ natives,
80
88
  });
81
89
  }
82
90
  }
@@ -192,19 +200,21 @@ export function prepareAssets(root, pkgJson, outDir) {
192
200
  }
193
201
 
194
202
  // ── 原生服务可信性声明(native manifest)───────────────────────
195
- // 依赖包 / 主项目在 yeow.config.json 声明 native:[{serviceId, files[], source}];
196
- // 构建时把 files 映射为打包后路径(assets/<id>/...)并计算 SHA-256,
197
- // 相同 serviceId 合并(files 归并到一项)。产物写入 yeow.json 的 native 字段:
203
+ // 依赖包 / 主项目在各自 yeow.config.json 声明 native:[{serviceId, files[], source}];
204
+ // 构建时遍历 **全部候选**(主项目 + 每个依赖包),把各包 files 按该包命名空间映射为
205
+ // 打包后路径(assets/<id>/...)并计算 SHA-256,相同 serviceId 合并(files 归并)。
206
+ // 产物写入 yeow.json 的 native 字段:
198
207
  // [{ "serviceId": "...", "files": [{ "<打包后路径>": "<sha256>" }, ...], "source": "..." }]
199
208
  export function computeNativeManifest(prepared) {
200
- const merged = new Map(); // serviceId → { files: Map<path, {abs, packaged}>, source }
209
+ const merged = new Map(); // serviceId → { files: Map<path, abs>, source, packages: Set<key> }
201
210
  for (const c of prepared.candidates) {
202
211
  for (const n of c.natives || []) {
203
212
  const sid = n.serviceId;
204
213
  if (!sid) continue;
205
214
  let e = merged.get(sid);
206
- if (!e) { e = { files: new Map(), source: n.source || '' }; merged.set(sid, e); }
215
+ if (!e) { e = { files: new Map(), source: n.source || '', packages: new Set() }; merged.set(sid, e); }
207
216
  else if (!e.source && n.source) e.source = n.source;
217
+ e.packages.add(c.key);
208
218
  for (const f of n.files || []) {
209
219
  const raw = String(f).replace(/\\/g, '/').replace(/^\/+/, '');
210
220
  const packaged = 'assets/' + c.id + '/' + raw;
@@ -218,10 +228,13 @@ export function computeNativeManifest(prepared) {
218
228
  for (const [sid, e] of merged) {
219
229
  const files = [];
220
230
  for (const [packaged, abs] of e.files) {
221
- let hash = null;
231
+ let hash;
222
232
  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 });
233
+ catch (err) {
234
+ throw new Error('native file not found: ' + packaged
235
+ + ' (service "' + sid + '", declared in yeow.config.json of ' + [...e.packages].join(', ') + ')');
236
+ }
237
+ files.push({ [packaged]: hash });
225
238
  }
226
239
  if (files.length === 0) continue;
227
240
  out.push({ serviceId: sid, files, ...(e.source ? { source: e.source } : {}) });
@@ -8,7 +8,7 @@
8
8
  "permissions": "node .yeow/permissions.js"
9
9
  },
10
10
  "dependencies": {
11
- "yeow-api": "^0.5.0"
11
+ "yeow-api": "^0.6.0"
12
12
  },
13
13
  "devDependencies": {
14
14
  "esbuild": "^0.25.0",
@@ -10,10 +10,10 @@
10
10
  | 概览 | `https://cn.yexin.wiki/yeow/v1/overview` | 项目总览:用 TypeScript 写 Paper 插件(QuickJS 引擎,每插件独立线程)。按角色(初学者/开发者/服主/平台实现者)的文档入口导引 + 关键概念速览 |
11
11
  | AI 辅助启动指南 | `https://cn.yexin.wiki/yeow/v1/ai-agent` | 面向 AI 代理 / Vibe Coding:Yeow 项目简介、启动命令(`--ts`)、下一步、文档查阅策略(站点地图/docs.zip/Harness 用法) |
12
12
  | 快速开始 | `https://cn.yexin.wiki/yeow/v1/getting-started` | 从零开始:`npm create yeow` 建项目 → `npm run dev` 开发(热重载)→ `npm run build` 构建 → 部署方式。含插件示例(/back 传送)、异步/同步约定 |
13
- | 环境能力 | `https://cn.yexin.wiki/yeow/v1/environment` | 运行时环境速览:全局能力($send/fetch/TextEncoder/TextDecoder/定时器)、线程与异步模型、与浏览器/Node 环境的差异、性能建议 |
13
+ | 环境能力 | `https://cn.yexin.wiki/yeow/v1/environment` | 运行时环境速览:全局能力($send/fetch/TextEncoder/TextDecoder/performance/定时器)、线程与异步模型、与浏览器/Node 环境的差异、性能建议 |
14
14
  | CLI 参考 | `https://cn.yexin.wiki/yeow/v1/cli` | create-yeow 脚手架与 dev-server 的命令行用法:交互式/非交互创建、开发服务器参数(-y/--stop)、构建脚本、调试体验(source-map 错误定位与异步调用链) |
15
15
  | 构建与分发 | `https://cn.yexin.wiki/yeow/v1/distribution` | 两种产物:标准 Paper JAR(plugins/)与平台无关 .yeow.zip(plugins/Yeow/ 自动扫描或 /yeow install);分发建议与 Modrinth 发布 |
16
- | 权限与原生服务可信性 | `https://cn.yexin.wiki/yeow/v1/permissions` | 敏感权限声明(默认拒绝表/通配规则/computedPermissions)、原生服务 SHA-256 可信性声明与不可信警告开关 |
16
+ | 权限与原生服务可信性 | `https://cn.yexin.wiki/yeow/v1/permissions` | 统一门控的敏感权限声明(默认拒绝表/通配规则/computedPermissions)、原生服务强制 SHA-256 声明(构建/加载/注册三层)与不可信警告开关 |
17
17
  | 运行时运维 | `https://cn.yexin.wiki/yeow/v1/operations` | 服主视角:/yeow 管理命令全集、运行时配置(config.yml 含 Folia 节)、部署形态速查 |
18
18
  | 运行时警告 | `https://cn.yexin.wiki/yeow/v1/runtime-warning` | 预警引擎:heartbeat.timeout / event.slow / plugin.hung / budget.congested 等告警的触发条件、含义与解决方案;配置阈值;动态扩容机制 |
19
19
  | 进阶知识 | `https://cn.yexin.wiki/yeow/v1/advanced` | 进阶索引:架构/调度器/事件/生命周期/通道/服务/Folia/关于;告警与运维指向根级文档 |
@@ -55,10 +55,10 @@
55
55
  | Event | `https://cn.yexin.wiki/yeow/v1/api/event` | 事件订阅:`eventOn`/`eventOff`、自动/手动模式(取消、回写)、全事件字段表、消息(Message 对象) |
56
56
  | Command | `https://cn.yexin.wiki/yeow/v1/api/command` | 命令注册 + Tab 补全(含 yeow-command 重载式命令 Command.create 与模式化参数) |
57
57
  | ItemStack | `https://cn.yexin.wiki/yeow/v1/api/item` | 物品纯数据描述符:type/amount/meta(显示名/附魔/耐久/染色/药水/头颅/属性修饰符);构造工具(create/clone/equals);值语义(快照,不绑定真实物品) |
58
- | Service | `https://cn.yexin.wiki/yeow/v1/api/service` | 插件间服务(registerService/request/subscribe/publish)与原生服务(registerNativeService,spawn 子进程 + TCP 通信) |
58
+ | Service | `https://cn.yexin.wiki/yeow/v1/api/service` | 插件间服务(OOP Service 对象:registerService/getService/hasService/request/subscribe/publish/unregister)与原生服务(registerNativeService,spawn 子进程 + TCP 通信) |
59
59
  | HTTP | `https://cn.yexin.wiki/yeow/v1/api/http` | 底层 HTTP 客户端:`request`(异步,请求/响应体二进制与 fs 同语义、encoding/timeout 可选)、全局 `fetch`(text/json 按需解码 + base64/bytes) |
60
60
  | HTTP Server | `https://cn.yexin.wiki/yeow/v1/api/http-server` | 高层 `createServer`(yeow-server):洋葱中间件、路由、mount/mountAssets 静态挂载、二进制响应(Uint8Array/encoding)、返回对象自动 JSON、资源包下载闭环 |
61
- | Worker | `https://cn.yexin.wiki/yeow/v1/api/worker` | 虚拟插件(独立线程):createWorker(仅注册)/load/unload/reload、双向 postMessage、Worker 侧 onMessage/postMessage;共享数据目录/权限、禁嵌套、/yeow 不覆盖 |
61
+ | Worker | `https://cn.yexin.wiki/yeow/v1/api/worker` | 虚拟插件(独立线程):createWorker(仅注册,可声明 permissions.allow/deny)/load/unload/destroy/reload、双向 postMessage、Worker 侧 onMessage/postMessage;默认继承主插件权限(allow 不可提权)、禁嵌套、/yeow 不覆盖 |
62
62
  | FS | `https://cn.yexin.wiki/yeow/v1/api/fs` | 文件系统:plugin/server/outer 三级(路径安全)、读写/追加/二进制、目录操作、systemPaths、path 工具 |
63
63
  | Assets | `https://cn.yexin.wiki/yeow/v1/api/assets` | 打包资源:`getAssetsPath`(yeow-dev,构建期注入命名空间)+ 读取/解压(单文件与目录) |
64
64
  | PDC | `https://cn.yexin.wiki/yeow/v1/api/pdc` | 持久数据容器:JSON 自动序列化、全量读取、插件命名空间(跨插件不冲突)、Player/Block 实例方法 |
@@ -72,10 +72,8 @@
72
72
  | -------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
73
73
  | 规范总览 | `https://cn.yexin.wiki/yeow/v1/specifications/` | 协议层总纲:包结构(yeow.json/.yeow/main.js/assets)、加载流程、权限模型、运行时架构、任务执行器、事件/命令桥、Native Service、合格运行时检查清单 |
74
74
  | 值域附录 | `https://cn.yexin.wiki/yeow/v1/specifications/values` | 取值格式规则(R1-R5)与清单:平台枚举直接维护(游戏模式/难度/BossBar/计分板/ClickType/ItemFlag/InventoryType 等);参考实现(非强制:DamageCause/传送原因/回血原因);版本变迁域规则+链接(方块/物品/实体/生物群系/音效/粒子/附魔/药水/属性/伤害类型/游戏规则/翻译键/进度/配方) |
75
- | Java 插件集成 | `https://cn.yexin.wiki/yeow/v1/specifications/java-api` | 其他 Java 插件调用 Yeow 服务(requestService 请求-响应、subscribeService 订阅事件)、提交游戏任务、约束 |
76
- | 适配器规范 | `https://cn.yexin.wiki/yeow/v1/specifications/adapter/` | 多语言/社区适配器:PluginEntity 接口、消息契约、submitTask、注册 API、检查清单 |
77
- | 运行时环境标准 | `https://cn.yexin.wiki/yeow/v1/specifications/runtime/` | JS 环境:语言标准(ES2025+SecU8)、回调系统(cb 语义)、事件循环、通道总览与权限、全局变量($send/$dev/fetch/timers) |
78
- | 原生服务 | `https://cn.yexin.wiki/yeow/v1/specifications/native-service/` | 原生子进程协议:平台选择、提取、TCP JSON line(ready/request/response/publish) |
75
+ | 运行时环境标准 | `https://cn.yexin.wiki/yeow/v1/specifications/runtime/` | JS 环境:语言标准(ES2025+SecU8)、回调系统(cb 语义)、事件循环、通道总览与权限、全局变量($send/$dev/fetch/timers/performance) |
76
+ | 原生服务 | `https://cn.yexin.wiki/yeow/v1/specifications/native-service/` | 原生子进程协议:平台选择(仅单文件)、强制 SHA-256 声明、提取、TCP 帧协议(header JSON + raw body,ready/request/response/publish) |
79
77
 
80
78
  ### 消息通道(/v1/specifications/message/)
81
79
 
@@ -87,12 +85,12 @@
87
85
  | FS | `https://cn.yexin.wiki/yeow/v1/specifications/message/fs` | fs 通道:plugin/server/outer 三级、各操作(读写/删除/列出/base64/systemPaths)请求格式与路径规则 |
88
86
  | HTTP | `https://cn.yexin.wiki/yeow/v1/specifications/message/http` | http 通道:listen/respond(body + encoding 二进制)/close/request/requestAsync 消息格式 |
89
87
  | Assets | `https://cn.yexin.wiki/yeow/v1/specifications/message/assets` | assets 通道:read/readBase64/extract/extractDir 消息格式(命名空间路径) |
90
- | Service | `https://cn.yexin.wiki/yeow/v1/specifications/message/service` | service 通道:注册(plugin/native)、请求、订阅/发布、原生 terminate 回调 |
88
+ | Service | `https://cn.yexin.wiki/yeow/v1/specifications/message/service` | service 通道:注册(plugin/native)、查询/卸载、请求、订阅/发布、原生 terminate 回调 |
91
89
  | Log | `https://cn.yexin.wiki/yeow/v1/specifications/message/log` | log 通道:日志消息格式 |
92
90
  | Lifecycle | `https://cn.yexin.wiki/yeow/v1/specifications/message/lifecycle` | lifecycle 通道:unloadDone 确认、gc-collect 资源回收 |
93
91
  | Debug | `https://cn.yexin.wiki/yeow/v1/specifications/message/debug` | debug 通道:reportError 错误上报、ping-pong 心跳 |
94
92
  | Util | `https://cn.yexin.wiki/yeow/v1/specifications/message/util` | util 通道:gzip 压缩/解压(一次性与流式分块)、UTF-8 ↔ 字节转换(encode.utf8/decode.utf8) |
95
- | Worker | `https://cn.yexin.wiki/yeow/v1/specifications/message/worker` | worker 通道:create(仅注册)/load/unload/post/reload/postToMain 消息格式、生命周期、origin 错误字段、约束(禁嵌套/共享数据与权限) |
93
+ | Worker | `https://cn.yexin.wiki/yeow/v1/specifications/message/worker` | worker 通道:create(仅注册,可带 permissions)/load/unload/destroy/post/reload/postToMain 消息格式、生命周期、origin 错误字段、约束(禁嵌套/共享数据与资源/权限可收紧) |
96
94
 
97
95
  ### 任务类型(/v1/specifications/task/)
98
96
 
@@ -130,5 +128,5 @@
130
128
  进阶(默认折叠):关于 Yeow · 进阶索引(架构/调度器/事件/生命周期/通道/服务/运维与安全)
131
129
  依赖包开发:编写依赖包
132
130
  API 参考:索引 → 玩家与服务器(Player/Server/Env) · 世界与方块(World/Chunk/Location/Block/Material) · 实体(Entity/Potion/Particle) · 交互界面(Inventory/BossBar/Scoreboard/Advancement/Recipe) · 事件与命令(Event/Command) · 物品(ItemStack) · 服务与网络(Service/HTTP/HTTP Server) · 多线程(Worker) · 文件与数据(FS/Assets/PDC/Util) · 文本(Text) · 日志(Log)
133
- 平台规范:规范总览 → 消息通道 · 任务类型 · 事件 · 运行时 · 原生服务 · 适配器
131
+ 平台规范:规范总览 → 消息通道 · 任务类型 · 事件 · 运行时 · 原生服务
134
132
  ```