handoff-app 2.0.0-5 → 2.0.0-7
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 +174 -41
- package/UPGRADE.md +198 -0
- package/config/config.template.js +1 -4
- package/config/config.template.ts +1 -2
- package/dist/app-builder/build.js +11 -6
- package/dist/app-builder/client-config.js +1 -0
- package/dist/app-builder/config-diff/strategies/pattern.js +3 -3
- package/dist/app-builder/watchers/component.js +5 -5
- package/dist/app-builder/watchers/utils.d.ts +2 -3
- package/dist/app-builder/watchers.d.ts +8 -15
- package/dist/app-builder/watchers.js +53 -54
- package/dist/cache/build-cache.js +18 -22
- package/dist/catalog/define.d.ts +6 -0
- package/dist/catalog/define.js +72 -0
- package/dist/catalog/implementation.d.ts +27 -0
- package/dist/catalog/implementation.js +133 -0
- package/dist/catalog/index.d.ts +6 -0
- package/dist/catalog/index.js +22 -0
- package/dist/catalog/normalize.d.ts +16 -0
- package/dist/catalog/normalize.js +115 -0
- package/dist/catalog/previews.d.ts +18 -0
- package/dist/catalog/previews.js +106 -0
- package/dist/catalog/renderers.d.ts +43 -0
- package/dist/catalog/renderers.js +62 -0
- package/dist/catalog/types.d.ts +63 -0
- package/dist/cli/make.d.ts +0 -5
- package/dist/cli/make.js +22 -67
- package/dist/cli/scaffold.js +25 -33
- package/dist/commands/checkout/index.d.ts +7 -4
- package/dist/commands/checkout/index.js +9 -6
- package/dist/commands/compat/push-args.d.ts +2 -2
- package/dist/commands/index.js +0 -2
- package/dist/commands/publish/index.d.ts +9 -6
- package/dist/commands/publish/index.js +11 -8
- package/dist/commands/pull/index.js +1 -1
- package/dist/commands/push/index.js +1 -1
- package/dist/commands/utils.d.ts +15 -4
- package/dist/commands/utils.js +19 -6
- package/dist/config/catalog-include.d.ts +43 -0
- package/dist/config/catalog-include.js +203 -0
- package/dist/config/defaults.d.ts +2 -0
- package/dist/config/defaults.js +4 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.js +6 -5
- package/dist/config/loader.js +9 -1
- package/dist/config/runtime.d.ts +5 -6
- package/dist/config/runtime.js +154 -154
- package/dist/handlebars.d.ts +9 -0
- package/dist/handlebars.js +16 -0
- package/dist/index.d.ts +15 -4
- package/dist/index.js +29 -15
- package/dist/pattern.d.ts +7 -0
- package/dist/pattern.js +13 -0
- package/dist/react.d.ts +43 -0
- package/dist/react.js +11 -0
- package/dist/registry/asset-storage/define.d.ts +1 -1
- package/dist/registry/asset-storage/define.js +1 -1
- package/dist/registry/checkout/index.d.ts +9 -0
- package/dist/registry/checkout/index.js +335 -149
- package/dist/registry/db/schema.d.ts +34 -0
- package/dist/registry/db/schema.js +2 -0
- package/dist/registry/publish/index.d.ts +13 -2
- package/dist/registry/publish/index.js +109 -25
- package/dist/registry/publish/package.js +14 -1
- package/dist/registry/selection.d.ts +20 -0
- package/dist/registry/selection.js +37 -1
- package/dist/store/filesystem.d.ts +1 -1
- package/dist/store/filesystem.js +7 -7
- package/dist/store/registry.js +24 -3
- package/dist/transformers/plugins/csf-render.js +4 -2
- package/dist/transformers/plugins/ssr-render.js +14 -5
- package/dist/transformers/preview/component/api.d.ts +8 -0
- package/dist/transformers/preview/component/api.js +11 -15
- package/dist/transformers/preview/component/artifacts.d.ts +1 -1
- package/dist/transformers/preview/component/artifacts.js +11 -7
- package/dist/transformers/preview/component/builder.js +15 -18
- package/dist/transformers/preview/component/css.d.ts +2 -0
- package/dist/transformers/preview/component/css.js +8 -11
- package/dist/transformers/preview/component/html.js +18 -16
- package/dist/transformers/preview/component/javascript.js +2 -4
- package/dist/transformers/preview/pattern/builder.js +31 -18
- package/dist/transformers/preview/types.d.ts +15 -1
- package/dist/types/config.d.ts +36 -11
- package/docs/api.md +3 -0
- package/docs/cli.md +1 -1
- package/drizzle/0006_add_component_source_format.sql +3 -0
- package/drizzle/meta/0006_snapshot.json +1941 -0
- package/drizzle/meta/_journal.json +8 -1
- package/package.json +37 -2
- package/src/app/components/Component/Preview.tsx +36 -50
- package/src/app/components/CopyToClipboard.tsx +27 -26
- package/src/app/components/Layout/Header.tsx +4 -12
- package/src/app/components/Layout/RuntimeModeBadge.tsx +18 -0
- package/src/app/components/Markdown/CodeHighlight.tsx +73 -70
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +349 -0
- package/src/app/components/McpIntegration/McpIcon.tsx +10 -0
- package/src/app/components/Navigation/MobileNav.tsx +3 -1
- package/src/app/components/context/PreviewContext.tsx +5 -5
- package/src/app/components/ui/dialog.tsx +73 -0
- package/src/app/components/util/index.ts +7 -15
- package/src/app/lib/docs-api/backend.ts +5 -1
- package/src/app/lib/docs-api/page-discovery.ts +1 -6
- package/src/app/lib/docs-api/page-rendering.ts +21 -1
- package/src/app/lib/docs-api/records.ts +25 -10
- package/src/app/lib/docs-api/registry.ts +4 -2
- package/src/app/lib/docs-api/runtime-config.ts +5 -0
- package/src/app/lib/docs-api/search.ts +7 -2
- package/src/app/lib/mcp/auth.ts +64 -0
- package/src/app/lib/mcp/index.ts +2 -0
- package/src/app/lib/mcp/server.ts +343 -0
- package/src/app/lib/mcp/shape.ts +596 -0
- package/src/app/lib/registry-api/transfer.ts +7 -5
- package/src/app/next.config.mjs +3 -0
- package/src/app/pages/[...slug]/index.tsx +16 -30
- package/src/app/pages/api/mcp.ts +56 -0
- package/src/app/pages/index.tsx +10 -9
- package/src/app-builder/build.ts +12 -8
- package/src/app-builder/client-config.ts +2 -1
- package/src/app-builder/config-diff/strategies/pattern.ts +1 -1
- package/src/app-builder/watchers/component.ts +3 -3
- package/src/app-builder/watchers/utils.ts +2 -3
- package/src/app-builder/watchers.ts +46 -50
- package/src/cache/build-cache.ts +11 -14
- package/src/catalog/README.md +92 -0
- package/src/catalog/define.ts +79 -0
- package/src/catalog/implementation.ts +145 -0
- package/src/catalog/index.ts +31 -0
- package/src/catalog/normalize.ts +143 -0
- package/src/catalog/previews.ts +111 -0
- package/src/catalog/renderers.ts +94 -0
- package/src/catalog/types.ts +74 -0
- package/src/cli/README.md +1 -1
- package/src/cli/make.ts +20 -72
- package/src/cli/scaffold.ts +25 -31
- package/src/commands/README.md +1 -1
- package/src/commands/checkout/index.ts +17 -7
- package/src/commands/compat/push-args.ts +2 -2
- package/src/commands/index.ts +0 -2
- package/src/commands/publish/index.ts +19 -9
- package/src/commands/pull/index.ts +2 -2
- package/src/commands/push/index.ts +2 -2
- package/src/commands/utils.ts +22 -7
- package/src/config/README.md +2 -1
- package/src/config/catalog-include.ts +227 -0
- package/src/config/defaults.ts +3 -0
- package/src/config/index.ts +4 -4
- package/src/config/loader.ts +12 -0
- package/src/config/runtime.ts +186 -191
- package/src/handlebars.ts +18 -0
- package/src/index.ts +39 -26
- package/src/pattern.ts +14 -0
- package/src/react.ts +52 -0
- package/src/registry/asset-storage/define.ts +1 -1
- package/src/registry/checkout/index.ts +416 -152
- package/src/registry/db/schema.ts +2 -0
- package/src/registry/publish/index.ts +123 -26
- package/src/registry/publish/package.ts +14 -1
- package/src/registry/selection.ts +44 -0
- package/src/store/filesystem.ts +4 -4
- package/src/store/registry.ts +13 -2
- package/src/transformers/plugins/csf-render.ts +4 -2
- package/src/transformers/plugins/ssr-render.ts +15 -5
- package/src/transformers/preview/component/api.ts +13 -1
- package/src/transformers/preview/component/artifacts.ts +8 -4
- package/src/transformers/preview/component/builder.ts +17 -4
- package/src/transformers/preview/component/css.ts +6 -10
- package/src/transformers/preview/component/html.ts +30 -19
- package/src/transformers/preview/component/javascript.ts +1 -3
- package/src/transformers/preview/pattern/builder.ts +33 -20
- package/src/transformers/preview/types.ts +15 -1
- package/src/types/config.ts +38 -11
- package/templates/default/README.md.tpl +10 -0
- package/templates/default/components/button/button.react.handoff.js.tpl +19 -23
- package/templates/default/components/button/button.react.handoff.ts.tpl +22 -22
- package/templates/default/handoff.config.js.tpl +11 -18
- package/templates/default/handoff.config.ts.tpl +11 -18
- package/templates/default/handoff.config.with-examples.js.tpl +12 -16
- package/templates/default/handoff.config.with-examples.ts.tpl +12 -16
- package/config/templates/component/template.json +0 -49
- package/config/templates/template.html +0 -7
- package/dist/commands/make/template.d.ts +0 -8
- package/dist/commands/make/template.js +0 -43
- package/dist/config/entries.d.ts +0 -47
- package/dist/config/entries.js +0 -162
- package/dist/config/normalizers/declaration.d.ts +0 -11
- package/dist/config/normalizers/declaration.js +0 -122
- package/dist/config/normalizers/pattern.d.ts +0 -8
- package/dist/config/normalizers/pattern.js +0 -41
- package/dist/declarations/helpers.d.ts +0 -6
- package/dist/declarations/helpers.js +0 -19
- package/dist/declarations/index.d.ts +0 -2
- package/dist/declarations/index.js +0 -9
- package/dist/declarations/types.d.ts +0 -60
- package/src/commands/make/template.ts +0 -46
- package/src/config/entries.ts +0 -175
- package/src/config/normalizers/declaration.ts +0 -179
- package/src/config/normalizers/pattern.ts +0 -59
- package/src/declarations/helpers.ts +0 -36
- package/src/declarations/index.ts +0 -19
- package/src/declarations/types.ts +0 -70
- /package/dist/{declarations → catalog}/types.js +0 -0
package/dist/config/defaults.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getClientConfig = exports.defaultConfig = void 0;
|
|
3
|
+
exports.getClientConfig = exports.defaultConfig = exports.isMcpEnabled = void 0;
|
|
4
4
|
const connection_1 = require("../registry/connection");
|
|
5
|
+
/** Whether the MCP endpoint is served. On unless `runtime.mcp` is explicitly `false`. */
|
|
6
|
+
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; };
|
|
7
|
+
exports.isMcpEnabled = isMcpEnabled;
|
|
5
8
|
const defaultConfig = () => {
|
|
6
9
|
var _a, _b, _c, _d;
|
|
7
10
|
return ({
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { defaultConfig, getClientConfig } from './defaults';
|
|
1
|
+
export { defaultConfig, getClientConfig, isMcpEnabled } from './defaults';
|
|
2
2
|
export type { ImageStyle } from './defaults';
|
|
3
3
|
export { HandoffConfigError, initConfig, initConfigWithMetadata } from './loader';
|
|
4
4
|
export type { ConfigLoadContext } from './loader';
|
|
5
5
|
export { defineConfig } from './helpers';
|
|
6
6
|
export { initRuntimeConfig } from './runtime';
|
|
7
7
|
export { validateConfig } from './validator';
|
|
8
|
-
export {
|
|
9
|
-
export type {
|
|
8
|
+
export { addToCatalog, isIncluded } from './catalog-include';
|
|
9
|
+
export type { AddToCatalogResult } from './catalog-include';
|
package/dist/config/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isIncluded = exports.addToCatalog = exports.validateConfig = exports.initRuntimeConfig = exports.defineConfig = exports.initConfigWithMetadata = exports.initConfig = exports.HandoffConfigError = 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; } });
|
|
7
7
|
Object.defineProperty(exports, "getClientConfig", { enumerable: true, get: function () { return defaults_1.getClientConfig; } });
|
|
8
|
+
Object.defineProperty(exports, "isMcpEnabled", { enumerable: true, get: function () { return defaults_1.isMcpEnabled; } });
|
|
8
9
|
// Config file loading
|
|
9
10
|
var loader_1 = require("./loader");
|
|
10
11
|
Object.defineProperty(exports, "HandoffConfigError", { enumerable: true, get: function () { return loader_1.HandoffConfigError; } });
|
|
@@ -19,7 +20,7 @@ Object.defineProperty(exports, "initRuntimeConfig", { enumerable: true, get: fun
|
|
|
19
20
|
// Config validation
|
|
20
21
|
var validator_1 = require("./validator");
|
|
21
22
|
Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return validator_1.validateConfig; } });
|
|
22
|
-
// Registering
|
|
23
|
-
var
|
|
24
|
-
Object.defineProperty(exports, "
|
|
25
|
-
Object.defineProperty(exports, "
|
|
23
|
+
// Registering catalog item directories under `catalog.include`
|
|
24
|
+
var catalog_include_1 = require("./catalog-include");
|
|
25
|
+
Object.defineProperty(exports, "addToCatalog", { enumerable: true, get: function () { return catalog_include_1.addToCatalog; } });
|
|
26
|
+
Object.defineProperty(exports, "isIncluded", { enumerable: true, get: function () { return catalog_include_1.isIncluded; } });
|
package/dist/config/loader.js
CHANGED
|
@@ -104,7 +104,7 @@ const resolveConfigFilePath = (workingPath, requestedPath) => {
|
|
|
104
104
|
* Loads the handoff configuration for the given working directory and returns metadata.
|
|
105
105
|
*/
|
|
106
106
|
const initConfigWithMetadata = (configOverride, context) => {
|
|
107
|
-
var _a;
|
|
107
|
+
var _a, _b, _c;
|
|
108
108
|
let config = {};
|
|
109
109
|
const { selected: configPath, ignored } = resolveConfigFilePath((_a = context === null || context === void 0 ? void 0 : context.workingPath) !== null && _a !== void 0 ? _a : (0, path_2.resolveWorkingPath)(), context === null || context === void 0 ? void 0 : context.configPath);
|
|
110
110
|
if (ignored.length > 0 && configPath) {
|
|
@@ -123,6 +123,14 @@ const initConfigWithMetadata = (configOverride, context) => {
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
|
+
const entries = config.entries;
|
|
127
|
+
if (entries && ('components' in entries || 'patterns' in entries)) {
|
|
128
|
+
throw new HandoffConfigError('entries.components and entries.patterns were removed. Use catalog.include. See UPGRADE.md#catalog-items.');
|
|
129
|
+
}
|
|
130
|
+
const format = (_c = (_b = config.runtime) === null || _b === void 0 ? void 0 : _b.workspace) === null || _c === void 0 ? void 0 : _c.declarationFormat;
|
|
131
|
+
if (format !== undefined && !['ts', 'js', 'cjs'].includes(format)) {
|
|
132
|
+
throw new HandoffConfigError('Item declarations support ts, js, and cjs. Convert JSON declarations to defineCatalogItem. See UPGRADE.md#catalog-items.');
|
|
133
|
+
}
|
|
126
134
|
const defaults = (0, defaults_1.defaultConfig)();
|
|
127
135
|
// Top-level merge stays shallow to preserve 1.x semantics, except for the `runtime`
|
|
128
136
|
// block which is deep-merged so a partial user `runtime` (e.g. only `mode`) does not
|
package/dist/config/runtime.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ type DeclarationResolution = {
|
|
|
12
12
|
fileName: string;
|
|
13
13
|
};
|
|
14
14
|
export declare const resolveComponentDeclaration: (componentDir: string, componentBaseName: string) => DeclarationResolution | null;
|
|
15
|
+
/**
|
|
16
|
+
* Expands catalog.include into item directories and removes duplicate paths.
|
|
17
|
+
*/
|
|
18
|
+
export declare const getCatalogItemDirectories: (config: Config, workingPath: string) => string[];
|
|
15
19
|
/**
|
|
16
20
|
* Initializes the runtime configuration by resolving component entries,
|
|
17
21
|
* SCSS/JS paths, and transformer options from the handoff config.
|
|
@@ -22,7 +26,7 @@ export declare const resolveComponentDeclaration: (componentDir: string, compone
|
|
|
22
26
|
export declare const initRuntimeConfig: (handoff: HandoffContext) => [runtimeConfig: RuntimeConfig, configs: string[], configFileIndex: Map<string, ConfigFileEntry>];
|
|
23
27
|
/**
|
|
24
28
|
* True when `searchPath` is itself a single component directory: it holds a declaration file named
|
|
25
|
-
*
|
|
29
|
+
* with a .handoff.ts, .handoff.js, or .handoff.cjs suffix. This is what
|
|
26
30
|
* separates a declared component from a collection directory.
|
|
27
31
|
*/
|
|
28
32
|
export declare const isComponentDirectory: (searchPath: string) => boolean;
|
|
@@ -34,11 +38,6 @@ export declare const isComponentDirectory: (searchPath: string) => boolean;
|
|
|
34
38
|
* @returns Paths to the component directories.
|
|
35
39
|
*/
|
|
36
40
|
export declare const getComponentsForPath: (searchPath: string) => string[];
|
|
37
|
-
/**
|
|
38
|
-
* Generic directory discovery for both components and patterns.
|
|
39
|
-
* Reuses the same logic as getComponentsForPath.
|
|
40
|
-
*/
|
|
41
|
-
export declare const getItemsForPath: (searchPath: string) => string[];
|
|
42
41
|
/**
|
|
43
42
|
* Recursively converts all keys and string values in an object to lowercase.
|
|
44
43
|
*/
|
package/dist/config/runtime.js
CHANGED
|
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.toLowerCaseKeysAndValues = exports.
|
|
6
|
+
exports.toLowerCaseKeysAndValues = exports.getComponentsForPath = exports.isComponentDirectory = exports.initRuntimeConfig = exports.getCatalogItemDirectories = exports.resolveComponentDeclaration = void 0;
|
|
7
7
|
const esbuild_1 = __importDefault(require("esbuild"));
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
9
|
const module_1 = require("module");
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const catalog_1 = require("../catalog");
|
|
11
12
|
const content_kinds_1 = require("../registry/content-kinds");
|
|
12
13
|
const csf_1 = require("../transformers/utils/csf");
|
|
13
14
|
const module_2 = require("../transformers/utils/module");
|
|
@@ -15,51 +16,31 @@ const logger_1 = require("../utils/logger");
|
|
|
15
16
|
const markdown_1 = require("../utils/markdown");
|
|
16
17
|
const pages_1 = require("../utils/pages");
|
|
17
18
|
const path_2 = require("../utils/path");
|
|
18
|
-
const declaration_1 = require("./normalizers/declaration");
|
|
19
19
|
const page_1 = require("./normalizers/page");
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
`${componentBaseName}.js`,
|
|
25
|
-
`${componentBaseName}.cjs`,
|
|
26
|
-
];
|
|
27
|
-
const getModernDeclarationFiles = (componentBaseName) => MODERN_EXTENSIONS.map((ext) => `${componentBaseName}.handoff.${ext}`);
|
|
28
|
-
const findPreferredModernDeclaration = (componentDir, componentBaseName) => {
|
|
29
|
-
const exactCandidates = getModernDeclarationFiles(componentBaseName);
|
|
20
|
+
const DECLARATION_EXTENSIONS = ['ts', 'js', 'cjs'];
|
|
21
|
+
const getDeclarationFiles = (componentBaseName) => DECLARATION_EXTENSIONS.map((ext) => `${componentBaseName}.handoff.${ext}`);
|
|
22
|
+
const findPreferredDeclaration = (componentDir, componentBaseName) => {
|
|
23
|
+
const exactCandidates = getDeclarationFiles(componentBaseName);
|
|
30
24
|
const exactMatch = exactCandidates.find((candidate) => fs_extra_1.default.existsSync(path_1.default.resolve(componentDir, candidate)));
|
|
31
25
|
if (exactMatch)
|
|
32
26
|
return exactMatch;
|
|
33
27
|
const allFiles = fs_extra_1.default.existsSync(componentDir) ? fs_extra_1.default.readdirSync(componentDir) : [];
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
.sort((a, b) => a.localeCompare(b));
|
|
37
|
-
if (!modernFiles.length)
|
|
28
|
+
const declarationFiles = allFiles.filter((file) => /\.handoff\.(ts|js|cjs)$/.test(file)).sort((a, b) => a.localeCompare(b));
|
|
29
|
+
if (!declarationFiles.length)
|
|
38
30
|
return undefined;
|
|
39
|
-
for (const ext of
|
|
40
|
-
const extMatch =
|
|
31
|
+
for (const ext of DECLARATION_EXTENSIONS) {
|
|
32
|
+
const extMatch = declarationFiles.find((file) => file.endsWith(`.handoff.${ext}`));
|
|
41
33
|
if (extMatch)
|
|
42
34
|
return extMatch;
|
|
43
35
|
}
|
|
44
|
-
return
|
|
36
|
+
return declarationFiles[0];
|
|
45
37
|
};
|
|
46
38
|
const resolveComponentDeclaration = (componentDir, componentBaseName) => {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const legacyMatch = legacyFiles.find((candidate) => fs_extra_1.default.existsSync(path_1.default.resolve(componentDir, candidate)));
|
|
50
|
-
if (modernMatch) {
|
|
51
|
-
if (legacyMatch) {
|
|
52
|
-
logger_1.Logger.warn(`Both modern and legacy declarations found in "${componentDir}". Using "${modernMatch}" and ignoring "${legacyMatch}".`);
|
|
53
|
-
}
|
|
54
|
-
return { fileName: modernMatch };
|
|
55
|
-
}
|
|
56
|
-
if (legacyMatch) {
|
|
57
|
-
return { fileName: legacyMatch };
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
39
|
+
const declarationMatch = findPreferredDeclaration(componentDir, componentBaseName);
|
|
40
|
+
return declarationMatch ? { fileName: declarationMatch } : null;
|
|
60
41
|
};
|
|
61
42
|
exports.resolveComponentDeclaration = resolveComponentDeclaration;
|
|
62
|
-
const
|
|
43
|
+
const evaluateDeclaration = (filePath, handoffModulePath) => {
|
|
63
44
|
var _a, _b;
|
|
64
45
|
const buildResult = esbuild_1.default.buildSync({
|
|
65
46
|
entryPoints: [filePath],
|
|
@@ -91,26 +72,16 @@ const evaluateTypeScriptDeclaration = (filePath, handoffModulePath) => {
|
|
|
91
72
|
evaluator(runtimeRequire, mod, mod.exports, filePath, path_1.default.dirname(filePath));
|
|
92
73
|
return mod.exports;
|
|
93
74
|
};
|
|
94
|
-
const loadDeclarationFile =
|
|
95
|
-
if (filePath.endsWith('.json')) {
|
|
96
|
-
const componentJson = fs_extra_1.default.readFileSync(filePath, 'utf8');
|
|
97
|
-
return JSON.parse(componentJson);
|
|
98
|
-
}
|
|
99
|
-
if (filePath.endsWith('.ts')) {
|
|
100
|
-
return evaluateTypeScriptDeclaration(filePath, handoffModulePath);
|
|
101
|
-
}
|
|
102
|
-
// Invalidate require cache to ensure fresh read
|
|
103
|
-
delete require.cache[require.resolve(filePath)];
|
|
104
|
-
return require(filePath);
|
|
105
|
-
};
|
|
75
|
+
const loadDeclarationFile = evaluateDeclaration;
|
|
106
76
|
const discoverCsfPreviews = (component, handoff) => {
|
|
107
77
|
var _a;
|
|
108
|
-
if (component.
|
|
78
|
+
if (component.sourceFormat !== 'csf' || !((_a = component.entries) === null || _a === void 0 ? void 0 : _a.template)) {
|
|
109
79
|
return component.previews;
|
|
110
80
|
}
|
|
111
81
|
try {
|
|
112
82
|
const loaded = (0, module_2.buildAndEvaluateModuleSync)(component.entries.template, handoff);
|
|
113
|
-
|
|
83
|
+
// esbuild emits its export map alphabetically, so story order comes from the source text.
|
|
84
|
+
const discoveredPreviews = (0, catalog_1.orderPreviews)((0, csf_1.createCsfStoryPreviews)(loaded.exports), (0, catalog_1.readExportOrder)(component.entries.template));
|
|
114
85
|
if (Object.keys(discoveredPreviews).length === 0) {
|
|
115
86
|
logger_1.Logger.warn(`No named stories found in CSF file for "${component.id}": ${component.entries.template}`);
|
|
116
87
|
return component.previews;
|
|
@@ -123,6 +94,49 @@ const discoverCsfPreviews = (component, handoff) => {
|
|
|
123
94
|
return component.previews;
|
|
124
95
|
}
|
|
125
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Expands catalog.include into item directories and removes duplicate paths.
|
|
99
|
+
*/
|
|
100
|
+
const getCatalogItemDirectories = (config, workingPath) => {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
const registered = [...((_b = (_a = config.catalog) === null || _a === void 0 ? void 0 : _a.include) !== null && _b !== void 0 ? _b : [])];
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
const directories = [];
|
|
105
|
+
for (const included of registered) {
|
|
106
|
+
for (const directory of (0, exports.getComponentsForPath)(path_1.default.resolve(workingPath, included))) {
|
|
107
|
+
const key = (0, path_2.normalizePathForCompare)(directory);
|
|
108
|
+
if (seen.has(key))
|
|
109
|
+
continue;
|
|
110
|
+
seen.add(key);
|
|
111
|
+
directories.push(directory);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return directories;
|
|
115
|
+
};
|
|
116
|
+
exports.getCatalogItemDirectories = getCatalogItemDirectories;
|
|
117
|
+
/**
|
|
118
|
+
* Records the React component a CSF file documents, so it is watched, documented, and published.
|
|
119
|
+
* `csf-render` reads `meta.component` as a value; only the source text says which file it came
|
|
120
|
+
* from. A component outside the item directory is left unrecorded, because publish rejects a
|
|
121
|
+
* source path that escapes the entity directory.
|
|
122
|
+
*/
|
|
123
|
+
const resolveCsfComponentSource = (component) => {
|
|
124
|
+
var _a, _b;
|
|
125
|
+
if (component.sourceFormat !== 'csf')
|
|
126
|
+
return;
|
|
127
|
+
const storyPath = (_a = component.entries) === null || _a === void 0 ? void 0 : _a.story;
|
|
128
|
+
if (!storyPath || ((_b = component.entries) === null || _b === void 0 ? void 0 : _b.component))
|
|
129
|
+
return;
|
|
130
|
+
const resolved = (0, catalog_1.resolvePropertySource)(storyPath, 'component');
|
|
131
|
+
if (!resolved)
|
|
132
|
+
return;
|
|
133
|
+
if (!(0, catalog_1.isInsideDirectory)(resolved.file, component.path)) {
|
|
134
|
+
logger_1.Logger.warn(`Catalog item "${component.id}" documents a component at "${resolved.file}", outside "${component.path}". ` +
|
|
135
|
+
`Previews still build, but that file is not published. Move it into the item directory to publish it.`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
component.entries.component = resolved.file;
|
|
139
|
+
};
|
|
126
140
|
/**
|
|
127
141
|
* Initializes the runtime configuration by resolving component entries,
|
|
128
142
|
* SCSS/JS paths, and transformer options from the handoff config.
|
|
@@ -131,8 +145,8 @@ const discoverCsfPreviews = (component, handoff) => {
|
|
|
131
145
|
* @returns A tuple of [RuntimeConfig, configFilePaths, configFileIndex].
|
|
132
146
|
*/
|
|
133
147
|
const initRuntimeConfig = (handoff) => {
|
|
134
|
-
var _a, _b, _c, _d, _e, _f
|
|
135
|
-
var
|
|
148
|
+
var _a, _b, _c, _d, _e, _f;
|
|
149
|
+
var _g;
|
|
136
150
|
const configFiles = [];
|
|
137
151
|
const configFileIndex = new Map();
|
|
138
152
|
const result = {
|
|
@@ -140,103 +154,96 @@ const initRuntimeConfig = (handoff) => {
|
|
|
140
154
|
entries: {
|
|
141
155
|
scss: undefined,
|
|
142
156
|
js: undefined,
|
|
157
|
+
},
|
|
158
|
+
entities: {
|
|
143
159
|
components: {},
|
|
144
160
|
patterns: {},
|
|
145
161
|
pages: {},
|
|
146
162
|
},
|
|
163
|
+
duplicateCatalogIds: [],
|
|
147
164
|
};
|
|
165
|
+
// The id addresses artifacts, transfer routes and docs URLs, so it has to resolve to one item.
|
|
166
|
+
// Components and patterns share one namespace, so one map covers both lanes.
|
|
167
|
+
const declaredIds = new Map();
|
|
148
168
|
if (!!((_a = handoff.config.entries) === null || _a === void 0 ? void 0 : _a.scss)) {
|
|
149
169
|
result.entries.scss = path_1.default.resolve(handoff.workingPath, (_b = handoff.config.entries) === null || _b === void 0 ? void 0 : _b.scss);
|
|
150
170
|
}
|
|
151
171
|
if (!!((_c = handoff.config.entries) === null || _c === void 0 ? void 0 : _c.js)) {
|
|
152
172
|
result.entries.js = path_1.default.resolve(handoff.workingPath, (_d = handoff.config.entries) === null || _d === void 0 ? void 0 : _d.js);
|
|
153
173
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
174
|
+
// A directory's lane depends on what its declaration holds, not on which config key registered
|
|
175
|
+
// it, so the declaration is loaded before the lane is chosen.
|
|
176
|
+
for (const itemPath of (0, exports.getCatalogItemDirectories)(handoff.config, handoff.workingPath)) {
|
|
177
|
+
const itemBaseName = path_1.default.basename(itemPath);
|
|
178
|
+
const declaration = (0, exports.resolveComponentDeclaration)(itemPath, itemBaseName);
|
|
179
|
+
if (!declaration) {
|
|
180
|
+
const declarationFiles = getDeclarationFiles(itemBaseName);
|
|
181
|
+
logger_1.Logger.warn(`Missing catalog declaration (use .handoff.ts, .handoff.js, or .handoff.cjs; see UPGRADE.md#catalog-items): ${path_1.default.resolve(itemPath, declarationFiles.join(' or '))}`);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const declarationPath = path_1.default.resolve(itemPath, declaration.fileName);
|
|
185
|
+
const indexKey = (0, path_2.normalizePathForCompare)(declarationPath);
|
|
186
|
+
configFiles.push(declarationPath);
|
|
187
|
+
// A declaration can be mid-edit under `start`, so every failure is a warning and the file is
|
|
188
|
+
// retried on the next save. The index records it with an unknown kind, so a watcher does not
|
|
189
|
+
// guess the wrong lane.
|
|
190
|
+
const skip = (message, error) => {
|
|
191
|
+
// The message carries the authoring error, so it belongs in the warning rather than in a
|
|
192
|
+
// debug line the default log level hides.
|
|
193
|
+
const detail = error instanceof Error && error.message ? ` — ${error.message}` : '';
|
|
194
|
+
logger_1.Logger.warn(`${message}: ${declarationPath}${detail}`);
|
|
195
|
+
logger_1.Logger.debug('Declaration parse detail:', error);
|
|
196
|
+
configFileIndex.set(indexKey, { kind: 'unknown', entityId: itemBaseName });
|
|
197
|
+
};
|
|
198
|
+
let classified;
|
|
199
|
+
try {
|
|
200
|
+
const moduleExports = loadDeclarationFile(declarationPath, handoff.modulePath);
|
|
201
|
+
classified = (0, catalog_1.normalizeCatalogItem)(moduleExports, {
|
|
202
|
+
declarationPath,
|
|
203
|
+
fallbackId: itemBaseName,
|
|
204
|
+
warn: (message) => logger_1.Logger.warn(message),
|
|
185
205
|
});
|
|
186
|
-
(_l = component.options).transformer || (_l.transformer = { defaults: {}, replace: {} });
|
|
187
|
-
const transformer = component.options.transformer;
|
|
188
|
-
(_g = transformer.cssRootClass) !== null && _g !== void 0 ? _g : (transformer.cssRootClass = null);
|
|
189
|
-
(_h = transformer.tokenNameSegments) !== null && _h !== void 0 ? _h : (transformer.tokenNameSegments = null);
|
|
190
|
-
// Normalize keys and values to lowercase
|
|
191
|
-
transformer.defaults = (0, exports.toLowerCaseKeysAndValues)(Object.assign({}, transformer.defaults));
|
|
192
|
-
transformer.replace = (0, exports.toLowerCaseKeysAndValues)(Object.assign({}, transformer.replace));
|
|
193
|
-
// Save transformer config
|
|
194
|
-
result.options[component.id] = transformer;
|
|
195
|
-
// Discover CSF stories early so patterns can resolve stories like normal previews.
|
|
196
|
-
component.previews = discoverCsfPreviews(component, handoff);
|
|
197
|
-
// Save full component entry
|
|
198
|
-
result.entries.components[component.id] = component;
|
|
199
|
-
configFileIndex.set((0, path_2.normalizePathForCompare)(resolvedComponentConfigPath), { kind: 'component', entityId: component.id });
|
|
200
206
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// -------------------------------------------------------------------------
|
|
205
|
-
if ((_k = (_j = handoff.config.entries) === null || _j === void 0 ? void 0 : _j.patterns) === null || _k === void 0 ? void 0 : _k.length) {
|
|
206
|
-
const patternPaths = handoff.config.entries.patterns.flatMap(exports.getItemsForPath);
|
|
207
|
-
for (const patternPath of patternPaths) {
|
|
208
|
-
const resolvedPatternPath = path_1.default.resolve(handoff.workingPath, patternPath);
|
|
209
|
-
const patternBaseName = path_1.default.basename(resolvedPatternPath);
|
|
210
|
-
const declaration = (0, exports.resolveComponentDeclaration)(resolvedPatternPath, patternBaseName);
|
|
211
|
-
if (!declaration) {
|
|
212
|
-
const modernFiles = getModernDeclarationFiles(patternBaseName);
|
|
213
|
-
const legacyFiles = getLegacyDeclarationFiles(patternBaseName);
|
|
214
|
-
logger_1.Logger.warn(`Missing pattern config: ${path_1.default.resolve(resolvedPatternPath, [...modernFiles, ...legacyFiles].join(' or '))}`);
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
const resolvedPatternConfigPath = path_1.default.resolve(resolvedPatternPath, declaration.fileName);
|
|
218
|
-
configFiles.push(resolvedPatternConfigPath);
|
|
219
|
-
let pattern;
|
|
220
|
-
try {
|
|
221
|
-
const importedDeclaration = loadDeclarationFile(resolvedPatternConfigPath, handoff.modulePath);
|
|
222
|
-
const rawPattern = importedDeclaration.default || importedDeclaration;
|
|
223
|
-
pattern = (0, pattern_1.normalizePatternDeclaration)(rawPattern, {
|
|
224
|
-
declarationPath: resolvedPatternConfigPath,
|
|
225
|
-
fallbackId: patternBaseName,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
catch (err) {
|
|
229
|
-
// Treat as a warning rather than an error: the file may be empty or
|
|
230
|
-
// mid-edit. It is already tracked in configFiles above, so
|
|
231
|
-
// watchRuntimeConfiguration will pick it up once the file is saved
|
|
232
|
-
// with valid content.
|
|
233
|
-
logger_1.Logger.warn(`Pattern config skipped (incomplete or invalid) — will retry on next save: ${resolvedPatternConfigPath}`);
|
|
234
|
-
logger_1.Logger.debug(`Pattern parse detail:`, err);
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
configFileIndex.set((0, path_2.normalizePathForCompare)(resolvedPatternConfigPath), { kind: 'pattern', entityId: pattern.id });
|
|
238
|
-
result.entries.patterns[pattern.id] = pattern;
|
|
207
|
+
catch (err) {
|
|
208
|
+
skip('Declaration skipped (incomplete or invalid) — will retry on next save', err);
|
|
209
|
+
continue;
|
|
239
210
|
}
|
|
211
|
+
const takenBy = declaredIds.get(classified.item.id);
|
|
212
|
+
if (takenBy) {
|
|
213
|
+
logger_1.Logger.warn(`Catalog id "${classified.item.id}" is already declared by ${takenBy}. Skipping ${declarationPath}. ` +
|
|
214
|
+
`Give each catalog item a unique id.`);
|
|
215
|
+
result.duplicateCatalogIds.push({ id: classified.item.id, kept: takenBy, skipped: declarationPath });
|
|
216
|
+
// An unknown kind makes the watcher skip a rebuild. Any other kind rebuilds the item that owns the id.
|
|
217
|
+
configFileIndex.set(indexKey, { kind: 'unknown', entityId: classified.item.id });
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
declaredIds.set(classified.item.id, declarationPath);
|
|
221
|
+
if (classified.kind === 'pattern') {
|
|
222
|
+
const pattern = classified.item;
|
|
223
|
+
configFileIndex.set(indexKey, { kind: 'pattern', entityId: pattern.id });
|
|
224
|
+
result.entities.patterns[pattern.id] = pattern;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const component = classified.item;
|
|
228
|
+
// Initialize options with safe defaults
|
|
229
|
+
component.options || (component.options = {
|
|
230
|
+
transformer: { defaults: {}, replace: {} },
|
|
231
|
+
});
|
|
232
|
+
(_g = component.options).transformer || (_g.transformer = { defaults: {}, replace: {} });
|
|
233
|
+
const transformer = component.options.transformer;
|
|
234
|
+
(_e = transformer.cssRootClass) !== null && _e !== void 0 ? _e : (transformer.cssRootClass = null);
|
|
235
|
+
(_f = transformer.tokenNameSegments) !== null && _f !== void 0 ? _f : (transformer.tokenNameSegments = null);
|
|
236
|
+
// Normalize keys and values to lowercase
|
|
237
|
+
transformer.defaults = (0, exports.toLowerCaseKeysAndValues)(Object.assign({}, transformer.defaults));
|
|
238
|
+
transformer.replace = (0, exports.toLowerCaseKeysAndValues)(Object.assign({}, transformer.replace));
|
|
239
|
+
// Save transformer config
|
|
240
|
+
result.options[component.id] = transformer;
|
|
241
|
+
// Discover CSF stories early so compositions can resolve stories like normal previews.
|
|
242
|
+
component.previews = discoverCsfPreviews(component, handoff);
|
|
243
|
+
resolveCsfComponentSource(component);
|
|
244
|
+
// Save full component entry
|
|
245
|
+
result.entities.components[component.id] = component;
|
|
246
|
+
configFileIndex.set(indexKey, { kind: 'component', entityId: component.id });
|
|
240
247
|
}
|
|
241
248
|
// -------------------------------------------------------------------------
|
|
242
249
|
// Discover markdown pages
|
|
@@ -252,7 +259,7 @@ const initRuntimeConfig = (handoff) => {
|
|
|
252
259
|
const { data: frontmatter } = (0, markdown_1.parseMarkdown)(fs_extra_1.default.readFileSync(sourcePath, 'utf-8'));
|
|
253
260
|
const routePath = slug === content_kinds_1.HOME_PAGE_ID ? content_kinds_1.HOME_PAGE_PATH : `/${slug}`;
|
|
254
261
|
const page = (0, page_1.normalizePageDeclaration)(frontmatter, { id: slug, routePath, sourcePath });
|
|
255
|
-
result.
|
|
262
|
+
result.entities.pages[page.id] = page;
|
|
256
263
|
}
|
|
257
264
|
catch (err) {
|
|
258
265
|
logger_1.Logger.warn(`Page skipped (unreadable or invalid frontmatter): ${sourcePath}`);
|
|
@@ -268,7 +275,7 @@ const initRuntimeConfig = (handoff) => {
|
|
|
268
275
|
exports.initRuntimeConfig = initRuntimeConfig;
|
|
269
276
|
/**
|
|
270
277
|
* True when `searchPath` is itself a single component directory: it holds a declaration file named
|
|
271
|
-
*
|
|
278
|
+
* with a .handoff.ts, .handoff.js, or .handoff.cjs suffix. This is what
|
|
272
279
|
* separates a declared component from a collection directory.
|
|
273
280
|
*/
|
|
274
281
|
const isComponentDirectory = (searchPath) => !!(0, exports.resolveComponentDeclaration)(searchPath, path_1.default.basename(searchPath));
|
|
@@ -301,14 +308,6 @@ const getComponentsForPath = (searchPath) => {
|
|
|
301
308
|
return [searchPath];
|
|
302
309
|
};
|
|
303
310
|
exports.getComponentsForPath = getComponentsForPath;
|
|
304
|
-
/**
|
|
305
|
-
* Generic directory discovery for both components and patterns.
|
|
306
|
-
* Reuses the same logic as getComponentsForPath.
|
|
307
|
-
*/
|
|
308
|
-
const getItemsForPath = (searchPath) => {
|
|
309
|
-
return (0, exports.getComponentsForPath)(searchPath);
|
|
310
|
-
};
|
|
311
|
-
exports.getItemsForPath = getItemsForPath;
|
|
312
311
|
/**
|
|
313
312
|
* After both components and patterns are loaded, this function iterates all
|
|
314
313
|
* pattern component refs and auto-registers synthetic preview entries on the
|
|
@@ -316,30 +315,32 @@ exports.getItemsForPath = getItemsForPath;
|
|
|
316
315
|
*
|
|
317
316
|
* This ensures the component build renders every preview needed by patterns
|
|
318
317
|
* so that pattern composition is purely file I/O (no rendering).
|
|
318
|
+
*
|
|
319
|
+
* A ref that does not resolve records its reason in `unresolvedReason`. Nothing is logged here.
|
|
320
|
+
* Discovery runs for every command, and only the pattern build knows whether a ref is skipped or
|
|
321
|
+
* composed from a fallback. `buildPattern` reports it.
|
|
319
322
|
*/
|
|
320
323
|
const injectPatternPreviews = (result) => {
|
|
321
|
-
var _a, _b
|
|
322
|
-
const patterns =
|
|
323
|
-
const components =
|
|
324
|
+
var _a, _b;
|
|
325
|
+
const patterns = result.entities.patterns;
|
|
326
|
+
const components = result.entities.components;
|
|
324
327
|
for (const [patternId, pattern] of Object.entries(patterns)) {
|
|
325
328
|
for (let i = 0; i < pattern.components.length; i++) {
|
|
326
329
|
const ref = pattern.components[i];
|
|
327
330
|
const component = components[ref.id];
|
|
328
331
|
if (!component) {
|
|
329
|
-
const error = `Pattern "${patternId}" references component "${ref.id}" which is not declared. This fragment will be skipped.`;
|
|
330
|
-
logger_1.Logger.warn(error);
|
|
331
332
|
ref.resolved = false;
|
|
333
|
+
ref.unresolvedReason = `component "${ref.id}" is not declared`;
|
|
332
334
|
continue;
|
|
333
335
|
}
|
|
334
336
|
// Case 1: only preview, no args -> use the existing preview as-is
|
|
335
337
|
if (ref.preview && !ref.args) {
|
|
336
|
-
if ((
|
|
338
|
+
if ((_a = component.previews) === null || _a === void 0 ? void 0 : _a[ref.preview]) {
|
|
337
339
|
ref.resolved = true;
|
|
338
340
|
}
|
|
339
341
|
else {
|
|
340
|
-
const error = `Pattern "${patternId}" references preview "${ref.preview}" on component "${ref.id}" which does not exist. This fragment may be skipped.`;
|
|
341
|
-
logger_1.Logger.warn(error);
|
|
342
342
|
ref.resolved = false;
|
|
343
|
+
ref.unresolvedReason = `preview "${ref.preview}" of component "${ref.id}" is not declared`;
|
|
343
344
|
}
|
|
344
345
|
ref.resolvedPreview = ref.preview;
|
|
345
346
|
continue;
|
|
@@ -353,22 +354,21 @@ const injectPatternPreviews = (result) => {
|
|
|
353
354
|
ref.resolved = true;
|
|
354
355
|
}
|
|
355
356
|
else {
|
|
356
|
-
logger_1.Logger.warn(`Pattern "${patternId}" component ref "${ref.id}" has neither "preview" nor "args", and the component has no previews. This fragment will be skipped.`);
|
|
357
357
|
ref.resolved = false;
|
|
358
|
+
ref.unresolvedReason = `component "${ref.id}" has no previews, and the ref names no "preview" or "args"`;
|
|
358
359
|
}
|
|
359
360
|
continue;
|
|
360
361
|
}
|
|
361
362
|
// Case 3: args present (with or without preview base) -> create synthetic preview
|
|
362
363
|
let resolvedValues = {};
|
|
363
364
|
if (ref.preview) {
|
|
364
|
-
const basePreview = (
|
|
365
|
+
const basePreview = (_b = component.previews) === null || _b === void 0 ? void 0 : _b[ref.preview];
|
|
365
366
|
if (basePreview) {
|
|
366
367
|
resolvedValues = Object.assign({}, basePreview.values);
|
|
367
368
|
}
|
|
368
369
|
else {
|
|
369
|
-
const error = `Pattern "${patternId}" references preview "${ref.preview}" on component "${ref.id}" which does not exist. Using args only.`;
|
|
370
|
-
logger_1.Logger.warn(error);
|
|
371
370
|
ref.resolved = false;
|
|
371
|
+
ref.unresolvedReason = `preview "${ref.preview}" of component "${ref.id}" is not declared, so only "args" were used`;
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
resolvedValues = Object.assign(Object.assign({}, resolvedValues), ref.args);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CatalogItem, CatalogItemMeta } from './catalog/types';
|
|
2
|
+
export type { CatalogItem, CatalogItemMeta, CatalogPreview, CompositionRef, Preview, SourceDescriptor } from './catalog/types';
|
|
3
|
+
/**
|
|
4
|
+
* Declares a Handlebars catalog item. `implementation` is the path to its `.hbs` template. The
|
|
5
|
+
* renderer comes from this module, so the build fails an item whose file does not match it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const defineCatalogItem: <TArgs = Record<string, unknown>>(input: CatalogItemMeta & {
|
|
8
|
+
implementation: string;
|
|
9
|
+
}) => CatalogItem<TArgs>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineCatalogItem = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Handlebars catalog items.
|
|
6
|
+
*
|
|
7
|
+
* A template carries no type information, so arguments default to `Record<string, unknown>`. Pass
|
|
8
|
+
* an argument type to check previews: `defineCatalogItem<BadgeArgs>`.
|
|
9
|
+
*/
|
|
10
|
+
const define_1 = require("./catalog/define");
|
|
11
|
+
/**
|
|
12
|
+
* Declares a Handlebars catalog item. `implementation` is the path to its `.hbs` template. The
|
|
13
|
+
* renderer comes from this module, so the build fails an item whose file does not match it.
|
|
14
|
+
*/
|
|
15
|
+
const defineCatalogItem = (input) => (0, define_1.createCatalogItem)(input, 'handlebars');
|
|
16
|
+
exports.defineCatalogItem = defineCatalogItem;
|
package/dist/index.d.ts
CHANGED
|
@@ -90,6 +90,20 @@ declare class Handoff {
|
|
|
90
90
|
* client never enters the docs app bundle.
|
|
91
91
|
*/
|
|
92
92
|
checkout(kind: TransferEntityKind, id?: string | string[]): Promise<Handoff>;
|
|
93
|
+
/**
|
|
94
|
+
* Publish the catalog items declared in this connected workspace to the configured remote registry:
|
|
95
|
+
* every one, or only the named ids. An item takes the component lane or the pattern lane depending
|
|
96
|
+
* on whether it declares an implementation or a composition, so the lane is resolved from the
|
|
97
|
+
* workspace rather than named by the caller. One build covers both lanes. The publish module is
|
|
98
|
+
* loaded lazily so the registry client and build code never enter the docs app bundle.
|
|
99
|
+
*/
|
|
100
|
+
publishCatalog(id?: string | string[]): Promise<Handoff>;
|
|
101
|
+
/**
|
|
102
|
+
* Checkout published catalog items from the connected remote registry into this workspace: every
|
|
103
|
+
* one, or only the named ids. The lane an item was published into is looked up in the registry.
|
|
104
|
+
* Mirrors {@link publishCatalog}.
|
|
105
|
+
*/
|
|
106
|
+
checkoutCatalog(id?: string | string[]): Promise<Handoff>;
|
|
93
107
|
/**
|
|
94
108
|
* Publish design token sets from this connected workspace to the configured remote registry. Runs a
|
|
95
109
|
* fresh token build (Figma extract + style transformers), discovers the logical sets, and uploads
|
|
@@ -140,7 +154,6 @@ declare class Handoff {
|
|
|
140
154
|
ejectConfig(): Promise<Handoff>;
|
|
141
155
|
ejectPages(): Promise<Handoff>;
|
|
142
156
|
ejectTheme(): Promise<Handoff>;
|
|
143
|
-
makeTemplate(component: string, state: string): Promise<Handoff>;
|
|
144
157
|
makePage(name: string, parent: string): Promise<Handoff>;
|
|
145
158
|
makeComponent(name: string): Promise<Handoff>;
|
|
146
159
|
start(): Promise<Handoff>;
|
|
@@ -215,12 +228,10 @@ declare class Handoff {
|
|
|
215
228
|
*/
|
|
216
229
|
private readJsonFile;
|
|
217
230
|
}
|
|
218
|
-
export type { ComponentObject as Component } from './transformers/preview/types';
|
|
219
231
|
export type { Config, RegisterHandlebarsHelpersContext } from './types/config';
|
|
220
232
|
export { defineConfig } from './config';
|
|
221
|
-
export {
|
|
233
|
+
export type { CatalogItem, CatalogItemEntries, CatalogItemInput, CatalogItemMeta, CatalogPreview, CompositionRef, Preview, SourceDescriptor, SourceFormat, RendererKind, } from './catalog';
|
|
222
234
|
export { defineAssetStorage } from './registry/asset-storage/define';
|
|
223
235
|
export type { AssetStorage, AssetStorageContext, AssetStorageFactory, AssetStorageInput, AssetStorageReadResult, } from './registry/asset-storage/types';
|
|
224
|
-
export type { CsfDeclarationConfig, DeclarationPreview, GenericDeclarationConfig, GenericPatternDeclarationConfig, HandlebarsDeclarationConfig, PatternComponentRef, ReactDeclarationConfig, RendererKind, } from './declarations';
|
|
225
236
|
export { Transformers as CoreTransformers, TransformerUtils as CoreTransformerUtils, Types as CoreTypes } from 'handoff-core';
|
|
226
237
|
export default Handoff;
|