@substrat-run/contracts 0.48.1 → 0.49.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/dist/ci.d.ts ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The builder's CI vocabulary: preview tag conventions, the PR sticky-comment bodies,
3
+ * and the generated GitHub Actions workflow.
4
+ *
5
+ * It lives here — not in the dashboard, not in the CLI — for the same reason the deploy
6
+ * manifest does: BOTH ends must speak the same shape. Three writers exist for the same
7
+ * two artifacts and any drift between them is a silent bug:
8
+ *
9
+ * - the **dashboard's one-click CI setup** commits the workflow to a customer repo and
10
+ * (via `GithubRepoLinkDO`) posts the PR comment from the platform side;
11
+ * - **`substrat init --ci github`** writes the same workflow for a builder who owns their
12
+ * own CI and never connected the GitHub App;
13
+ * - the **workflow itself** posts the same comment from the CI side, as the fallback for
14
+ * an App installation that lacks `pull-requests: write`.
15
+ *
16
+ * The comment bodies are generated once here and rendered into the workflow's `printf`
17
+ * format string, so the platform-written and CI-written comments cannot say different
18
+ * things about the same PR. One generator, three writers, no drift.
19
+ *
20
+ * Pure string building — no zod, no network, no node. Safe in a worker, a CLI, and a
21
+ * browser bundle alike.
22
+ */
23
+ /**
24
+ * The sticky preview tag for a PR — one long-lived fork, REBOUND on every push, so the
25
+ * URL always serves the PR's latest code. The git analogy is a **branch ref**: a moving
26
+ * pointer, bookmarked once. Successive pushes roll their migrations forward on the one
27
+ * fork, which is the rehearsal that de-risks the eventual release.
28
+ */
29
+ export declare const previewTag: (prNumber: number) => string;
30
+ /**
31
+ * The per-build preview tag — a FRESH scope per build, bound once and never rebound, so
32
+ * the URL is frozen to exactly that build forever. The git analogy is a **sha**.
33
+ *
34
+ * A moving pointer is only safe when every build is *also* addressable immutably: "the bug
35
+ * on the PR preview" must always de-reference to a fixed artifact. That is the whole reason
36
+ * this tag exists alongside the sticky one.
37
+ */
38
+ export declare const buildPreviewTag: (prNumber: number, runId: string | number) => string;
39
+ /**
40
+ * The prefix that matches every per-build tag of one PR, and NOTHING else — note that
41
+ * PR 12's sticky tag (`pr-12`) does not start with PR 1's build prefix (`pr-1-`), so the
42
+ * two numbering spaces never collide.
43
+ */
44
+ export declare const buildPreviewTagPrefix: (prNumber: number) => string;
45
+ /**
46
+ * The sticky-comment marker. Every writer upserts the comment that starts with this
47
+ * string, so whichever of the platform and CI posts first, the other updates in place
48
+ * rather than double-posting.
49
+ */
50
+ export declare const PREVIEW_COMMENT_MARKER = "<!-- substrat-preview -->";
51
+ /**
52
+ * The sticky comment while the preview is live.
53
+ *
54
+ * `build` is the per-build immutable URL and is optional: it is present only when the repo
55
+ * opted into per-build previews (`SUBSTRAT_PER_BUILD_PREVIEW`), because a frozen scope per
56
+ * build is a real cost that not every project wants to pay.
57
+ *
58
+ * NOTE: keep the prose free of apostrophes. This same text is rendered into the workflow's
59
+ * single-quoted `printf` format string, where one apostrophe closes the quote and takes the
60
+ * whole preview job red on what looks like a copy-edit.
61
+ */
62
+ export declare function previewCommentBody(urls: {
63
+ sticky: string;
64
+ build?: string | null;
65
+ }): string;
66
+ /** The sticky comment after the PR closed and the preview forks were deleted. */
67
+ export declare const previewReapedBody: () => string;
68
+ /**
69
+ * How a merge to the deploy branch turns into a prod release.
70
+ *
71
+ * - `trunk` — **every merge releases.** The push carries no `--version`, so the registry
72
+ * patch-bumps and `--promote prod` points prod at it in the same run. The simplest thing
73
+ * that works, and the default the dashboard commits.
74
+ * - `changesets` — **the repo owns the version** (`package.json`), so a merge that only
75
+ * lands a changeset must NOT release; only the merge that MOVES the version does. The job
76
+ * compares `package.json` against the previous commit and no-ops when it did not change.
77
+ * This is the workflow the release-train table in the docs describes.
78
+ *
79
+ * Both are legitimate; the platform enables workflows rather than encoding one (#509 §3).
80
+ */
81
+ export type ReleaseMode = 'trunk' | 'changesets';
82
+ export interface DeployWorkflowOptions {
83
+ /** The branch whose pushes deploy prod. */
84
+ branch: string;
85
+ /** The vertical's bare slug — the control plane forms the `<tenant>/` prefix. */
86
+ slug: string;
87
+ /** The control-plane API base, e.g. `https://console.substrat.net/api`. */
88
+ cpUrl: string;
89
+ /** Defaults to `trunk`. */
90
+ release?: ReleaseMode;
91
+ }
92
+ /**
93
+ * The workflow the one-click setup commits and `substrat init --ci github` writes.
94
+ *
95
+ * Self-contained on purpose: a committed file is read by humans, so there is no
96
+ * reusable-workflow indirection to chase. The install step is load-bearing — `substrat
97
+ * push`/`preview` runs the repo's OWN build (a wrangler custom build), which needs the
98
+ * repo's devDependencies on disk; corepack picks the package manager from the lockfile.
99
+ *
100
+ * Two behaviours are opt-in through **repository variables**, so one generated file serves
101
+ * every project and enabling them never means regenerating it:
102
+ *
103
+ * - `SUBSTRAT_TEST_SCOPE_ID` — a long-lived test scope. Set it and every merge rebinds that
104
+ * scope to the just-built version: the "tracks main" environment, kept a CI step rather
105
+ * than a platform noun (a "this scope auto-tracks X" setting would be the retired
106
+ * dev/staging channel re-buried one layer down).
107
+ * - `SUBSTRAT_PER_BUILD_PREVIEW` — set it to `1` and each PR push also creates a frozen,
108
+ * short-TTL clean-room preview whose URL names exactly that build.
109
+ */
110
+ export declare function deployWorkflowYaml(opts: DeployWorkflowOptions): string;
111
+ //# sourceMappingURL=ci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../src/ci.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH;;;;;GAKG;AACH,eAAO,MAAM,UAAU,aAAc,MAAM,KAAG,MAA0B,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,aAAc,MAAM,SAAS,MAAM,GAAG,MAAM,KAAG,MAChD,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,aAAc,MAAM,KAAG,MAA2B,CAAC;AAMrF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,8BAA8B,CAAC;AAElE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAa1F;AAED,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAO,MACiF,CAAC;AAMvH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,YAAY,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAKD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CA8LtE"}
package/dist/ci.js ADDED
@@ -0,0 +1,279 @@
1
+ /**
2
+ * The builder's CI vocabulary: preview tag conventions, the PR sticky-comment bodies,
3
+ * and the generated GitHub Actions workflow.
4
+ *
5
+ * It lives here — not in the dashboard, not in the CLI — for the same reason the deploy
6
+ * manifest does: BOTH ends must speak the same shape. Three writers exist for the same
7
+ * two artifacts and any drift between them is a silent bug:
8
+ *
9
+ * - the **dashboard's one-click CI setup** commits the workflow to a customer repo and
10
+ * (via `GithubRepoLinkDO`) posts the PR comment from the platform side;
11
+ * - **`substrat init --ci github`** writes the same workflow for a builder who owns their
12
+ * own CI and never connected the GitHub App;
13
+ * - the **workflow itself** posts the same comment from the CI side, as the fallback for
14
+ * an App installation that lacks `pull-requests: write`.
15
+ *
16
+ * The comment bodies are generated once here and rendered into the workflow's `printf`
17
+ * format string, so the platform-written and CI-written comments cannot say different
18
+ * things about the same PR. One generator, three writers, no drift.
19
+ *
20
+ * Pure string building — no zod, no network, no node. Safe in a worker, a CLI, and a
21
+ * browser bundle alike.
22
+ */
23
+ // ---------------------------------------------------------------------------
24
+ // Tag conventions
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * The sticky preview tag for a PR — one long-lived fork, REBOUND on every push, so the
28
+ * URL always serves the PR's latest code. The git analogy is a **branch ref**: a moving
29
+ * pointer, bookmarked once. Successive pushes roll their migrations forward on the one
30
+ * fork, which is the rehearsal that de-risks the eventual release.
31
+ */
32
+ export const previewTag = (prNumber) => `pr-${prNumber}`;
33
+ /**
34
+ * The per-build preview tag — a FRESH scope per build, bound once and never rebound, so
35
+ * the URL is frozen to exactly that build forever. The git analogy is a **sha**.
36
+ *
37
+ * A moving pointer is only safe when every build is *also* addressable immutably: "the bug
38
+ * on the PR preview" must always de-reference to a fixed artifact. That is the whole reason
39
+ * this tag exists alongside the sticky one.
40
+ */
41
+ export const buildPreviewTag = (prNumber, runId) => `pr-${prNumber}-${runId}`;
42
+ /**
43
+ * The prefix that matches every per-build tag of one PR, and NOTHING else — note that
44
+ * PR 12's sticky tag (`pr-12`) does not start with PR 1's build prefix (`pr-1-`), so the
45
+ * two numbering spaces never collide.
46
+ */
47
+ export const buildPreviewTagPrefix = (prNumber) => `pr-${prNumber}-`;
48
+ // ---------------------------------------------------------------------------
49
+ // The PR sticky comment
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * The sticky-comment marker. Every writer upserts the comment that starts with this
53
+ * string, so whichever of the platform and CI posts first, the other updates in place
54
+ * rather than double-posting.
55
+ */
56
+ export const PREVIEW_COMMENT_MARKER = '<!-- substrat-preview -->';
57
+ /**
58
+ * The sticky comment while the preview is live.
59
+ *
60
+ * `build` is the per-build immutable URL and is optional: it is present only when the repo
61
+ * opted into per-build previews (`SUBSTRAT_PER_BUILD_PREVIEW`), because a frozen scope per
62
+ * build is a real cost that not every project wants to pay.
63
+ *
64
+ * NOTE: keep the prose free of apostrophes. This same text is rendered into the workflow's
65
+ * single-quoted `printf` format string, where one apostrophe closes the quote and takes the
66
+ * whole preview job red on what looks like a copy-edit.
67
+ */
68
+ export function previewCommentBody(urls) {
69
+ if (!urls.build) {
70
+ return (`${PREVIEW_COMMENT_MARKER}\n🔎 **Substrat preview:** ${urls.sticky}\n\n` +
71
+ '_Runs the code in this PR against a fork of prod, and follows the PR — every push rebinds it. ' +
72
+ 'Reaped when the PR closes._');
73
+ }
74
+ return (`${PREVIEW_COMMENT_MARKER}\n🔎 **Substrat preview:** ${urls.sticky}\n📌 **This build:** ${urls.build}\n\n` +
75
+ '_The preview URL follows the PR — every push rebinds it, so it always serves the latest code. ' +
76
+ 'The build URL is frozen to this one build and never moves. Both are reaped when the PR closes._');
77
+ }
78
+ /** The sticky comment after the PR closed and the preview forks were deleted. */
79
+ export const previewReapedBody = () => `${PREVIEW_COMMENT_MARKER}\n🔎 **Substrat preview:** reaped — this PR is closed and the preview forks were deleted.`;
80
+ /** Render a comment body as a single-quoted `printf` format string (literal `\n`, `%s` holes). */
81
+ const printfFormat = (body) => body.replace(/\n/g, '\\n');
82
+ /**
83
+ * The workflow the one-click setup commits and `substrat init --ci github` writes.
84
+ *
85
+ * Self-contained on purpose: a committed file is read by humans, so there is no
86
+ * reusable-workflow indirection to chase. The install step is load-bearing — `substrat
87
+ * push`/`preview` runs the repo's OWN build (a wrangler custom build), which needs the
88
+ * repo's devDependencies on disk; corepack picks the package manager from the lockfile.
89
+ *
90
+ * Two behaviours are opt-in through **repository variables**, so one generated file serves
91
+ * every project and enabling them never means regenerating it:
92
+ *
93
+ * - `SUBSTRAT_TEST_SCOPE_ID` — a long-lived test scope. Set it and every merge rebinds that
94
+ * scope to the just-built version: the "tracks main" environment, kept a CI step rather
95
+ * than a platform noun (a "this scope auto-tracks X" setting would be the retired
96
+ * dev/staging channel re-buried one layer down).
97
+ * - `SUBSTRAT_PER_BUILD_PREVIEW` — set it to `1` and each PR push also creates a frozen,
98
+ * short-TTL clean-room preview whose URL names exactly that build.
99
+ */
100
+ export function deployWorkflowYaml(opts) {
101
+ const { branch, slug, cpUrl } = opts;
102
+ const release = opts.release ?? 'trunk';
103
+ const cli = 'npx @substrat-run/cli';
104
+ // The install block repeats across jobs (self-contained file, see above). `fetch-depth: 2`
105
+ // is what lets the changesets release gate diff package.json against the previous commit.
106
+ const setup = (fetchDepth) => ` - uses: actions/checkout@v4${fetchDepth ? `\n with:\n fetch-depth: ${fetchDepth}` : ''}
107
+ - uses: actions/setup-node@v4
108
+ with:
109
+ # 22+: corepack resolves the latest pnpm for lockfile-only repos, and pnpm 11
110
+ # needs Node >= 22.13 (node:sqlite).
111
+ node-version: 22
112
+ - name: Install dependencies
113
+ env:
114
+ COREPACK_ENABLE_DOWNLOAD_PROMPT: '0'
115
+ run: |
116
+ if [ -f pnpm-lock.yaml ]; then corepack enable && pnpm install --frozen-lockfile
117
+ elif [ -f yarn.lock ]; then corepack enable && yarn install --frozen-lockfile
118
+ elif [ -f package-lock.json ]; then npm ci
119
+ else npm install
120
+ fi`;
121
+ const cpEnv = ` env:
122
+ SUBSTRAT_SERVICE_TOKEN: \${{ secrets.SUBSTRAT_SERVICE_TOKEN }}
123
+ SUBSTRAT_CP_URL: ${cpUrl}`;
124
+ // --- the release step, per mode ------------------------------------------------------
125
+ //
126
+ // Both print the pushed version id on the `✓ pushed … version <id> …` line; the test-env
127
+ // bind below reads it back out of the captured stdout. `set -euo pipefail` means a failed
128
+ // push fails the step rather than letting a masked non-zero exit reach the bind.
129
+ const release_ = release === 'changesets'
130
+ ? ` - name: Release (only when package.json version moved)
131
+ ${cpEnv}
132
+ run: |
133
+ set -euo pipefail
134
+ CUR=$(node -p "require('./package.json').version")
135
+ PREV=$(git show HEAD^:package.json 2>/dev/null | node -pe "JSON.parse(require('fs').readFileSync(0,'utf8')).version" 2>/dev/null || echo '')
136
+ if [ "$CUR" = "$PREV" ]; then
137
+ echo "package.json version is still $CUR — this merge landed a changeset, not a release. Skipping prod."
138
+ exit 0
139
+ fi
140
+ echo "releasing $CUR (was \${PREV:-none})"
141
+ ${cli} push . --slug ${slug} --version "$CUR" --promote prod`
142
+ : ` - name: Release to prod
143
+ ${cpEnv}
144
+ run: |
145
+ set -euo pipefail
146
+ ${cli} push . --slug ${slug} --promote prod`;
147
+ // --- the "tracks main" test environment ---------------------------------------------
148
+ //
149
+ // Runs on EVERY merge, release or not — that is the point of a test env: it is always the
150
+ // head of the branch, a merge ahead of prod, rehearsing each migration on accumulated data.
151
+ // It pushes its OWN build rather than reusing the release step's, because in `changesets`
152
+ // mode most merges produce no release at all and the test env must still move; doing it the
153
+ // same way in both modes keeps one legible file. The label is a PRERELEASE, so this push can
154
+ // never claim or advance the release coordinate the repo owns.
155
+ const testEnv = ` - name: Update the test environment
156
+ if: vars.SUBSTRAT_TEST_SCOPE_ID != ''
157
+ ${cpEnv}
158
+ run: |
159
+ set -euo pipefail
160
+ BASE=$(node -p "require('./package.json').version")
161
+ ${cli} push . --slug ${slug} --version "$BASE-test.\${{ github.run_number }}" | tee push.out
162
+ # '|| true' so an unmatched grep does not trip pipefail before the message below —
163
+ # "could not read the pushed version id" beats a bare exit 1 from grep.
164
+ VID=$(grep -F '✓ pushed' push.out | grep -oE 'version [A-Za-z0-9]+' | head -1 | cut -d' ' -f2 || true)
165
+ if [ -z "$VID" ]; then echo "could not read the pushed version id from:" >&2; cat push.out >&2; exit 1; fi
166
+ ${cli} scope bind \${{ vars.SUBSTRAT_TEST_SCOPE_ID }} --version "$VID" --snapshot`;
167
+ // --- the PR previews -----------------------------------------------------------------
168
+ //
169
+ // Sticky first (it is the URL a reviewer bookmarks and must exist even if the optional
170
+ // per-build one fails), then the frozen per-build clean room when the repo opted in.
171
+ const previewSteps = ` - name: Create/update the preview
172
+ ${cpEnv}
173
+ run: |
174
+ set -euo pipefail
175
+ ${cli} preview create . --slug ${slug} --tag pr-\${{ github.event.number }} | tee preview.out
176
+ # Take the URL from the CLI success line (the ✓ marker) only — the push it runs
177
+ # first also prints an https:// *deploy endpoint* we must never mistake for a preview.
178
+ grep -F '✓ preview' preview.out | grep -oE 'https://[a-zA-Z0-9.:/_-]+' | tail -1 > preview.url || true
179
+ - name: Create the per-build preview
180
+ if: vars.SUBSTRAT_PER_BUILD_PREVIEW != ''
181
+ ${cpEnv}
182
+ run: |
183
+ set -euo pipefail
184
+ # A FRESH scope, bound once and never rebound, so this URL is frozen to this build
185
+ # forever. Clean-room (--empty) rather than a fork: a throwaway per build should not
186
+ # copy prod data every push. Short TTL — the sticky preview is the one that lives.
187
+ ${cli} preview create . --slug ${slug} \\
188
+ --tag pr-\${{ github.event.number }}-\${{ github.run_id }} --empty --ttl 24h | tee build.out
189
+ grep -F '✓ preview' build.out | grep -oE 'https://[a-zA-Z0-9.:/_-]+' | tail -1 > build.url || true`;
190
+ // The comment body comes from previewCommentBody() so the CI-written and platform-written
191
+ // comments cannot diverge. Two formats: with and without the per-build line.
192
+ const stickyOnlyFmt = printfFormat(previewCommentBody({ sticky: '%s' }));
193
+ const withBuildFmt = printfFormat(previewCommentBody({ sticky: '%s', build: '%s' }));
194
+ const commentStep = ` - name: Comment the preview URLs
195
+ env:
196
+ GH_TOKEN: \${{ github.token }}
197
+ run: |
198
+ set -uo pipefail
199
+ URL=$(cat preview.url 2>/dev/null || true)
200
+ [ -z "$URL" ] && exit 0
201
+ BUILD=$(cat build.url 2>/dev/null || true)
202
+ if [ -n "$BUILD" ]; then
203
+ BODY=$(printf '${withBuildFmt}' "$URL" "$BUILD")
204
+ else
205
+ BODY=$(printf '${stickyOnlyFmt}' "$URL")
206
+ fi
207
+ REPO=\${{ github.repository }}
208
+ PR=\${{ github.event.number }}
209
+ ID=$(gh api "repos/$REPO/issues/$PR/comments" --jq '.[] | select(.body | startswith("${PREVIEW_COMMENT_MARKER}")) | .id' | head -1)
210
+ if [ -n "$ID" ]; then
211
+ gh api -X PATCH "repos/$REPO/issues/comments/$ID" -f body="$BODY" >/dev/null
212
+ else
213
+ gh api -X POST "repos/$REPO/issues/$PR/comments" -f body="$BODY" >/dev/null
214
+ fi`;
215
+ // Close ⇒ reap both forks. The per-build tag is unknown at close time (it named a run id),
216
+ // so the sticky one is deleted by tag and the rest are left to their 24h TTL — the GC sweep
217
+ // is the backstop the short TTL exists for.
218
+ const cleanup = ` preview_cleanup:
219
+ # Reap only — no repo build needed, so skip checkout/install and just run the CLI.
220
+ if: github.event_name == 'pull_request' && github.event.action == 'closed'
221
+ runs-on: ubuntu-latest
222
+ concurrency: substrat-preview-\${{ github.event.number }}
223
+ steps:
224
+ - uses: actions/setup-node@v4
225
+ with:
226
+ node-version: 22
227
+ - name: Reap the preview
228
+ ${cpEnv}
229
+ run: ${cli} preview delete --slug ${slug} --tag pr-\${{ github.event.number }}`;
230
+ const releaseNote = release === 'changesets'
231
+ ? ` # Release train: the version lives in package.json and only a version PR moves it, so a
232
+ # merge releases ONLY when that version changed. Every merge still updates the test env.`
233
+ : ` # Trunk-based: every merge to ${branch} releases. A private vertical's push lands admitted
234
+ # and prod is self-serve, so the same run points prod at the new version.`;
235
+ return `name: Deploy to Substrat
236
+
237
+ # Generated by Substrat (substrat init --ci github). The workflow this encodes — one prod
238
+ # channel, previews as the only non-prod environment — is documented at
239
+ # https://substrat.net/guide/environments-and-previews
240
+ #
241
+ # Optional repository variables (Settings → Secrets and variables → Actions → Variables):
242
+ # SUBSTRAT_TEST_SCOPE_ID a long-lived scope rebound to every merge (the test env)
243
+ # SUBSTRAT_PER_BUILD_PREVIEW set to 1 to also mint a frozen per-build preview URL per push
244
+
245
+ on:
246
+ push:
247
+ branches: [${branch}]
248
+ # Per-PR previews: open/update a PR → a preview instance running the PR's code against a
249
+ # FORK of prod on its own URL; close the PR → it is reaped (the TTL is the GC backstop).
250
+ pull_request:
251
+ types: [opened, synchronize, reopened, closed]
252
+
253
+ jobs:
254
+ deploy:
255
+ ${releaseNote}
256
+ if: github.event_name == 'push'
257
+ runs-on: ubuntu-latest
258
+ steps:
259
+ ${setup(release === 'changesets' ? 2 : undefined)}
260
+ ${release_}
261
+ ${testEnv}
262
+
263
+ preview:
264
+ if: github.event_name == 'pull_request' && github.event.action != 'closed'
265
+ runs-on: ubuntu-latest
266
+ # Never overlap two runs for the same PR — a rapid re-push waits for the first.
267
+ concurrency: substrat-preview-\${{ github.event.number }}
268
+ permissions:
269
+ contents: read
270
+ pull-requests: write
271
+ steps:
272
+ ${setup()}
273
+ ${previewSteps}
274
+ ${commentStep}
275
+
276
+ ${cleanup}
277
+ `;
278
+ }
279
+ //# sourceMappingURL=ci.js.map
package/dist/ci.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.js","sourceRoot":"","sources":["../src/ci.ts"],"names":[],"mappings":"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"}
package/dist/deploy.d.ts CHANGED
@@ -102,6 +102,65 @@ export type BlobStoreHandle = z.infer<typeof blobStoreHandle>;
102
102
  * `D1Database`. On the pure adapter there is no binding to name.
103
103
  */
104
104
  export declare function blobStoreBindingName(binding: string, tenantId: string): string;
105
+ /**
106
+ * How the runtime routes a request between the vertical's STATIC files and its worker
107
+ * (#340) — the substrate-vocabulary form of Cloudflare's `assets.config`. Every field is
108
+ * optional with a runtime default, so a vertical that only wants "serve my SPA" declares
109
+ * a directory and nothing else.
110
+ *
111
+ * The two that matter for a Substrat vertical, and why:
112
+ * - `notFoundHandling: 'single-page-application'` — a deep client route (`/jobs/123`) is
113
+ * not a file, and must resolve to `index.html` rather than 404. This is the inline
114
+ * `serveAsset` fallback, expressed as configuration.
115
+ * - `runWorkerFirst` — SPA fallback would otherwise swallow the vertical's OWN routes,
116
+ * which are not files either. Listing `/api/*` + `/internal/*` keeps the worker in
117
+ * front of exactly the paths it owns while everything else is served from the edge
118
+ * without invoking it. `true` runs the worker in front of every request (asset serving
119
+ * still happens behind it) — correct only for a vertical that inspects every path.
120
+ */
121
+ export declare const assetRouting: z.ZodObject<{
122
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
123
+ "auto-trailing-slash": "auto-trailing-slash";
124
+ "drop-trailing-slash": "drop-trailing-slash";
125
+ "force-trailing-slash": "force-trailing-slash";
126
+ none: "none";
127
+ }>>;
128
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
129
+ "404-page": "404-page";
130
+ none: "none";
131
+ "single-page-application": "single-page-application";
132
+ }>>;
133
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
134
+ }, z.core.$strip>;
135
+ export type AssetRouting = z.infer<typeof assetRouting>;
136
+ /**
137
+ * The vertical's STATIC files, as a NEED (#340): a directory of built bytes the platform
138
+ * uploads to the runtime's own asset store, served from the edge without invoking the
139
+ * worker. Native assets are not a binding — they are a top-level upload path — so this is
140
+ * a `runtimeNeeds` need and never rides the §4 binding allowlist (see
141
+ * {@link ADMISSIBLE_BINDING_TYPES}); the platform's own hash verification is what makes
142
+ * accepting builder-supplied bytes safe (self-serve-deploy.md §4.1).
143
+ *
144
+ * Replaces the inline-into-the-worker workaround every demo carried while WfP dispatch had
145
+ * no asset path: base64 in the bundle costs ~+33 % against the script-size limit, is
146
+ * re-parsed on every cold start, and invokes the worker for every image.
147
+ */
148
+ export declare const assetsNeed: z.ZodObject<{
149
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
150
+ "auto-trailing-slash": "auto-trailing-slash";
151
+ "drop-trailing-slash": "drop-trailing-slash";
152
+ "force-trailing-slash": "force-trailing-slash";
153
+ none: "none";
154
+ }>>;
155
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
156
+ "404-page": "404-page";
157
+ none: "none";
158
+ "single-page-application": "single-page-application";
159
+ }>>;
160
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
161
+ directory: z.ZodString;
162
+ }, z.core.$strip>;
163
+ export type AssetsNeed = z.infer<typeof assetsNeed>;
105
164
  /**
106
165
  * What a vertical needs from the runtime, in substrate vocabulary (package.json
107
166
  * `substrat.runtimeNeeds`). A vertical authored with this section never writes deploy
@@ -127,6 +186,21 @@ export declare const runtimeNeeds: z.ZodObject<{
127
186
  binding: z.ZodString;
128
187
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
129
188
  }, z.core.$strip>>>;
189
+ assets: z.ZodOptional<z.ZodObject<{
190
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
191
+ "auto-trailing-slash": "auto-trailing-slash";
192
+ "drop-trailing-slash": "drop-trailing-slash";
193
+ "force-trailing-slash": "force-trailing-slash";
194
+ none: "none";
195
+ }>>;
196
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
197
+ "404-page": "404-page";
198
+ none: "none";
199
+ "single-page-application": "single-page-application";
200
+ }>>;
201
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
202
+ directory: z.ZodString;
203
+ }, z.core.$strip>>;
130
204
  }, z.core.$strip>;
131
205
  export type RuntimeNeeds = z.infer<typeof runtimeNeeds>;
132
206
  /**
@@ -145,6 +219,14 @@ export type RuntimeNeeds = z.infer<typeof runtimeNeeds>;
145
219
  * `mtls_certificate`) — the outside world is a connector concern, and outbound policy is an
146
220
  * open question (§6 / #303); least-privilege means these are refused until decided.
147
221
  *
222
+ * NOT on this list because it is not a binding at all: **native static assets** (#340). They
223
+ * are a top-level upload path (`assets: { jwt, config }` in the script metadata), so they can
224
+ * neither be allowed nor refused here. They are admitted by a separate, narrower rule written
225
+ * down in self-serve-deploy.md §4.1: the bytes are inert and public — no code, no authority,
226
+ * no cross-tenant reach — but their content-address is a namespace-wide dedup key, so the
227
+ * platform RE-DERIVES every hash from the uploaded bytes ({@link assetHash}) and refuses a
228
+ * mismatch. What is trusted is the bytes; what is verified is the key.
229
+ *
148
230
  * Caveat on `d1`: admissible as an own relational store (e.g. a Better-Auth `AUTH_DB`), but
149
231
  * the check does not yet PROVE the declared `database_id` is the vertical's own rather than
150
232
  * another tenant's — trusted under model-B human admission; platform provisioning closes that
@@ -253,6 +335,81 @@ export declare function definePermissions(input: PermissionsInput): PermissionsI
253
335
  * of declaration order.
254
336
  */
255
337
  export declare function buildPermissionRegistry(input: PermissionsInput): PermissionRegistry;
338
+ /**
339
+ * One static file in the shipped manifest (#340). The trio Cloudflare's asset store keys
340
+ * on — content-addressed `hash`, `size` — plus the `contentType` the platform attaches at
341
+ * upload and the runtime serves back.
342
+ *
343
+ * `hash` is the platform's DEDUP KEY, and the reason it is re-derived at the trust boundary
344
+ * rather than trusted: the asset store dedups by hash across the whole dispatch namespace,
345
+ * so bytes accepted under a hash they do not have would let one push decide what a DIFFERENT
346
+ * vertical's identical-hash asset serves. The bytes themselves are inert and public; the
347
+ * *key* is not. The control plane recomputes every hash from the uploaded bytes and refuses
348
+ * a mismatch (self-serve-deploy.md §4.1).
349
+ *
350
+ * The recipe is Cloudflare's, and must stay byte-identical on both ends or nothing dedups:
351
+ * `sha256(base64(content) + extension)`, first 32 hex chars ({@link assetHash}).
352
+ */
353
+ export declare const assetEntry: z.ZodObject<{
354
+ path: z.ZodString;
355
+ hash: z.ZodString;
356
+ size: z.ZodNumber;
357
+ contentType: z.ZodString;
358
+ }, z.core.$strip>;
359
+ export type AssetEntry = z.infer<typeof assetEntry>;
360
+ /**
361
+ * The multipart part-name prefix static files ride under in a push (#340) —
362
+ * `asset:/index.html`. Here, with the manifest schema, for the reason this file exists:
363
+ * both ends must speak the same shape. The prefix is what separates the two kinds of part
364
+ * in one body — anything unprefixed is a worker module — so an asset called `worker.js`
365
+ * can never be uploaded as code, and a served path is never constrained to be a legal
366
+ * module name.
367
+ */
368
+ export declare const ASSET_PART_PREFIX = "asset:";
369
+ /**
370
+ * The content-address of one static file — **Cloudflare's recipe, not ours**:
371
+ * `sha256(base64(content) + extension)` (extension without the dot), first 32 hex chars.
372
+ * It is reproduced here rather than imported because both ends must compute it identically:
373
+ * the CLI to build the manifest it ships, the control plane to VERIFY that manifest against
374
+ * the bytes before either reaches the asset store (see {@link assetEntry}). A divergence
375
+ * would not merely fail — it would silently defeat dedup, or store bytes under a key that
376
+ * is not theirs.
377
+ *
378
+ * Web Crypto (`globalThis.crypto.subtle`), so the one implementation runs unchanged in node,
379
+ * workerd, and the browser.
380
+ */
381
+ export declare function assetHash(content: Uint8Array, path: string): Promise<string>;
382
+ /**
383
+ * The static-file half of a push (#340): the routing config, plus the full file manifest.
384
+ *
385
+ * The manifest is retained (it rides `manifest_json` like the rest of the deploy manifest)
386
+ * for a load-bearing reason: a promote re-uploads a version onto the STABLE serving script
387
+ * from its archive (#286), and an asset upload session is driven by the manifest, not by
388
+ * bytes — content already in the namespace's asset store is skipped, so the retained
389
+ * manifest is what lets a promote re-attach the same assets without the builder re-pushing.
390
+ * It is also what the dashboard renders as the per-version asset list.
391
+ */
392
+ export declare const deployAssets: z.ZodObject<{
393
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
394
+ "auto-trailing-slash": "auto-trailing-slash";
395
+ "drop-trailing-slash": "drop-trailing-slash";
396
+ "force-trailing-slash": "force-trailing-slash";
397
+ none: "none";
398
+ }>>;
399
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
400
+ "404-page": "404-page";
401
+ none: "none";
402
+ "single-page-application": "single-page-application";
403
+ }>>;
404
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
405
+ files: z.ZodArray<z.ZodObject<{
406
+ path: z.ZodString;
407
+ hash: z.ZodString;
408
+ size: z.ZodNumber;
409
+ contentType: z.ZodString;
410
+ }, z.core.$strip>>;
411
+ }, z.core.$strip>;
412
+ export type DeployAssets = z.infer<typeof deployAssets>;
256
413
  /** The JSON part a `substrat push` sends alongside the module files. */
257
414
  export declare const deployManifest: z.ZodObject<{
258
415
  version: z.ZodString;
@@ -276,6 +433,26 @@ export declare const deployManifest: z.ZodObject<{
276
433
  binding: z.ZodString;
277
434
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
278
435
  }, z.core.$strip>>>;
436
+ assets: z.ZodOptional<z.ZodObject<{
437
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
438
+ "auto-trailing-slash": "auto-trailing-slash";
439
+ "drop-trailing-slash": "drop-trailing-slash";
440
+ "force-trailing-slash": "force-trailing-slash";
441
+ none: "none";
442
+ }>>;
443
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
444
+ "404-page": "404-page";
445
+ none: "none";
446
+ "single-page-application": "single-page-application";
447
+ }>>;
448
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
449
+ files: z.ZodArray<z.ZodObject<{
450
+ path: z.ZodString;
451
+ hash: z.ZodString;
452
+ size: z.ZodNumber;
453
+ contentType: z.ZodString;
454
+ }, z.core.$strip>>;
455
+ }, z.core.$strip>>;
279
456
  envSpec: z.ZodOptional<z.ZodArray<z.ZodObject<{
280
457
  key: z.ZodString;
281
458
  label: z.ZodOptional<z.ZodString>;
@@ -348,6 +525,26 @@ export declare const storedDeployManifest: z.ZodObject<{
348
525
  binding: z.ZodString;
349
526
  kind: z.ZodDefault<z.ZodLiteral<"blob">>;
350
527
  }, z.core.$strip>>>;
528
+ assets: z.ZodOptional<z.ZodObject<{
529
+ htmlHandling: z.ZodOptional<z.ZodEnum<{
530
+ "auto-trailing-slash": "auto-trailing-slash";
531
+ "drop-trailing-slash": "drop-trailing-slash";
532
+ "force-trailing-slash": "force-trailing-slash";
533
+ none: "none";
534
+ }>>;
535
+ notFoundHandling: z.ZodOptional<z.ZodEnum<{
536
+ "404-page": "404-page";
537
+ none: "none";
538
+ "single-page-application": "single-page-application";
539
+ }>>;
540
+ runWorkerFirst: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
541
+ files: z.ZodArray<z.ZodObject<{
542
+ path: z.ZodString;
543
+ hash: z.ZodString;
544
+ size: z.ZodNumber;
545
+ contentType: z.ZodString;
546
+ }, z.core.$strip>>;
547
+ }, z.core.$strip>>;
351
548
  envSpec: z.ZodOptional<z.ZodArray<z.ZodObject<{
352
549
  key: z.ZodString;
353
550
  label: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
package/dist/deploy.js CHANGED
@@ -115,6 +115,48 @@ export const blobStoreHandle = z.object({
115
115
  export function blobStoreBindingName(binding, tenantId) {
116
116
  return `${binding}__${tenantId}`;
117
117
  }
118
+ /**
119
+ * How the runtime routes a request between the vertical's STATIC files and its worker
120
+ * (#340) — the substrate-vocabulary form of Cloudflare's `assets.config`. Every field is
121
+ * optional with a runtime default, so a vertical that only wants "serve my SPA" declares
122
+ * a directory and nothing else.
123
+ *
124
+ * The two that matter for a Substrat vertical, and why:
125
+ * - `notFoundHandling: 'single-page-application'` — a deep client route (`/jobs/123`) is
126
+ * not a file, and must resolve to `index.html` rather than 404. This is the inline
127
+ * `serveAsset` fallback, expressed as configuration.
128
+ * - `runWorkerFirst` — SPA fallback would otherwise swallow the vertical's OWN routes,
129
+ * which are not files either. Listing `/api/*` + `/internal/*` keeps the worker in
130
+ * front of exactly the paths it owns while everything else is served from the edge
131
+ * without invoking it. `true` runs the worker in front of every request (asset serving
132
+ * still happens behind it) — correct only for a vertical that inspects every path.
133
+ */
134
+ export const assetRouting = z.object({
135
+ /** Trailing-slash/`.html` normalisation. Cloudflare's default is `auto-trailing-slash`. */
136
+ htmlHandling: z
137
+ .enum(['auto-trailing-slash', 'force-trailing-slash', 'drop-trailing-slash', 'none'])
138
+ .optional(),
139
+ /** What a path matching no asset gets. `none` (default) falls through to the worker. */
140
+ notFoundHandling: z.enum(['none', '404-page', 'single-page-application']).optional(),
141
+ /** Routes the worker handles BEFORE asset matching — `true` for all, or a glob list. */
142
+ runWorkerFirst: z.union([z.boolean(), z.array(z.string().min(1)).min(1)]).optional(),
143
+ });
144
+ /**
145
+ * The vertical's STATIC files, as a NEED (#340): a directory of built bytes the platform
146
+ * uploads to the runtime's own asset store, served from the edge without invoking the
147
+ * worker. Native assets are not a binding — they are a top-level upload path — so this is
148
+ * a `runtimeNeeds` need and never rides the §4 binding allowlist (see
149
+ * {@link ADMISSIBLE_BINDING_TYPES}); the platform's own hash verification is what makes
150
+ * accepting builder-supplied bytes safe (self-serve-deploy.md §4.1).
151
+ *
152
+ * Replaces the inline-into-the-worker workaround every demo carried while WfP dispatch had
153
+ * no asset path: base64 in the bundle costs ~+33 % against the script-size limit, is
154
+ * re-parsed on every cold start, and invokes the worker for every image.
155
+ */
156
+ export const assetsNeed = assetRouting.extend({
157
+ /** Directory of built files, relative to the vertical root (e.g. `app/dist`). */
158
+ directory: z.string().min(1),
159
+ });
118
160
  /**
119
161
  * What a vertical needs from the runtime, in substrate vocabulary (package.json
120
162
  * `substrat.runtimeNeeds`). A vertical authored with this section never writes deploy
@@ -139,6 +181,9 @@ export const runtimeNeeds = z.object({
139
181
  /** Per-tenant blob stores for attachment bytes (#473). Same non-binding rule as
140
182
  * `tenantStores`: one bucket per tenant, minted in the tenant lifecycle. */
141
183
  blobStores: z.array(blobStoreNeed).default([]),
184
+ /** Static files served from the edge (#340). Absent ⇒ the vertical serves no static
185
+ * files (or still inlines them into the bundle), and nothing about its push changes. */
186
+ assets: assetsNeed.optional(),
142
187
  });
143
188
  /**
144
189
  * The §4 sandbox allowlist: the binding types a hosted vertical may declare, because each
@@ -156,6 +201,14 @@ export const runtimeNeeds = z.object({
156
201
  * `mtls_certificate`) — the outside world is a connector concern, and outbound policy is an
157
202
  * open question (§6 / #303); least-privilege means these are refused until decided.
158
203
  *
204
+ * NOT on this list because it is not a binding at all: **native static assets** (#340). They
205
+ * are a top-level upload path (`assets: { jwt, config }` in the script metadata), so they can
206
+ * neither be allowed nor refused here. They are admitted by a separate, narrower rule written
207
+ * down in self-serve-deploy.md §4.1: the bytes are inert and public — no code, no authority,
208
+ * no cross-tenant reach — but their content-address is a namespace-wide dedup key, so the
209
+ * platform RE-DERIVES every hash from the uploaded bytes ({@link assetHash}) and refuses a
210
+ * mismatch. What is trusted is the bytes; what is verified is the key.
211
+ *
159
212
  * Caveat on `d1`: admissible as an own relational store (e.g. a Better-Auth `AUTH_DB`), but
160
213
  * the check does not yet PROVE the declared `database_id` is the vertical's own rather than
161
214
  * another tenant's — trusted under model-B human admission; platform provisioning closes that
@@ -268,6 +321,85 @@ export function buildPermissionRegistry(input) {
268
321
  .map((g) => ({ entityType: g.entityType, permissions: sortKeys(g.permissions) }));
269
322
  return { permissions, roles, entityGrants };
270
323
  }
324
+ /**
325
+ * One static file in the shipped manifest (#340). The trio Cloudflare's asset store keys
326
+ * on — content-addressed `hash`, `size` — plus the `contentType` the platform attaches at
327
+ * upload and the runtime serves back.
328
+ *
329
+ * `hash` is the platform's DEDUP KEY, and the reason it is re-derived at the trust boundary
330
+ * rather than trusted: the asset store dedups by hash across the whole dispatch namespace,
331
+ * so bytes accepted under a hash they do not have would let one push decide what a DIFFERENT
332
+ * vertical's identical-hash asset serves. The bytes themselves are inert and public; the
333
+ * *key* is not. The control plane recomputes every hash from the uploaded bytes and refuses
334
+ * a mismatch (self-serve-deploy.md §4.1).
335
+ *
336
+ * The recipe is Cloudflare's, and must stay byte-identical on both ends or nothing dedups:
337
+ * `sha256(base64(content) + extension)`, first 32 hex chars ({@link assetHash}).
338
+ */
339
+ export const assetEntry = z.object({
340
+ /** Served path, always leading-slash, `/`-separated (e.g. `/assets/app-4f2.js`). */
341
+ path: z.string().regex(/^\/(?!\/)[^\s]*$/),
342
+ /** `sha256(base64(content) + extension)`, first 32 hex — Cloudflare's manifest key. */
343
+ hash: z.string().regex(/^[0-9a-f]{32}$/),
344
+ size: z.number().int().nonnegative(),
345
+ /** The MIME type the runtime serves this file as (attached at upload time). */
346
+ contentType: z.string().min(1),
347
+ });
348
+ /**
349
+ * The multipart part-name prefix static files ride under in a push (#340) —
350
+ * `asset:/index.html`. Here, with the manifest schema, for the reason this file exists:
351
+ * both ends must speak the same shape. The prefix is what separates the two kinds of part
352
+ * in one body — anything unprefixed is a worker module — so an asset called `worker.js`
353
+ * can never be uploaded as code, and a served path is never constrained to be a legal
354
+ * module name.
355
+ */
356
+ export const ASSET_PART_PREFIX = 'asset:';
357
+ /** Bytes → base64, web-standard only (`btoa` over a binary string, chunked so a large file
358
+ * does not blow the argument limit of `String.fromCharCode`). No `Buffer`: this runs in the
359
+ * CLI (node), in the control plane (workerd), and in the browser. */
360
+ function toBase64(bytes) {
361
+ let binary = '';
362
+ const CHUNK = 0x8000;
363
+ for (let i = 0; i < bytes.length; i += CHUNK) {
364
+ binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
365
+ }
366
+ return btoa(binary);
367
+ }
368
+ /**
369
+ * The content-address of one static file — **Cloudflare's recipe, not ours**:
370
+ * `sha256(base64(content) + extension)` (extension without the dot), first 32 hex chars.
371
+ * It is reproduced here rather than imported because both ends must compute it identically:
372
+ * the CLI to build the manifest it ships, the control plane to VERIFY that manifest against
373
+ * the bytes before either reaches the asset store (see {@link assetEntry}). A divergence
374
+ * would not merely fail — it would silently defeat dedup, or store bytes under a key that
375
+ * is not theirs.
376
+ *
377
+ * Web Crypto (`globalThis.crypto.subtle`), so the one implementation runs unchanged in node,
378
+ * workerd, and the browser.
379
+ */
380
+ export async function assetHash(content, path) {
381
+ const base = path.split('/').pop() ?? '';
382
+ const dot = base.lastIndexOf('.');
383
+ const extension = dot > 0 ? base.slice(dot + 1) : '';
384
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(toBase64(content) + extension));
385
+ return [...new Uint8Array(digest)]
386
+ .map((b) => b.toString(16).padStart(2, '0'))
387
+ .join('')
388
+ .slice(0, 32);
389
+ }
390
+ /**
391
+ * The static-file half of a push (#340): the routing config, plus the full file manifest.
392
+ *
393
+ * The manifest is retained (it rides `manifest_json` like the rest of the deploy manifest)
394
+ * for a load-bearing reason: a promote re-uploads a version onto the STABLE serving script
395
+ * from its archive (#286), and an asset upload session is driven by the manifest, not by
396
+ * bytes — content already in the namespace's asset store is skipped, so the retained
397
+ * manifest is what lets a promote re-attach the same assets without the builder re-pushing.
398
+ * It is also what the dashboard renders as the per-version asset list.
399
+ */
400
+ export const deployAssets = assetRouting.extend({
401
+ files: z.array(assetEntry),
402
+ });
271
403
  /** The JSON part a `substrat push` sends alongside the module files. */
272
404
  export const deployManifest = z.object({
273
405
  version: z.string().min(1),
@@ -287,6 +419,10 @@ export const deployManifest = z.object({
287
419
  /** Per-tenant blob stores (#473) — same carry-for-provisioning rule as `tenantStores`:
288
420
  * never a static binding; the platform mints one bucket per tenant and injects it. */
289
421
  blobStores: z.array(blobStoreNeed).default([]),
422
+ /** The vertical's static files (#340): routing config + the full path/hash/size/type
423
+ * manifest. Never a binding — native assets are a top-level upload path, so they do not
424
+ * ride the §4 allowlist. Optional ⇒ a vertical that ships none is unaffected. */
425
+ assets: deployAssets.optional(),
290
426
  /** The vertical's declared env-spec (from its package.json `substrat.envSpec`), stored on
291
427
  * the registry so a host/console renders a config form for it. Optional + validated here. */
292
428
  envSpec: z.array(envVarSpec).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ export * from './platform-request.js';
31
31
  export * from './manifest.js';
32
32
  export * from './openapi.js';
33
33
  export * from './deploy.js';
34
+ export * from './ci.js';
34
35
  export * from './money.js';
35
36
  export * from './attachments.js';
36
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ export * from './platform-request.js';
31
31
  export * from './manifest.js';
32
32
  export * from './openapi.js';
33
33
  export * from './deploy.js';
34
+ export * from './ci.js';
34
35
  export * from './money.js';
35
36
  export * from './attachments.js';
36
37
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/contracts",
3
- "version": "0.48.1",
3
+ "version": "0.49.0",
4
4
  "description": "Substrat kernel contract schemas — Zod is the source of truth (master plan D-22); OAS/JSON Schema are emitted artifacts",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {