Skip to content

Commit cc2de0e

Browse files
authored
chore(packaging): every published package declares a files whitelist (#4248) (#4262)
20 of the 49 publishable packages declared no `files` field, so npm fell back to packing the whole package directory. `npm pack --dry-run` on @objectstack/plugin-webhooks listed 21 files -- 15 under src/, three of them unit tests, plus the build-time scripts/i18n-extract.config.ts. dist/ lands on top of that at publish time rather than instead of it. Each now declares ["dist", "README.md"], matching the 29 packages that already did. Nothing a consumer imports moves: every main / types / exports target in all 20 already resolved inside dist/. The other half is the gate. check:published-files (wired into the always-required lint job) holds every non-private workspace package to four invariants: DECLARED, SUFFICIENT (covers every entry point, so tightening a whitelist cannot ship a package that fails to resolve), MINIMAL (admits no test, test-harness config or build script), and REGISTERED (anything beyond dist + README.md carries a reason, reconciled in both directions). MINIMAL also closes an assumption #4206 rested on: that no package publishes scripts/ as runtime code held, but it held by hand-checking three packages. It is now checked on every PR.
1 parent 59b85c0 commit cc2de0e

24 files changed

Lines changed: 622 additions & 8 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.

.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
}

packages/plugins/knowledge-memory/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,9 @@
3333
"rag",
3434
"memory",
3535
"in-memory"
36+
],
37+
"files": [
38+
"dist",
39+
"README.md"
3640
]
3741
}

0 commit comments

Comments
 (0)