handoff-app 2.0.0-0 → 2.0.0-2
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/README.md +39 -17
- package/config/docs/foundations/colors/guidelines.md +9 -0
- package/config/docs/foundations/effects/guidelines.md +9 -0
- package/config/docs/foundations/effects/resources.md +9 -0
- package/config/docs/foundations/grid.md +10 -0
- package/config/docs/foundations/icons/guidelines.md +9 -0
- package/config/docs/foundations/images/guidelines.md +9 -0
- package/config/docs/foundations/images/resources.md +9 -0
- package/config/docs/foundations/images.md +10 -0
- package/config/docs/foundations/logo/resources.md +9 -0
- package/config/docs/foundations/typography/guidelines.md +9 -0
- package/config/docs/foundations/typography/resources.md +9 -0
- package/config/docs/foundations.md +5 -3
- package/dist/app-builder/build.js +89 -46
- package/dist/app-builder/client-config.js +5 -5
- package/dist/app-builder/paths.js +23 -1
- package/dist/app-builder/static-export.js +25 -0
- package/dist/app-builder/vercel-output.js +2 -2
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.js +4 -1
- package/dist/artifacts/url.d.ts +18 -0
- package/dist/artifacts/url.js +31 -1
- package/dist/cli/create.js +48 -3
- package/dist/commands/checkout/index.d.ts +6 -6
- package/dist/commands/checkout/index.js +8 -12
- package/dist/commands/publish/index.d.ts +6 -5
- package/dist/commands/publish/index.js +8 -11
- package/dist/commands/utils.d.ts +6 -0
- package/dist/commands/utils.js +9 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +26 -10
- package/dist/registry/asset-storage/resolve.d.ts +1 -1
- package/dist/registry/asset-storage/resolve.js +1 -1
- package/dist/registry/checkout/index.d.ts +10 -5
- package/dist/registry/checkout/index.js +62 -11
- package/dist/registry/client.d.ts +2 -1
- package/dist/registry/client.js +8 -0
- package/dist/registry/db/client.d.ts +9 -9
- package/dist/registry/db/client.js +7 -7
- package/dist/registry/db/{adapter.d.ts → driver.d.ts} +16 -14
- package/dist/registry/db/{adapter.js → driver.js} +17 -15
- package/dist/registry/db/index.d.ts +1 -1
- package/dist/registry/db/index.js +9 -9
- package/dist/registry/db/migrate.d.ts +1 -1
- package/dist/registry/db/migrate.js +5 -5
- package/dist/registry/publish/index.d.ts +8 -1
- package/dist/registry/publish/index.js +88 -2
- package/dist/registry/transfer.d.ts +13 -0
- package/dist/types/config.d.ts +12 -8
- package/drizzle.config.ts +1 -1
- package/package.json +1 -1
- package/src/app/components/Foundations/DisplayLogo.tsx +8 -2
- package/src/app/lib/docs-api/runtime-config.ts +10 -10
- package/src/app/lib/registry-api/transfer.ts +29 -0
- package/src/app/lib/registry-connection.ts +2 -2
- package/src/app/next.config.mjs +1 -1
- package/src/app/pages/api/registry/transfer/[kind]/index.ts +21 -0
- package/src/app/pages/assets/logos.tsx +4 -1
- package/src/app/pages/foundations/icons/index.tsx +7 -5
- package/src/app/pages/foundations/icons/{[name] → library/[name]}/index.tsx +8 -8
- package/src/app/pages/foundations/logo.tsx +5 -4
- package/src/app-builder/build.ts +75 -55
- package/src/app-builder/client-config.ts +3 -3
- package/src/app-builder/paths.ts +25 -1
- package/src/app-builder/static-export.ts +27 -0
- package/src/app-builder/vercel-output.ts +2 -2
- package/src/artifacts/index.ts +8 -1
- package/src/artifacts/url.ts +32 -0
- package/src/cli/create.ts +58 -3
- package/src/commands/checkout/index.ts +10 -15
- package/src/commands/publish/index.ts +10 -14
- package/src/commands/utils.ts +12 -0
- package/src/index.ts +26 -12
- package/src/registry/asset-storage/resolve.ts +1 -1
- package/src/registry/checkout/index.ts +73 -11
- package/src/registry/client.ts +7 -1
- package/src/registry/db/client.ts +12 -12
- package/src/registry/db/{adapter.ts → driver.ts} +19 -17
- package/src/registry/db/index.ts +4 -4
- package/src/registry/db/migrate.ts +5 -5
- package/src/registry/publish/index.ts +100 -2
- package/src/registry/transfer.ts +14 -0
- package/src/types/config.ts +12 -8
- package/templates/default/README.md.tpl +40 -1
- package/templates/default/gitignore.tpl +18 -3
- package/templates/default/handoff.config.js.tpl +14 -0
- package/templates/default/handoff.config.ts.tpl +14 -0
- package/templates/default/handoff.config.with-examples.js.tpl +14 -0
- package/templates/default/handoff.config.with-examples.ts.tpl +14 -0
- package/templates/default/package.json.tpl +2 -1
- package/templates/default/vercel.json.tpl +4 -0
package/README.md
CHANGED
|
@@ -25,6 +25,7 @@ authoring locally or running a shared, deployed catalog.
|
|
|
25
25
|
* [Building artifacts](#building-artifacts)
|
|
26
26
|
* [Static site (default)](#static-site-default)
|
|
27
27
|
* [Registry app](#registry-app)
|
|
28
|
+
* [Deploying](#deploying)
|
|
28
29
|
* [Publishing and checkout](#publishing-and-checkout)
|
|
29
30
|
* [Configuration](#configuration)
|
|
30
31
|
* [The runtime block](#the-runtime-block)
|
|
@@ -144,7 +145,7 @@ my-handoff-project/
|
|
|
144
145
|
├─ patterns/ # multi-component compositions
|
|
145
146
|
├─ sass/ # optional global SCSS entry
|
|
146
147
|
├─ js/ # optional global JS entry
|
|
147
|
-
├─ exported/ #
|
|
148
|
+
├─ exported/ # fetched tokens and assets (commit these so clean/CI builds have data)
|
|
148
149
|
└─ out/ # build output (gitignored)
|
|
149
150
|
```
|
|
150
151
|
|
|
@@ -226,8 +227,9 @@ preview updates. The site boots at http://localhost:3000 by default.
|
|
|
226
227
|
|
|
227
228
|
## Building artifacts
|
|
228
229
|
|
|
229
|
-
`handoff-app build` accepts
|
|
230
|
-
|
|
230
|
+
`handoff-app build` accepts two independent flags. `--target` decides *what* is
|
|
231
|
+
produced — the target, not `NODE_ENV`, drives this. The optional `--package`
|
|
232
|
+
decides *how* that target is packaged for deployment.
|
|
231
233
|
|
|
232
234
|
### Static site (default)
|
|
233
235
|
|
|
@@ -240,9 +242,8 @@ The static target builds your workspace components, patterns, and tokens,
|
|
|
240
242
|
materializes the docs read model into route-shaped static files, and runs a
|
|
241
243
|
static export to `out/<projectId>` (respecting `sitesOutputDirectory`). The
|
|
242
244
|
output is plain static files: it renders list, detail, preview, and inspect
|
|
243
|
-
pages and loads previews through canonical artifact URLs with no live server
|
|
244
|
-
|
|
245
|
-
host-specific rewrites.
|
|
245
|
+
pages and loads previews through canonical artifact URLs with no live server, so
|
|
246
|
+
any static file server or CDN can serve it with no host-specific rewrites.
|
|
246
247
|
|
|
247
248
|
The build fails clearly if a required artifact referenced by generated HTML
|
|
248
249
|
cannot be materialized, and it fails if the runtime is registry-only (there is
|
|
@@ -269,17 +270,38 @@ DATABASE_URL="postgres://…" node out/registry/server.js
|
|
|
269
270
|
```
|
|
270
271
|
|
|
271
272
|
A generated `README.md` next to the bundle documents the required env vars and
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
how to run it. Apply database migrations from the CLI as a controlled release
|
|
274
|
+
step (e.g. in CI/CD) before deploying:
|
|
274
275
|
|
|
275
276
|
```bash
|
|
276
277
|
handoff-app db:migrate
|
|
277
278
|
```
|
|
278
279
|
|
|
279
280
|
`db:migrate` reads your project config and DB env vars, applies the
|
|
280
|
-
package-owned migration set, and runs independently of `build`.
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
package-owned migration set, and runs independently of `build`. PostgreSQL is
|
|
282
|
+
the supported database; `runtime.registry.database.driver` selects the
|
|
283
|
+
connection driver (`pg` or `neon`) — how to connect, not the database engine —
|
|
284
|
+
and both drivers ship with the package.
|
|
285
|
+
|
|
286
|
+
### Deploying
|
|
287
|
+
|
|
288
|
+
* **Static** produces plain files under `out/<projectId>`. Serve them with any
|
|
289
|
+
static file server or CDN. Commit `exported/` so a clean checkout has token
|
|
290
|
+
data to build from.
|
|
291
|
+
* **Registry** produces a self-contained Node bundle under `out/registry`. Run it
|
|
292
|
+
on any Node host with `node out/registry/server.js` and a `DATABASE_URL` in the
|
|
293
|
+
environment.
|
|
294
|
+
|
|
295
|
+
The optional `--package` flag repackages a target without changing what it
|
|
296
|
+
builds:
|
|
297
|
+
|
|
298
|
+
| `--package` | Output |
|
|
299
|
+
| --- | --- |
|
|
300
|
+
| omitted (default) | `out/<projectId>` (static) or the `out/registry` Node bundle (registry) |
|
|
301
|
+
| `vercel` | `.vercel/output`, a Vercel Build Output API bundle |
|
|
302
|
+
|
|
303
|
+
`handoff-app init` can scaffold a `vercel.json` that runs a packaged build; edit
|
|
304
|
+
its `buildCommand` to change the target.
|
|
283
305
|
|
|
284
306
|
## Publishing and checkout
|
|
285
307
|
|
|
@@ -304,8 +326,8 @@ HANDOFF_REGISTRY_ACCESS_TOKEN=your-registry-token
|
|
|
304
326
|
Then push and pull entities by `id`:
|
|
305
327
|
|
|
306
328
|
```bash
|
|
307
|
-
handoff-app publish
|
|
308
|
-
handoff-app checkout
|
|
329
|
+
handoff-app publish components button # build locally, upload that entity's package
|
|
330
|
+
handoff-app checkout patterns hero # pull a registry entity into this workspace
|
|
309
331
|
```
|
|
310
332
|
|
|
311
333
|
`publish` runs a fresh targeted build of the selected entity and uploads only
|
|
@@ -373,7 +395,7 @@ runtime: {
|
|
|
373
395
|
registry: {
|
|
374
396
|
databaseUrlEnv: 'DATABASE_URL',
|
|
375
397
|
apiTokenEnv: 'HANDOFF_REGISTRY_API_TOKEN',
|
|
376
|
-
database: {
|
|
398
|
+
database: { driver: 'pg' }, // connection driver: 'pg' | 'neon' (PostgreSQL only)
|
|
377
399
|
},
|
|
378
400
|
},
|
|
379
401
|
```
|
|
@@ -410,10 +432,10 @@ See [docs/api.md](docs/api.md#hooks) for hook arguments and examples.
|
|
|
410
432
|
| `fetch` | Fetch design tokens from Figma |
|
|
411
433
|
| `dev` | Start the local dev server with the live docs read API |
|
|
412
434
|
| `start` | Start the dev server with file watchers for live authoring |
|
|
413
|
-
| `build [--target static\|registry]` | Build the static site (default) or package
|
|
435
|
+
| `build [--target static\|registry] [--package standalone\|vercel]` | Build the static site (default) or registry app; `--package vercel` emits a Vercel Build Output bundle |
|
|
414
436
|
| `build:components [component]` | Build components without building the full app |
|
|
415
|
-
| `publish <
|
|
416
|
-
| `checkout <
|
|
437
|
+
| `publish <components\|patterns\|pages\|tokens\|assets> [id]` | Build and publish entities to the connected registry (all of the kind, or one by id) |
|
|
438
|
+
| `checkout <components\|patterns\|pages\|tokens\|assets> [id]` | Pull entities from the connected registry into this workspace |
|
|
417
439
|
| `db:migrate` | Run registry database migrations (Drizzle / PostgreSQL) |
|
|
418
440
|
| `make:component <name>` | Scaffold a new component |
|
|
419
441
|
| `make:page <name> [parent]` | Scaffold a documentation page |
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Color Guidelines
|
|
3
|
+
description: How to apply the color palette consistently and accessibly across products.
|
|
4
|
+
metaTitle: 'Color Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'How to apply the color palette consistently and accessibly across products.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Color Guidelines** page. Replace it with your rules for
|
|
9
|
+
contrast, pairing, and semantic usage. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Effects Guidelines
|
|
3
|
+
description: When and how to apply shadows, blurs, and elevation across the interface.
|
|
4
|
+
metaTitle: 'Effects Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'When and how to apply shadows, blurs, and elevation across the interface.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Effects Guidelines** page. Replace it with your rules for
|
|
9
|
+
elevation, depth, and motion. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Effects Resources
|
|
3
|
+
description: Reference values and assets for reproducing the brand's effects in any tool.
|
|
4
|
+
metaTitle: 'Effects Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Reference values and assets for reproducing effects in any tool.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Effects Resources** page. Replace it with your shadow tokens,
|
|
9
|
+
blur values, and export notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Grid
|
|
3
|
+
description: Layout grid and spacing system that keeps compositions aligned and balanced.
|
|
4
|
+
image: hero-design
|
|
5
|
+
metaTitle: 'Grid | Handoff Design System'
|
|
6
|
+
metaDescription: 'Layout grid and spacing system that keeps compositions aligned and balanced.'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This is placeholder content for the **Grid** page. Replace it with your columns, gutters, and
|
|
10
|
+
breakpoint rules. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Icon Guidelines
|
|
3
|
+
description: Sizing, spacing, and usage rules that keep the icon set consistent.
|
|
4
|
+
metaTitle: 'Icon Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'Sizing, spacing, and usage rules that keep the icon set consistent.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Icon Guidelines** page. Replace it with your rules for grid
|
|
9
|
+
sizing, stroke, and when to use each icon. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Image Guidelines
|
|
3
|
+
description: How to select, crop, and treat imagery so it stays on brand.
|
|
4
|
+
metaTitle: 'Image Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'How to select, crop, and treat imagery so it stays on brand.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Image Guidelines** page. Replace it with your rules for
|
|
9
|
+
composition, cropping, and treatments. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Image Resources
|
|
3
|
+
description: Source files and downloads for approved photography and illustration.
|
|
4
|
+
metaTitle: 'Image Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Source files and downloads for approved photography and illustration.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Image Resources** page. Replace it with your image library,
|
|
9
|
+
downloads, and licensing notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Images
|
|
3
|
+
description: Photography and illustration style that shapes how the brand looks and feels.
|
|
4
|
+
image: hero-design
|
|
5
|
+
metaTitle: 'Images | Handoff Design System'
|
|
6
|
+
metaDescription: 'Photography and illustration style that shapes how the brand looks and feels.'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This is placeholder content for the **Images** page. Replace it with your art direction,
|
|
10
|
+
photography style, and illustration principles. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Logo Resources
|
|
3
|
+
description: Downloadable logo files and everything teams need to represent the brand correctly.
|
|
4
|
+
metaTitle: 'Logo Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Downloadable logo files and everything teams need to represent the brand correctly.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Logo Resources** page. Replace it with your logo downloads,
|
|
9
|
+
file formats, and usage notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Typography Guidelines
|
|
3
|
+
description: Best practices for type scale, hierarchy, and readability across the system.
|
|
4
|
+
metaTitle: 'Typography Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'Best practices for type scale, hierarchy, and readability across the system.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Typography Guidelines** page. Replace it with your rules for
|
|
9
|
+
hierarchy, spacing, and responsive type. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Typography Resources
|
|
3
|
+
description: Font files, licenses, and assets needed to work with the brand typography.
|
|
4
|
+
metaTitle: 'Typography Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Font files, licenses, and assets needed to work with the brand typography.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Typography Resources** page. Replace it with your font
|
|
9
|
+
downloads, licensing details, and platform notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -67,8 +67,10 @@ menu:
|
|
|
67
67
|
title: Images
|
|
68
68
|
icon: image
|
|
69
69
|
menu:
|
|
70
|
-
- path: foundations/
|
|
71
|
-
title:
|
|
72
|
-
- path: foundations/
|
|
70
|
+
- path: foundations/images
|
|
71
|
+
title: Overview
|
|
72
|
+
- path: foundations/images/guidelines
|
|
73
73
|
title: Guidelines
|
|
74
|
+
- path: foundations/images/resources
|
|
75
|
+
title: Resources
|
|
74
76
|
---
|
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -13,6 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
36
|
};
|
|
14
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
38
|
exports.devApp = exports.watchApp = exports.getRegistryBuildOutputPath = exports.HandoffBuildError = exports.DEFAULT_BUILD_TARGET = void 0;
|
|
39
|
+
const p = __importStar(require("@clack/prompts"));
|
|
16
40
|
const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
17
41
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
42
|
const path_1 = __importDefault(require("path"));
|
|
@@ -21,7 +45,7 @@ const patterns_1 = require("../pipeline/patterns");
|
|
|
21
45
|
const builder_1 = __importDefault(require("../transformers/preview/component/builder"));
|
|
22
46
|
const css_1 = require("../transformers/preview/component/css");
|
|
23
47
|
const javascript_1 = require("../transformers/preview/component/javascript");
|
|
24
|
-
const
|
|
48
|
+
const driver_1 = require("../registry/db/driver");
|
|
25
49
|
const resolve_1 = require("../registry/asset-storage/resolve");
|
|
26
50
|
const logger_1 = require("../utils/logger");
|
|
27
51
|
const client_config_1 = require("./client-config");
|
|
@@ -78,6 +102,51 @@ const assertStaticBuildAllowed = (handoff) => {
|
|
|
78
102
|
'or package the registry app with `handoff-app build --target registry`.');
|
|
79
103
|
}
|
|
80
104
|
};
|
|
105
|
+
/**
|
|
106
|
+
* Run the Next.js production build while keeping its delayed output out of the successful CLI flow.
|
|
107
|
+
* Captured output is replayed only when the child fails so compiler diagnostics remain available.
|
|
108
|
+
*/
|
|
109
|
+
const runNextBuild = (appPath, target, errorLabel) => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
const spinner = p.spinner();
|
|
111
|
+
spinner.start('Building Next.js app...');
|
|
112
|
+
const stdout = [];
|
|
113
|
+
const stderr = [];
|
|
114
|
+
yield new Promise((resolve, reject) => {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
const buildProcess = (0, cross_spawn_1.default)('npx', ['next', 'build'], {
|
|
117
|
+
cwd: appPath,
|
|
118
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
119
|
+
env: Object.assign(Object.assign({}, process.env), { NODE_ENV: 'production', HANDOFF_BUILD_TARGET: target }),
|
|
120
|
+
});
|
|
121
|
+
(_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (chunk) => stdout.push(Buffer.from(chunk)));
|
|
122
|
+
(_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (chunk) => stderr.push(Buffer.from(chunk)));
|
|
123
|
+
let settled = false;
|
|
124
|
+
const fail = (message) => {
|
|
125
|
+
if (settled)
|
|
126
|
+
return;
|
|
127
|
+
settled = true;
|
|
128
|
+
spinner.stop('Next.js app build failed');
|
|
129
|
+
logger_1.Logger.childProcessBuffer(Buffer.concat(stdout));
|
|
130
|
+
logger_1.Logger.childProcessBuffer(Buffer.concat(stderr));
|
|
131
|
+
reject(new Error(message));
|
|
132
|
+
};
|
|
133
|
+
buildProcess.once('error', (error) => {
|
|
134
|
+
fail(`${errorLabel} failed to start\nSpawn error: ${error.message}`);
|
|
135
|
+
});
|
|
136
|
+
buildProcess.once('close', (code, signal) => {
|
|
137
|
+
if (settled)
|
|
138
|
+
return;
|
|
139
|
+
if (code === 0) {
|
|
140
|
+
settled = true;
|
|
141
|
+
spinner.stop('Next.js app built successfully');
|
|
142
|
+
resolve();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const reason = signal ? ` because it was terminated by signal ${signal}` : ` with exit code ${code}`;
|
|
146
|
+
fail(`${errorLabel} failed${reason}`);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
81
150
|
/**
|
|
82
151
|
* Output directory for the packaged registry app. Lives under the configurable sites output
|
|
83
152
|
* directory (`sitesOutputDirectory`, default `out`) alongside the static target's `out/<projectId>`
|
|
@@ -147,9 +216,9 @@ const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handof
|
|
|
147
216
|
// Resolved runtime mode + registry connection inputs (names only) baked into the Next bundle so the
|
|
148
217
|
// deployed registry app resolves its mode/DB env-var name without any build-machine filesystem.
|
|
149
218
|
const escapedRuntimeMode = escapeForSingleQuotedJsString(runtimeMode);
|
|
150
|
-
const
|
|
151
|
-
const escapedDatabaseUrlEnv = escapeForSingleQuotedJsString((0,
|
|
152
|
-
const escapedApiTokenEnv = escapeForSingleQuotedJsString((0,
|
|
219
|
+
const escapedRegistryDriver = escapeForSingleQuotedJsString((0, driver_1.resolveRegistryDriver)(handoff.config));
|
|
220
|
+
const escapedDatabaseUrlEnv = escapeForSingleQuotedJsString((0, driver_1.resolveDatabaseUrlEnv)(handoff.config));
|
|
221
|
+
const escapedApiTokenEnv = escapeForSingleQuotedJsString((0, driver_1.resolveApiTokenEnv)(handoff.config));
|
|
153
222
|
// Asset storage selection baked (provider + module + env-var names + non-secret options JSON).
|
|
154
223
|
const assetStorage = (0, resolve_1.resolveAssetStorageFromConfig)(handoff.config);
|
|
155
224
|
const escapedAssetStorageAdapter = escapeForSingleQuotedJsString(assetStorage.adapterKind);
|
|
@@ -165,7 +234,7 @@ const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handof
|
|
|
165
234
|
'%HANDOFF_EXPORT_PATH%': escapedExportPath,
|
|
166
235
|
'%HANDOFF_WEBSOCKET_PORT%': escapedWebsocketPort,
|
|
167
236
|
'%HANDOFF_RUNTIME_MODE%': escapedRuntimeMode,
|
|
168
|
-
'%
|
|
237
|
+
'%HANDOFF_REGISTRY_DRIVER%': escapedRegistryDriver,
|
|
169
238
|
'%HANDOFF_REGISTRY_DATABASE_URL_ENV%': escapedDatabaseUrlEnv,
|
|
170
239
|
'%HANDOFF_REGISTRY_API_TOKEN_ENV%': escapedApiTokenEnv,
|
|
171
240
|
'%HANDOFF_ASSET_STORAGE_ADAPTER%': escapedAssetStorageAdapter,
|
|
@@ -216,20 +285,7 @@ const buildApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1, ...args
|
|
|
216
285
|
(0, static_export_1.validateReferencedArtifacts)(handoff);
|
|
217
286
|
// Build app. The static target drives Next's `output: 'export'` via HANDOFF_BUILD_TARGET so the
|
|
218
287
|
// export gate is tied to the resolved target, not to NODE_ENV.
|
|
219
|
-
|
|
220
|
-
cwd: appPath,
|
|
221
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
222
|
-
env: Object.assign(Object.assign({}, process.env), { NODE_ENV: 'production', HANDOFF_BUILD_TARGET: target }),
|
|
223
|
-
});
|
|
224
|
-
logger_1.Logger.childProcessBuffer(buildResult.stdout);
|
|
225
|
-
logger_1.Logger.childProcessBuffer(buildResult.stderr);
|
|
226
|
-
if (buildResult.status !== 0) {
|
|
227
|
-
let errorMsg = `Next.js build failed with exit code ${buildResult.status}`;
|
|
228
|
-
if (buildResult.error) {
|
|
229
|
-
errorMsg += `\nSpawn error: ${buildResult.error.message}`;
|
|
230
|
-
}
|
|
231
|
-
throw new Error(errorMsg);
|
|
232
|
-
}
|
|
288
|
+
yield runNextBuild(appPath, target, 'Next.js build');
|
|
233
289
|
// Reproduce the docs read API (`/api/docs/*`) as route-shaped static files in the export output,
|
|
234
290
|
// since `output: 'export'` disables the live API routes.
|
|
235
291
|
const exportDir = path_1.default.resolve(appPath, 'out');
|
|
@@ -306,7 +362,7 @@ pipeline) before deploying new code:
|
|
|
306
362
|
${databaseUrlEnv}="postgres://…" handoff-app db:migrate
|
|
307
363
|
\`\`\`
|
|
308
364
|
|
|
309
|
-
\`db:migrate\` reads your project config + DB env vars, resolves the same database
|
|
365
|
+
\`db:migrate\` reads your project config + DB env vars, resolves the same database driver the app was
|
|
310
366
|
built with, and applies the package-owned migration set. It runs independently of \`build\` and of
|
|
311
367
|
starting the server, so run it as a release/one-shot job.
|
|
312
368
|
|
|
@@ -352,15 +408,15 @@ containers, custom Node servers, and other non-Vercel hosts.
|
|
|
352
408
|
});
|
|
353
409
|
/**
|
|
354
410
|
* Resolve the set of npm packages the packaged registry app must be able to `require`/`import` at
|
|
355
|
-
* runtime, given the configured database
|
|
411
|
+
* runtime, given the configured database driver. `next`/`react`/`react-dom` run the server and React
|
|
356
412
|
* runtime; `drizzle-orm` backs both the request-time DB client and the migration runner; the driver
|
|
357
|
-
* is
|
|
413
|
+
* package is driver-specific (the Neon serverless driver also needs `ws` for its Node WebSocket transport).
|
|
358
414
|
*/
|
|
359
415
|
const getRequiredRegistryRuntimeModules = (handoff) => {
|
|
360
416
|
var _a;
|
|
361
417
|
const base = ['next', 'react', 'react-dom', 'drizzle-orm'];
|
|
362
|
-
const
|
|
363
|
-
const
|
|
418
|
+
const driver = (0, driver_1.resolveRegistryDriver)(handoff.config);
|
|
419
|
+
const driverModules = driver === 'neon' ? ['@neondatabase/serverless', 'ws'] : ['pg'];
|
|
364
420
|
// Asset-storage SDKs the deployed registry must be able to load at request time. The pre-packaged
|
|
365
421
|
// Vercel Blob adapter needs `@vercel/blob`; a custom adapter may declare its installed SDK
|
|
366
422
|
// package(s) via `assetStorage.options.sdkModules` so the trace/assertion covers them.
|
|
@@ -373,7 +429,7 @@ const getRequiredRegistryRuntimeModules = (handoff) => {
|
|
|
373
429
|
if (Array.isArray(sdkModules)) {
|
|
374
430
|
storage.push(...sdkModules.filter((mod) => typeof mod === 'string'));
|
|
375
431
|
}
|
|
376
|
-
return [...base, ...
|
|
432
|
+
return [...base, ...driverModules, ...storage];
|
|
377
433
|
};
|
|
378
434
|
/**
|
|
379
435
|
* Build-time guard against the empty-`node_modules` regression (the artifact would otherwise boot-fail
|
|
@@ -482,7 +538,7 @@ const assembleRegistryStandalone = (handoff, appPath, standaloneRoot, entryDir)
|
|
|
482
538
|
* - `vercel` → the Vercel Build Output API directory (`.vercel/output`) at the repo root: the
|
|
483
539
|
* traced bundle wrapped as a Node function plus CDN static assets and a route table.
|
|
484
540
|
*
|
|
485
|
-
* Mode is forced to `registry`; the database
|
|
541
|
+
* Mode is forced to `registry`; the database driver is honored from config (single-sourced so build
|
|
486
542
|
* and `db:migrate` never diverge). No connection-string value is ever baked — only env-var *names*.
|
|
487
543
|
*/
|
|
488
544
|
const buildRegistryApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1, ...args_1], void 0, function* (handoff, buildPackage = 'standalone') {
|
|
@@ -495,15 +551,15 @@ const buildRegistryApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1,
|
|
|
495
551
|
if (sourceMode !== 'registry') {
|
|
496
552
|
logger_1.Logger.info(`Source runtime.mode is "${sourceMode}"; forcing "registry" mode in the packaged registry app.`);
|
|
497
553
|
}
|
|
498
|
-
// The
|
|
554
|
+
// The driver stays single-sourced from config (never flipped by the package flag), so build and
|
|
499
555
|
// `db:migrate` always resolve the same one. `pg` uses long-lived TCP connections that pool poorly on
|
|
500
556
|
// serverless; warn (non-fatally) so the operator points DATABASE_URL at a pooled endpoint or selects
|
|
501
|
-
// the Neon
|
|
557
|
+
// the Neon driver. The connection-string value is not available at build time, so this cannot be
|
|
502
558
|
// validated — it is guidance only and never fails the build.
|
|
503
|
-
if (buildPackage === 'vercel' && (0,
|
|
504
|
-
logger_1.Logger.warn('Registry Vercel build uses the "pg"
|
|
559
|
+
if (buildPackage === 'vercel' && (0, driver_1.resolveRegistryDriver)(handoff.config) === 'pg') {
|
|
560
|
+
logger_1.Logger.warn('Registry Vercel build uses the "pg" driver (standard TCP connections), which pools poorly on ' +
|
|
505
561
|
'serverless and can exhaust the database connection limit. Point DATABASE_URL at a pooled endpoint ' +
|
|
506
|
-
'(PgBouncer / transaction pooling), or set runtime.registry.database.
|
|
562
|
+
'(PgBouncer / transaction pooling), or set runtime.registry.database.driver: "neon" for a ' +
|
|
507
563
|
'serverless-native HTTP/WebSocket driver. The build will continue.');
|
|
508
564
|
}
|
|
509
565
|
// Stage the app without any workspace-derived artifacts — the registry serves from the database.
|
|
@@ -524,20 +580,7 @@ const buildRegistryApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1,
|
|
|
524
580
|
yield fs_extra_1.default.remove((0, vercel_output_1.getVercelOutputPath)(handoff));
|
|
525
581
|
// Build the dynamic app. `output: 'standalone'` (driven by HANDOFF_BUILD_TARGET) traces the runtime
|
|
526
582
|
// and the selected Postgres/Neon driver into a self-contained bundle — never a static export.
|
|
527
|
-
|
|
528
|
-
cwd: appPath,
|
|
529
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
530
|
-
env: Object.assign(Object.assign({}, process.env), { NODE_ENV: 'production', HANDOFF_BUILD_TARGET: 'registry' }),
|
|
531
|
-
});
|
|
532
|
-
logger_1.Logger.childProcessBuffer(buildResult.stdout);
|
|
533
|
-
logger_1.Logger.childProcessBuffer(buildResult.stderr);
|
|
534
|
-
if (buildResult.status !== 0) {
|
|
535
|
-
let errorMsg = `Registry app build failed with exit code ${buildResult.status}`;
|
|
536
|
-
if (buildResult.error) {
|
|
537
|
-
errorMsg += `\nSpawn error: ${buildResult.error.message}`;
|
|
538
|
-
}
|
|
539
|
-
throw new Error(errorMsg);
|
|
540
|
-
}
|
|
583
|
+
yield runNextBuild(appPath, 'registry', 'Registry app build');
|
|
541
584
|
// Assemble the deployable package. Standalone tracing is rooted at the package (modulePath), so the
|
|
542
585
|
// app's traced files land under `<relAppDir>` inside the standalone tree; static assets and public
|
|
543
586
|
// files are not traced and must be copied alongside the server entry.
|
|
@@ -561,7 +604,7 @@ const buildRegistryApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1,
|
|
|
561
604
|
// `handoff-app` source/CLI (`handoff-app db:migrate`) as a controlled release step (e.g. CI/CD),
|
|
562
605
|
// never from the deployed bundle. See the generated README for the migrate-then-deploy flow.
|
|
563
606
|
const entryRelativePath = path_1.default.relative(output, serverEntry).split(path_1.default.sep).join('/');
|
|
564
|
-
yield writeRegistryDeploymentReadme(output, entryRelativePath, (0,
|
|
607
|
+
yield writeRegistryDeploymentReadme(output, entryRelativePath, (0, driver_1.resolveDatabaseUrlEnv)(handoff.config));
|
|
565
608
|
logger_1.Logger.success(`Packaged registry app at ${output} (start: \`node ${entryRelativePath}\`, migrate: \`handoff-app db:migrate\`).`);
|
|
566
609
|
});
|
|
567
610
|
/**
|
|
@@ -17,7 +17,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const config_1 = require("../config");
|
|
19
19
|
const resolve_1 = require("../registry/asset-storage/resolve");
|
|
20
|
-
const
|
|
20
|
+
const driver_1 = require("../registry/db/driver");
|
|
21
21
|
const paths_1 = require("./paths");
|
|
22
22
|
/**
|
|
23
23
|
* Publishes the tokens API files to the public directory.
|
|
@@ -55,7 +55,7 @@ exports.generateTokensApi = generateTokensApi;
|
|
|
55
55
|
* Build the server-only runtime config consumed by the docs read API.
|
|
56
56
|
*
|
|
57
57
|
* The browser-facing `client.config.json` carries only the resolved mode; the server additionally
|
|
58
|
-
* needs the registry connection *inputs* (selected
|
|
58
|
+
* needs the registry connection *inputs* (selected driver + the *name* of the database-URL env
|
|
59
59
|
* var) to back the registry-mode docs read API. These are non-secret — the connection-string value
|
|
60
60
|
* itself is never persisted, only resolved from the env var at request time.
|
|
61
61
|
*/
|
|
@@ -65,9 +65,9 @@ const buildServerRuntimeConfig = (config, modeOverride) => {
|
|
|
65
65
|
return {
|
|
66
66
|
mode: (_b = modeOverride !== null && modeOverride !== void 0 ? modeOverride : (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : 'workspace',
|
|
67
67
|
registry: {
|
|
68
|
-
|
|
69
|
-
databaseUrlEnv: (0,
|
|
70
|
-
apiTokenEnv: (0,
|
|
68
|
+
driver: (0, driver_1.resolveRegistryDriver)(config),
|
|
69
|
+
databaseUrlEnv: (0, driver_1.resolveDatabaseUrlEnv)(config),
|
|
70
|
+
apiTokenEnv: (0, driver_1.resolveApiTokenEnv)(config),
|
|
71
71
|
},
|
|
72
72
|
assetStorage: {
|
|
73
73
|
adapter: assetStorage.adapterKind,
|
|
@@ -50,14 +50,33 @@ const mirrorDirectory = (sourcePath, destinationPath) => __awaiter(void 0, void
|
|
|
50
50
|
yield fs_extra_1.default.ensureDir(path_1.default.dirname(destinationPath));
|
|
51
51
|
yield fs_extra_1.default.copy(sourcePath, destinationPath, { overwrite: true });
|
|
52
52
|
});
|
|
53
|
+
/**
|
|
54
|
+
* Copy the fetch-produced asset bundles (`exported/<id>/{collection}.zip`) into the app's public
|
|
55
|
+
* root, where the docs read API serves them at `/api/docs/assets/{collection}/{collection}.zip`.
|
|
56
|
+
* `fetch` writes these bundles, but `build`/`start` cleans and re-stages `.handoff` without them, so
|
|
57
|
+
* the download links 404 until the next fetch. Copying them here keeps the route working in workspace
|
|
58
|
+
* dev and static builds. Projects with no logos/icons have no bundles, so those are skipped.
|
|
59
|
+
*/
|
|
60
|
+
const stageAssetDownloadBundles = (handoff, destinationPublicPath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
const bundles = [
|
|
62
|
+
{ src: handoff.getLogosZipFilePath(), name: 'logos.zip' },
|
|
63
|
+
{ src: handoff.getIconsZipFilePath(), name: 'icons.zip' },
|
|
64
|
+
];
|
|
65
|
+
for (const { src, name } of bundles) {
|
|
66
|
+
if (fs_extra_1.default.existsSync(src) && fs_extra_1.default.statSync(src).isFile()) {
|
|
67
|
+
yield fs_extra_1.default.ensureDir(destinationPublicPath);
|
|
68
|
+
yield fs_extra_1.default.copy(src, path_1.default.resolve(destinationPublicPath, name), { overwrite: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
53
72
|
/**
|
|
54
73
|
* Copy the public dir from the working dir to the module dir.
|
|
55
74
|
*/
|
|
56
75
|
const syncPublicFiles = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
76
|
const appPath = (0, exports.getAppPath)(handoff);
|
|
77
|
+
const destinationPublicPath = path_1.default.resolve(appPath, 'public');
|
|
58
78
|
const workingPublicPath = (0, exports.getWorkingPublicPath)(handoff);
|
|
59
79
|
if (workingPublicPath) {
|
|
60
|
-
const destinationPublicPath = path_1.default.resolve(appPath, 'public');
|
|
61
80
|
const sourceApiPath = path_1.default.resolve(workingPublicPath, 'api');
|
|
62
81
|
const destinationApiPath = path_1.default.resolve(destinationPublicPath, 'api');
|
|
63
82
|
yield fs_extra_1.default.copy(workingPublicPath, destinationPublicPath, {
|
|
@@ -69,5 +88,8 @@ const syncPublicFiles = (handoff) => __awaiter(void 0, void 0, void 0, function*
|
|
|
69
88
|
});
|
|
70
89
|
yield mirrorDirectory(sourceApiPath, destinationApiPath);
|
|
71
90
|
}
|
|
91
|
+
// Stage the asset bundles even when the workspace has no `public/` dir; they come from the fetch
|
|
92
|
+
// output, not the workspace public tree.
|
|
93
|
+
yield stageAssetDownloadBundles(handoff, destinationPublicPath);
|
|
72
94
|
});
|
|
73
95
|
exports.syncPublicFiles = syncPublicFiles;
|
|
@@ -176,6 +176,31 @@ const materializeDocsReadModel = (handoff, outDir) => __awaiter(void 0, void 0,
|
|
|
176
176
|
const detail = Object.assign(Object.assign({}, pattern), { build: { status: deriveBuildStatus(artifactRoot, path_1.default.join('pattern', `${pattern.id}.json`)) } });
|
|
177
177
|
yield fs_extra_1.default.writeJson(path_1.default.join(docsRoot, 'patterns', `${pattern.id}.json`), detail);
|
|
178
178
|
}
|
|
179
|
+
yield materializeAssetDownloads(handoff, docsRoot);
|
|
179
180
|
logger_1.Logger.success(`Materialized docs read model (${components.length} component(s), ${patterns.length} pattern(s)) for static export.`);
|
|
180
181
|
});
|
|
181
182
|
exports.materializeDocsReadModel = materializeDocsReadModel;
|
|
183
|
+
/**
|
|
184
|
+
* Write the whole-collection asset bundles to the asset route
|
|
185
|
+
* (`api/docs/assets/{collection}/{collection}.zip`), the same URL the docs read API serves in
|
|
186
|
+
* registry mode, so the "Download" links work identically on a static host. The bundles come from the
|
|
187
|
+
* fetch output (`exported/<id>/{collection}.zip`); `next build` never re-creates them and the
|
|
188
|
+
* fetch-time copy into `public/` is wiped by the build's clean+restage, so we copy them here again.
|
|
189
|
+
* Projects with no logos/icons have no bundles, so those are skipped rather than treated as an error.
|
|
190
|
+
*/
|
|
191
|
+
const materializeAssetDownloads = (handoff, docsRoot) => __awaiter(void 0, void 0, void 0, function* () {
|
|
192
|
+
const bundles = [
|
|
193
|
+
{ collection: 'logos', src: handoff.getLogosZipFilePath() },
|
|
194
|
+
{ collection: 'icons', src: handoff.getIconsZipFilePath() },
|
|
195
|
+
];
|
|
196
|
+
let copied = 0;
|
|
197
|
+
for (const { collection, src } of bundles) {
|
|
198
|
+
if (fs_extra_1.default.existsSync(src) && fs_extra_1.default.statSync(src).isFile()) {
|
|
199
|
+
yield fs_extra_1.default.copy(src, path_1.default.join(docsRoot, 'assets', collection, `${collection}.zip`), { overwrite: true });
|
|
200
|
+
copied += 1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (copied > 0) {
|
|
204
|
+
logger_1.Logger.info(`Materialized ${copied} asset download bundle(s) for static export.`);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
@@ -74,7 +74,7 @@ const writeStaticVercelOutput = (handoff, exportDir) => __awaiter(void 0, void 0
|
|
|
74
74
|
});
|
|
75
75
|
exports.writeStaticVercelOutput = writeStaticVercelOutput;
|
|
76
76
|
/**
|
|
77
|
-
* Node.js runtime identifier baked into the registry function's `.vc-config.json`. The `pg`
|
|
77
|
+
* Node.js runtime identifier baked into the registry function's `.vc-config.json`. The `pg` driver
|
|
78
78
|
* (and the Neon serverless driver in its Node fallback) need the Node.js runtime, not the edge
|
|
79
79
|
* runtime — this is the required baseline. Vercel resolves the patch
|
|
80
80
|
* version within this major; pinning the major keeps the artifact stable.
|
|
@@ -102,7 +102,7 @@ const MUTABLE_REGISTRY_PAGE_SRC_ROUTE = '/[...slug]';
|
|
|
102
102
|
* data routes resolve the same way they do under the standalone server. `minimalMode:false` keeps
|
|
103
103
|
* the function doing full in-process routing (the catch-all route forwards everything here).
|
|
104
104
|
*
|
|
105
|
-
* Runtime mode,
|
|
105
|
+
* Runtime mode, driver, and the DB env-var *name* are already baked into the resolved config the
|
|
106
106
|
* standalone build wrote to `.next/required-server-files.json`; the connection-string value is still
|
|
107
107
|
* read from the named env var at request time, never baked.
|
|
108
108
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ARTIFACT_METADATA_PATH, REACT_PREVIEW_FORMAT_VERSION, SHARED_MAIN_CSS_ARTIFACT_PATH, SHARED_MAIN_JS_ARTIFACT_PATH, SHARED_STYLES_CSS_ARTIFACT_PATH, type ArtifactBuildMetadata, type ArtifactBuildStatus, type ArtifactDescriptor, type ArtifactKind, type ArtifactOwnerKind, type ArtifactReference, type ArtifactReferenceKind, type ArtifactSizeDiagnostics, } from './types';
|
|
2
|
-
export { ARTIFACTS_ROUTE_SEGMENT, buildArtifactUrl, normalizeBasePath } from './url';
|
|
2
|
+
export { ARTIFACTS_ROUTE_SEGMENT, ASSETS_ROUTE_SEGMENT, buildArtifactUrl, buildAssetDownloadUrl, buildAssetUrl, normalizeBasePath, } from './url';
|