Skip to content

Commit 7faf5ae

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/sys-secret-producer-conflict-157867
2 parents 5515efe + d5749d7 commit 7faf5ae

39 files changed

Lines changed: 1233 additions & 342 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
"@objectstack/formula": patch
3+
"@objectstack/sdui-parser": patch
4+
"@objectstack/connector-mcp": patch
5+
"@objectstack/connector-openapi": patch
6+
"@objectstack/connector-rest": patch
7+
"@objectstack/connector-slack": patch
8+
"@objectstack/embedder-openai": patch
9+
"@objectstack/knowledge-memory": patch
10+
"@objectstack/knowledge-ragflow": patch
11+
"@objectstack/plugin-approvals": patch
12+
"@objectstack/plugin-email": patch
13+
"@objectstack/plugin-pinyin-search": patch
14+
"@objectstack/plugin-reports": patch
15+
"@objectstack/plugin-sharing": patch
16+
"@objectstack/plugin-webhooks": patch
17+
"@objectstack/service-cluster": patch
18+
"@objectstack/service-cluster-redis": patch
19+
"@objectstack/service-datasource": patch
20+
"@objectstack/service-sms": patch
21+
"@objectstack/trigger-api": patch
22+
---
23+
24+
chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
25+
26+
These 20 packages declared no `files` field, so npm fell back to packing the
27+
whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
28+
listed **21 files** — 15 under `src/`, three of them unit tests
29+
(`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
30+
build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
31+
publish time rather than instead of it, so consumers were installing the
32+
TypeScript sources and the test suite alongside the artifact they asked for.
33+
34+
Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
35+
that already did. Nothing a consumer imports moves: every `main` / `types` /
36+
`exports` target in all 20 already resolved inside `dist/`, which the new
37+
`check:published-files` guard verifies rather than assumes. The visible change
38+
is a smaller install and a smaller dependency-scanning surface — `npm pack` on
39+
`@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
40+
41+
The other half of the fix is the gate. Half the packages declaring `files` and
42+
half not was the #3786 shape — a hand-copied convention with nothing enforcing
43+
it, where whoever forgets the line gets no signal at all. `check:published-files`
44+
(new, wired into the always-required `lint` job) holds every non-private
45+
workspace package to four invariants: `files` is **declared**; it is
46+
**sufficient** (covers every entry point, so tightening a whitelist cannot ship
47+
a package that fails to resolve); it is **minimal** (admits no test, test-harness
48+
config or build script); and anything beyond `dist` + `README.md` is
49+
**registered** with a reason, reconciled in both directions so a stale exemption
50+
is an error rather than dead text. `@objectstack/spec` is the one package with
51+
registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
52+
`CHANGELOG.md` are product, not build input.
53+
54+
This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
55+
from the docs-drift implementation test is sound only while no package publishes
56+
`scripts/` as runtime code; that held, but it held because someone read all three
57+
offenders by hand. It is now checked on every PR.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
"@objectstack/types": minor
3+
"@objectstack/rest": patch
4+
"@objectstack/service-storage": patch
5+
"@objectstack/service-settings": patch
6+
"@objectstack/service-datasource": patch
7+
"@objectstack/service-i18n": patch
8+
"@objectstack/plugin-sharing": patch
9+
---
10+
11+
refactor(types,rest,services,plugin-sharing): one shared writer for the response envelope, and `error.code` is enforced at compile time (#3973)
12+
13+
`BaseResponseSchema` declares one envelope for every REST body the platform
14+
emits. It declared it once; the code that *wrote* it was copied per route
15+
module. After #3843 and #3983 converted the last drifting one, seven modules
16+
each carried their own two-line `sendOk` / `sendError` pair — so the envelope's
17+
shape lived in fourteen places rather than one.
18+
19+
`pnpm check:route-envelope` proved those seven copies agreed, which is why this
20+
is a cleanup rather than a bug fix. But a guard proves agreement; it does not
21+
create it. An eighth module starts by copying the pair again — not
22+
hypothetically: `share-link-routes.ts` was found already drifting by the
23+
repo-wide scan, and its drift had broken `client.shareLinks.create()` and
24+
`.list()` through `unwrapResponse` (#3983).
25+
26+
## What moved
27+
28+
`sendOk` / `sendError` now live once, in `@objectstack/types`
29+
(`response-envelope.ts`), and all seven modules import them:
30+
31+
| Module |
32+
|---|
33+
| `service-storage/storage-routes.ts` |
34+
| `service-settings/settings-routes.ts` |
35+
| `service-datasource/admin-routes.ts` |
36+
| `rest/external-datasource-routes.ts` |
37+
| `rest/package-routes.ts` |
38+
| `service-i18n/i18n-service-plugin.ts` |
39+
| `plugin-sharing/share-link-routes.ts` |
40+
41+
Placement was the open question in #3973, not design. `packages/spec` is
42+
schemas-only (Prime Directive #2), and the callers span `rest`, four
43+
`services/*` and one `plugins/*`, which rules out anything depending on them.
44+
`@objectstack/types` depends on nothing but `@objectstack/spec`, so every caller
45+
can reach it, and it is already where the repo puts a helper the HTTP boundaries
46+
share — `looksLikeInternalErrorLeak` (#3867) sits one file over and made the
47+
same argument first.
48+
49+
The builders take a structural `{ status(n), json(body) }`, so the package
50+
imports no HTTP contract at all: `IHttpResponse` satisfies it, and so does the
51+
`any`-typed `res` the older modules carry.
52+
53+
## `error.code` is now checked by the compiler
54+
55+
All seven copies typed the parameter `code: string`. ADR-0112 (#3841) closed the
56+
vocabulary — `ErrorCode` is `StandardErrorCode ∪ ERROR_CODE_LEDGER` — but an
57+
invented code was still caught only at runtime, by a conformance suite parsing a
58+
driven body, i.e. only on routes some test happened to drive.
59+
60+
The shared `sendError` types `code` as `ErrorCode`, so an unregistered code now
61+
fails to compile, at every call site at once:
62+
63+
```ts
64+
sendError(res, 400, 'NOT_A_REGISTERED_CODE', 'invented');
65+
// Argument of type '"NOT_A_REGISTERED_CODE"' is not assignable to parameter of type 'ErrorCode'.
66+
```
67+
68+
This cost no call-site churn: every code the seven modules emit was already
69+
registered.
70+
71+
## `extra` is closed at the same place
72+
73+
`sendError`'s last parameter is `Pick<ApiError, 'category' | 'httpStatus' |
74+
'details' | 'requestId'>` — exactly what `ApiErrorSchema` declares beside `code`
75+
and `message`.
76+
77+
It was `Record<string, unknown>` while `settings-routes` still hung `namespace` /
78+
`key` / `reason` / `fields` beside `code`. Those bodies passed every gate anyway:
79+
`ApiErrorSchema` is a plain `z.object`, so unknown keys were STRIPPED rather than
80+
rejected, and `envelopeViolations` inspects only the body's top level —
81+
conformant *by stripping* rather than by declaration. #4224 moved that module
82+
onto `details`, which is what lets the parameter close here. Closing it at the
83+
shared builder is the part that lasts: an undeclared sibling is now a compile
84+
error in every module at once, rather than a key that quietly evaporates in
85+
whichever module reintroduces it.
86+
87+
## Nothing changes on the wire
88+
89+
The seven pairs were identical modulo the optional `status` and `extra`
90+
parameters this one unions, and each module's driven conformance suite still
91+
parses its real bodies against the real spec schemas. One internal call site was
92+
rewritten: `package-routes` passed `details` positionally and now passes
93+
`{ details }`, producing the same `error.details` it always did.
94+
95+
## The guard got stronger
96+
97+
`scripts/check-route-envelope.mjs` counts response write sites per module. A
98+
module that routes everything through the shared pair builds **none** itself, so
99+
the seven now declare `0 / 0 / 0` where they used to declare `2 / 1 / 1`, and the
100+
shared pair is pinned separately at `2 / 1 / 1` so the invariant stays total for
101+
the surface rather than per-module. What the count asserts is no longer "your two
102+
builders are the enveloped ones" but "you have no builders" — and a new route
103+
that hand-rolls a body still moves it off zero and fails.

.github/workflows/lint.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,22 @@ jobs:
166166
- name: Node-version drift guard
167167
run: pnpm check:node-version
168168

169+
# #4248 packaging-hygiene guard. Without a `files` whitelist npm packs the
170+
# whole package directory, and 20 of the 49 publishable packages declared
171+
# none — so consumers installed TypeScript sources, unit tests and build
172+
# tooling, with dist/ landing on top of them rather than instead of them
173+
# (@objectstack/plugin-webhooks: 21 files, three of them unit tests). The
174+
# other 29 did declare it, so this was a hand-copied line with no gate —
175+
# the #3786 shape, where whoever forgets it gets no signal at all. Also
176+
# checks the whitelist is SUFFICIENT (covers every entry point, so
177+
# tightening one cannot ship a package that fails to resolve) and MINIMAL
178+
# (admits no test or build script), which keeps #4206's "`<pkg>/scripts/**`
179+
# is never runtime code" assumption continuously verified instead of
180+
# hand-checked. Runs its own --self-test first: the pattern semantics can
181+
# be wrong while every package is right.
182+
- name: Published-files whitelist guard
183+
run: pnpm check:published-files
184+
169185
typecheck:
170186
name: TypeScript Type Check
171187
runs-on: ubuntu-latest

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
"check:wildcard-fallthrough": "node scripts/check-wildcard-fallthrough.mjs --self-test && node scripts/check-wildcard-fallthrough.mjs",
4141
"check:console-sha": "node scripts/check-console-sha.mjs",
4242
"check:release-notes": "node scripts/check-release-notes.mjs",
43-
"check:node-version": "node scripts/check-node-version.mjs"
43+
"check:node-version": "node scripts/check-node-version.mjs",
44+
"check:published-files": "node scripts/check-published-files.mjs --self-test && node scripts/check-published-files.mjs"
4445
},
4546
"keywords": [
4647
"objectstack",

packages/connectors/connector-mcp/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@
3535
"integration",
3636
"ai",
3737
"tools"
38+
],
39+
"files": [
40+
"dist",
41+
"README.md"
3842
]
3943
}

packages/connectors/connector-openapi/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,9 @@
3333
"swagger",
3434
"integration",
3535
"api"
36-
]
36+
],
37+
"files": [
38+
"dist",
39+
"README.md"
40+
]
3741
}

packages/connectors/connector-rest/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@
3232
"rest",
3333
"integration",
3434
"http"
35+
],
36+
"files": [
37+
"dist",
38+
"README.md"
3539
]
3640
}

packages/connectors/connector-slack/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@
3232
"slack",
3333
"integration",
3434
"messaging"
35+
],
36+
"files": [
37+
"dist",
38+
"README.md"
3539
]
3640
}

packages/formula/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,9 @@
4141
"bugs": "https://github.com/objectstack-ai/objectstack/issues",
4242
"publishConfig": {
4343
"access": "public"
44-
}
44+
},
45+
"files": [
46+
"dist",
47+
"README.md"
48+
]
4549
}

packages/plugins/embedder-openai/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,9 @@
3636
"zhipu",
3737
"siliconflow",
3838
"ollama"
39+
],
40+
"files": [
41+
"dist",
42+
"README.md"
3943
]
4044
}

0 commit comments

Comments
 (0)