handoff-app 2.0.0-8 → 2.0.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/{Changelog.md → CHANGELOG.md} +85 -1
- package/{License.md → LICENSE.md} +1 -1
- package/README.md +816 -393
- package/RECIPES.md +975 -0
- package/UPGRADE.md +57 -9
- package/components.json +20 -20
- package/config/docs/foundations/colors/guidelines.md +0 -1
- package/config/docs/foundations/colors.md +0 -1
- package/config/docs/foundations/effects/guidelines.md +0 -1
- package/config/docs/foundations/effects/resources.md +0 -1
- package/config/docs/foundations/effects.md +0 -1
- package/config/docs/foundations/fonts.md +0 -1
- package/config/docs/foundations/grid.md +0 -1
- package/config/docs/foundations/icon.md +0 -1
- package/config/docs/foundations/icons/guidelines.md +0 -1
- package/config/docs/foundations/icons.md +0 -1
- package/config/docs/foundations/images/guidelines.md +0 -1
- package/config/docs/foundations/images/resources.md +0 -1
- package/config/docs/foundations/images.md +0 -1
- package/config/docs/foundations/logo/resources.md +0 -1
- package/config/docs/foundations/logo.md +0 -1
- package/config/docs/foundations/typography/guidelines.md +0 -1
- package/config/docs/foundations/typography/resources.md +0 -1
- package/config/docs/foundations/typography.md +0 -1
- package/config/docs/foundations.md +0 -1
- package/config/docs/guidelines.md +0 -1
- package/config/docs/index.md +0 -1
- package/config/docs/system/tokens/foundations/colors.md +0 -4
- package/config/docs/system/tokens/foundations/effects.md +0 -4
- package/config/docs/system/tokens/foundations/typography.md +0 -2
- package/config/docs/system.md +0 -2
- package/config/templates/page.md +2 -1
- package/config/templates/page.mdx +2 -1
- package/dist/ai/connections.d.ts +66 -0
- package/dist/ai/connections.js +149 -0
- package/dist/ai/define.d.ts +10 -0
- package/dist/ai/define.js +13 -0
- package/dist/ai/types.d.ts +26 -0
- package/dist/ai/types.js +10 -0
- package/dist/app-builder/build.d.ts +14 -7
- package/dist/app-builder/build.js +195 -66
- package/dist/app-builder/client-config.js +3 -2
- package/dist/app-builder/paths.d.ts +0 -12
- package/dist/app-builder/paths.js +3 -20
- package/dist/app-builder/static-export.js +1 -1
- package/dist/app-builder/vercel-output.d.ts +1 -1
- package/dist/app-builder/vercel-output.js +5 -4
- package/dist/cache/build-cache.d.ts +27 -4
- package/dist/cache/build-cache.js +114 -47
- package/dist/cache/build-inputs.d.ts +13 -0
- package/dist/cache/build-inputs.js +19 -0
- package/dist/cache/index.d.ts +2 -1
- package/dist/cache/index.js +5 -1
- package/dist/catalog/normalize.js +3 -0
- package/dist/catalog/previews.js +5 -4
- package/dist/catalog/types.d.ts +8 -0
- package/dist/cli/create.js +1 -2
- package/dist/commands/build/index.d.ts +1 -1
- package/dist/commands/build/index.js +1 -1
- package/dist/commands/utils.d.ts +3 -3
- package/dist/config/defaults.js +7 -4
- package/dist/config/from-env.d.ts +4 -0
- package/dist/config/from-env.js +38 -1
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +1 -4
- package/dist/config/loader.js +28 -2
- package/dist/config/resolve-env.d.ts +2 -1
- package/dist/config/resolve-env.js +28 -12
- package/dist/config/runtime.js +9 -11
- package/dist/handlebars.d.ts +10 -2
- package/dist/index.d.ts +12 -7
- package/dist/index.js +18 -22
- package/dist/nav/index.d.ts +2 -2
- package/dist/nav/registry.d.ts +3 -3
- package/dist/nav/registry.js +1 -1
- package/dist/nav/workspace.d.ts +3 -3
- package/dist/nav/workspace.js +1 -1
- package/dist/pipeline/figma.d.ts +13 -2
- package/dist/pipeline/figma.js +86 -46
- package/dist/pipeline/styles.js +1 -1
- package/dist/pipeline/validation.d.ts +1 -1
- package/dist/pipeline/validation.js +3 -3
- package/dist/providers.d.ts +10 -0
- package/dist/providers.js +13 -0
- package/dist/registry/asset-storage/define.d.ts +5 -5
- package/dist/registry/asset-storage/define.js +4 -4
- package/dist/registry/asset-storage/resolve.d.ts +9 -19
- package/dist/registry/asset-storage/resolve.js +33 -21
- package/dist/registry/asset-storage/types.d.ts +37 -17
- package/dist/registry/asset-storage/types.js +5 -5
- package/dist/registry/auth/ai-keys.d.ts +32 -0
- package/dist/registry/auth/ai-keys.js +69 -0
- package/dist/registry/auth/crypto.d.ts +17 -0
- package/dist/registry/auth/crypto.js +61 -1
- package/dist/registry/auth/index.d.ts +2 -1
- package/dist/registry/auth/index.js +11 -2
- package/dist/registry/checkout/index.d.ts +2 -1
- package/dist/registry/checkout/index.js +57 -127
- package/dist/registry/client.js +53 -17
- package/dist/registry/db/driver.js +3 -3
- package/dist/registry/db/schema.d.ts +261 -3
- package/dist/registry/db/schema.js +29 -4
- package/dist/registry/email/define.d.ts +10 -0
- package/dist/registry/email/define.js +13 -0
- package/dist/registry/email/providers/smtp.d.ts +10 -0
- package/dist/registry/email/providers/smtp.js +73 -0
- package/dist/registry/email/resolve.d.ts +28 -0
- package/dist/registry/email/resolve.js +74 -0
- package/dist/registry/email/types.d.ts +24 -0
- package/dist/registry/email/types.js +6 -0
- package/dist/registry/path.d.ts +2 -0
- package/dist/registry/path.js +11 -1
- package/dist/registry/publish/package.js +8 -0
- package/dist/registry/transfer.d.ts +4 -0
- package/dist/store/registry.d.ts +3 -3
- package/dist/store/registry.js +4 -4
- package/dist/transformers/plugins/ssr-render.js +40 -15
- package/dist/transformers/preview/component/builder.d.ts +1 -9
- package/dist/transformers/preview/component/builder.js +17 -17
- package/dist/transformers/preview/component/css.d.ts +3 -1
- package/dist/transformers/preview/component/css.js +92 -51
- package/dist/transformers/preview/component/html.d.ts +3 -1
- package/dist/transformers/preview/component/html.js +6 -2
- package/dist/transformers/preview/component/javascript.d.ts +2 -1
- package/dist/transformers/preview/component/javascript.js +10 -4
- package/dist/transformers/preview/pattern/html.js +3 -1
- package/dist/transformers/preview/types.d.ts +13 -0
- package/dist/transformers/utils/build.d.ts +24 -0
- package/dist/transformers/utils/build.js +100 -1
- package/dist/transformers/utils/module.js +2 -1
- package/dist/types/config.d.ts +135 -18
- package/dist/utils/path.d.ts +1 -5
- package/dist/utils/path.js +6 -23
- package/docs/api.md +6 -4
- package/docs/cli.md +275 -54
- package/drizzle/0007_add_ai_keys.sql +11 -0
- package/drizzle/0008_add_source_dir.sql +2 -0
- package/drizzle/meta/0007_snapshot.json +2013 -0
- package/drizzle/meta/0008_snapshot.json +2025 -0
- package/drizzle/meta/_journal.json +14 -0
- package/package.json +19 -8
- package/src/ai/README.md +42 -0
- package/src/ai/connections.ts +189 -0
- package/src/ai/define.ts +15 -0
- package/src/ai/types.ts +30 -0
- package/src/app/components/AiAssistant/AiAssistantPanel.tsx +144 -0
- package/src/app/components/AiAssistant/AiAssistantProvider.tsx +215 -0
- package/src/app/components/AiAssistant/AiConversation.tsx +737 -0
- package/src/app/components/AiAssistant/AiToolResult.tsx +99 -0
- package/src/app/components/AiAssistant/dockState.ts +86 -0
- package/src/app/components/AiAssistant/toolLabel.ts +24 -0
- package/src/app/components/AiAssistant/useAiChat.ts +147 -0
- package/src/app/components/AiAssistant/useAiConnections.ts +86 -0
- package/src/app/components/AiAssistant/usePageContext.ts +63 -0
- package/src/app/components/Auth/AccountLayout.tsx +58 -19
- package/src/app/components/Auth/AuthShell.tsx +27 -33
- package/src/app/components/Auth/RegistryInstallGate.tsx +4 -8
- package/src/app/components/Auth/installStatus.ts +29 -0
- package/src/app/components/Component/PageSliceResolver.tsx +1 -0
- package/src/app/components/Component/Preview.tsx +383 -189
- package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +4 -0
- package/src/app/components/Foundations/ColorGrid.tsx +13 -14
- package/src/app/components/Layout/Header.tsx +21 -15
- package/src/app/components/Layout/Main.tsx +2 -2
- package/src/app/components/Markdown/MarkdownComponents.tsx +30 -32
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +12 -51
- package/src/app/components/Navigation/MobileNav.tsx +2 -2
- package/src/app/components/Navigation/SideNav.tsx +1 -15
- package/src/app/components/context/NavProvider.tsx +7 -3
- package/src/app/components/ui/attachment.tsx +50 -0
- package/src/app/components/ui/bubble.tsx +57 -0
- package/src/app/components/ui/button.tsx +3 -1
- package/src/app/components/ui/confirm-dialog.tsx +87 -0
- package/src/app/components/ui/dialog.tsx +7 -2
- package/src/app/components/ui/marker.tsx +56 -0
- package/src/app/components/ui/sidebar.tsx +3 -1
- package/src/app/components/util/index.ts +3 -12
- package/src/app/css/index.css +64 -0
- package/src/app/lib/ai/auth.ts +33 -0
- package/src/app/lib/ai/context.ts +99 -0
- package/src/app/lib/ai/model.ts +79 -0
- package/src/app/lib/ai/prompt.ts +36 -0
- package/src/app/lib/ai/resolve.ts +97 -0
- package/src/app/lib/ai/tools.ts +120 -0
- package/src/app/lib/api/methods.ts +13 -0
- package/src/app/lib/asset-storage.ts +35 -36
- package/src/app/lib/auth/api.ts +4 -12
- package/src/app/lib/auth/email.ts +96 -23
- package/src/app/lib/docs-api/page-rendering.ts +1 -1
- package/src/app/lib/docs-api/registry.ts +2 -3
- package/src/app/lib/docs-api/runtime-config.ts +47 -21
- package/src/app/lib/mcp/components.ts +523 -0
- package/src/app/lib/mcp/page-url.ts +24 -0
- package/src/app/lib/mcp/pages.ts +84 -0
- package/src/app/lib/mcp/result.ts +33 -0
- package/src/app/lib/mcp/server.ts +39 -318
- package/src/app/lib/mcp/tokens.ts +334 -0
- package/src/app/lib/mcp/tool.ts +19 -0
- package/src/app/lib/registry-api/asset-transfer.ts +119 -11
- package/src/app/lib/registry-api/errors.ts +2 -0
- package/src/app/lib/registry-api/handler.ts +7 -1
- package/src/app/lib/registry-api/transfer.ts +28 -6
- package/src/app/lib/server-module.ts +34 -0
- package/src/app/lib/utils.ts +20 -0
- package/src/app/next.config.mjs +26 -24
- package/src/app/pages/[...slug]/index.tsx +2 -1
- package/src/app/pages/_app.tsx +6 -2
- package/src/app/pages/_document.tsx +6 -0
- package/src/app/pages/account/ai.tsx +183 -0
- package/src/app/pages/account/index.tsx +68 -68
- package/src/app/pages/account/tokens.tsx +37 -7
- package/src/app/pages/account/users.tsx +75 -15
- package/src/app/pages/api/account/ai/keys/[connectionId].ts +60 -0
- package/src/app/pages/api/account/ai/keys/index.ts +20 -0
- package/src/app/pages/api/admin/users/[id]/[action].ts +80 -11
- package/src/app/pages/api/admin/users/index.ts +2 -2
- package/src/app/pages/api/ai/chat.ts +115 -0
- package/src/app/pages/api/ai/connections.ts +23 -0
- package/src/app/pages/api/auth/request-reset.ts +14 -16
- package/src/app/pages/api/docs/nav.json.ts +1 -1
- package/src/app/pages/api/install.ts +3 -3
- package/src/app/pages/api/mcp.ts +6 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash]/complete.ts +11 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash]/upload.ts +12 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +1 -1
- package/src/app/pages/cli/device.tsx +10 -5
- package/src/app/pages/foundations/colors.tsx +9 -8
- package/src/app/pages/foundations/index.tsx +3 -3
- package/src/app/pages/index.tsx +2 -2
- package/src/app/pages/install.tsx +7 -2
- package/src/app/pages/login.tsx +32 -27
- package/src/app/pages/reset-password.tsx +21 -20
- package/src/app/pages/system/component/[component]/index.tsx +2 -5
- package/src/app/pages/system/index.tsx +11 -11
- package/src/app/pages/system/pattern/[pattern]/index.tsx +2 -2
- package/src/app/pages/system/tokens/components/[component]/index.tsx +0 -4
- package/src/app-builder/README.md +2 -1
- package/src/app-builder/build.ts +218 -73
- package/src/app-builder/client-config.ts +3 -2
- package/src/app-builder/paths.ts +3 -22
- package/src/app-builder/static-export.ts +1 -1
- package/src/app-builder/vercel-output.ts +5 -4
- package/src/cache/README.md +4 -1
- package/src/cache/build-cache.ts +128 -43
- package/src/cache/build-inputs.ts +28 -0
- package/src/cache/index.ts +4 -0
- package/src/catalog/README.md +3 -0
- package/src/catalog/normalize.ts +2 -0
- package/src/catalog/previews.ts +6 -3
- package/src/catalog/types.ts +8 -0
- package/src/cli/create.ts +1 -2
- package/src/commands/build/index.ts +1 -1
- package/src/config/README.md +10 -9
- package/src/config/defaults.ts +7 -4
- package/src/config/from-env.ts +33 -0
- package/src/config/helpers.ts +1 -3
- package/src/config/index.ts +0 -3
- package/src/config/loader.ts +27 -3
- package/src/config/resolve-env.ts +28 -15
- package/src/config/runtime.ts +10 -5
- package/src/handlebars.ts +8 -2
- package/src/index.ts +33 -29
- package/src/nav/index.ts +2 -2
- package/src/nav/registry.ts +3 -3
- package/src/nav/workspace.ts +3 -3
- package/src/pipeline/README.md +1 -1
- package/src/pipeline/figma.ts +98 -49
- package/src/pipeline/styles.ts +1 -1
- package/src/pipeline/validation.ts +3 -3
- package/src/providers.ts +18 -0
- package/src/registry/asset-storage/define.ts +6 -6
- package/src/registry/asset-storage/resolve.ts +38 -37
- package/src/registry/asset-storage/types.ts +39 -17
- package/src/registry/auth/ai-keys.ts +62 -0
- package/src/registry/auth/crypto.ts +63 -1
- package/src/registry/auth/index.ts +11 -1
- package/src/registry/checkout/index.ts +60 -138
- package/src/registry/client.ts +60 -20
- package/src/registry/db/driver.ts +2 -2
- package/src/registry/db/schema.ts +49 -22
- package/src/registry/email/define.ts +15 -0
- package/src/registry/email/providers/smtp.ts +39 -0
- package/src/registry/email/resolve.ts +94 -0
- package/src/registry/email/types.ts +28 -0
- package/src/registry/path.ts +11 -0
- package/src/registry/publish/package.ts +9 -0
- package/src/registry/transfer.ts +4 -0
- package/src/store/registry.ts +7 -7
- package/src/transformers/plugins/ssr-render.ts +53 -16
- package/src/transformers/preview/component/builder.ts +19 -25
- package/src/transformers/preview/component/css.ts +101 -53
- package/src/transformers/preview/component/html.ts +6 -2
- package/src/transformers/preview/component/javascript.ts +14 -4
- package/src/transformers/preview/pattern/html.ts +3 -1
- package/src/transformers/preview/types.ts +14 -0
- package/src/transformers/utils/build.ts +93 -0
- package/src/transformers/utils/module.ts +4 -2
- package/src/types/config.ts +148 -20
- package/src/utils/README.md +1 -1
- package/src/utils/path.ts +6 -29
- package/templates/default/handoff.config.js.tpl +10 -2
- package/templates/default/handoff.config.ts.tpl +10 -2
- package/templates/default/handoff.config.with-examples.js.tpl +10 -2
- package/templates/default/handoff.config.with-examples.ts.tpl +10 -2
- package/templates/default/package.json.tpl +2 -2
- package/.editorconfig +0 -19
- package/.eslintrc.json +0 -4
- package/.prettierignore +0 -0
- package/.prettierrc.json +0 -8
- package/.vscode/settings.json +0 -17
- package/dist/config/validator.d.ts +0 -9
- package/dist/config/validator.js +0 -24
- package/dist/registry/asset-storage/adapters/vercel-blob.d.ts +0 -17
- package/dist/registry/asset-storage/adapters/vercel-blob.js +0 -87
- package/src/app/components/old/Header.tsx +0 -89
- package/src/app/lib/mcp/shape.ts +0 -596
- package/src/app/pages/assets/fonts.tsx +0 -129
- package/src/app/pages/assets/index.tsx +0 -91
- package/src/app/pages/assets/logos.tsx +0 -75
- package/src/config/validator.ts +0 -22
- package/src/registry/asset-storage/adapters/vercel-blob.ts +0 -51
|
@@ -50,7 +50,7 @@ const resolveBasePath = (rawBasePath) => {
|
|
|
50
50
|
* no functions, no database.
|
|
51
51
|
*
|
|
52
52
|
* @param exportDir Absolute path of the materialized static export (the same content the static
|
|
53
|
-
* target writes to `out
|
|
53
|
+
* target writes to `out/static`).
|
|
54
54
|
*/
|
|
55
55
|
const writeStaticVercelOutput = (handoff, exportDir) => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
56
|
var _a, _b;
|
|
@@ -77,10 +77,11 @@ exports.writeStaticVercelOutput = writeStaticVercelOutput;
|
|
|
77
77
|
/**
|
|
78
78
|
* Node.js runtime identifier baked into the registry function's `.vc-config.json`. The `pg` driver
|
|
79
79
|
* (and the Neon serverless driver in its Node fallback) need the Node.js runtime, not the edge
|
|
80
|
-
* runtime
|
|
81
|
-
* version within this major; pinning the major keeps
|
|
80
|
+
* runtime. The major matches the package `engines` minimum, and the Vercel project's Node.js setting
|
|
81
|
+
* does not override it. Vercel resolves the patch version within this major; pinning the major keeps
|
|
82
|
+
* the artifact stable.
|
|
82
83
|
*/
|
|
83
|
-
const VERCEL_NODE_RUNTIME = '
|
|
84
|
+
const VERCEL_NODE_RUNTIME = 'nodejs22.x';
|
|
84
85
|
/** Name (sans `.func`) of the single registry function. Served at `/` and the catch-all route. */
|
|
85
86
|
const REGISTRY_FUNCTION_NAME = 'index';
|
|
86
87
|
/** Handler file the Node launcher executes; wraps the Next standalone server as a request listener. */
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import Handoff from '../index';
|
|
2
|
+
import { BuildInputs } from './build-inputs';
|
|
2
3
|
import { FileState } from './file-state';
|
|
3
4
|
/**
|
|
4
5
|
* Cache entry for a single component
|
|
5
6
|
*/
|
|
6
7
|
export interface ComponentCacheEntry {
|
|
7
|
-
/** File states for
|
|
8
|
+
/** File states for the declared source files of this component and every file its last build read */
|
|
8
9
|
files: Record<string, FileState>;
|
|
9
10
|
/** States for template directory files (if templates is a directory) */
|
|
10
11
|
templateDirFiles?: Record<string, FileState>;
|
|
@@ -21,6 +22,18 @@ export interface GlobalDepsState {
|
|
|
21
22
|
globalScss?: FileState;
|
|
22
23
|
/** Global JS entry file state */
|
|
23
24
|
globalJs?: FileState;
|
|
25
|
+
/** Main config file state. The build hooks are declared there */
|
|
26
|
+
mainConfig?: FileState;
|
|
27
|
+
/** Profile config file state */
|
|
28
|
+
profileConfig?: FileState;
|
|
29
|
+
/** Selected profile. All profiles write to the same output, so a switch invalidates all of it */
|
|
30
|
+
profile?: string;
|
|
31
|
+
/** Lockfile state. It stands in for the files under `node_modules`, which the cache does not track */
|
|
32
|
+
lockfile?: FileState;
|
|
33
|
+
/** handoff-app version that built the output */
|
|
34
|
+
version?: string;
|
|
35
|
+
/** Base path written into the generated HTML */
|
|
36
|
+
basePath?: string;
|
|
24
37
|
}
|
|
25
38
|
/**
|
|
26
39
|
* Complete build cache structure
|
|
@@ -70,12 +83,22 @@ export declare function computeComponentFileStates(handoff: Handoff, componentId
|
|
|
70
83
|
templateDirFiles?: Record<string, FileState>;
|
|
71
84
|
}>;
|
|
72
85
|
/**
|
|
73
|
-
* Checks if a component needs to be rebuilt based on file states
|
|
86
|
+
* Checks if a component needs to be rebuilt based on file states. This also compares the files that
|
|
87
|
+
* the last build read with their current state on disk.
|
|
74
88
|
*/
|
|
75
89
|
export declare function hasComponentChanged(cached: ComponentCacheEntry | null | undefined, current: {
|
|
76
90
|
files: Record<string, FileState>;
|
|
77
91
|
templateDirFiles?: Record<string, FileState>;
|
|
78
|
-
}): boolean
|
|
92
|
+
}): Promise<boolean>;
|
|
93
|
+
/**
|
|
94
|
+
* File states for every file that the builds of a component read, or `null` when that list is
|
|
95
|
+
* incomplete and the component must not be cached.
|
|
96
|
+
*
|
|
97
|
+
* Previews compile their sources with esbuild inside a Vite plugin, so Rollup does not see those
|
|
98
|
+
* imports. The esbuild graph of each script entry supplies them. The lockfile covers the files under
|
|
99
|
+
* `node_modules`, so they are skipped, together with the generated files in the output directory.
|
|
100
|
+
*/
|
|
101
|
+
export declare function computeBuildInputStates(handoff: Handoff, componentId: string, inputs: BuildInputs): Promise<Record<string, FileState> | null>;
|
|
79
102
|
/**
|
|
80
103
|
* Checks if the component output files exist
|
|
81
104
|
*/
|
|
@@ -90,7 +113,7 @@ export declare function createEmptyCache(): BuildCache;
|
|
|
90
113
|
export declare function updateComponentCacheEntry(cache: BuildCache, componentId: string, fileStates: {
|
|
91
114
|
files: Record<string, FileState>;
|
|
92
115
|
templateDirFiles?: Record<string, FileState>;
|
|
93
|
-
}): void;
|
|
116
|
+
}, inputStates: Record<string, FileState>): void;
|
|
94
117
|
/**
|
|
95
118
|
* Removes components from cache that are no longer in runtime config
|
|
96
119
|
*/
|
|
@@ -20,26 +20,29 @@ exports.haveGlobalDepsChanged = haveGlobalDepsChanged;
|
|
|
20
20
|
exports.getComponentFilePaths = getComponentFilePaths;
|
|
21
21
|
exports.computeComponentFileStates = computeComponentFileStates;
|
|
22
22
|
exports.hasComponentChanged = hasComponentChanged;
|
|
23
|
+
exports.computeBuildInputStates = computeBuildInputStates;
|
|
23
24
|
exports.checkOutputExists = checkOutputExists;
|
|
24
25
|
exports.createEmptyCache = createEmptyCache;
|
|
25
26
|
exports.updateComponentCacheEntry = updateComponentCacheEntry;
|
|
26
27
|
exports.pruneRemovedComponents = pruneRemovedComponents;
|
|
27
28
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
28
29
|
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const build_1 = require("../transformers/utils/build");
|
|
29
31
|
const logger_1 = require("../utils/logger");
|
|
30
32
|
const path_2 = require("../utils/path");
|
|
31
33
|
const file_state_1 = require("./file-state");
|
|
32
34
|
/** Current cache format version - bump when structure changes */
|
|
33
|
-
const CACHE_VERSION = '
|
|
35
|
+
const CACHE_VERSION = '2.0.0';
|
|
36
|
+
const GLOBAL_FILE_DEPS = ['tokens', 'globalScss', 'globalJs', 'mainConfig', 'profileConfig', 'lockfile'];
|
|
37
|
+
const GLOBAL_VALUE_DEPS = ['profile', 'version', 'basePath'];
|
|
38
|
+
const LOCKFILE_NAMES = ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lock', 'bun.lockb'];
|
|
34
39
|
/**
|
|
35
40
|
* Gets the path to the build cache file
|
|
36
41
|
*/
|
|
37
42
|
function getCachePath(handoff) {
|
|
38
|
-
//
|
|
39
|
-
// the
|
|
40
|
-
|
|
41
|
-
const fileName = profile ? `build-cache.${profile}.json` : 'build-cache.json';
|
|
42
|
-
return path_1.default.resolve(handoff.modulePath, '.handoff', handoff.getProjectId(), '.cache', fileName);
|
|
43
|
+
// The cache describes the output in the working directory, so it lives there too. A build deletes
|
|
44
|
+
// the staged app under the package, so a cache there would not survive.
|
|
45
|
+
return path_1.default.resolve(handoff.workingPath, '.handoff', '.cache', 'build-cache.json');
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
48
|
* Loads the build cache from disk
|
|
@@ -99,7 +102,7 @@ function saveBuildCache(handoff, cache) {
|
|
|
99
102
|
*/
|
|
100
103
|
function computeGlobalDepsState(handoff) {
|
|
101
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
105
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
103
106
|
const result = {};
|
|
104
107
|
// tokens.json
|
|
105
108
|
const tokensPath = handoff.getTokensFilePath();
|
|
@@ -112,27 +115,61 @@ function computeGlobalDepsState(handoff) {
|
|
|
112
115
|
if ((_f = (_e = handoff.runtimeConfig) === null || _e === void 0 ? void 0 : _e.entries) === null || _f === void 0 ? void 0 : _f.js) {
|
|
113
116
|
result.globalJs = (_g = (yield (0, file_state_1.computeFileState)(handoff.runtimeConfig.entries.js))) !== null && _g !== void 0 ? _g : undefined;
|
|
114
117
|
}
|
|
118
|
+
const mainConfigPath = handoff.getMainConfigFilePath();
|
|
119
|
+
if (mainConfigPath) {
|
|
120
|
+
result.mainConfig = (_h = (yield (0, file_state_1.computeFileState)(mainConfigPath))) !== null && _h !== void 0 ? _h : undefined;
|
|
121
|
+
}
|
|
122
|
+
const profileConfigPath = handoff.getProfileConfigFilePath();
|
|
123
|
+
if (profileConfigPath) {
|
|
124
|
+
result.profileConfig = (_j = (yield (0, file_state_1.computeFileState)(profileConfigPath))) !== null && _j !== void 0 ? _j : undefined;
|
|
125
|
+
}
|
|
126
|
+
result.profile = handoff.getProfile();
|
|
127
|
+
const lockfilePath = findLockfile(handoff.workingPath);
|
|
128
|
+
if (lockfilePath) {
|
|
129
|
+
result.lockfile = (_k = (yield (0, file_state_1.computeFileState)(lockfilePath))) !== null && _k !== void 0 ? _k : undefined;
|
|
130
|
+
}
|
|
131
|
+
result.version = yield readPackageVersion(handoff);
|
|
132
|
+
result.basePath = (_l = process.env.HANDOFF_APP_BASE_PATH) !== null && _l !== void 0 ? _l : '';
|
|
115
133
|
return result;
|
|
116
134
|
});
|
|
117
135
|
}
|
|
136
|
+
/** The nearest lockfile, searched up from the working directory so that a monorepo root lockfile is found. */
|
|
137
|
+
function findLockfile(fromDirectory) {
|
|
138
|
+
for (let directory = path_1.default.resolve(fromDirectory);; directory = path_1.default.dirname(directory)) {
|
|
139
|
+
const lockfile = LOCKFILE_NAMES.map((name) => path_1.default.join(directory, name)).find((file) => fs_extra_1.default.existsSync(file));
|
|
140
|
+
if (lockfile)
|
|
141
|
+
return lockfile;
|
|
142
|
+
if (path_1.default.dirname(directory) === directory)
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function readPackageVersion(handoff) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
try {
|
|
149
|
+
return (yield fs_extra_1.default.readJson(path_1.default.resolve(handoff.modulePath, 'package.json'))).version;
|
|
150
|
+
}
|
|
151
|
+
catch (_a) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
118
156
|
/**
|
|
119
157
|
* Checks if global dependencies have changed
|
|
120
158
|
*/
|
|
121
159
|
function haveGlobalDepsChanged(cached, current) {
|
|
122
160
|
if (!cached)
|
|
123
161
|
return true;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (!(0, file_state_1.statesMatch)(cached.globalScss, current.globalScss)) {
|
|
130
|
-
logger_1.Logger.debug('Global dependency changed: global SCSS entry');
|
|
131
|
-
return true;
|
|
162
|
+
for (const key of GLOBAL_FILE_DEPS) {
|
|
163
|
+
if (!(0, file_state_1.statesMatch)(cached[key], current[key])) {
|
|
164
|
+
logger_1.Logger.debug(`Global dependency changed: ${key}`);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
132
167
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
168
|
+
for (const key of GLOBAL_VALUE_DEPS) {
|
|
169
|
+
if (cached[key] !== current[key]) {
|
|
170
|
+
logger_1.Logger.debug(`Global dependency changed: ${key}`);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
136
173
|
}
|
|
137
174
|
return false;
|
|
138
175
|
}
|
|
@@ -243,37 +280,67 @@ function computeComponentFileStates(handoff, componentId) {
|
|
|
243
280
|
});
|
|
244
281
|
}
|
|
245
282
|
/**
|
|
246
|
-
* Checks if a component needs to be rebuilt based on file states
|
|
283
|
+
* Checks if a component needs to be rebuilt based on file states. This also compares the files that
|
|
284
|
+
* the last build read with their current state on disk.
|
|
247
285
|
*/
|
|
248
286
|
function hasComponentChanged(cached, current) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
// Check regular files
|
|
253
|
-
const cachedFiles = Object.keys(cached.files);
|
|
254
|
-
const currentFiles = Object.keys(current.files);
|
|
255
|
-
// Check if file count changed
|
|
256
|
-
if (cachedFiles.length !== currentFiles.length) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
// Check if any files were added or removed
|
|
260
|
-
const cachedSet = new Set(cachedFiles);
|
|
261
|
-
for (const file of currentFiles) {
|
|
262
|
-
if (!cachedSet.has(file)) {
|
|
263
|
-
return true;
|
|
287
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
288
|
+
if (!cached) {
|
|
289
|
+
return true; // No cache entry means new component
|
|
264
290
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return true;
|
|
291
|
+
for (const [file, state] of Object.entries(current.files)) {
|
|
292
|
+
if (!(0, file_state_1.statesMatch)(cached.files[file], state)) {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
270
295
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
296
|
+
for (const [file, state] of Object.entries(cached.files)) {
|
|
297
|
+
if (!(file in current.files) && !(0, file_state_1.statesMatch)(state, yield (0, file_state_1.computeFileState)(file))) {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return !(0, file_state_1.directoryStatesMatch)(cached.templateDirFiles, current.templateDirFiles);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const SCRIPT_EXTENSIONS = new Set(['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.mts', '.cts']);
|
|
305
|
+
/**
|
|
306
|
+
* File states for every file that the builds of a component read, or `null` when that list is
|
|
307
|
+
* incomplete and the component must not be cached.
|
|
308
|
+
*
|
|
309
|
+
* Previews compile their sources with esbuild inside a Vite plugin, so Rollup does not see those
|
|
310
|
+
* imports. The esbuild graph of each script entry supplies them. The lockfile covers the files under
|
|
311
|
+
* `node_modules`, so they are skipped, together with the generated files in the output directory.
|
|
312
|
+
*/
|
|
313
|
+
function computeBuildInputStates(handoff, componentId, inputs) {
|
|
314
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
315
|
+
var _a, _b;
|
|
316
|
+
if (inputs.failed) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
const files = new Set(inputs.files);
|
|
320
|
+
const entries = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entities.components[componentId]) === null || _b === void 0 ? void 0 : _b.entries;
|
|
321
|
+
const scriptEntries = new Set(Object.values(entries !== null && entries !== void 0 ? entries : {}).filter((entry) => !!entry && SCRIPT_EXTENSIONS.has(path_1.default.extname(entry))));
|
|
322
|
+
for (const entry of scriptEntries) {
|
|
323
|
+
const moduleInputs = yield (0, build_1.collectModuleInputs)(entry, handoff);
|
|
324
|
+
if (!moduleInputs) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
for (const file of moduleInputs)
|
|
328
|
+
files.add(file);
|
|
329
|
+
}
|
|
330
|
+
const outputDirectory = path_1.default.resolve(handoff.workingPath, 'public/api/component');
|
|
331
|
+
const states = {};
|
|
332
|
+
for (const id of files) {
|
|
333
|
+
const file = id.split('?')[0];
|
|
334
|
+
if (!path_1.default.isAbsolute(file) || file.split(path_1.default.sep).includes('node_modules') || file.startsWith(outputDirectory + path_1.default.sep)) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const state = yield (0, file_state_1.computeFileState)(file);
|
|
338
|
+
if (state) {
|
|
339
|
+
states[path_1.default.resolve(file)] = state;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return states;
|
|
343
|
+
});
|
|
277
344
|
}
|
|
278
345
|
/**
|
|
279
346
|
* Checks if the component output files exist
|
|
@@ -323,9 +390,9 @@ function createEmptyCache() {
|
|
|
323
390
|
/**
|
|
324
391
|
* Updates cache entry for a specific component
|
|
325
392
|
*/
|
|
326
|
-
function updateComponentCacheEntry(cache, componentId, fileStates) {
|
|
393
|
+
function updateComponentCacheEntry(cache, componentId, fileStates, inputStates) {
|
|
327
394
|
cache.components[componentId] = {
|
|
328
|
-
files: fileStates.files,
|
|
395
|
+
files: Object.assign(Object.assign({}, inputStates), fileStates.files),
|
|
329
396
|
templateDirFiles: fileStates.templateDirFiles,
|
|
330
397
|
buildTimestamp: Date.now(),
|
|
331
398
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { InlineConfig } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* The files that the builds of one component read, so the build cache can tell when an imported
|
|
4
|
+
* file changes. A failed build can stop before it reads the file that broke it, so its list is
|
|
5
|
+
* incomplete and must not be cached.
|
|
6
|
+
*/
|
|
7
|
+
export interface BuildInputs {
|
|
8
|
+
files: Set<string>;
|
|
9
|
+
failed: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const createBuildInputs: () => BuildInputs;
|
|
12
|
+
/** Call after the consumer hooks, so that a hook that replaces `plugins` cannot drop the collector. */
|
|
13
|
+
export declare const withBuildInputs: (config: InlineConfig, inputs?: BuildInputs) => InlineConfig;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withBuildInputs = exports.createBuildInputs = void 0;
|
|
4
|
+
const createBuildInputs = () => ({ files: new Set(), failed: false });
|
|
5
|
+
exports.createBuildInputs = createBuildInputs;
|
|
6
|
+
/**
|
|
7
|
+
* Records every file that a Vite build loaded, Sass partials included. The Vite CSS plugin registers
|
|
8
|
+
* partials with `addWatchFile`, and Rollup keeps this list in every build, not only in watch mode.
|
|
9
|
+
*/
|
|
10
|
+
const collectBuildInputs = (inputs) => ({
|
|
11
|
+
name: 'handoff:collect-build-inputs',
|
|
12
|
+
buildEnd() {
|
|
13
|
+
for (const file of this.getWatchFiles())
|
|
14
|
+
inputs.files.add(file);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
/** Call after the consumer hooks, so that a hook that replaces `plugins` cannot drop the collector. */
|
|
18
|
+
const withBuildInputs = (config, inputs) => { var _a; return inputs ? Object.assign(Object.assign({}, config), { plugins: [...((_a = config.plugins) !== null && _a !== void 0 ? _a : []), collectBuildInputs(inputs)] }) : config; };
|
|
19
|
+
exports.withBuildInputs = withBuildInputs;
|
package/dist/cache/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { computeDirectoryState, computeFileState, directoryStatesMatch, statesMatch, type FileState } from './file-state';
|
|
2
|
-
export { checkOutputExists, computeComponentFileStates, computeGlobalDepsState, createEmptyCache, getCachePath, hasComponentChanged, haveGlobalDepsChanged, loadBuildCache, pruneRemovedComponents, saveBuildCache, updateComponentCacheEntry, type BuildCache, type ComponentCacheEntry, type GlobalDepsState, } from './build-cache';
|
|
2
|
+
export { checkOutputExists, computeBuildInputStates, computeComponentFileStates, computeGlobalDepsState, createEmptyCache, getCachePath, hasComponentChanged, haveGlobalDepsChanged, loadBuildCache, pruneRemovedComponents, saveBuildCache, updateComponentCacheEntry, type BuildCache, type ComponentCacheEntry, type GlobalDepsState, } from './build-cache';
|
|
3
|
+
export { createBuildInputs, type BuildInputs } from './build-inputs';
|
package/dist/cache/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateComponentCacheEntry = exports.saveBuildCache = exports.pruneRemovedComponents = exports.loadBuildCache = exports.haveGlobalDepsChanged = exports.hasComponentChanged = exports.getCachePath = exports.createEmptyCache = exports.computeGlobalDepsState = exports.computeComponentFileStates = exports.checkOutputExists = exports.statesMatch = exports.directoryStatesMatch = exports.computeFileState = exports.computeDirectoryState = void 0;
|
|
3
|
+
exports.createBuildInputs = exports.updateComponentCacheEntry = exports.saveBuildCache = exports.pruneRemovedComponents = exports.loadBuildCache = exports.haveGlobalDepsChanged = exports.hasComponentChanged = exports.getCachePath = exports.createEmptyCache = exports.computeGlobalDepsState = exports.computeComponentFileStates = exports.computeBuildInputStates = exports.checkOutputExists = exports.statesMatch = exports.directoryStatesMatch = exports.computeFileState = exports.computeDirectoryState = void 0;
|
|
4
4
|
// File state utilities
|
|
5
5
|
var file_state_1 = require("./file-state");
|
|
6
6
|
Object.defineProperty(exports, "computeDirectoryState", { enumerable: true, get: function () { return file_state_1.computeDirectoryState; } });
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "statesMatch", { enumerable: true, get: function
|
|
|
10
10
|
// Build cache utilities
|
|
11
11
|
var build_cache_1 = require("./build-cache");
|
|
12
12
|
Object.defineProperty(exports, "checkOutputExists", { enumerable: true, get: function () { return build_cache_1.checkOutputExists; } });
|
|
13
|
+
Object.defineProperty(exports, "computeBuildInputStates", { enumerable: true, get: function () { return build_cache_1.computeBuildInputStates; } });
|
|
13
14
|
Object.defineProperty(exports, "computeComponentFileStates", { enumerable: true, get: function () { return build_cache_1.computeComponentFileStates; } });
|
|
14
15
|
Object.defineProperty(exports, "computeGlobalDepsState", { enumerable: true, get: function () { return build_cache_1.computeGlobalDepsState; } });
|
|
15
16
|
Object.defineProperty(exports, "createEmptyCache", { enumerable: true, get: function () { return build_cache_1.createEmptyCache; } });
|
|
@@ -20,3 +21,6 @@ Object.defineProperty(exports, "loadBuildCache", { enumerable: true, get: functi
|
|
|
20
21
|
Object.defineProperty(exports, "pruneRemovedComponents", { enumerable: true, get: function () { return build_cache_1.pruneRemovedComponents; } });
|
|
21
22
|
Object.defineProperty(exports, "saveBuildCache", { enumerable: true, get: function () { return build_cache_1.saveBuildCache; } });
|
|
22
23
|
Object.defineProperty(exports, "updateComponentCacheEntry", { enumerable: true, get: function () { return build_cache_1.updateComponentCacheEntry; } });
|
|
24
|
+
// Build input collection
|
|
25
|
+
var build_inputs_1 = require("./build-inputs");
|
|
26
|
+
Object.defineProperty(exports, "createBuildInputs", { enumerable: true, get: function () { return build_inputs_1.createBuildInputs; } });
|
|
@@ -88,6 +88,9 @@ const normalizeCatalogItem = (moduleExports, options) => {
|
|
|
88
88
|
entries[entryKey] = path_1.default.resolve(directory, source.file);
|
|
89
89
|
// Existing builders consume template as the primary build input for every renderer.
|
|
90
90
|
entries.template = entries[entryKey];
|
|
91
|
+
// The renderer and the hydration bundle both read a preview `render` from the declaration.
|
|
92
|
+
if (options.declarationPath)
|
|
93
|
+
entries.declaration = options.declarationPath;
|
|
91
94
|
// A wrong renderer builds a broken preview without failing on its own, so a mismatch is fatal.
|
|
92
95
|
// `config/runtime.ts` turns the throw into a skipped item that retries on the next save.
|
|
93
96
|
const claim = (0, renderers_1.sourceForFile)(source.file);
|
package/dist/catalog/previews.js
CHANGED
|
@@ -8,16 +8,17 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
8
8
|
const lodash_1 = require("lodash");
|
|
9
9
|
/**
|
|
10
10
|
* A declaration module exports more than previews: the item itself, the implementation it
|
|
11
|
-
* re-exports, helper values. Accept only a plain object that owns
|
|
12
|
-
* component or helper is never mistaken for a preview.
|
|
11
|
+
* re-exports, helper values. Accept only a plain object that owns one of the preview fields, so an
|
|
12
|
+
* exported component or helper is never mistaken for a preview.
|
|
13
13
|
*
|
|
14
14
|
* `getCsfStoryEntries` does not fit here: on a CSF file every named export is a story, and on a
|
|
15
15
|
* declaration file it is not.
|
|
16
16
|
*/
|
|
17
|
+
const PREVIEW_KEYS = ['args', 'name', 'render'];
|
|
17
18
|
const isPreviewDeclaration = (value) => {
|
|
18
19
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
19
20
|
return false;
|
|
20
|
-
return
|
|
21
|
+
return PREVIEW_KEYS.some((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
21
22
|
};
|
|
22
23
|
/** Matches an exported binding, an export list, or a CommonJS export assignment. */
|
|
23
24
|
const EXPORT_PATTERNS = [
|
|
@@ -99,7 +100,7 @@ const createCatalogPreviews = (moduleExports, declarationPath) => {
|
|
|
99
100
|
throw new Error(`Preview "${exportName}" uses removed fields. Use args and name. See UPGRADE.md#catalog-items.`);
|
|
100
101
|
}
|
|
101
102
|
const preview = value;
|
|
102
|
-
previews[exportName] = Object.assign({ title: preview.name || (0, lodash_1.startCase)(exportName), values: Object.assign({}, ((_a = preview.args) !== null && _a !== void 0 ? _a : {})), url: (_b = preview.url) !== null && _b !== void 0 ? _b : '' }, (preview.usage ? { usage: preview.usage } : {}));
|
|
103
|
+
previews[exportName] = Object.assign(Object.assign({ title: preview.name || (0, lodash_1.startCase)(exportName), values: Object.assign({}, ((_a = preview.args) !== null && _a !== void 0 ? _a : {})), url: (_b = preview.url) !== null && _b !== void 0 ? _b : '' }, (preview.usage ? { usage: preview.usage } : {})), (typeof preview.render === 'function' ? { render: preview.render } : {}));
|
|
103
104
|
}
|
|
104
105
|
return declarationPath ? (0, exports.orderPreviews)(previews, (0, exports.readExportOrder)(declarationPath)) : previews;
|
|
105
106
|
};
|
package/dist/catalog/types.d.ts
CHANGED
|
@@ -43,6 +43,14 @@ export type CatalogPreview<TArgs = Record<string, unknown>> = {
|
|
|
43
43
|
args?: TArgs;
|
|
44
44
|
usage?: string;
|
|
45
45
|
url?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Renders this preview in place of the implementation, for props it cannot carry as data: an icon
|
|
48
|
+
* component, a callback, JSX children, or state the preview owns.
|
|
49
|
+
*
|
|
50
|
+
* Rendered as a component with `args`, so it can use hooks. The item still documents the
|
|
51
|
+
* implementation, so a wrapper never becomes the published API.
|
|
52
|
+
*/
|
|
53
|
+
render?: (args: TArgs) => unknown;
|
|
46
54
|
};
|
|
47
55
|
/**
|
|
48
56
|
* `__args` exists only in the type system so `Preview<typeof item>` can infer the preview argument type.
|
package/dist/cli/create.js
CHANGED
|
@@ -130,8 +130,7 @@ const renderTemplate = (content, data) => {
|
|
|
130
130
|
});
|
|
131
131
|
};
|
|
132
132
|
const getDependenciesToInstall = (options) => {
|
|
133
|
-
|
|
134
|
-
const dependencies = ['handoff-app@next'];
|
|
133
|
+
const dependencies = ['handoff-app@latest'];
|
|
135
134
|
const devDependencies = [];
|
|
136
135
|
if (options.includeExamples) {
|
|
137
136
|
dependencies.push('react', 'react-dom');
|
|
@@ -10,7 +10,7 @@ export interface BuildArgs extends SharedArgs {
|
|
|
10
10
|
* `handoff-app build [--target static|registry] [--package standalone|vercel]` — builds the
|
|
11
11
|
* documentation site for the resolved target and packages it for the resolved deliverable.
|
|
12
12
|
* `--target` selects *what* is built; the optional, additive `--package` selects *how* it is
|
|
13
|
-
* packaged. Bare `build` resolves to the static target with the `out
|
|
13
|
+
* packaged. Bare `build` resolves to the static target with the `out/static` export;
|
|
14
14
|
* `--package` never implies a `--target`.
|
|
15
15
|
*/
|
|
16
16
|
declare const command: CommandModule<{}, BuildArgs>;
|
|
@@ -18,7 +18,7 @@ const BUILD_PACKAGES = ['standalone', 'vercel'];
|
|
|
18
18
|
* `handoff-app build [--target static|registry] [--package standalone|vercel]` — builds the
|
|
19
19
|
* documentation site for the resolved target and packages it for the resolved deliverable.
|
|
20
20
|
* `--target` selects *what* is built; the optional, additive `--package` selects *how* it is
|
|
21
|
-
* packaged. Bare `build` resolves to the static target with the `out
|
|
21
|
+
* packaged. Bare `build` resolves to the static target with the `out/static` export;
|
|
22
22
|
* `--package` never implies a `--target`.
|
|
23
23
|
*/
|
|
24
24
|
const command = {
|
package/dist/commands/utils.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare const createHandoff: (args: SharedArgs, options?: Pick<HandoffOpt
|
|
|
23
23
|
* trace.
|
|
24
24
|
*/
|
|
25
25
|
export declare const runRegistryCommand: (args: SharedArgs, run: (handoff: Handoff) => Promise<unknown>) => Promise<void>;
|
|
26
|
-
export declare const getSharedOptions: (yargs: Argv) => Argv<import("yargs").Omit<{}, "debug" | "
|
|
26
|
+
export declare const getSharedOptions: (yargs: Argv) => Argv<import("yargs").Omit<{}, "debug" | "profile" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
27
27
|
config: {
|
|
28
28
|
alias: string;
|
|
29
29
|
type: "string";
|
|
@@ -45,7 +45,7 @@ export declare const getSharedOptions: (yargs: Argv) => Argv<import("yargs").Omi
|
|
|
45
45
|
};
|
|
46
46
|
}>>;
|
|
47
47
|
/** Shared options plus the transfer options: publish and its compatibility aliases use these. */
|
|
48
|
-
export declare const getPublishOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "
|
|
48
|
+
export declare const getPublishOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "profile" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
49
49
|
config: {
|
|
50
50
|
alias: string;
|
|
51
51
|
type: "string";
|
|
@@ -77,7 +77,7 @@ export declare const getPublishOptions: (yargs: Argv) => Argv<import("yargs").Om
|
|
|
77
77
|
};
|
|
78
78
|
}>>;
|
|
79
79
|
/** Shared options plus `--dry-run`: checkout and its compatibility aliases use these. */
|
|
80
|
-
export declare const getCheckoutOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "
|
|
80
|
+
export declare const getCheckoutOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "profile" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
81
81
|
config: {
|
|
82
82
|
alias: string;
|
|
83
83
|
type: "string";
|
package/dist/config/defaults.js
CHANGED
|
@@ -7,8 +7,12 @@ const connection_1 = require("../registry/connection");
|
|
|
7
7
|
const isMcpEnabled = (config) => { var _a; return ((_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.mcp) !== false; };
|
|
8
8
|
exports.isMcpEnabled = isMcpEnabled;
|
|
9
9
|
const defaultConfig = () => ({
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
integrations: {
|
|
11
|
+
figma: {
|
|
12
|
+
projectId: (0, from_env_1.fromEnv)('HANDOFF_FIGMA_PROJECT_ID', { default: null }),
|
|
13
|
+
accessToken: (0, from_env_1.fromEnv)('HANDOFF_DEV_ACCESS_TOKEN', { default: null }),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
12
16
|
runtime: {
|
|
13
17
|
mode: 'workspace',
|
|
14
18
|
registryConnection: {
|
|
@@ -16,8 +20,7 @@ const defaultConfig = () => ({
|
|
|
16
20
|
accessToken: (0, from_env_1.fromEnv)('HANDOFF_REGISTRY_ACCESS_TOKEN', { default: '' }),
|
|
17
21
|
},
|
|
18
22
|
registry: {
|
|
19
|
-
|
|
20
|
-
assetStorage: { token: (0, from_env_1.fromEnv)('BLOB_READ_WRITE_TOKEN') },
|
|
23
|
+
database: { url: (0, from_env_1.fromEnv)('DATABASE_URL') },
|
|
21
24
|
},
|
|
22
25
|
},
|
|
23
26
|
exportsOutputDirectory: (0, from_env_1.fromEnv)('HANDOFF_OUTPUT_DIR', { default: 'exported' }),
|
|
@@ -22,3 +22,7 @@ export declare const fromEnv: <T = string>(name: string, options?: {
|
|
|
22
22
|
default: T;
|
|
23
23
|
}) => EnvReference<T>;
|
|
24
24
|
export declare const isEnvReference: (value: unknown) => value is EnvReference<unknown>;
|
|
25
|
+
/** Replace each reference nested in `options` with its value from `env`. An unset or empty variable becomes `undefined`. */
|
|
26
|
+
export declare const resolveEnvReferences: (options: Record<string, unknown>, env: NodeJS.ProcessEnv) => Record<string, unknown>;
|
|
27
|
+
/** The variable names that the references nested in `options` use, for deployment instructions. */
|
|
28
|
+
export declare const envReferenceNames: (options: Record<string, unknown>) => string[];
|
package/dist/config/from-env.js
CHANGED
|
@@ -1,7 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isEnvReference = exports.fromEnv = void 0;
|
|
3
|
+
exports.envReferenceNames = exports.resolveEnvReferences = exports.isEnvReference = exports.fromEnv = void 0;
|
|
4
4
|
const fromEnv = (name, options) => options === undefined ? { $env: name } : { $env: name, default: options.default };
|
|
5
5
|
exports.fromEnv = fromEnv;
|
|
6
6
|
const isEnvReference = (value) => value !== null && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, '$env');
|
|
7
7
|
exports.isEnvReference = isEnvReference;
|
|
8
|
+
const isPlainRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
9
|
+
/** Replace each reference nested in `options` with its value from `env`. An unset or empty variable becomes `undefined`. */
|
|
10
|
+
const resolveEnvReferences = (options, env) => {
|
|
11
|
+
const resolve = (value) => {
|
|
12
|
+
var _a;
|
|
13
|
+
if ((0, exports.isEnvReference)(value)) {
|
|
14
|
+
const resolved = typeof value.$env === 'string' ? (_a = env[value.$env]) === null || _a === void 0 ? void 0 : _a.trim() : undefined;
|
|
15
|
+
return resolved || undefined;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(value))
|
|
18
|
+
return value.map(resolve);
|
|
19
|
+
if (isPlainRecord(value))
|
|
20
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolve(entry)]));
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
return resolve(options);
|
|
24
|
+
};
|
|
25
|
+
exports.resolveEnvReferences = resolveEnvReferences;
|
|
26
|
+
/** The variable names that the references nested in `options` use, for deployment instructions. */
|
|
27
|
+
const envReferenceNames = (options) => {
|
|
28
|
+
const names = new Set();
|
|
29
|
+
const collect = (value) => {
|
|
30
|
+
if ((0, exports.isEnvReference)(value)) {
|
|
31
|
+
if (typeof value.$env === 'string')
|
|
32
|
+
names.add(value.$env);
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(value)) {
|
|
35
|
+
value.forEach(collect);
|
|
36
|
+
}
|
|
37
|
+
else if (isPlainRecord(value)) {
|
|
38
|
+
Object.values(value).forEach(collect);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
collect(options);
|
|
42
|
+
return [...names];
|
|
43
|
+
};
|
|
44
|
+
exports.envReferenceNames = envReferenceNames;
|
package/dist/config/helpers.js
CHANGED
|
@@ -19,8 +19,8 @@ const normalizeAppConfig = (app) => {
|
|
|
19
19
|
return Object.assign(Object.assign({}, rest), { google_tag_manager: googleTagManager !== null && googleTagManager !== void 0 ? googleTagManager : app.google_tag_manager, type_copy: typeCopy !== null && typeCopy !== void 0 ? typeCopy : app.type_copy, type_sort: typeSort !== null && typeSort !== void 0 ? typeSort : app.type_sort, color_sort: colorSort !== null && colorSort !== void 0 ? colorSort : app.color_sort, component_sort: componentSort !== null && componentSort !== void 0 ? componentSort : app.component_sort, base_path: basePath !== null && basePath !== void 0 ? basePath : app.base_path });
|
|
20
20
|
};
|
|
21
21
|
const normalizeConfig = (config) => {
|
|
22
|
-
const {
|
|
23
|
-
return Object.assign(Object.assign({}, rest), {
|
|
22
|
+
const { assetsZipLinks, app } = config, rest = __rest(config, ["assetsZipLinks", "app"]);
|
|
23
|
+
return Object.assign(Object.assign({}, rest), { assets_zip_links: assetsZipLinks !== null && assetsZipLinks !== void 0 ? assetsZipLinks : config.assets_zip_links, app: normalizeAppConfig(app) });
|
|
24
24
|
};
|
|
25
25
|
exports.normalizeConfig = normalizeConfig;
|
|
26
26
|
/**
|
package/dist/config/index.d.ts
CHANGED
|
@@ -5,6 +5,5 @@ export { CONFIG_FILE_PREFERENCE, HandoffConfigError, initConfig, initConfigWithM
|
|
|
5
5
|
export type { ConfigLoadContext } from './loader';
|
|
6
6
|
export { defineConfig } from './helpers';
|
|
7
7
|
export { initRuntimeConfig } from './runtime';
|
|
8
|
-
export { validateConfig } from './validator';
|
|
9
8
|
export { addToCatalog, isIncluded } from './catalog-include';
|
|
10
9
|
export type { AddToCatalogResult } from './catalog-include';
|
package/dist/config/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isIncluded = exports.addToCatalog = exports.
|
|
3
|
+
exports.isIncluded = exports.addToCatalog = exports.initRuntimeConfig = exports.defineConfig = exports.resolveProfileSelection = exports.initConfigWithMetadata = exports.initConfig = exports.HandoffConfigError = exports.CONFIG_FILE_PREFERENCE = exports.loadProfileEnv = exports.isMcpEnabled = exports.getClientConfig = exports.defaultConfig = void 0;
|
|
4
4
|
// Config defaults and client config
|
|
5
5
|
var defaults_1 = require("./defaults");
|
|
6
6
|
Object.defineProperty(exports, "defaultConfig", { enumerable: true, get: function () { return defaults_1.defaultConfig; } });
|
|
@@ -22,9 +22,6 @@ Object.defineProperty(exports, "defineConfig", { enumerable: true, get: function
|
|
|
22
22
|
// Runtime config resolution
|
|
23
23
|
var runtime_1 = require("./runtime");
|
|
24
24
|
Object.defineProperty(exports, "initRuntimeConfig", { enumerable: true, get: function () { return runtime_1.initRuntimeConfig; } });
|
|
25
|
-
// Config validation
|
|
26
|
-
var validator_1 = require("./validator");
|
|
27
|
-
Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return validator_1.validateConfig; } });
|
|
28
25
|
// Registering catalog item directories under `catalog.include`
|
|
29
26
|
var catalog_include_1 = require("./catalog-include");
|
|
30
27
|
Object.defineProperty(exports, "addToCatalog", { enumerable: true, get: function () { return catalog_include_1.addToCatalog; } });
|