handoff-app 1.1.0-experimental.2 → 1.1.1
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 +6 -3
- package/config/docs/system.md +0 -2
- package/dist/app/components/Component/Cards.jsx +32 -0
- package/dist/app-builder/build.d.ts +1 -6
- package/dist/app-builder/build.js +34 -54
- package/dist/app-builder/index.d.ts +0 -1
- package/dist/app-builder/index.js +1 -9
- package/dist/app-builder/watchers.d.ts +1 -5
- package/dist/app-builder/watchers.js +9 -68
- package/dist/cache/build-cache.js +25 -10
- package/dist/cli.js +1 -1
- package/dist/commands/index.js +2 -16
- package/dist/config/runtime.d.ts +0 -5
- package/dist/config/runtime.js +4 -67
- package/dist/index.d.ts +1 -4
- package/dist/index.js +2 -2
- package/dist/pipeline/index.d.ts +0 -1
- package/dist/pipeline/index.js +1 -3
- package/dist/transformers/plugins/csf-render.js +1 -18
- package/dist/transformers/plugins/handlebars-previews.js +12 -1
- package/dist/transformers/plugins/ssr-render.js +0 -14
- package/dist/transformers/preview/component/builder.js +16 -1
- package/dist/transformers/utils/build.d.ts +0 -18
- package/dist/transformers/utils/build.js +0 -108
- package/dist/transformers/utils/html.js +15 -3
- package/dist/types/config.d.ts +0 -19
- package/dist/utils/path.d.ts +15 -0
- package/dist/utils/path.js +31 -0
- package/docs/api.md +279 -0
- package/docs/api_spec.yml +0 -0
- package/docs/cli.md +52 -66
- package/docs/props.md +34 -0
- package/package.json +6 -10
- package/src/app/components/Component/ComponentLists.tsx +5 -4
- package/src/app/components/Navigation/MainNav.tsx +3 -5
- package/src/app/components/Navigation/SideNav.tsx +4 -7
- package/src/app/components/SideNav/Custom.tsx +5 -3
- package/src/app/components/ui/mobile-nav.tsx +10 -7
- package/src/app/components/util/index.ts +11 -64
- package/src/app/lib/utils.ts +13 -0
- package/src/app/next.config.mjs +31 -15
- package/src/app/pages/system/component/[component]/index.tsx +15 -8
- package/src/app/pages/system/component/index.tsx +10 -87
- package/src/app/pages/system/index.tsx +5 -24
- package/src/app/pages/system/tokens/components/[component]/index.tsx +14 -1
- package/src/app/pages/system/tokens/index.tsx +10 -85
- package/src/app/tsconfig.json +1 -1
- package/src/app-builder/README.md +1 -1
- package/src/app-builder/build.ts +37 -70
- package/src/app-builder/index.ts +0 -9
- package/src/app-builder/watchers.ts +9 -67
- package/src/cache/README.md +2 -2
- package/src/cache/build-cache.ts +29 -11
- package/src/cli.ts +1 -1
- package/src/commands/index.ts +0 -14
- package/src/config/runtime.ts +0 -76
- package/src/index.ts +3 -3
- package/src/pipeline/README.md +1 -0
- package/src/pipeline/index.ts +0 -1
- package/src/transformers/README.md +3 -2
- package/src/transformers/plugins/csf-render.ts +0 -17
- package/src/transformers/plugins/handlebars-previews.ts +13 -1
- package/src/transformers/plugins/ssr-render.ts +8 -17
- package/src/transformers/preview/component/builder.ts +17 -1
- package/src/transformers/utils/build.ts +0 -112
- package/src/transformers/utils/html.ts +16 -3
- package/src/types/README.md +2 -1
- package/src/types/config.ts +0 -21
- package/src/utils/path.ts +29 -0
- package/tsconfig.json +1 -1
- package/config/docs/playground.md +0 -14
- package/config/docs/system/alert.md +0 -30
- package/config/docs/system/button.md +0 -34
- package/config/docs/system/checkbox.md +0 -30
- package/config/docs/system/input.md +0 -31
- package/config/docs/system/modal.md +0 -32
- package/config/docs/system/pagination.md +0 -30
- package/config/docs/system/radio.md +0 -30
- package/config/docs/system/select.md +0 -30
- package/config/docs/system/switch.md +0 -30
- package/config/docs/system/tooltip.md +0 -30
- package/dist/app/components/Component/Cards.js +0 -17
- package/dist/app-builder/isr-paths.d.ts +0 -44
- package/dist/app-builder/isr-paths.js +0 -213
- package/dist/commands/isr/component.d.ts +0 -10
- package/dist/commands/isr/component.js +0 -63
- package/dist/commands/isr/pages.d.ts +0 -11
- package/dist/commands/isr/pages.js +0 -64
- package/dist/commands/platform/init.d.ts +0 -6
- package/dist/commands/platform/init.js +0 -231
- package/dist/commands/platform/login.d.ts +0 -6
- package/dist/commands/platform/login.js +0 -108
- package/dist/commands/platform/logout.d.ts +0 -6
- package/dist/commands/platform/logout.js +0 -88
- package/dist/commands/platform/pull.d.ts +0 -8
- package/dist/commands/platform/pull.js +0 -112
- package/dist/commands/platform/push.d.ts +0 -8
- package/dist/commands/platform/push.js +0 -428
- package/dist/pipeline/pages.d.ts +0 -6
- package/dist/pipeline/pages.js +0 -21
- package/dist/platform/client.d.ts +0 -122
- package/dist/platform/client.js +0 -228
- package/dist/platform/credentials.d.ts +0 -40
- package/dist/platform/credentials.js +0 -91
- package/dist/platform/sync.d.ts +0 -68
- package/dist/platform/sync.js +0 -349
- package/dist/transformers/preview/page/api.d.ts +0 -8
- package/dist/transformers/preview/page/api.js +0 -74
- package/dist/transformers/preview/page/builder.d.ts +0 -7
- package/dist/transformers/preview/page/builder.js +0 -173
- package/dist/transformers/preview/page/types.d.ts +0 -38
- package/dist/transformers/preview/page/types.js +0 -2
- package/docs/components.md +0 -107
- package/docs/isr.md +0 -113
- package/docs/pages.md +0 -152
- package/docs/rest.yml +0 -590
- package/docs/rest_api.md +0 -78
- package/eslint.config.mjs +0 -18
- package/handoff.config.js +0 -90
- package/src/app/components/Page/PageLists.tsx +0 -218
- package/src/app/components/Page/types.ts +0 -19
- package/src/app/components/Playground/ComponentCard.tsx +0 -78
- package/src/app/components/Playground/ComponentLibrary.tsx +0 -99
- package/src/app/components/Playground/EditContext.tsx +0 -159
- package/src/app/components/Playground/EditSheet.tsx +0 -80
- package/src/app/components/Playground/MediaBrowser.tsx +0 -56
- package/src/app/components/Playground/PlaygroundBuilder.tsx +0 -160
- package/src/app/components/Playground/PlaygroundContext.tsx +0 -276
- package/src/app/components/Playground/Preview.tsx +0 -174
- package/src/app/components/Playground/SortableItem.tsx +0 -45
- package/src/app/components/Playground/TemplateManager.tsx +0 -81
- package/src/app/components/Playground/Wizard/ApiKeySettings.tsx +0 -125
- package/src/app/components/Playground/Wizard/WizardDialog.tsx +0 -228
- package/src/app/components/Playground/Wizard/llm-client.ts +0 -87
- package/src/app/components/Playground/Wizard/prompt-builder.ts +0 -78
- package/src/app/components/Playground/Wizard/response-parser.ts +0 -81
- package/src/app/components/Playground/fields/ButtonField.tsx +0 -24
- package/src/app/components/Playground/fields/Field.tsx +0 -112
- package/src/app/components/Playground/fields/FieldLabel.tsx +0 -20
- package/src/app/components/Playground/fields/ImageField.tsx +0 -92
- package/src/app/components/Playground/fields/LinkField.tsx +0 -24
- package/src/app/components/Playground/fields/RichTextField.tsx +0 -34
- package/src/app/components/Playground/fields/TextField.tsx +0 -13
- package/src/app/components/Playground/types.ts +0 -30
- package/src/app/components/ui/dialog.tsx +0 -80
- package/src/app/components/ui/textarea.tsx +0 -19
- package/src/app/pages/playground/index.tsx +0 -30
- package/src/app/pages/system/page/[page]/index.tsx +0 -300
- package/src/app/pages/system/page/index.tsx +0 -124
- package/src/app-builder/isr-paths.ts +0 -209
- package/src/commands/isr/component.ts +0 -68
- package/src/commands/isr/pages.ts +0 -68
- package/src/commands/platform/init.ts +0 -229
- package/src/commands/platform/login.ts +0 -96
- package/src/commands/platform/logout.ts +0 -63
- package/src/commands/platform/pull.ts +0 -98
- package/src/commands/platform/push.ts +0 -469
- package/src/pipeline/pages.ts +0 -10
- package/src/platform/client.ts +0 -335
- package/src/platform/credentials.ts +0 -106
- package/src/platform/sync.ts +0 -428
- package/src/transformers/preview/page/api.ts +0 -65
- package/src/transformers/preview/page/builder.ts +0 -200
- package/src/transformers/preview/page/types.ts +0 -37
- package/test_components/example/example.js +0 -110
- package/test_components/example/style.scss +0 -56
- package/test_components/example/template.hbs +0 -19
- package/test_components/example-csf/example-csf.js +0 -16
- package/test_components/example-csf/style.scss +0 -52
- package/test_components/example-csf/template.stories.tsx +0 -97
- package/test_components/example-react/example-react.js +0 -69
- package/test_components/example-react/style.scss +0 -56
- package/test_components/example-react/template.tsx +0 -49
- package/test_pages/boilerplate/boilerplate.json +0 -73
package/dist/config/runtime.js
CHANGED
|
@@ -3,7 +3,7 @@ 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.initRuntimeConfig = void 0;
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const logger_1 = require("../utils/logger");
|
|
@@ -15,8 +15,8 @@ const logger_1 = require("../utils/logger");
|
|
|
15
15
|
* @returns A tuple of [RuntimeConfig, configFilePaths].
|
|
16
16
|
*/
|
|
17
17
|
const initRuntimeConfig = (handoff) => {
|
|
18
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
19
|
-
var
|
|
18
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
19
|
+
var _j;
|
|
20
20
|
const configFiles = [];
|
|
21
21
|
const result = {
|
|
22
22
|
options: {},
|
|
@@ -24,7 +24,6 @@ const initRuntimeConfig = (handoff) => {
|
|
|
24
24
|
scss: undefined,
|
|
25
25
|
js: undefined,
|
|
26
26
|
components: {},
|
|
27
|
-
pages: {},
|
|
28
27
|
},
|
|
29
28
|
};
|
|
30
29
|
if (!!((_a = handoff.config.entries) === null || _a === void 0 ? void 0 : _a.scss)) {
|
|
@@ -77,7 +76,7 @@ const initRuntimeConfig = (handoff) => {
|
|
|
77
76
|
component.options || (component.options = {
|
|
78
77
|
transformer: { defaults: {}, replace: {} },
|
|
79
78
|
});
|
|
80
|
-
(
|
|
79
|
+
(_j = component.options).transformer || (_j.transformer = { defaults: {}, replace: {} });
|
|
81
80
|
const transformer = component.options.transformer;
|
|
82
81
|
(_g = transformer.cssRootClass) !== null && _g !== void 0 ? _g : (transformer.cssRootClass = null);
|
|
83
82
|
(_h = transformer.tokenNameSegments) !== null && _h !== void 0 ? _h : (transformer.tokenNameSegments = null);
|
|
@@ -90,47 +89,6 @@ const initRuntimeConfig = (handoff) => {
|
|
|
90
89
|
result.entries.components[component.id] = component;
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
|
-
if ((_k = (_j = handoff.config.entries) === null || _j === void 0 ? void 0 : _j.pages) === null || _k === void 0 ? void 0 : _k.length) {
|
|
94
|
-
const pagePaths = handoff.config.entries.pages.flatMap(exports.getPagesForPath);
|
|
95
|
-
for (const pagePath of pagePaths) {
|
|
96
|
-
const resolvedPagePath = path_1.default.resolve(handoff.workingPath, pagePath);
|
|
97
|
-
const pageBaseName = path_1.default.basename(resolvedPagePath);
|
|
98
|
-
const possibleConfigFiles = [`${pageBaseName}.json`, `${pageBaseName}.js`, `${pageBaseName}.cjs`];
|
|
99
|
-
const configFileName = possibleConfigFiles.find((file) => fs_extra_1.default.existsSync(path_1.default.resolve(resolvedPagePath, file)));
|
|
100
|
-
if (!configFileName) {
|
|
101
|
-
logger_1.Logger.warn(`Missing page config: ${path_1.default.resolve(resolvedPagePath, possibleConfigFiles.join(' or '))}`);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
const resolvedPageConfigPath = path_1.default.resolve(resolvedPagePath, configFileName);
|
|
105
|
-
configFiles.push(resolvedPageConfigPath);
|
|
106
|
-
let page;
|
|
107
|
-
try {
|
|
108
|
-
if (configFileName.endsWith('.json')) {
|
|
109
|
-
const pageJson = fs_extra_1.default.readFileSync(resolvedPageConfigPath, 'utf8');
|
|
110
|
-
page = JSON.parse(pageJson);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
delete require.cache[require.resolve(resolvedPageConfigPath)];
|
|
114
|
-
const importedPage = require(resolvedPageConfigPath);
|
|
115
|
-
page = importedPage.default || importedPage;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
logger_1.Logger.error(`Failed to read or parse page config: ${resolvedPageConfigPath}`, err);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
page.id = pageBaseName;
|
|
123
|
-
// Validate that referenced components exist
|
|
124
|
-
if (page.components) {
|
|
125
|
-
for (const componentId of page.components) {
|
|
126
|
-
if (!result.entries.components[componentId]) {
|
|
127
|
-
logger_1.Logger.warn(`Page '${page.id}' references unknown component '${componentId}'`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
result.entries.pages[page.id] = page;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
92
|
return [result, Array.from(configFiles)];
|
|
135
93
|
};
|
|
136
94
|
exports.initRuntimeConfig = initRuntimeConfig;
|
|
@@ -170,27 +128,6 @@ const getComponentsForPath = (searchPath) => {
|
|
|
170
128
|
return [searchPath];
|
|
171
129
|
};
|
|
172
130
|
exports.getComponentsForPath = getComponentsForPath;
|
|
173
|
-
/**
|
|
174
|
-
* Returns a list of page directories for a given path.
|
|
175
|
-
* Mirrors getComponentsForPath but for page definitions.
|
|
176
|
-
*/
|
|
177
|
-
const getPagesForPath = (searchPath) => {
|
|
178
|
-
const dirName = path_1.default.basename(searchPath);
|
|
179
|
-
const possibleConfigFiles = [`${dirName}.json`, `${dirName}.js`, `${dirName}.cjs`];
|
|
180
|
-
const hasOwnConfig = possibleConfigFiles.some((file) => fs_extra_1.default.existsSync(path_1.default.resolve(searchPath, file)));
|
|
181
|
-
if (hasOwnConfig) {
|
|
182
|
-
return [searchPath];
|
|
183
|
-
}
|
|
184
|
-
const subdirectories = fs_extra_1.default
|
|
185
|
-
.readdirSync(searchPath, { withFileTypes: true })
|
|
186
|
-
.filter((entry) => entry.isDirectory())
|
|
187
|
-
.map((entry) => entry.name);
|
|
188
|
-
if (subdirectories.length > 0) {
|
|
189
|
-
return subdirectories.map((subdir) => path_1.default.join(searchPath, subdir));
|
|
190
|
-
}
|
|
191
|
-
return [searchPath];
|
|
192
|
-
};
|
|
193
|
-
exports.getPagesForPath = getPagesForPath;
|
|
194
131
|
/**
|
|
195
132
|
* Recursively converts all keys and string values in an object to lowercase.
|
|
196
133
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -26,10 +26,7 @@ declare class Handoff {
|
|
|
26
26
|
preRunner(validate?: boolean): Handoff;
|
|
27
27
|
fetch(): Promise<Handoff>;
|
|
28
28
|
component(name: string | null): Promise<Handoff>;
|
|
29
|
-
build(skipComponents?: boolean
|
|
30
|
-
copyOnlyPaths?: string[];
|
|
31
|
-
deployDir?: string;
|
|
32
|
-
}): Promise<Handoff>;
|
|
29
|
+
build(skipComponents?: boolean): Promise<Handoff>;
|
|
33
30
|
ejectConfig(): Promise<Handoff>;
|
|
34
31
|
ejectPages(): Promise<Handoff>;
|
|
35
32
|
ejectTheme(): Promise<Handoff>;
|
package/dist/index.js
CHANGED
|
@@ -114,10 +114,10 @@ class Handoff {
|
|
|
114
114
|
return this;
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
|
-
build(skipComponents
|
|
117
|
+
build(skipComponents) {
|
|
118
118
|
return __awaiter(this, void 0, void 0, function* () {
|
|
119
119
|
this.preRunner();
|
|
120
|
-
yield (0, app_builder_1.default)(this, skipComponents
|
|
120
|
+
yield (0, app_builder_1.default)(this, skipComponents);
|
|
121
121
|
return this;
|
|
122
122
|
});
|
|
123
123
|
}
|
package/dist/pipeline/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import 'dotenv/config';
|
|
|
2
2
|
import Handoff from '..';
|
|
3
3
|
export { readPrevJSONFile, zip, zipAssets } from './archive';
|
|
4
4
|
export { buildComponents } from './components';
|
|
5
|
-
export { buildPages } from './pages';
|
|
6
5
|
/**
|
|
7
6
|
* Run the entire Figma data pipeline:
|
|
8
7
|
* 1. Validate runtime requirements
|
package/dist/pipeline/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.buildComponents = exports.zipAssets = exports.zip = exports.readPrevJSONFile = void 0;
|
|
16
16
|
require("dotenv/config");
|
|
17
17
|
const app_builder_1 = __importDefault(require("../app-builder"));
|
|
18
18
|
const logger_1 = require("../utils/logger");
|
|
@@ -26,8 +26,6 @@ Object.defineProperty(exports, "zip", { enumerable: true, get: function () { ret
|
|
|
26
26
|
Object.defineProperty(exports, "zipAssets", { enumerable: true, get: function () { return archive_1.zipAssets; } });
|
|
27
27
|
var components_1 = require("./components");
|
|
28
28
|
Object.defineProperty(exports, "buildComponents", { enumerable: true, get: function () { return components_1.buildComponents; } });
|
|
29
|
-
var pages_1 = require("./pages");
|
|
30
|
-
Object.defineProperty(exports, "buildPages", { enumerable: true, get: function () { return pages_1.buildPages; } });
|
|
31
29
|
/**
|
|
32
30
|
* Run the entire Figma data pipeline:
|
|
33
31
|
* 1. Validate runtime requirements
|
|
@@ -20,7 +20,6 @@ const react_1 = __importDefault(require("react"));
|
|
|
20
20
|
const server_1 = __importDefault(require("react-dom/server"));
|
|
21
21
|
const logger_1 = require("../../utils/logger");
|
|
22
22
|
const component_1 = require("../preview/component");
|
|
23
|
-
const build_1 = require("../utils/build");
|
|
24
23
|
const html_1 = require("../utils/html");
|
|
25
24
|
const module_1 = require("../utils/module");
|
|
26
25
|
const schema_1 = require("../utils/schema");
|
|
@@ -154,7 +153,7 @@ function csfRenderPlugin(componentData, _documentationComponents, handoff) {
|
|
|
154
153
|
},
|
|
155
154
|
generateBundle(_, bundle) {
|
|
156
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
var _a, _b, _c, _d, _e
|
|
156
|
+
var _a, _b, _c, _d, _e;
|
|
158
157
|
for (const [fileName, chunkInfo] of Object.entries(bundle)) {
|
|
159
158
|
if (chunkInfo.type === 'chunk' && fileName.includes(PLUGIN_CONSTANTS.SCRIPT_ID)) {
|
|
160
159
|
delete bundle[fileName];
|
|
@@ -261,22 +260,6 @@ function csfRenderPlugin(componentData, _documentationComponents, handoff) {
|
|
|
261
260
|
preview.url = fileName;
|
|
262
261
|
lastHtml = html;
|
|
263
262
|
}
|
|
264
|
-
// Emit standalone client module for Playground live rendering
|
|
265
|
-
const firstStoryKey = (_f = stories[0]) === null || _f === void 0 ? void 0 : _f[0];
|
|
266
|
-
if (firstStoryKey) {
|
|
267
|
-
try {
|
|
268
|
-
const clientModuleSource = (0, build_1.generateCsfClientComponentSource)(templatePath, firstStoryKey);
|
|
269
|
-
const clientModuleJs = yield (0, build_1.buildClientModule)(clientModuleSource, handoff);
|
|
270
|
-
this.emitFile({
|
|
271
|
-
type: 'asset',
|
|
272
|
-
fileName: `${componentId}.module.js`,
|
|
273
|
-
source: clientModuleJs,
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
catch (error) {
|
|
277
|
-
logger_1.Logger.warn(`Failed to build client module for ${componentId}: ${error}`);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
263
|
componentData.format = 'react';
|
|
281
264
|
componentData.preview = '';
|
|
282
265
|
componentData.code = (0, html_1.trimPreview)(sourceCode);
|
|
@@ -131,6 +131,16 @@ function handlebarsPreviewsPlugin(componentData, documentationComponents, handof
|
|
|
131
131
|
}
|
|
132
132
|
// Process component instances from documentation
|
|
133
133
|
processComponentInstances(componentData, documentationComponents);
|
|
134
|
+
if (!componentData.previews || Object.keys(componentData.previews).length === 0) {
|
|
135
|
+
logger_1.Logger.warn(`No previews defined for ${componentId}; using default preview values.`);
|
|
136
|
+
componentData.previews = {
|
|
137
|
+
default: {
|
|
138
|
+
title: 'Default',
|
|
139
|
+
values: {},
|
|
140
|
+
url: '',
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
134
144
|
const generatedPreviews = {};
|
|
135
145
|
// Generate previews for each variation
|
|
136
146
|
for (const previewKey in componentData.previews) {
|
|
@@ -153,7 +163,8 @@ function handlebarsPreviewsPlugin(componentData, documentationComponents, handof
|
|
|
153
163
|
componentData.format = PLUGIN_CONSTANTS.OUTPUT_FORMAT;
|
|
154
164
|
componentData.preview = '';
|
|
155
165
|
componentData.code = (0, html_1.trimPreview)(templateContent);
|
|
156
|
-
|
|
166
|
+
const firstGeneratedPreview = Object.values(generatedPreviews)[0];
|
|
167
|
+
componentData.html = (0, html_1.trimPreview)(firstGeneratedPreview !== null && firstGeneratedPreview !== void 0 ? firstGeneratedPreview : templateContent);
|
|
157
168
|
});
|
|
158
169
|
},
|
|
159
170
|
};
|
|
@@ -257,20 +257,6 @@ function ssrRenderPlugin(componentData, documentationComponents, handoff) {
|
|
|
257
257
|
generatedPreviews[previewKey] = finalHtml;
|
|
258
258
|
componentData.previews[previewKey].url = `${componentId}-${previewKey}.html`;
|
|
259
259
|
}
|
|
260
|
-
// Emit standalone client module for Playground live rendering
|
|
261
|
-
console.log('Emmiting Module componentPath', componentId, componentPath);
|
|
262
|
-
try {
|
|
263
|
-
const clientModuleSource = (0, build_1.generateClientComponentSource)(componentPath);
|
|
264
|
-
const clientModuleJs = yield (0, build_1.buildClientModule)(clientModuleSource, handoff);
|
|
265
|
-
this.emitFile({
|
|
266
|
-
type: 'asset',
|
|
267
|
-
fileName: `${componentId}.module.js`,
|
|
268
|
-
source: clientModuleJs,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
catch (error) {
|
|
272
|
-
logger_1.Logger.warn(`Failed to build client module for ${componentId}: ${error}`);
|
|
273
|
-
}
|
|
274
260
|
// Format final HTML and update component data
|
|
275
261
|
finalHtml = yield (0, html_1.formatHtml)(finalHtml);
|
|
276
262
|
componentData.format = 'react';
|
|
@@ -66,6 +66,19 @@ var ComponentSegment;
|
|
|
66
66
|
ComponentSegment["Previews"] = "previews";
|
|
67
67
|
ComponentSegment["Validation"] = "validation";
|
|
68
68
|
})(ComponentSegment || (exports.ComponentSegment = ComponentSegment = {}));
|
|
69
|
+
const ensureDefaultPreview = (data) => {
|
|
70
|
+
if (!data)
|
|
71
|
+
return;
|
|
72
|
+
if (!data.previews || Object.keys(data.previews).length === 0) {
|
|
73
|
+
data.previews = {
|
|
74
|
+
default: {
|
|
75
|
+
title: 'Default',
|
|
76
|
+
values: {},
|
|
77
|
+
url: '',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
69
82
|
/**
|
|
70
83
|
* Returns a normalized build plan describing which component segments need rebuilding.
|
|
71
84
|
*
|
|
@@ -200,7 +213,7 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
200
213
|
// those will override this default (standard "config overrides defaults" behavior).
|
|
201
214
|
if (!restMetadata.figmaComponentId) {
|
|
202
215
|
componentDefaults.previews = {
|
|
203
|
-
|
|
216
|
+
default: {
|
|
204
217
|
title: 'Default',
|
|
205
218
|
values: {},
|
|
206
219
|
url: '',
|
|
@@ -246,6 +259,8 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
246
259
|
data.properties = existingData.properties;
|
|
247
260
|
}
|
|
248
261
|
}
|
|
262
|
+
// Components should always have at least one preview variation.
|
|
263
|
+
ensureDefaultPreview(data);
|
|
249
264
|
// Build JS if needed (new build, validation missing, or explicit segment request).
|
|
250
265
|
if (buildPlan.js) {
|
|
251
266
|
data = yield (0, javascript_1.default)(data, handoff);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import esbuild from 'esbuild';
|
|
2
|
-
import Handoff from '../../index';
|
|
3
2
|
/**
|
|
4
3
|
* Default esbuild configuration for SSR builds
|
|
5
4
|
*/
|
|
@@ -26,20 +25,3 @@ export declare function createReactResolvePlugin(workingPath: string, handoffMod
|
|
|
26
25
|
name: string;
|
|
27
26
|
setup(build: any): void;
|
|
28
27
|
};
|
|
29
|
-
/**
|
|
30
|
-
* Generates the entry source for a standalone client-side React component module.
|
|
31
|
-
* The resulting module exports `render(container, props)` and `update(props)`
|
|
32
|
-
* so the Playground can dynamically load and re-render it in an iframe.
|
|
33
|
-
*/
|
|
34
|
-
export declare function generateClientComponentSource(componentPath: string): string;
|
|
35
|
-
/**
|
|
36
|
-
* Generates the entry source for a standalone CSF component module.
|
|
37
|
-
* Replicates the story rendering logic (meta.render / story.render / meta.component)
|
|
38
|
-
* so the Playground can render CSF components client-side.
|
|
39
|
-
*/
|
|
40
|
-
export declare function generateCsfClientComponentSource(componentPath: string, storyKey: string): string;
|
|
41
|
-
/**
|
|
42
|
-
* Builds a self-contained browser ESM module from the given source code.
|
|
43
|
-
* React and ReactDOM are bundled into the output so the module works standalone.
|
|
44
|
-
*/
|
|
45
|
-
export declare function buildClientModule(sourceCode: string, handoff: Handoff): Promise<string>;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -15,12 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
6
|
exports.DEFAULT_CLIENT_BUILD_CONFIG = exports.DEFAULT_SSR_BUILD_CONFIG = void 0;
|
|
16
7
|
exports.resolveModule = resolveModule;
|
|
17
8
|
exports.createReactResolvePlugin = createReactResolvePlugin;
|
|
18
|
-
exports.generateClientComponentSource = generateClientComponentSource;
|
|
19
|
-
exports.generateCsfClientComponentSource = generateCsfClientComponentSource;
|
|
20
|
-
exports.buildClientModule = buildClientModule;
|
|
21
|
-
const esbuild_1 = __importDefault(require("esbuild"));
|
|
22
9
|
const path_1 = __importDefault(require("path"));
|
|
23
|
-
const logger_1 = require("../../utils/logger");
|
|
24
10
|
/**
|
|
25
11
|
* Default esbuild configuration for SSR builds
|
|
26
12
|
*/
|
|
@@ -88,97 +74,3 @@ function createReactResolvePlugin(workingPath, handoffModulePath) {
|
|
|
88
74
|
},
|
|
89
75
|
};
|
|
90
76
|
}
|
|
91
|
-
function toForwardSlash(p) {
|
|
92
|
-
return p.replace(/\\/g, '/');
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Generates the entry source for a standalone client-side React component module.
|
|
96
|
-
* The resulting module exports `render(container, props)` and `update(props)`
|
|
97
|
-
* so the Playground can dynamically load and re-render it in an iframe.
|
|
98
|
-
*/
|
|
99
|
-
function generateClientComponentSource(componentPath) {
|
|
100
|
-
return `
|
|
101
|
-
import React from 'react';
|
|
102
|
-
import { createRoot } from 'react-dom/client';
|
|
103
|
-
import Component from '${toForwardSlash(componentPath)}';
|
|
104
|
-
|
|
105
|
-
let root = null;
|
|
106
|
-
|
|
107
|
-
export function render(container, props) {
|
|
108
|
-
root = createRoot(container);
|
|
109
|
-
root.render(React.createElement(Component, props));
|
|
110
|
-
return root;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function update(props) {
|
|
114
|
-
if (root) {
|
|
115
|
-
root.render(React.createElement(Component, props));
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
`;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Generates the entry source for a standalone CSF component module.
|
|
122
|
-
* Replicates the story rendering logic (meta.render / story.render / meta.component)
|
|
123
|
-
* so the Playground can render CSF components client-side.
|
|
124
|
-
*/
|
|
125
|
-
function generateCsfClientComponentSource(componentPath, storyKey) {
|
|
126
|
-
return `
|
|
127
|
-
import React from 'react';
|
|
128
|
-
import { createRoot } from 'react-dom/client';
|
|
129
|
-
import * as stories from '${toForwardSlash(componentPath)}';
|
|
130
|
-
|
|
131
|
-
const meta = stories.default || {};
|
|
132
|
-
const story = stories['${storyKey}'];
|
|
133
|
-
|
|
134
|
-
let root = null;
|
|
135
|
-
|
|
136
|
-
function renderElement(props) {
|
|
137
|
-
const storyRender = typeof story === 'function' ? story : (story && story.render);
|
|
138
|
-
const renderFn = storyRender || meta.render;
|
|
139
|
-
if (renderFn) {
|
|
140
|
-
const result = renderFn(props);
|
|
141
|
-
return React.isValidElement(result) ? result : React.createElement(meta.component, props);
|
|
142
|
-
}
|
|
143
|
-
if (meta.component) {
|
|
144
|
-
return React.createElement(meta.component, props);
|
|
145
|
-
}
|
|
146
|
-
return React.createElement('pre', null, JSON.stringify(props, null, 2));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function render(container, props) {
|
|
150
|
-
root = createRoot(container);
|
|
151
|
-
root.render(renderElement(props));
|
|
152
|
-
return root;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function update(props) {
|
|
156
|
-
if (root) {
|
|
157
|
-
root.render(renderElement(props));
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
`;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Builds a self-contained browser ESM module from the given source code.
|
|
164
|
-
* React and ReactDOM are bundled into the output so the module works standalone.
|
|
165
|
-
*/
|
|
166
|
-
function buildClientModule(sourceCode, handoff) {
|
|
167
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
-
var _a, _b;
|
|
169
|
-
const config = Object.assign(Object.assign({}, exports.DEFAULT_CLIENT_BUILD_CONFIG), { logLevel: 'silent', stdin: {
|
|
170
|
-
contents: sourceCode,
|
|
171
|
-
resolveDir: process.cwd(),
|
|
172
|
-
loader: 'tsx',
|
|
173
|
-
}, plugins: [createReactResolvePlugin(handoff.workingPath, handoff.modulePath)] });
|
|
174
|
-
const finalConfig = ((_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b.clientBuildConfig)
|
|
175
|
-
? handoff.config.hooks.clientBuildConfig(config)
|
|
176
|
-
: config;
|
|
177
|
-
const result = yield esbuild_1.default.build(finalConfig);
|
|
178
|
-
if (result.warnings.length > 0) {
|
|
179
|
-
const messages = yield esbuild_1.default.formatMessages(result.warnings, { kind: 'warning', color: true });
|
|
180
|
-
messages.forEach((msg) => logger_1.Logger.warn(msg));
|
|
181
|
-
}
|
|
182
|
-
return result.outputFiles[0].text;
|
|
183
|
-
});
|
|
184
|
-
}
|
|
@@ -21,9 +21,21 @@ const prettier_1 = __importDefault(require("prettier"));
|
|
|
21
21
|
* @returns Trimmed HTML content
|
|
22
22
|
*/
|
|
23
23
|
const trimPreview = (preview) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
if (typeof preview !== 'string') {
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
const normalizedPreview = preview.trim();
|
|
28
|
+
if (!normalizedPreview) {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const bodyEl = (0, node_html_parser_1.parse)(normalizedPreview).querySelector('body');
|
|
33
|
+
return bodyEl ? bodyEl.innerHTML.trim() : normalizedPreview;
|
|
34
|
+
}
|
|
35
|
+
catch (_a) {
|
|
36
|
+
// Keep build resilient if parser fails on malformed HTML.
|
|
37
|
+
return normalizedPreview;
|
|
38
|
+
}
|
|
27
39
|
};
|
|
28
40
|
exports.trimPreview = trimPreview;
|
|
29
41
|
/**
|
package/dist/types/config.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { Types as HandoffTypes } from 'handoff-core';
|
|
|
3
3
|
import { InlineConfig } from 'vite';
|
|
4
4
|
import { SlotMetadata } from '../transformers/preview/component';
|
|
5
5
|
import { ComponentListObject, TransformComponentTokensResult } from '../transformers/preview/types';
|
|
6
|
-
import { PageListObject } from '../transformers/preview/page/types';
|
|
7
6
|
import { ValidationResult } from './preview';
|
|
8
7
|
export interface ImageStyle {
|
|
9
8
|
name: string;
|
|
@@ -114,11 +113,6 @@ export interface Config {
|
|
|
114
113
|
* @example ["components/button", "components/input"]
|
|
115
114
|
*/
|
|
116
115
|
components?: string[];
|
|
117
|
-
/**
|
|
118
|
-
* Array of page paths to be included in the build
|
|
119
|
-
* @example ["pages/homepage", "pages/about"]
|
|
120
|
-
*/
|
|
121
|
-
pages?: string[];
|
|
122
116
|
};
|
|
123
117
|
/**
|
|
124
118
|
* Configuration for asset zip file download links
|
|
@@ -136,16 +130,6 @@ export interface Config {
|
|
|
136
130
|
*/
|
|
137
131
|
logos?: string;
|
|
138
132
|
};
|
|
139
|
-
/**
|
|
140
|
-
* Platform project ID (UUID). Set by `platform:init` to link this
|
|
141
|
-
* local project with a remote handoff-service project.
|
|
142
|
-
*/
|
|
143
|
-
platformProjectId?: string;
|
|
144
|
-
/**
|
|
145
|
-
* Platform base URL (e.g. "http://localhost:3000" or "https://handoff.example.com").
|
|
146
|
-
* Set by `platform:init` so subsequent sync commands know where to connect.
|
|
147
|
-
*/
|
|
148
|
-
platformUrl?: string;
|
|
149
133
|
/**
|
|
150
134
|
* Configuration hooks for extending functionality
|
|
151
135
|
*/
|
|
@@ -277,9 +261,6 @@ export interface RuntimeConfig {
|
|
|
277
261
|
components: {
|
|
278
262
|
[id: string]: ComponentListObject;
|
|
279
263
|
};
|
|
280
|
-
pages: {
|
|
281
|
-
[id: string]: PageListObject;
|
|
282
|
-
};
|
|
283
264
|
};
|
|
284
265
|
options: {
|
|
285
266
|
[key: string]: RuntimeConfigComponentOptions;
|
package/dist/utils/path.d.ts
CHANGED
|
@@ -4,3 +4,18 @@
|
|
|
4
4
|
* @returns A filesystem-safe string suitable for use as a directory name
|
|
5
5
|
*/
|
|
6
6
|
export declare function generateFilesystemSafeId(workingPath: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a filesystem path for cross-platform string comparison.
|
|
9
|
+
* - Resolves to absolute path
|
|
10
|
+
* - Normalizes separators to forward slashes
|
|
11
|
+
* - Lowercases on Windows where paths are case-insensitive
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizePathForCompare(inputPath: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* True when both paths resolve to the same normalized filesystem path.
|
|
16
|
+
*/
|
|
17
|
+
export declare function arePathsEqual(pathA: string, pathB: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* True when childPath is equal to or within parentPath.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isPathInside(childPath: string, parentPath: string): boolean;
|
package/dist/utils/path.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.generateFilesystemSafeId = generateFilesystemSafeId;
|
|
7
|
+
exports.normalizePathForCompare = normalizePathForCompare;
|
|
8
|
+
exports.arePathsEqual = arePathsEqual;
|
|
9
|
+
exports.isPathInside = isPathInside;
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
4
11
|
/**
|
|
5
12
|
* Generates a filesystem-safe directory name from an absolute path
|
|
6
13
|
* @param workingPath - The absolute working path to transform
|
|
@@ -26,3 +33,27 @@ function generateFilesystemSafeId(workingPath) {
|
|
|
26
33
|
}
|
|
27
34
|
return safeId;
|
|
28
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Normalize a filesystem path for cross-platform string comparison.
|
|
38
|
+
* - Resolves to absolute path
|
|
39
|
+
* - Normalizes separators to forward slashes
|
|
40
|
+
* - Lowercases on Windows where paths are case-insensitive
|
|
41
|
+
*/
|
|
42
|
+
function normalizePathForCompare(inputPath) {
|
|
43
|
+
const normalized = path_1.default.resolve(inputPath).replace(/\\/g, '/');
|
|
44
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* True when both paths resolve to the same normalized filesystem path.
|
|
48
|
+
*/
|
|
49
|
+
function arePathsEqual(pathA, pathB) {
|
|
50
|
+
return normalizePathForCompare(pathA) === normalizePathForCompare(pathB);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* True when childPath is equal to or within parentPath.
|
|
54
|
+
*/
|
|
55
|
+
function isPathInside(childPath, parentPath) {
|
|
56
|
+
const normalizedChild = normalizePathForCompare(childPath);
|
|
57
|
+
const normalizedParent = normalizePathForCompare(parentPath);
|
|
58
|
+
return normalizedChild === normalizedParent || normalizedChild.startsWith(`${normalizedParent}/`);
|
|
59
|
+
}
|