From 3d86999027b6f3efe327c986c3decf6f0e88e77e Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 24 Sep 2026 23:02:20 -0700 Subject: [PATCH 1/4] refactor!: stop exporting the drizzle tables from the package entry The tables are internal to the package's queries; hosts reach artifacts through the routes and functions instead. ARTIFACTS_SCHEMA stays public so a host can see which Postgres schema the package owns. --- CHANGELOG.md | 4 ++++ CONTRIBUTING.md | 7 ++++--- src/index.ts | 8 +------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56b5878..5d62bcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -119,6 +119,10 @@ always called out under their own heading. ### Breaking +- The drizzle tables (`artifact`, `artifactVersion`, `upload`, + `mailAttachmentRef`) are no longer exported from the package entry. Hosts + reach artifacts through the routes and functions; `ARTIFACTS_SCHEMA` and the + `*Row` types stay public. - `mountArtifacts` takes `Hono`, reads the host-provided tenant and principal context natively, and requires the host's Interchange `RequireGrant` middleware. The `resolvePrincipal`, `isAdmin`, and `identity` options and the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8a3666f..d6f8494 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,9 +76,10 @@ rendered SQL, so editing one that has already been applied fails with `MigrationChecksumError` on the next boot rather than letting fresh and existing databases diverge. Add a new migration instead. -`schema.ts` and `migrations.ts` must agree — the drizzle table objects are public -exports, and a test asserts the migrations create exactly the tables `schema.ts` -declares, no more and no less. Change one, change the other, in the same commit. +`schema.ts` and `migrations.ts` must agree — every query goes through the drizzle +table objects, and a test asserts the migrations create exactly the tables +`schema.ts` declares, no more and no less. Change one, change the other, in the +same commit. ## Pull requests diff --git a/src/index.ts b/src/index.ts index 80da872..b5235f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,13 +25,7 @@ export type { RunArtifactMigrationsOptions } from "./migrations.js"; export { createArtifactDb } from "./db.js"; export type { ArtifactDb, ArtifactTx } from "./db.js"; -export { - ARTIFACTS_SCHEMA, - artifact, - artifactVersion, - upload, - mailAttachmentRef, -} from "./schema.js"; +export { ARTIFACTS_SCHEMA } from "./schema.js"; export type { ArtifactRow, ArtifactVersionRow, From 2eee341aa7da51ba6c899deff5aa002b820cb8e0 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 24 Sep 2026 23:03:38 -0700 Subject: [PATCH 2/4] build(deps): mark @intx/agent as an optional peer Only the ./sidecar-bundle entry imports it, so hosts that mount the routes alone no longer have to install the agent runtime. --- CHANGELOG.md | 2 ++ bun.lock | 3 +++ package.json | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d62bcb..1b83a20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,8 @@ always called out under their own heading. ### Changed +- `@intx/agent` is an optional peer. Only `@corbits/artifacts/sidecar-bundle` + imports it, so a host that mounts the routes alone need not install it. - Minimum `@intx/*` is now **0.3.0**. (`@intx/*` lines before 0.3.0 do not install — older lines pin the unpublished `@intx/*@0.0.0` or ship raw TypeScript.) diff --git a/bun.lock b/bun.lock index d680ee7..4ccf8da 100644 --- a/bun.lock +++ b/bun.lock @@ -31,6 +31,9 @@ "hono-openapi": "^1.2.0", "postgres": "^3.4.9", }, + "optionalPeers": [ + "@intx/agent", + ], }, }, "overrides": { diff --git a/package.json b/package.json index 500e884..4059b03 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,11 @@ "@intx/hub-api": "^0.4.0", "@intx/agent": "^0.4.0" }, + "peerDependenciesMeta": { + "@intx/agent": { + "optional": true + } + }, "devDependencies": { "@intx/types": "0.4.0", "@types/bun": "1.1.14", From dd99bc2c1f600ccba907fa1ca5ce855a9e75369d Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 24 Sep 2026 23:04:19 -0700 Subject: [PATCH 3/4] build(deps): depend on arktype directly instead of as a peer Corbits packages treat arktype as internal validation, so hosts should not have to install it. The exported query schemas stay arktype types; a host on another arktype version gets its own copy alongside. hono-openapi stays a peer because its route descriptions merge into the host's OpenAPI document. --- CHANGELOG.md | 3 +++ bun.lock | 11 +++++------ examples/reference-host/bun.lock | 1 - examples/reference-host/package.json | 1 - package.json | 5 ++--- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b83a20..2bac9d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,9 @@ always called out under their own heading. - `@intx/agent` is an optional peer. Only `@corbits/artifacts/sidecar-bundle` imports it, so a host that mounts the routes alone need not install it. +- `arktype` is a regular dependency (`^2.2.3`) instead of a peer, so hosts no + longer install it themselves. The exported query schemas are still arktype + types; a host on another arktype version gets its own copy alongside. - Minimum `@intx/*` is now **0.3.0**. (`@intx/*` lines before 0.3.0 do not install — older lines pin the unpublished `@intx/*@0.0.0` or ship raw TypeScript.) diff --git a/bun.lock b/bun.lock index 4ccf8da..e21314e 100644 --- a/bun.lock +++ b/bun.lock @@ -6,6 +6,7 @@ "name": "@corbits/artifacts", "dependencies": { "@hono/standard-validator": "^0.2.3", + "arktype": "^2.2.3", }, "devDependencies": { "@intx/agent": "0.4.0", @@ -14,7 +15,6 @@ "@intx/types": "0.4.0", "@types/bun": "1.1.14", "@types/node": "22.10.5", - "arktype": "2.1.29", "drizzle-orm": "0.45.2", "hono": "4.12.32", "hono-openapi": "1.2.0", @@ -25,7 +25,6 @@ "@intx/agent": "^0.4.0", "@intx/hub-api": "^0.4.0", "@intx/types": "^0.4.0", - "arktype": "^2.1.29", "drizzle-orm": "^0.45.2", "hono": "^4.12.32", "hono-openapi": "^1.2.0", @@ -40,9 +39,9 @@ "drizzle-orm": "0.45.2", }, "packages": { - "@ark/schema": ["@ark/schema@0.56.0", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA=="], + "@ark/schema": ["@ark/schema@0.56.4", "", { "dependencies": { "@ark/util": "0.56.4" } }, "sha512-nd4OqaWdKZJeGF5zNmZysDQO7NyyJ1ycl4S7i16Hj1VxqL+x72Z66lOn7ErpsoMUZtCtslAMHMjqJhuQSxciyw=="], - "@ark/util": ["@ark/util@0.56.0", "", {}, "sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA=="], + "@ark/util": ["@ark/util@0.56.4", "", {}, "sha512-KKqwGSia44cvuuDY70jGfbiUdG2E8F2cM4npdqvJ22S5a0LknlwG6nIrfQG1nF8fzxpzP30098wp0a8ASs0prQ=="], "@better-auth/core": ["@better-auth/core@1.6.25", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.39.0", "@standard-schema/spec": "^1.1.0", "zod": "^4.3.6" }, "peerDependencies": { "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.1", "@cloudflare/workers-types": ">=4", "@opentelemetry/api": "^1.9.0", "better-call": "1.3.7", "jose": "^6.1.0", "kysely": "^0.28.5 || ^0.29.0", "nanostores": "^1.0.1" }, "optionalPeers": ["@cloudflare/workers-types", "@opentelemetry/api"] }, "sha512-lMTlhtwyK4NpY9kPF+2rQCRKYpg136d3gM2xl8esxT1PjJx5Nh5YwZvxcYCIjDuO759sx6TCloJTuwcZGG6ZBw=="], @@ -138,9 +137,9 @@ "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "arkregex": ["arkregex@0.0.5", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw=="], + "arkregex": ["arkregex@0.0.10", "", { "dependencies": { "@ark/util": "0.56.4" } }, "sha512-+iDWBYBjH8w7wqEv8VY4loBwRldFxX84KNwKbobH3FJPay/18XI9sTesmXYpKyIrgbC5z/s16+vSJYHCC9FEvQ=="], - "arktype": ["arktype@2.1.29", "", { "dependencies": { "@ark/schema": "0.56.0", "@ark/util": "0.56.0", "arkregex": "0.0.5" } }, "sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ=="], + "arktype": ["arktype@2.2.5", "", { "dependencies": { "@ark/schema": "0.56.4", "@ark/util": "0.56.4", "arkregex": "0.0.10" } }, "sha512-c9oqY1eBab2LceqvpWX50xae2HB8P/nJPxRhuhPVf5lEDi3WQpf7WQflJFMsyCiA3NGh6zENOlse30gWBzlwDg=="], "async-lock": ["async-lock@1.4.1", "", {}, "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ=="], diff --git a/examples/reference-host/bun.lock b/examples/reference-host/bun.lock index fc99e4c..37eae64 100644 --- a/examples/reference-host/bun.lock +++ b/examples/reference-host/bun.lock @@ -11,7 +11,6 @@ "@intx/hub-common": "0.4.0", "@intx/hub-sessions": "0.4.0", "@intx/types": "0.4.0", - "arktype": "2.1.29", "drizzle-orm": "0.45.2", "hono": "4.12.32", "hono-openapi": "1.2.0", diff --git a/examples/reference-host/package.json b/examples/reference-host/package.json index 2732800..0cdc9ac 100644 --- a/examples/reference-host/package.json +++ b/examples/reference-host/package.json @@ -17,7 +17,6 @@ "@intx/hub-common": "0.4.0", "@intx/hub-sessions": "0.4.0", "@intx/types": "0.4.0", - "arktype": "2.1.29", "drizzle-orm": "0.45.2", "hono": "4.12.32", "hono-openapi": "1.2.0", diff --git a/package.json b/package.json index 4059b03..dedf317 100644 --- a/package.json +++ b/package.json @@ -62,11 +62,11 @@ "test:acceptance": "bun run build && bun test --cwd examples/reference-host" }, "dependencies": { - "@hono/standard-validator": "^0.2.3" + "@hono/standard-validator": "^0.2.3", + "arktype": "^2.2.3" }, "peerDependencies": { "@intx/types": "^0.4.0", - "arktype": "^2.1.29", "drizzle-orm": "^0.45.2", "hono": "^4.12.32", "hono-openapi": "^1.2.0", @@ -83,7 +83,6 @@ "@intx/types": "0.4.0", "@types/bun": "1.1.14", "@types/node": "22.10.5", - "arktype": "2.1.29", "drizzle-orm": "0.45.2", "hono": "4.12.32", "hono-openapi": "1.2.0", From 98045dc472152b283b8c01cb9d9802fa61b6adfd Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 24 Sep 2026 23:04:34 -0700 Subject: [PATCH 4/4] build: drop the check-deps pretest gate and the test:package alias The @workbench/* grep ran before every test run and in CI to catch an import nobody writes; the rule stays in CONTRIBUTING. test:package was only an alias of test. --- .github/workflows/test.yml | 5 ----- CONTRIBUTING.md | 7 +++---- package.json | 6 ++---- scripts/check-deps.ts | 19 ------------------- 4 files changed, 5 insertions(+), 32 deletions(-) delete mode 100644 scripts/check-deps.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85a4e94..352a090 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,11 +39,6 @@ jobs: - run: bun install --frozen-lockfile - # No unpublished @workbench/* scope may leak in — it does not exist on - # npm, so a leak makes the package uninstallable outside the monorepo. - - name: check-deps - run: bun run scripts/check-deps.ts - # typecheck builds first: examples import @corbits/artifacts through the # published dist types, same path a consumer resolves. - name: typecheck diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6f8494..584fbf7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ docker run -d --name corbits-artifact-pg -p 5457:5432 \ export ALLOW_DESTRUCTIVE_ARTIFACT_TESTS=1 bun run typecheck -bun run test # pretest dependency check, then unit + integration +bun run test # unit + integration bun run build # dist/ (JS + .d.ts) bun run test:acceptance # builds, then examples/reference-host ``` @@ -53,8 +53,7 @@ reference host is where that change has to be shown working. ## Dependency rule No `@workbench/*` imports anywhere — it is an unpublished scope, and importing it would -make this package uninstallable outside the project that defines it. Checked by -`scripts/check-deps.ts`, which runs as `pretest` and again in CI. +make this package uninstallable outside the project that defines it. ## Tests @@ -85,7 +84,7 @@ same commit. - Keep commits focused, and keep the diff to the change you are describing. - Explain *why* in the commit message; the code already says what. -- CI must be green: dependency check, typecheck, unit + integration, build, reference-host +- CI must be green: typecheck, unit + integration, build, reference-host acceptance, and a Node consumer smoke test that installs the packed tarball. - Contributions are accepted under the repository's LGPL-2.1-only licence. diff --git a/package.json b/package.json index dedf317..ae9b78a 100644 --- a/package.json +++ b/package.json @@ -55,10 +55,8 @@ "typecheck": "tsc --noEmit", "build": "rm -rf dist && tsc -p tsconfig.build.json", "prepack": "bun run build", - "pretest": "bun run scripts/check-deps.ts", - "test": "bun run pretest && bun test src", - "test:coverage": "bun run pretest && bun test --coverage src", - "test:package": "bun run test", + "test": "bun test src", + "test:coverage": "bun test --coverage src", "test:acceptance": "bun run build && bun test --cwd examples/reference-host" }, "dependencies": { diff --git a/scripts/check-deps.ts b/scripts/check-deps.ts deleted file mode 100644 index 869fd16..0000000 --- a/scripts/check-deps.ts +++ /dev/null @@ -1,19 +0,0 @@ -// The one dependency rule left: nothing here may import the unpublished -// @workbench/* scope — it does not exist on npm, so a leak makes the package -// uninstallable for everyone outside this repository. -import { execSync } from "node:child_process"; - -try { - const hits = execSync( - `grep -rn '@workbench/' src examples --include='*.ts' || true`, - { cwd: new URL("..", import.meta.url).pathname, encoding: "utf8" }, - ).trim(); - if (hits) { - console.error(`check-deps: unpublished @workbench/* import found:\n${hits}`); - process.exit(1); - } -} catch (error) { - console.error(error); - process.exit(1); -} -console.log("check-deps: clean — no @workbench/* imports.");