From 4d46b5b8397526e46f992736707b3b21f90888de Mon Sep 17 00:00:00 2001 From: YBF <47051132+YBFACC@users.noreply.github.com> Date: Sat, 12 Sep 2026 14:01:16 +0800 Subject: [PATCH] refactor(onetalk-contract): move shared contract to packages --- .gitignore | 3 ++- .trellis/config.yaml | 2 +- .../frontend/onetalk/runtime-sync.md | 2 +- .trellis/spec/project/missing-values.md | 4 +-- .trellis/spec/project/module-ownership.md | 2 +- .../worktree-registry.yaml | 10 +++---- Dockerfile.server | 4 +-- ...talk-image-send-observation-feasibility.md | 4 +-- ...talk-media-message-format-investigation.md | 2 +- docs/onetalk-message-content-formats.md | 4 +-- package.json | 3 ++- .../onetalk-contract/package.json | 0 .../onetalk-contract/src/authorization.ts | 0 .../onetalk-contract/src/buyer-facts.ts | 0 .../onetalk-contract/src/connection.ts | 0 .../onetalk-contract/src/contact-profiles.ts | 0 .../onetalk-contract/src/content.ts | 0 .../onetalk-contract/src/conversation-sync.ts | 0 .../onetalk-contract/src/decoder.ts | 0 .../onetalk-contract/src/guards.ts | 0 .../onetalk-contract/src/index.ts | 0 .../onetalk-contract/src/messages.ts | 0 .../onetalk-contract/src/read-api.ts | 0 .../onetalk-contract/src/sending.ts | 0 .../onetalk-contract/src/wire.ts | 0 .../onetalk-contract/test/contract.test.ts | 0 .../onetalk-contract/tsconfig.json | 0 pnpm-lock.yaml | 24 ++++++++--------- pnpm-workspace.yaml | 1 + scripts/clean-generated-dist.mjs | 2 +- scripts/package-version.mjs | 18 ++++++++----- scripts/package-version.test.mjs | 26 ++++++++++++++----- scripts/release.test.mjs | 24 ++++++++++++----- 33 files changed, 85 insertions(+), 50 deletions(-) rename {apps => packages}/onetalk-contract/package.json (100%) rename {apps => packages}/onetalk-contract/src/authorization.ts (100%) rename {apps => packages}/onetalk-contract/src/buyer-facts.ts (100%) rename {apps => packages}/onetalk-contract/src/connection.ts (100%) rename {apps => packages}/onetalk-contract/src/contact-profiles.ts (100%) rename {apps => packages}/onetalk-contract/src/content.ts (100%) rename {apps => packages}/onetalk-contract/src/conversation-sync.ts (100%) rename {apps => packages}/onetalk-contract/src/decoder.ts (100%) rename {apps => packages}/onetalk-contract/src/guards.ts (100%) rename {apps => packages}/onetalk-contract/src/index.ts (100%) rename {apps => packages}/onetalk-contract/src/messages.ts (100%) rename {apps => packages}/onetalk-contract/src/read-api.ts (100%) rename {apps => packages}/onetalk-contract/src/sending.ts (100%) rename {apps => packages}/onetalk-contract/src/wire.ts (100%) rename {apps => packages}/onetalk-contract/test/contract.test.ts (100%) rename {apps => packages}/onetalk-contract/tsconfig.json (100%) diff --git a/.gitignore b/.gitignore index 52f21a3..c7adf66 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules/ .pnpm-store/ dist/ apps/*/dist/ +packages/*/dist/ .vite/ *.tsbuildinfo .env @@ -13,4 +14,4 @@ apps/chrome-extension/.keys/ mock-log.text -.claude/skills/gitnexus \ No newline at end of file +.claude/skills/gitnexus diff --git a/.trellis/config.yaml b/.trellis/config.yaml index 5b929f5..de6d473 100644 --- a/.trellis/config.yaml +++ b/.trellis/config.yaml @@ -164,7 +164,7 @@ packages: mind-test-harness: path: apps/mind-test-harness onetalk-contract: - path: apps/onetalk-contract + path: packages/onetalk-contract server: path: apps/server default_package: @trade-message-center/chrome-extension diff --git a/.trellis/spec/chrome-extension/frontend/onetalk/runtime-sync.md b/.trellis/spec/chrome-extension/frontend/onetalk/runtime-sync.md index b1ad7bb..e114d1a 100644 --- a/.trellis/spec/chrome-extension/frontend/onetalk/runtime-sync.md +++ b/.trellis/spec/chrome-extension/frontend/onetalk/runtime-sync.md @@ -288,7 +288,7 @@ decodeOneTalkMessageContent(source: OneTalkMessageContentSource) -> | { status: "anomaly", code: OneTalkMediaAnomalyCode, mediaKind: "image" | "file" | "card" }; ``` -`apps/onetalk-contract/src/content.ts` 是这六个 kind、exact-shape guard 和跨层读取模型的唯一 owner。`message-observer/content-decoder.ts` 是历史 SDK tuple 分类、受控 Base64 摘要解码和白名单投影的唯一生产点;它对名片只生产 marker,不生产客户资料 view。`read-projection.ts` 是服务端读取时将 marker 与同一账号/会话的当前 profile 组合为 `OneTalkBusinessCardViewContent` 的唯一 owner。 +`packages/onetalk-contract/src/content.ts` 是这六个 kind、exact-shape guard 和跨层读取模型的唯一 owner。`message-observer/content-decoder.ts` 是历史 SDK tuple 分类、受控 Base64 摘要解码和白名单投影的唯一生产点;它对名片只生产 marker,不生产客户资料 view。`read-projection.ts` 是服务端读取时将 marker 与同一账号/会话的当前 profile 组合为 `OneTalkBusinessCardViewContent` 的唯一 owner。 ### 7.3 Contracts diff --git a/.trellis/spec/project/missing-values.md b/.trellis/spec/project/missing-values.md index e78dcdb..98a4e13 100644 --- a/.trellis/spec/project/missing-values.md +++ b/.trellis/spec/project/missing-values.md @@ -84,13 +84,13 @@ const retryLimit = options.retryLimit ?? DEFAULT_RETRY_LIMIT; ### 1. Scope / Trigger - Trigger:根 package 版本跨 workspace package metadata、扩展构建/watch 和 release CI 传播,且这些边界不得各自补偿或推导版本。 -- Scope:根 `package.json:version` 是唯一可编辑事实源;`apps/*/package.json` 的具体版本是同步镜像;扩展最终只加载生成的 `dist/manifest.json`。 +- Scope:根 `package.json:version` 是唯一可编辑事实源;`apps/*/package.json` 与 `packages/*/package.json` 的具体版本是同步镜像;扩展最终只加载生成的 `dist/manifest.json`。 ### 2. Signatures - `validatePackageVersion(value: unknown, source?: string): string`:验证同时满足 package metadata 和 Chrome Manifest 的三段数字版本。 - `readRootPackageVersion(rootDir?: string): string`:只读取并验证 workspace 根 `package.json`。 -- `pnpm version:sync`:把根版本写入所有 `apps/*/package.json` 镜像。 +- `pnpm version:sync`:把根版本写入所有 `apps/*/package.json` 与 `packages/*/package.json` 镜像。 - `pnpm version:check`:只检查镜像,不自动修复。 - `pnpm version:ensure`:先执行 `version:sync`,再执行 `version:check`;根级 dev/build/typecheck/test/format:check 通过它获得稳定的一致版本环境。 - `TMC_PACKAGE_VERSION`:由 workspace 根命令注入给下游扩展命令;扩展直接执行时缺失必须失败。 diff --git a/.trellis/spec/project/module-ownership.md b/.trellis/spec/project/module-ownership.md index 6a6f84e..5065f5c 100644 --- a/.trellis/spec/project/module-ownership.md +++ b/.trellis/spec/project/module-ownership.md @@ -86,7 +86,7 @@ export const isObjectRecord = (value: unknown): value is Record ### 3. Contracts -- `apps/onetalk-contract/src/guards.ts` owns strict `isPlainRecord` and the +- `packages/onetalk-contract/src/guards.ts` owns strict `isPlainRecord` and the contract root facade is the only cross-package import path. It accepts current-realm plain objects and null-prototype objects, and rejects arrays, primitives, class/custom-prototype values, and cross-realm ordinary objects. diff --git a/.trellis/tasks/09-11-onetalk-structured-message-information-collection-classification/worktree-registry.yaml b/.trellis/tasks/09-11-onetalk-structured-message-information-collection-classification/worktree-registry.yaml index e3b99ee..83c4a30 100644 --- a/.trellis/tasks/09-11-onetalk-structured-message-information-collection-classification/worktree-registry.yaml +++ b/.trellis/tasks/09-11-onetalk-structured-message-information-collection-classification/worktree-registry.yaml @@ -8,11 +8,11 @@ scope_lanes: path: /Users/ybf/work/trade-message-center role: task-branch owns: - - apps/onetalk-contract/src/content.ts - - apps/onetalk-contract/src/guards.ts - - apps/onetalk-contract/src/contact-profiles.ts - - apps/onetalk-contract/src/index.ts - - apps/onetalk-contract/test/contract.test.ts + - packages/onetalk-contract/src/content.ts + - packages/onetalk-contract/src/guards.ts + - packages/onetalk-contract/src/contact-profiles.ts + - packages/onetalk-contract/src/index.ts + - packages/onetalk-contract/test/contract.test.ts - apps/chrome-extension/src/onetalk/main-page/message-observer/content-decoder.ts - apps/chrome-extension/src/onetalk/main-page/message-observer/history.ts - apps/chrome-extension/src/onetalk/page-bridge/model.ts diff --git a/Dockerfile.server b/Dockerfile.server index ccef6a6..860d67f 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -8,13 +8,13 @@ RUN corepack enable && corepack prepare pnpm@11.7.0 --activate ENV HUSKY=0 COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.base.json ./ -COPY apps/onetalk-contract/package.json apps/onetalk-contract/package.json +COPY packages/onetalk-contract/package.json packages/onetalk-contract/package.json COPY apps/server/package.json apps/server/package.json COPY apps/chrome-extension/package.json apps/chrome-extension/package.json RUN pnpm install --frozen-lockfile --registry=https://registry.npmjs.org -COPY apps/onetalk-contract apps/onetalk-contract +COPY packages/onetalk-contract packages/onetalk-contract COPY apps/server apps/server RUN pnpm --filter @trade-message-center/server build && \ diff --git a/docs/onetalk-image-send-observation-feasibility.md b/docs/onetalk-image-send-observation-feasibility.md index 7a23696..14b26e1 100644 --- a/docs/onetalk-image-send-observation-feasibility.md +++ b/docs/onetalk-image-send-observation-feasibility.md @@ -436,7 +436,7 @@ Base64 → normalized image content ``` -输出合同定义于 [`content.ts`](../apps/onetalk-contract/src/content.ts): +输出合同定义于 [`content.ts`](../packages/onetalk-contract/src/content.ts): ```ts type OneTalkImageContent = { @@ -688,7 +688,7 @@ raw `originalData` 只应在 MAIN world 短暂存在。send correlator 应消费 - live frame 分发:[`index.ts`](../apps/chrome-extension/src/onetalk/main-page/message-observer/index.ts) - live message 解析:[`new.ts`](../apps/chrome-extension/src/onetalk/main-page/message-observer/new.ts) - MAIN 内容归一化:[`content-decoder.ts`](../apps/chrome-extension/src/onetalk/main-page/message-observer/content-decoder.ts) -- 归一化媒体合同:[`content.ts`](../apps/onetalk-contract/src/content.ts) +- 归一化媒体合同:[`content.ts`](../packages/onetalk-contract/src/content.ts) - observer/correlator 接线:[`page-script-entry.ts`](../apps/chrome-extension/src/onetalk/main-page/page-script-entry.ts) - 当前文本发送确认:[`send-observation.ts`](../apps/chrome-extension/src/onetalk/main-page/message-observer/send-observation.ts) - 当前页面命令入口:[`page-command.ts`](../apps/chrome-extension/src/onetalk/main-page/current-conversation-history/page-command.ts) diff --git a/docs/onetalk-media-message-format-investigation.md b/docs/onetalk-media-message-format-investigation.md index 5fd47cc..3863652 100644 --- a/docs/onetalk-media-message-format-investigation.md +++ b/docs/onetalk-media-message-format-investigation.md @@ -416,7 +416,7 @@ nodeName ### 10.1 共享内容解码器 -在 `apps/onetalk-contract` 或其最近共同父目录增加一个唯一的内容投影器,输入原始 `content`,输出判别联合: +在 `packages/onetalk-contract` 或其最近共同父目录增加一个唯一的内容投影器,输入原始 `content`,输出判别联合: ```text text diff --git a/docs/onetalk-message-content-formats.md b/docs/onetalk-message-content-formats.md index d232fb7..184cdab 100644 --- a/docs/onetalk-message-content-formats.md +++ b/docs/onetalk-message-content-formats.md @@ -902,8 +902,8 @@ aliIdEncrypt | 历史只读 SDK | `apps/chrome-extension/src/onetalk/main-page/current-conversation-history/sdk.ts` | 调用 `fetchMessagesWithoutUpdateToRead` | | 页面到 SW | `apps/chrome-extension/src/onetalk/service-worker/sync-engine/helpers.ts` | 原样复制观察字段 | | IndexedDB 校验 | `apps/chrome-extension/src/onetalk/service-worker/storage.ts` | 只检查 JSON 与基础字段类型 | -| 共享合同 | `apps/onetalk-contract/src/model.ts` | `content` 为任意 JSON value | -| 共享 decoder | `apps/onetalk-contract/src/decoder.ts` | 不理解 text/image/file 语义 | +| 共享合同 | `packages/onetalk-contract/src/model.ts` | `content` 为任意 JSON value | +| 共享 decoder | `packages/onetalk-contract/src/decoder.ts` | 不理解 text/image/file 语义 | | Bright 清洗 | `apps/server/src/onetalk/service.ts` | 按键过滤对象,字符串原样通过 | | Bright 持久化 | `apps/server/src/database/schema/onetalk.ts` | `content jsonb`、`text nullable` | | 开发展示 | `apps/mind-test-harness/src/harness.ts` | 只展示 raw JSON | diff --git a/package.json b/package.json index 6422a9a..41d2e36 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "0.8.27", "private": true, "workspaces": [ - "apps/*" + "apps/*", + "packages/*" ], "type": "module", "scripts": { diff --git a/apps/onetalk-contract/package.json b/packages/onetalk-contract/package.json similarity index 100% rename from apps/onetalk-contract/package.json rename to packages/onetalk-contract/package.json diff --git a/apps/onetalk-contract/src/authorization.ts b/packages/onetalk-contract/src/authorization.ts similarity index 100% rename from apps/onetalk-contract/src/authorization.ts rename to packages/onetalk-contract/src/authorization.ts diff --git a/apps/onetalk-contract/src/buyer-facts.ts b/packages/onetalk-contract/src/buyer-facts.ts similarity index 100% rename from apps/onetalk-contract/src/buyer-facts.ts rename to packages/onetalk-contract/src/buyer-facts.ts diff --git a/apps/onetalk-contract/src/connection.ts b/packages/onetalk-contract/src/connection.ts similarity index 100% rename from apps/onetalk-contract/src/connection.ts rename to packages/onetalk-contract/src/connection.ts diff --git a/apps/onetalk-contract/src/contact-profiles.ts b/packages/onetalk-contract/src/contact-profiles.ts similarity index 100% rename from apps/onetalk-contract/src/contact-profiles.ts rename to packages/onetalk-contract/src/contact-profiles.ts diff --git a/apps/onetalk-contract/src/content.ts b/packages/onetalk-contract/src/content.ts similarity index 100% rename from apps/onetalk-contract/src/content.ts rename to packages/onetalk-contract/src/content.ts diff --git a/apps/onetalk-contract/src/conversation-sync.ts b/packages/onetalk-contract/src/conversation-sync.ts similarity index 100% rename from apps/onetalk-contract/src/conversation-sync.ts rename to packages/onetalk-contract/src/conversation-sync.ts diff --git a/apps/onetalk-contract/src/decoder.ts b/packages/onetalk-contract/src/decoder.ts similarity index 100% rename from apps/onetalk-contract/src/decoder.ts rename to packages/onetalk-contract/src/decoder.ts diff --git a/apps/onetalk-contract/src/guards.ts b/packages/onetalk-contract/src/guards.ts similarity index 100% rename from apps/onetalk-contract/src/guards.ts rename to packages/onetalk-contract/src/guards.ts diff --git a/apps/onetalk-contract/src/index.ts b/packages/onetalk-contract/src/index.ts similarity index 100% rename from apps/onetalk-contract/src/index.ts rename to packages/onetalk-contract/src/index.ts diff --git a/apps/onetalk-contract/src/messages.ts b/packages/onetalk-contract/src/messages.ts similarity index 100% rename from apps/onetalk-contract/src/messages.ts rename to packages/onetalk-contract/src/messages.ts diff --git a/apps/onetalk-contract/src/read-api.ts b/packages/onetalk-contract/src/read-api.ts similarity index 100% rename from apps/onetalk-contract/src/read-api.ts rename to packages/onetalk-contract/src/read-api.ts diff --git a/apps/onetalk-contract/src/sending.ts b/packages/onetalk-contract/src/sending.ts similarity index 100% rename from apps/onetalk-contract/src/sending.ts rename to packages/onetalk-contract/src/sending.ts diff --git a/apps/onetalk-contract/src/wire.ts b/packages/onetalk-contract/src/wire.ts similarity index 100% rename from apps/onetalk-contract/src/wire.ts rename to packages/onetalk-contract/src/wire.ts diff --git a/apps/onetalk-contract/test/contract.test.ts b/packages/onetalk-contract/test/contract.test.ts similarity index 100% rename from apps/onetalk-contract/test/contract.test.ts rename to packages/onetalk-contract/test/contract.test.ts diff --git a/apps/onetalk-contract/tsconfig.json b/packages/onetalk-contract/tsconfig.json similarity index 100% rename from apps/onetalk-contract/tsconfig.json rename to packages/onetalk-contract/tsconfig.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29be079..fda8431 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: dependencies: '@trade-message-center/onetalk-contract': specifier: workspace:* - version: link:../onetalk-contract + version: link:../../packages/onetalk-contract devDependencies: '@types/node': specifier: ^22.10.2 @@ -41,16 +41,7 @@ importers: dependencies: '@trade-message-center/onetalk-contract': specifier: workspace:* - version: link:../onetalk-contract - devDependencies: - '@types/node': - specifier: ^22.10.2 - version: 22.20.1 - typescript: - specifier: ^5.7.3 - version: 5.7.3 - - apps/onetalk-contract: + version: link:../../packages/onetalk-contract devDependencies: '@types/node': specifier: ^22.10.2 @@ -66,7 +57,7 @@ importers: version: 11.3.0 '@trade-message-center/onetalk-contract': specifier: workspace:* - version: link:../onetalk-contract + version: link:../../packages/onetalk-contract drizzle-orm: specifier: ^0.45.2 version: 0.45.2(postgres@3.4.9) @@ -87,6 +78,15 @@ importers: specifier: ^5.7.3 version: 5.7.3 + packages/onetalk-contract: + devDependencies: + '@types/node': + specifier: ^22.10.2 + version: 22.20.1 + typescript: + specifier: ^5.7.3 + version: 5.7.3 + packages: '@drizzle-team/brocli@0.10.2': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 6d670a6..a889f00 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,5 @@ packages: - apps/* + - packages/* allowBuilds: esbuild: true diff --git a/scripts/clean-generated-dist.mjs b/scripts/clean-generated-dist.mjs index d7e40e7..e50bea7 100644 --- a/scripts/clean-generated-dist.mjs +++ b/scripts/clean-generated-dist.mjs @@ -6,7 +6,7 @@ import { fileURLToPath, pathToFileURL } from "node:url"; const workspaceDir = resolve(fileURLToPath(new URL(".", import.meta.url)), ".."); export const GENERATED_DIST_RELATIVE_PATHS = [ - "apps/onetalk-contract/dist", + "packages/onetalk-contract/dist", "apps/server/dist", "apps/chrome-extension/dist", ]; diff --git a/scripts/package-version.mjs b/scripts/package-version.mjs index fd507da..e43f1ea 100644 --- a/scripts/package-version.mjs +++ b/scripts/package-version.mjs @@ -25,13 +25,19 @@ const readJsonFile = (filePath) => { } }; -/** 枚举 apps 下可参与版本镜像的 workspace package。 */ +const workspacePackageDirectories = ["apps", "packages"]; + +/** 按 workspace 根目录顺序枚举可参与版本镜像的 package。 */ export const listWorkspacePackagePaths = (rootDir = workspaceDir) => - readdirSync(resolve(rootDir, "apps"), { withFileTypes: true }) - .filter((entry) => entry.isDirectory()) - .map((entry) => resolve(rootDir, "apps", entry.name, "package.json")) - .filter((packagePath) => existsSync(packagePath)) - .sort(); + workspacePackageDirectories.flatMap((directory) => { + const directoryPath = resolve(rootDir, directory); + if (!existsSync(directoryPath)) return []; + return readdirSync(directoryPath, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => resolve(directoryPath, entry.name, "package.json")) + .filter((packagePath) => existsSync(packagePath)) + .sort(); + }); /** 校验同时满足 npm 与 Chrome Manifest 的三段版本。 */ export const validatePackageVersion = (version, source = "package.json") => { diff --git a/scripts/package-version.test.mjs b/scripts/package-version.test.mjs index c1041f8..2bde59a 100644 --- a/scripts/package-version.test.mjs +++ b/scripts/package-version.test.mjs @@ -3,13 +3,14 @@ import assert from "node:assert/strict"; import { mkdtempSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; -import { join } from "node:path"; +import { join, relative } from "node:path"; import test from "node:test"; import { bumpPackageVersion, readRootPackageVersion, validatePackageVersion, + listWorkspacePackagePaths, writeRootPackageVersion, } from "./package-version.mjs"; import { checkPackageVersions } from "./check-package-versions.mjs"; @@ -18,16 +19,17 @@ import { syncPackageVersions } from "./sync-package-versions.mjs"; const createWorkspace = (rootVersion, packageVersions) => { const rootDir = mkdtempSync(join(tmpdir(), "tmc-package-version-")); mkdirSync(join(rootDir, "apps")); + mkdirSync(join(rootDir, "packages")); writeFileSync( join(rootDir, "package.json"), `${JSON.stringify({ name: "fixture", version: rootVersion }, null, 4)}\n`, ); - for (const [name, version] of Object.entries(packageVersions)) { - const packageDir = join(rootDir, "apps", name); + for (const [relativePackagePath, version] of Object.entries(packageVersions)) { + const packageDir = join(rootDir, relativePackagePath); mkdirSync(packageDir); writeFileSync( join(packageDir, "package.json"), - `${JSON.stringify({ name, version }, null, 4)}\n`, + `${JSON.stringify({ name: relativePackagePath, version }, null, 4)}\n`, ); } return rootDir; @@ -72,13 +74,25 @@ test("bumps and writes the root version without creating another version source" assert.equal(readRootPackageVersion(rootDir), "0.8.17"); }); -test("syncs and checks every app package against the root version", () => { - const rootDir = createWorkspace("1.2.3", { extension: "0.1.0", server: "0.1.0" }); +test("syncs and checks app and shared workspace package mirrors against the root version", () => { + const rootDir = createWorkspace("1.2.3", { + "apps/extension": "0.1.0", + "apps/server": "0.1.0", + "packages/contract": "0.1.0", + }); assert.throws(() => checkPackageVersions(rootDir), /must equal root version 1.2.3/u); syncPackageVersions(rootDir); assert.equal(readRootPackageVersion(rootDir), "1.2.3"); checkPackageVersions(rootDir); + assert.deepEqual( + listWorkspacePackagePaths(rootDir).map((packagePath) => relative(rootDir, packagePath)), + [ + "apps/extension/package.json", + "apps/server/package.json", + "packages/contract/package.json", + ], + ); }); test("syncs version mirrors before root quality commands check them", () => { diff --git a/scripts/release.test.mjs b/scripts/release.test.mjs index f012a4d..2b6632e 100644 --- a/scripts/release.test.mjs +++ b/scripts/release.test.mjs @@ -11,12 +11,17 @@ import { prepareRelease, publishRelease } from "./release.mjs"; const createWorkspace = (version = "0.8.16") => { const rootDir = mkdtempSync(join(tmpdir(), "tmc-release-")); mkdirSync(join(rootDir, "apps")); + mkdirSync(join(rootDir, "packages")); writeFileSync( join(rootDir, "package.json"), `${JSON.stringify({ name: "fixture", version }, null, 4)}\n`, ); - for (const name of ["extension", "server"]) { - const packageDir = join(rootDir, "apps", name); + for (const [directory, name] of [ + ["apps", "extension"], + ["apps", "server"], + ["packages", "contract"], + ]) { + const packageDir = join(rootDir, directory, name); mkdirSync(packageDir); writeFileSync( join(packageDir, "package.json"), @@ -41,7 +46,12 @@ const createRunner = (responses) => { return { calls, execute }; }; -const expectedFiles = ["package.json", "apps/extension/package.json", "apps/server/package.json"]; +const expectedFiles = [ + "package.json", + "apps/extension/package.json", + "apps/server/package.json", + "packages/contract/package.json", +]; test("prepares a patch release using only root-derived version mirrors", () => { const rootDir = createWorkspace(); @@ -63,9 +73,11 @@ test("prepares a patch release using only root-derived version mirrors", () => { assert.equal(prepareRelease({ rootDir, execute }), "0.8.17"); assert.equal(JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8")).version, "0.8.17"); - for (const packageName of ["extension", "server"]) { - const packagePath = join(rootDir, "apps", packageName, "package.json"); - assert.equal(JSON.parse(readFileSync(packagePath, "utf8")).version, "0.8.17"); + for (const packagePath of expectedFiles.slice(1)) { + assert.equal( + JSON.parse(readFileSync(join(rootDir, packagePath), "utf8")).version, + "0.8.17", + ); } assert.deepEqual( calls.filter(({ command }) => command === "pnpm").map(({ arguments_ }) => arguments_),