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
|
@@ -17,11 +17,21 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const url_1 = require("../../../artifacts/url");
|
|
19
19
|
const previews_1 = require("./previews");
|
|
20
|
+
/**
|
|
21
|
+
* Strip the fields that must not reach the written artifact.
|
|
22
|
+
*
|
|
23
|
+
* The docs API serves this artifact publicly, and publish uploads it verbatim. An absolute path in
|
|
24
|
+
* the artifact exposes the filesystem layout of the build machine, so this drops the workspace
|
|
25
|
+
* locations `path` and `entries`. The build takes those locations from the runtime config, and
|
|
26
|
+
* publish remaps `entries` onto the registry record.
|
|
27
|
+
*/
|
|
20
28
|
const sanitizeComponentApiData = (component) => {
|
|
21
29
|
if (!component)
|
|
22
30
|
return component;
|
|
23
31
|
const sanitized = Object.assign(Object.assign({}, component), { previews: (0, previews_1.getDocumentedPreviews)(component.previews) });
|
|
24
32
|
delete sanitized.internalPatternPreviews;
|
|
33
|
+
delete sanitized.entries;
|
|
34
|
+
delete sanitized.path;
|
|
25
35
|
return sanitized;
|
|
26
36
|
};
|
|
27
37
|
exports.sanitizeComponentApiData = sanitizeComponentApiData;
|
|
@@ -126,21 +136,7 @@ const readComponentMetadataApi = (handoff, id) => __awaiter(void 0, void 0, void
|
|
|
126
136
|
return null;
|
|
127
137
|
}
|
|
128
138
|
// Construct the summary from the full component data
|
|
129
|
-
return {
|
|
130
|
-
id,
|
|
131
|
-
title: componentData.title,
|
|
132
|
-
description: componentData.description,
|
|
133
|
-
type: componentData.type,
|
|
134
|
-
group: componentData.group,
|
|
135
|
-
image: componentData.image ? componentData.image : '',
|
|
136
|
-
figma: componentData.figma ? componentData.figma : '',
|
|
137
|
-
figmaComponentId: componentData.figmaComponentId,
|
|
138
|
-
categories: componentData.categories ? componentData.categories : [],
|
|
139
|
-
tags: componentData.tags ? componentData.tags : [],
|
|
140
|
-
properties: componentData.properties,
|
|
141
|
-
previews: (0, previews_1.getDocumentedPreviews)(componentData.previews),
|
|
142
|
-
path: (0, url_1.buildComponentDetailUrl)(id, (_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : ''),
|
|
143
|
-
};
|
|
139
|
+
return Object.assign(Object.assign({ id, title: componentData.title, description: componentData.description, type: componentData.type, group: componentData.group, image: componentData.image ? componentData.image : '', figma: componentData.figma ? componentData.figma : '', figmaComponentId: componentData.figmaComponentId, categories: componentData.categories ? componentData.categories : [], tags: componentData.tags ? componentData.tags : [], properties: componentData.properties, previews: (0, previews_1.getDocumentedPreviews)(componentData.previews), path: (0, url_1.buildComponentDetailUrl)(id, (_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : '') }, (componentData.renderer ? { renderer: componentData.renderer } : {})), (componentData.sourceFormat ? { sourceFormat: componentData.sourceFormat } : {}));
|
|
144
140
|
});
|
|
145
141
|
exports.readComponentMetadataApi = readComponentMetadataApi;
|
|
146
142
|
exports.default = exports.writeComponentApi;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import Handoff from '../../../index';
|
|
2
2
|
export declare const getComponentApiPath: (handoff: Handoff) => string;
|
|
3
3
|
export declare const removeComponentApi: (handoff: Handoff, id: string) => Promise<void>;
|
|
4
|
-
export declare const syncComponentArtifacts: (handoff: Handoff) => Promise<void>;
|
|
4
|
+
export declare const syncComponentArtifacts: (handoff: Handoff, removedIds?: readonly string[]) => Promise<void>;
|
|
@@ -26,8 +26,8 @@ const CLIENT_ARTIFACT_SUFFIX = '.client.js';
|
|
|
26
26
|
const getComponentApiPath = (handoff) => path_1.default.resolve((0, api_1.getAPIPath)(handoff), 'component');
|
|
27
27
|
exports.getComponentApiPath = getComponentApiPath;
|
|
28
28
|
const getComponentPreviewKeys = (handoff, componentId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
-
var _a
|
|
30
|
-
const runtimeComponent = (
|
|
29
|
+
var _a;
|
|
30
|
+
const runtimeComponent = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entities.components[componentId];
|
|
31
31
|
const previewKeys = new Set();
|
|
32
32
|
const outputFilePath = path_1.default.resolve((0, exports.getComponentApiPath)(handoff), `${componentId}.json`);
|
|
33
33
|
if (fs_extra_1.default.existsSync(outputFilePath)) {
|
|
@@ -40,7 +40,7 @@ const getComponentPreviewKeys = (handoff, componentId) => __awaiter(void 0, void
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
catch (
|
|
43
|
+
catch (_b) {
|
|
44
44
|
// Fall back to runtime config below.
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -71,14 +71,18 @@ const removeComponentApi = (handoff, id) => __awaiter(void 0, void 0, void 0, fu
|
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
73
|
exports.removeComponentApi = removeComponentApi;
|
|
74
|
-
const syncComponentArtifacts = (
|
|
75
|
-
var _a, _b
|
|
74
|
+
const syncComponentArtifacts = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1, ...args_1], void 0, function* (handoff, removedIds = []) {
|
|
75
|
+
var _a, _b;
|
|
76
76
|
const componentPath = (0, exports.getComponentApiPath)(handoff);
|
|
77
77
|
yield fs_extra_1.default.ensureDir(componentPath);
|
|
78
|
-
const runtimeComponents = (
|
|
78
|
+
const runtimeComponents = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entities.components) !== null && _b !== void 0 ? _b : {};
|
|
79
79
|
const runtimeIds = Object.keys(runtimeComponents);
|
|
80
80
|
const entries = yield fs_extra_1.default.readdir(componentPath);
|
|
81
|
-
|
|
81
|
+
// `getArtifactComponentId` prunes a preview file only when it can name the owner. A deleted
|
|
82
|
+
// component is gone from the runtime config, and its `.json` is already removed, so nothing can
|
|
83
|
+
// match it. Naming it here restores the match without making its files valid. Every artifact it
|
|
84
|
+
// owns is then pruned, including the `__pattern_*` previews that the `.json` does not list.
|
|
85
|
+
const discoveredArtifactIds = new Set([...runtimeIds, ...removedIds]);
|
|
82
86
|
for (const entry of entries) {
|
|
83
87
|
const parsed = path_1.default.parse(entry);
|
|
84
88
|
if (parsed.ext === '.json' || parsed.ext === '.js' || parsed.ext === '.css') {
|
|
@@ -71,9 +71,17 @@ var ComponentSegment;
|
|
|
71
71
|
ComponentSegment["Previews"] = "previews";
|
|
72
72
|
ComponentSegment["Validation"] = "validation";
|
|
73
73
|
})(ComponentSegment || (exports.ComponentSegment = ComponentSegment = {}));
|
|
74
|
+
/**
|
|
75
|
+
* A source format reads its previews out of the source file. A placeholder there is a preview
|
|
76
|
+
* nothing can render: the docs would offer a "Default" entry with no artifact. Only a renderer
|
|
77
|
+
* that renders whatever previews it is given needs the placeholder.
|
|
78
|
+
*/
|
|
79
|
+
const ownsItsPreviews = (data) => !!(data === null || data === void 0 ? void 0 : data.sourceFormat);
|
|
74
80
|
const ensureDefaultPreview = (data) => {
|
|
75
81
|
if (!data)
|
|
76
82
|
return;
|
|
83
|
+
if (ownsItsPreviews(data))
|
|
84
|
+
return;
|
|
77
85
|
if (!data.previews || Object.keys(data.previews).length === 0) {
|
|
78
86
|
data.previews = {
|
|
79
87
|
default: {
|
|
@@ -155,7 +163,7 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
155
163
|
const documentationObject = yield handoff.getDocumentationObject();
|
|
156
164
|
const components = (_a = documentationObject === null || documentationObject === void 0 ? void 0 : documentationObject.components) !== null && _a !== void 0 ? _a : {};
|
|
157
165
|
// Resolve the component set through the storage-agnostic store (v2). The filesystem store is a
|
|
158
|
-
// read view over `runtimeConfig.
|
|
166
|
+
// read view over `runtimeConfig.entities.components`, so these are the same records the build has
|
|
159
167
|
// always used — rebuilt into the id-keyed map the build logic below expects.
|
|
160
168
|
const runtimeComponents = {};
|
|
161
169
|
for (const component of yield handoff.store.components.list()) {
|
|
@@ -166,7 +174,7 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
166
174
|
if (id && !runtimeComponents[id]) {
|
|
167
175
|
yield (0, artifacts_1.removeComponentApi)(handoff, id);
|
|
168
176
|
yield (0, summary_1.removeComponentFromSummaryApi)(handoff, id);
|
|
169
|
-
yield (0, artifacts_1.syncComponentArtifacts)(handoff);
|
|
177
|
+
yield (0, artifacts_1.syncComponentArtifacts)(handoff, [id]);
|
|
170
178
|
return [];
|
|
171
179
|
}
|
|
172
180
|
// Determine which components need building based on cache (when enabled)
|
|
@@ -268,7 +276,7 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
268
276
|
// If this is NOT a figma component, add the default generic preview.
|
|
269
277
|
// We add it here (before merge) so that if the user explicitly provided previews in 'restMetadata',
|
|
270
278
|
// those will override this default (standard "config overrides defaults" behavior).
|
|
271
|
-
if (!restMetadata.figmaComponentId) {
|
|
279
|
+
if (!restMetadata.figmaComponentId && !ownsItsPreviews(restMetadata)) {
|
|
272
280
|
componentDefaults.previews = {
|
|
273
281
|
default: {
|
|
274
282
|
title: 'Default',
|
|
@@ -296,12 +304,14 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
296
304
|
data.css = existingData.css;
|
|
297
305
|
data.sass = existingData.sass;
|
|
298
306
|
}
|
|
299
|
-
// If we're not building previews, preserve pre-existing HTML, code snippet, usage,
|
|
307
|
+
// If we're not building previews, preserve pre-existing HTML, code snippet, usage, previews,
|
|
308
|
+
// and the code language they were rendered in.
|
|
300
309
|
if (!buildPlan.previews) {
|
|
301
310
|
data.html = existingData.html;
|
|
302
311
|
data.code = existingData.code;
|
|
303
312
|
data.usage = existingData.usage;
|
|
304
313
|
data.previews = existingData.previews;
|
|
314
|
+
data.format = existingData.format;
|
|
305
315
|
}
|
|
306
316
|
/**
|
|
307
317
|
* Always keep validation results from the previous data,
|
|
@@ -396,19 +406,6 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
396
406
|
*/
|
|
397
407
|
const buildComponentSummary = (id, data) => {
|
|
398
408
|
var _a;
|
|
399
|
-
return {
|
|
400
|
-
id,
|
|
401
|
-
title: data.title,
|
|
402
|
-
description: data.description,
|
|
403
|
-
type: data.type,
|
|
404
|
-
group: data.group,
|
|
405
|
-
image: data.image ? data.image : '',
|
|
406
|
-
figma: data.figma ? data.figma : '',
|
|
407
|
-
categories: data.categories ? data.categories : [],
|
|
408
|
-
tags: data.tags ? data.tags : [],
|
|
409
|
-
properties: data.properties,
|
|
410
|
-
previews: (0, previews_1.getDocumentedPreviews)(data.previews),
|
|
411
|
-
path: (0, url_1.buildComponentDetailUrl)(id, (_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : ''),
|
|
412
|
-
};
|
|
409
|
+
return Object.assign(Object.assign({ id, title: data.title, description: data.description, type: data.type, group: data.group, image: data.image ? data.image : '', figma: data.figma ? data.figma : '', categories: data.categories ? data.categories : [], tags: data.tags ? data.tags : [], properties: data.properties, previews: (0, previews_1.getDocumentedPreviews)(data.previews), path: (0, url_1.buildComponentDetailUrl)(id, (_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : '') }, (data.renderer ? { renderer: data.renderer } : {})), (data.sourceFormat ? { sourceFormat: data.sourceFormat } : {}));
|
|
413
410
|
};
|
|
414
411
|
exports.default = processComponents;
|
|
@@ -44,6 +44,8 @@ declare const buildComponentCss: (data: TransformComponentTokensResult, handoff:
|
|
|
44
44
|
templates?: string;
|
|
45
45
|
};
|
|
46
46
|
renderer?: import("../../../index").RendererKind;
|
|
47
|
+
sourceFormat?: import("../../../index").SourceFormat;
|
|
48
|
+
componentExport?: string;
|
|
47
49
|
options?: {
|
|
48
50
|
preview?: {
|
|
49
51
|
groupBy?: string;
|
|
@@ -16,7 +16,6 @@ exports.buildMainCss = exports.SHARED_COMPONENT_CSS_FILE = exports.MAIN_COMPONEN
|
|
|
16
16
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const vite_1 = require("vite");
|
|
19
|
-
const config_1 = require("../../../config");
|
|
20
19
|
const duration_1 = require("../../../utils/duration");
|
|
21
20
|
const logger_1 = require("../../../utils/logger");
|
|
22
21
|
const vite_config_1 = __importDefault(require("../../vite-config"));
|
|
@@ -163,14 +162,14 @@ const buildComponentCss = (data, handoff) => __awaiter(void 0, void 0, void 0, f
|
|
|
163
162
|
* Build the main CSS file using Vite
|
|
164
163
|
*/
|
|
165
164
|
const buildMainCss = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
-
var _a, _b
|
|
165
|
+
var _a, _b;
|
|
167
166
|
const outputPath = (0, component_1.getComponentOutputPath)(handoff);
|
|
168
167
|
const mainCssPath = path_1.default.resolve(outputPath, exports.MAIN_COMPONENT_CSS_FILE);
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
171
|
-
const stat = yield fs_extra_1.default.stat(
|
|
172
|
-
const entryPath = stat.isDirectory() ? path_1.default.resolve(
|
|
173
|
-
if (entryPath ===
|
|
168
|
+
const scssEntry = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.scss;
|
|
169
|
+
if (scssEntry && fs_extra_1.default.existsSync(scssEntry)) {
|
|
170
|
+
const stat = yield fs_extra_1.default.stat(scssEntry);
|
|
171
|
+
const entryPath = stat.isDirectory() ? path_1.default.resolve(scssEntry, 'main.scss') : scssEntry;
|
|
172
|
+
if (entryPath === scssEntry || fs_extra_1.default.existsSync(entryPath)) {
|
|
174
173
|
logger_1.Logger.info(`Building styles for global entry (${exports.MAIN_COMPONENT_CSS_FILE})…`);
|
|
175
174
|
const startedAt = Date.now();
|
|
176
175
|
// Drop the previous artifact so a failed/empty rebuild cannot preserve stale global CSS that
|
|
@@ -178,13 +177,11 @@ const buildMainCss = (handoff) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
178
177
|
yield fs_extra_1.default.remove(mainCssPath);
|
|
179
178
|
try {
|
|
180
179
|
const loadPaths = [
|
|
180
|
+
path_1.default.dirname(scssEntry),
|
|
181
181
|
path_1.default.resolve(handoff.workingPath),
|
|
182
182
|
path_1.default.resolve(handoff.workingPath, handoff.exportsDirectory, handoff.getProjectId()),
|
|
183
183
|
path_1.default.resolve(handoff.workingPath, 'node_modules'),
|
|
184
184
|
];
|
|
185
|
-
if ((_c = (_b = handoff.runtimeConfig) === null || _b === void 0 ? void 0 : _b.entries) === null || _c === void 0 ? void 0 : _c.scss) {
|
|
186
|
-
loadPaths.unshift(path_1.default.dirname(handoff.runtimeConfig.entries.scss));
|
|
187
|
-
}
|
|
188
185
|
yield buildCssBundle({
|
|
189
186
|
entry: entryPath,
|
|
190
187
|
outputPath,
|
|
@@ -194,7 +191,7 @@ const buildMainCss = (handoff) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
194
191
|
});
|
|
195
192
|
logger_1.Logger.info(`Finished building styles for global entry (${exports.MAIN_COMPONENT_CSS_FILE}) in ${(0, duration_1.formatDurationMs)(Date.now() - startedAt)}`);
|
|
196
193
|
}
|
|
197
|
-
catch (
|
|
194
|
+
catch (_c) {
|
|
198
195
|
// buildCssBundle already logs failure for the entry path; ensure no stale artifact remains.
|
|
199
196
|
yield fs_extra_1.default.remove(mainCssPath);
|
|
200
197
|
}
|
|
@@ -19,15 +19,17 @@ const logger_1 = require("../../../utils/logger");
|
|
|
19
19
|
const plugins_1 = require("../../plugins");
|
|
20
20
|
const vite_config_1 = __importDefault(require("../../vite-config"));
|
|
21
21
|
const component_1 = require("../component");
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Exactly one entry builds an item. A source format claims it before its renderer, because a CSF
|
|
24
|
+
* item is also a React item and both plugins would write their own previews. The maps are
|
|
25
|
+
* exhaustive, so a new renderer fails to compile until its previews are built.
|
|
26
|
+
*/
|
|
27
|
+
const FORMAT_PLUGINS = {
|
|
28
|
+
csf: (data, components, handoff) => [(0, plugins_1.csfRenderPlugin)(data, components, handoff)],
|
|
29
|
+
};
|
|
30
|
+
const RENDERER_PLUGINS = {
|
|
31
|
+
handlebars: (data, components, handoff) => [(0, plugins_1.handlebarsPreviewsPlugin)(data, components, handoff)],
|
|
32
|
+
react: (data, components, handoff) => [(0, plugin_react_1.default)(), (0, plugins_1.ssrRenderPlugin)(data, components, handoff)],
|
|
31
33
|
};
|
|
32
34
|
/**
|
|
33
35
|
* Builds previews for components using Vite and Handlebars.
|
|
@@ -47,13 +49,13 @@ const buildPreviews = (data, handoff, components) => __awaiter(void 0, void 0, v
|
|
|
47
49
|
var _a, _b, _c;
|
|
48
50
|
if (!((_a = data.entries) === null || _a === void 0 ? void 0 : _a.template))
|
|
49
51
|
return data;
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
];
|
|
52
|
+
const { renderer, sourceFormat } = data;
|
|
53
|
+
const previewPlugins = sourceFormat ? FORMAT_PLUGINS[sourceFormat] : RENDERER_PLUGINS[renderer];
|
|
54
|
+
if (!previewPlugins) {
|
|
55
|
+
logger_1.Logger.error(`No preview support for renderer "${renderer}"${sourceFormat ? ` and source format "${sourceFormat}"` : ''}: ${data.entries.template}`);
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
58
|
+
const plugins = [...(vite_config_1.default.plugins || []), ...previewPlugins(data, components, handoff)];
|
|
57
59
|
// Store the current NODE_ENV value before vite build
|
|
58
60
|
// This is necessary because viteBuild forcibly sets NODE_ENV to 'production'
|
|
59
61
|
// which can cause issues with subsequent Next.js operations that rely on
|
|
@@ -16,7 +16,6 @@ exports.buildMainJS = exports.buildComponentJs = exports.MAIN_COMPONENT_JS_FILE
|
|
|
16
16
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const vite_1 = require("vite");
|
|
19
|
-
const config_1 = require("../../../config");
|
|
20
19
|
const duration_1 = require("../../../utils/duration");
|
|
21
20
|
const logger_1 = require("../../../utils/logger");
|
|
22
21
|
const vite_config_1 = __importDefault(require("../../vite-config"));
|
|
@@ -135,11 +134,10 @@ exports.buildComponentJs = buildComponentJs;
|
|
|
135
134
|
* @returns A Promise that resolves when the build process is complete
|
|
136
135
|
*/
|
|
137
136
|
const buildMainJS = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
138
|
-
var _a;
|
|
137
|
+
var _a, _b;
|
|
139
138
|
const outputPath = (0, component_1.getComponentOutputPath)(handoff);
|
|
140
139
|
const mainJsPath = path_1.default.resolve(outputPath, exports.MAIN_COMPONENT_JS_FILE);
|
|
141
|
-
const
|
|
142
|
-
const entry = (_a = runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.entries) === null || _a === void 0 ? void 0 : _a.js;
|
|
140
|
+
const entry = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.js;
|
|
143
141
|
// No usable global JS entry: drop any stale artifact and emit nothing to reference.
|
|
144
142
|
if (!entry || !fs_extra_1.default.existsSync(path_1.default.resolve(entry))) {
|
|
145
143
|
if (entry) {
|
|
@@ -25,54 +25,70 @@ const html_1 = require("./html");
|
|
|
25
25
|
* Returns pattern ids whose declarations reference any of the given component ids.
|
|
26
26
|
*/
|
|
27
27
|
const getPatternIdsReferencingComponents = (handoff, componentIds) => {
|
|
28
|
-
var _a, _b, _c
|
|
28
|
+
var _a, _b, _c;
|
|
29
29
|
if (componentIds.length === 0) {
|
|
30
30
|
return [];
|
|
31
31
|
}
|
|
32
32
|
const idSet = new Set(componentIds);
|
|
33
|
-
const runtimePatterns = (
|
|
33
|
+
const runtimePatterns = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entities.patterns) !== null && _b !== void 0 ? _b : {};
|
|
34
34
|
const result = [];
|
|
35
35
|
for (const patternId of Object.keys(runtimePatterns)) {
|
|
36
36
|
const pattern = runtimePatterns[patternId];
|
|
37
|
-
if ((
|
|
37
|
+
if ((_c = pattern.components) === null || _c === void 0 ? void 0 : _c.some((ref) => idSet.has(ref.id))) {
|
|
38
38
|
result.push(patternId);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
return result;
|
|
42
42
|
};
|
|
43
43
|
exports.getPatternIdsReferencingComponents = getPatternIdsReferencingComponents;
|
|
44
|
+
/** Collapses repeats into one item with a count, so one cause reads as one problem. */
|
|
45
|
+
const summarizeReasons = (reasons) => {
|
|
46
|
+
var _a;
|
|
47
|
+
const counts = new Map();
|
|
48
|
+
for (const reason of reasons) {
|
|
49
|
+
counts.set(reason, ((_a = counts.get(reason)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
50
|
+
}
|
|
51
|
+
return Array.from(counts, ([reason, count]) => (count > 1 ? `${reason} (x${count})` : reason)).join('; ');
|
|
52
|
+
};
|
|
44
53
|
function buildPattern(handoff, patternId, pattern, componentOutputDir, basePath, sharedArtifacts) {
|
|
45
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
var _a, _b, _c;
|
|
46
56
|
const fragments = [];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
// Composition is what drops a ref, so it is also what reports why. Discovery recorded its reason
|
|
58
|
+
// without logging it, and that reason is more precise than the one this loop can build.
|
|
59
|
+
const skipped = [];
|
|
60
|
+
const composedWithFallback = [];
|
|
61
|
+
for (const ref of pattern.components) {
|
|
50
62
|
if (ref.resolved === false && !ref.resolvedPreview) {
|
|
51
|
-
|
|
63
|
+
skipped.push((_a = ref.unresolvedReason) !== null && _a !== void 0 ? _a : `component "${ref.id}" did not resolve`);
|
|
52
64
|
continue;
|
|
53
65
|
}
|
|
54
66
|
const previewKey = ref.resolvedPreview || ref.preview;
|
|
55
67
|
if (!previewKey) {
|
|
56
|
-
|
|
57
|
-
logger_1.Logger.warn(error);
|
|
68
|
+
skipped.push((_b = ref.unresolvedReason) !== null && _b !== void 0 ? _b : `component "${ref.id}" has no preview to render`);
|
|
58
69
|
ref.resolved = false;
|
|
59
|
-
hasErrors = true;
|
|
60
70
|
continue;
|
|
61
71
|
}
|
|
62
72
|
const htmlFileName = `${ref.id}-${previewKey}.html`;
|
|
63
73
|
const htmlFilePath = path_1.default.resolve(componentOutputDir, htmlFileName);
|
|
64
74
|
if (!fs_extra_1.default.existsSync(htmlFilePath)) {
|
|
65
|
-
|
|
66
|
-
`Ensure the component has a preview named "${previewKey}".`;
|
|
67
|
-
logger_1.Logger.warn(error);
|
|
75
|
+
skipped.push((_c = ref.unresolvedReason) !== null && _c !== void 0 ? _c : `preview "${previewKey}" of component "${ref.id}" was not built (${htmlFileName})`);
|
|
68
76
|
ref.resolved = false;
|
|
69
|
-
hasErrors = true;
|
|
70
77
|
continue;
|
|
71
78
|
}
|
|
72
79
|
ref.resolved = true;
|
|
80
|
+
if (ref.unresolvedReason) {
|
|
81
|
+
composedWithFallback.push(ref.unresolvedReason);
|
|
82
|
+
}
|
|
73
83
|
const html = yield fs_extra_1.default.readFile(htmlFilePath, 'utf8');
|
|
74
84
|
fragments.push({ componentId: ref.id, html });
|
|
75
85
|
}
|
|
86
|
+
if (skipped.length > 0) {
|
|
87
|
+
logger_1.Logger.warn(`Pattern "${patternId}" skipped ${skipped.length} of ${pattern.components.length} fragment(s): ${summarizeReasons(skipped)}.`);
|
|
88
|
+
}
|
|
89
|
+
if (composedWithFallback.length > 0) {
|
|
90
|
+
logger_1.Logger.warn(`Pattern "${patternId}" composed ${composedWithFallback.length} fragment(s) from a fallback: ${summarizeReasons(composedWithFallback)}.`);
|
|
91
|
+
}
|
|
76
92
|
// Resolve component-owned artifact presence for each composed component so the pattern references
|
|
77
93
|
// only the stylesheets that actually exist (no dangling references for style-less components).
|
|
78
94
|
const componentArtifacts = new Map();
|
|
@@ -85,9 +101,6 @@ function buildPattern(handoff, patternId, pattern, componentOutputDir, basePath,
|
|
|
85
101
|
logger_1.Logger.warn(`Pattern "${patternId}" produced no fragments. Skipping.`);
|
|
86
102
|
return null;
|
|
87
103
|
}
|
|
88
|
-
if (hasErrors) {
|
|
89
|
-
logger_1.Logger.warn(`Pattern "${patternId}" has missing components but will be composed from available fragments.`);
|
|
90
|
-
}
|
|
91
104
|
const composedHtml = (0, html_1.composePatternHtml)(patternId, pattern.title, fragments, basePath, sharedArtifacts, componentArtifacts);
|
|
92
105
|
const patternUrl = `${patternId}.html`;
|
|
93
106
|
const patternData = Object.assign(Object.assign({}, pattern), { id: patternId, url: patternUrl, path: (0, url_1.buildPatternDetailUrl)(patternId, basePath) });
|
|
@@ -106,7 +119,7 @@ function processPatterns(handoff, options) {
|
|
|
106
119
|
return __awaiter(this, void 0, void 0, function* () {
|
|
107
120
|
var _a;
|
|
108
121
|
// Resolve the pattern set through the storage-agnostic store (v2). The filesystem store is a read
|
|
109
|
-
// view over `runtimeConfig.
|
|
122
|
+
// view over `runtimeConfig.entities.patterns`, so these are the same records the build has always
|
|
110
123
|
// used — rebuilt into the id-keyed map the build logic below expects.
|
|
111
124
|
const runtimePatterns = {};
|
|
112
125
|
for (const pattern of yield handoff.store.patterns.list()) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { GeneratedDocs } from 'handoff-docgen';
|
|
2
2
|
import { Card } from '../../app/components/Component/Cards';
|
|
3
|
-
import type { RendererKind } from '../../
|
|
3
|
+
import type { RendererKind, SourceFormat } from '../../catalog/renderers';
|
|
4
4
|
import { ValidationResult } from '../../types/preview';
|
|
5
5
|
import { Filter } from '../../utils/filter';
|
|
6
6
|
import { SlotMetadata } from './component';
|
|
@@ -105,6 +105,13 @@ export type ComponentObject = {
|
|
|
105
105
|
};
|
|
106
106
|
/** Optional explicit renderer id */
|
|
107
107
|
renderer?: RendererKind;
|
|
108
|
+
/**
|
|
109
|
+
* Implementation source format, such as CSF. The separate `format` field describes the preview code language.
|
|
110
|
+
* These names must differ because the build spreads this record over the preview.
|
|
111
|
+
*/
|
|
112
|
+
sourceFormat?: SourceFormat;
|
|
113
|
+
/** Export of `entries.component` that holds the implementation. Defaults to the default export. */
|
|
114
|
+
componentExport?: string;
|
|
108
115
|
/** Schema describing the expected properties (props/slots) for the component */
|
|
109
116
|
properties: {
|
|
110
117
|
[key: string]: SlotMetadata;
|
|
@@ -113,6 +120,8 @@ export type ComponentObject = {
|
|
|
113
120
|
previews: {
|
|
114
121
|
[key: string]: OptionalPreviewRender;
|
|
115
122
|
};
|
|
123
|
+
/** Source export order retained when publishing previews through jsonb storage. */
|
|
124
|
+
previewOrder?: string[];
|
|
116
125
|
/** Internal previews generated only for pattern composition, not public docs */
|
|
117
126
|
internalPatternPreviews?: {
|
|
118
127
|
[key: string]: OptionalPreviewRender;
|
|
@@ -180,6 +189,9 @@ export type TransformComponentTokensResult = {
|
|
|
180
189
|
templates?: string;
|
|
181
190
|
};
|
|
182
191
|
renderer?: RendererKind;
|
|
192
|
+
/** See `ComponentObject.sourceFormat`. Distinct from `format`, the preview's code language. */
|
|
193
|
+
sourceFormat?: SourceFormat;
|
|
194
|
+
componentExport?: string;
|
|
183
195
|
options?: {
|
|
184
196
|
preview?: {
|
|
185
197
|
groupBy?: string;
|
|
@@ -213,6 +225,8 @@ export type PatternComponentEntry = {
|
|
|
213
225
|
resolvedPreview?: string;
|
|
214
226
|
/** Whether the pattern entry resolved to a usable component preview */
|
|
215
227
|
resolved?: boolean;
|
|
228
|
+
/** Why discovery could not resolve this entry as authored. The pattern build reports it. */
|
|
229
|
+
unresolvedReason?: string;
|
|
216
230
|
};
|
|
217
231
|
export type PatternObject = {
|
|
218
232
|
title: string;
|
package/dist/types/config.d.ts
CHANGED
|
@@ -98,22 +98,20 @@ export interface ConfigEntries {
|
|
|
98
98
|
* @example "scripts/main.js"
|
|
99
99
|
*/
|
|
100
100
|
js?: string;
|
|
101
|
+
}
|
|
102
|
+
/** Catalog item registration. */
|
|
103
|
+
export interface ConfigCatalog {
|
|
101
104
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
|
|
105
|
-
components?: string[];
|
|
106
|
-
/**
|
|
107
|
-
* Array of pattern paths to be included in the build.
|
|
108
|
-
* Patterns compose multiple component previews into single-page views.
|
|
109
|
-
* @example ["patterns/hero-section", "patterns"]
|
|
105
|
+
* Directories to search for catalog items. A path is either an item directory or a collection
|
|
106
|
+
* directory whose subdirectories are each treated as an item.
|
|
107
|
+
* @example ["components", "patterns"]
|
|
110
108
|
*/
|
|
111
|
-
|
|
109
|
+
include?: string[];
|
|
112
110
|
}
|
|
113
111
|
/** Runtime mode. Resolved solely from `runtime.mode`; never inferred from env vars or connection settings. */
|
|
114
112
|
export type RuntimeMode = 'workspace' | 'registry';
|
|
115
113
|
/** Format used when synthesizing local workspace declarations. */
|
|
116
|
-
export type DeclarationFormat = 'ts' | 'js' | 'cjs'
|
|
114
|
+
export type DeclarationFormat = 'ts' | 'js' | 'cjs';
|
|
117
115
|
/**
|
|
118
116
|
* User-facing `runtime` configuration block. A single optional block that selects the runtime
|
|
119
117
|
* mode and carries mode-specific host/connection settings.
|
|
@@ -127,6 +125,13 @@ export interface HandoffRuntimeConfig {
|
|
|
127
125
|
* Mode is never inferred from environment variables, database settings, or token presence.
|
|
128
126
|
*/
|
|
129
127
|
mode?: RuntimeMode;
|
|
128
|
+
/**
|
|
129
|
+
* Whether the app serves the `/api/mcp/` Model Context Protocol endpoint. Set to `false` to leave
|
|
130
|
+
* the endpoint and the header affordance out of the build; the route then answers 404. Like
|
|
131
|
+
* `mode`, this is config-only and baked at build time, so changing it needs a rebuild.
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
mcp?: boolean;
|
|
130
135
|
/** Workspace-mode settings. */
|
|
131
136
|
workspace?: {
|
|
132
137
|
entries?: ConfigEntries;
|
|
@@ -220,6 +225,10 @@ export interface Config {
|
|
|
220
225
|
* Configuration for entry points to assets and components that will be built
|
|
221
226
|
*/
|
|
222
227
|
entries?: ConfigEntries;
|
|
228
|
+
/**
|
|
229
|
+
* Where catalog items are registered.
|
|
230
|
+
*/
|
|
231
|
+
catalog?: ConfigCatalog;
|
|
223
232
|
/**
|
|
224
233
|
* Override URLs for the asset zip download links. When unset, each link defaults to the
|
|
225
234
|
* basePath-aware asset route `{basePath}/api/docs/assets/{collection}/{collection}.zip`, served by
|
|
@@ -397,11 +406,22 @@ export interface ConfigFileEntry {
|
|
|
397
406
|
kind: string;
|
|
398
407
|
entityId: string;
|
|
399
408
|
}
|
|
409
|
+
/** A catalog declaration skipped because another declaration already took its id. */
|
|
410
|
+
export interface DuplicateCatalogId {
|
|
411
|
+
id: string;
|
|
412
|
+
/** Absolute path of the declaration that owns the id. */
|
|
413
|
+
kept: string;
|
|
414
|
+
/** Absolute path of the declaration that was skipped. */
|
|
415
|
+
skipped: string;
|
|
416
|
+
}
|
|
400
417
|
export interface RuntimeConfig {
|
|
418
|
+
/** Resolved absolute paths of the project-wide bundle entry points, from `config.entries`. */
|
|
401
419
|
entries?: {
|
|
402
420
|
scss?: string;
|
|
403
421
|
js?: string;
|
|
404
|
-
|
|
422
|
+
};
|
|
423
|
+
/** Entities discovered from the workspace, keyed by id. Always present, possibly empty. */
|
|
424
|
+
entities: {
|
|
405
425
|
components: {
|
|
406
426
|
[id: string]: ComponentListObject;
|
|
407
427
|
};
|
|
@@ -412,6 +432,11 @@ export interface RuntimeConfig {
|
|
|
412
432
|
[id: string]: PageListObject;
|
|
413
433
|
};
|
|
414
434
|
};
|
|
435
|
+
/**
|
|
436
|
+
* Catalog declarations skipped because their id was already taken. Always present, possibly empty.
|
|
437
|
+
* Discovery is the only pass that sees both declarations, so publish reads the duplicates from here.
|
|
438
|
+
*/
|
|
439
|
+
duplicateCatalogIds: DuplicateCatalogId[];
|
|
415
440
|
options: {
|
|
416
441
|
[key: string]: RuntimeConfigComponentOptions;
|
|
417
442
|
};
|
package/docs/api.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Handoff API
|
|
2
2
|
|
|
3
|
+
Register implementations and compositions with `defineCatalogItem`. See the
|
|
4
|
+
[catalog examples](../README.md#catalog-items) and [version 1.x.x to version 2.x.x migration guide](../UPGRADE.md#version-1xx-to-version-2xx).
|
|
5
|
+
|
|
3
6
|
Handoff exposes two APIs - A Javascript API for interacting with the pipeline
|
|
4
7
|
Handoff exposes a Javascript API allowing you to easily integrate Handoff into
|
|
5
8
|
existing Node based applications, CI/CD, and command line tools. This API also
|
package/docs/cli.md
CHANGED
|
@@ -63,7 +63,7 @@ Commands:
|
|
|
63
63
|
logout [--url <registry-url>] - Revokes the saved token when possible, then removes the local credential.
|
|
64
64
|
|
|
65
65
|
make
|
|
66
|
-
make:
|
|
66
|
+
make:component <name> [opts] - Creates a new catalog item with a declaration
|
|
67
67
|
make:page <component> <state> [opts] - Creates a new page
|
|
68
68
|
|
|
69
69
|
eject - Ejects the default entire configuration to the current directory
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
ALTER TABLE "components" ADD COLUMN "source_format" text;--> statement-breakpoint
|
|
2
|
+
-- Backfill from the authoritative record so components published before this migration get a value too.
|
|
3
|
+
UPDATE "components" SET "source_format" = "record"->>'sourceFormat' WHERE "record"->>'sourceFormat' IS NOT NULL;
|