handoff-app 1.1.0-experimental.2 → 1.1.0-experimental.3
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/dist/app-builder/build.d.ts +2 -0
- package/dist/app-builder/build.js +12 -7
- package/dist/app-builder/isr-paths.d.ts +9 -0
- package/dist/app-builder/isr-paths.js +29 -0
- package/dist/app-builder/watchers.d.ts +2 -2
- package/dist/app-builder/watchers.js +24 -24
- package/dist/commands/index.js +2 -0
- package/dist/commands/isr/pattern.d.ts +10 -0
- package/dist/commands/isr/pattern.js +63 -0
- package/dist/config/runtime.d.ts +3 -3
- package/dist/config/runtime.js +28 -28
- package/dist/index.d.ts +1 -0
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/index.js +3 -3
- package/dist/pipeline/patterns.d.ts +6 -0
- package/dist/pipeline/{pages.js → patterns.js} +6 -6
- package/dist/transformers/plugins/csf-render.js +16 -9
- package/dist/transformers/plugins/handlebars-previews.js +2 -0
- package/dist/transformers/preview/component/css.d.ts +1 -0
- package/dist/transformers/preview/component.d.ts +4 -0
- package/dist/transformers/preview/pattern/api.d.ts +8 -0
- package/dist/transformers/preview/{page → pattern}/api.js +25 -25
- package/dist/transformers/preview/pattern/builder.d.ts +7 -0
- package/dist/transformers/preview/{page → pattern}/builder.js +53 -51
- package/dist/transformers/preview/pattern/types.d.ts +47 -0
- package/dist/transformers/preview/types.d.ts +4 -0
- package/dist/transformers/utils/handlebars.d.ts +1 -0
- package/dist/transformers/utils/handlebars.js +5 -1
- package/dist/types/config.d.ts +6 -6
- package/docs/pages.md +22 -22
- package/handoff.config.js +1 -1
- package/package.json +1 -1
- package/src/app/components/{Page/PageLists.tsx → Pattern/PatternLists.tsx} +35 -35
- package/src/app/components/{Page → Pattern}/types.ts +1 -1
- package/src/app/components/Playground/PlaygroundBuilder.tsx +51 -5
- package/src/app/components/Playground/Preview.tsx +15 -3
- package/src/app/components/Playground/fields/Field.tsx +16 -1
- package/src/app/components/Playground/fields/SelectField.tsx +45 -0
- package/src/app/components/Playground/types.ts +16 -0
- package/src/app/components/util/index.ts +22 -22
- package/src/app/pages/system/{page/[page] → pattern/[pattern]}/index.tsx +48 -48
- package/src/app/pages/system/{page → pattern}/index.tsx +21 -21
- package/src/app-builder/build.ts +13 -9
- package/src/app-builder/isr-paths.ts +29 -0
- package/src/app-builder/watchers.ts +22 -22
- package/src/commands/index.ts +2 -0
- package/src/commands/isr/pattern.ts +68 -0
- package/src/config/runtime.ts +27 -27
- package/src/index.ts +1 -1
- package/src/pipeline/index.ts +1 -1
- package/src/pipeline/patterns.ts +10 -0
- package/src/transformers/plugins/csf-render.ts +13 -6
- package/src/transformers/plugins/handlebars-previews.ts +1 -0
- package/src/transformers/preview/component.ts +2 -0
- package/src/transformers/preview/pattern/api.ts +65 -0
- package/src/transformers/preview/{page → pattern}/builder.ts +57 -55
- package/src/transformers/preview/pattern/types.ts +46 -0
- package/src/transformers/preview/types.ts +4 -0
- package/src/transformers/utils/handlebars.ts +6 -2
- package/src/types/config.ts +6 -6
- package/test_components/example-react/template.tsx +1 -4
- package/{test_pages → test_patterns}/boilerplate/boilerplate.json +3 -0
- package/dist/pipeline/pages.d.ts +0 -6
- package/dist/transformers/preview/page/api.d.ts +0 -8
- package/dist/transformers/preview/page/builder.d.ts +0 -7
- package/dist/transformers/preview/page/types.d.ts +0 -38
- package/src/pipeline/pages.ts +0 -10
- package/src/transformers/preview/page/api.ts +0 -65
- package/src/transformers/preview/page/types.ts +0 -37
- /package/dist/transformers/preview/{page → pattern}/types.js +0 -0
|
@@ -3,10 +3,12 @@ import Handoff from '..';
|
|
|
3
3
|
* Build the Next.js documentation application.
|
|
4
4
|
* @param copyOnlyPaths - If set, do not remove output dir; copy only these paths (relative to out/) into existing output (merge).
|
|
5
5
|
* @param deployDir - If set, copy output to this directory instead of default (workingPath/sitesDirectory/projectId).
|
|
6
|
+
* @param skipPatterns - If true, skip the pattern build step (useful when patterns were pre-processed for ISR).
|
|
6
7
|
*/
|
|
7
8
|
declare const buildApp: (handoff: Handoff, skipComponents?: boolean, options?: {
|
|
8
9
|
copyOnlyPaths?: string[];
|
|
9
10
|
deployDir?: string;
|
|
11
|
+
skipPatterns?: boolean;
|
|
10
12
|
}) => Promise<void>;
|
|
11
13
|
/**
|
|
12
14
|
* Watch the Next.js application.
|
|
@@ -17,14 +17,14 @@ const cross_spawn_1 = __importDefault(require("cross-spawn"));
|
|
|
17
17
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
18
18
|
const path_1 = __importDefault(require("path"));
|
|
19
19
|
const components_1 = require("../pipeline/components");
|
|
20
|
-
const
|
|
20
|
+
const patterns_1 = require("../pipeline/patterns");
|
|
21
21
|
const builder_1 = __importDefault(require("../transformers/preview/component/builder"));
|
|
22
22
|
const css_1 = require("../transformers/preview/component/css");
|
|
23
23
|
const javascript_1 = require("../transformers/preview/component/javascript");
|
|
24
24
|
const logger_1 = require("../utils/logger");
|
|
25
25
|
const client_config_1 = require("./client-config");
|
|
26
26
|
const paths_1 = require("./paths");
|
|
27
|
-
const builder_2 = require("../transformers/preview/
|
|
27
|
+
const builder_2 = require("../transformers/preview/pattern/builder");
|
|
28
28
|
const watchers_1 = require("./watchers");
|
|
29
29
|
const websocket_1 = require("./websocket");
|
|
30
30
|
/**
|
|
@@ -85,9 +85,12 @@ const initializeProjectApp = (handoff) => __awaiter(void 0, void 0, void 0, func
|
|
|
85
85
|
* Build the Next.js documentation application.
|
|
86
86
|
* @param copyOnlyPaths - If set, do not remove output dir; copy only these paths (relative to out/) into existing output (merge).
|
|
87
87
|
* @param deployDir - If set, copy output to this directory instead of default (workingPath/sitesDirectory/projectId).
|
|
88
|
+
* @param skipPatterns - If true, skip the pattern build step (useful when patterns were pre-processed for ISR).
|
|
88
89
|
*/
|
|
89
90
|
const buildApp = (handoff, skipComponents, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
var _a;
|
|
90
92
|
skipComponents = skipComponents !== null && skipComponents !== void 0 ? skipComponents : false;
|
|
93
|
+
const skipPatterns = (_a = options === null || options === void 0 ? void 0 : options.skipPatterns) !== null && _a !== void 0 ? _a : false;
|
|
91
94
|
const copyOnlyPaths = options === null || options === void 0 ? void 0 : options.copyOnlyPaths;
|
|
92
95
|
const deployDir = options === null || options === void 0 ? void 0 : options.deployDir;
|
|
93
96
|
// Perform cleanup
|
|
@@ -96,8 +99,10 @@ const buildApp = (handoff, skipComponents, options) => __awaiter(void 0, void 0,
|
|
|
96
99
|
if (!skipComponents) {
|
|
97
100
|
yield (0, components_1.buildComponents)(handoff);
|
|
98
101
|
}
|
|
99
|
-
// Build
|
|
100
|
-
|
|
102
|
+
// Build patterns (must run after components so rendered outputs exist)
|
|
103
|
+
if (!skipPatterns) {
|
|
104
|
+
yield (0, patterns_1.buildPatterns)(handoff);
|
|
105
|
+
}
|
|
101
106
|
// Prepare app
|
|
102
107
|
const appPath = yield initializeProjectApp(handoff);
|
|
103
108
|
yield (0, client_config_1.persistClientConfig)(handoff);
|
|
@@ -154,8 +159,8 @@ const watchApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
154
159
|
yield (0, builder_1.default)(handoff, undefined, undefined, { useCache: true });
|
|
155
160
|
yield (0, javascript_1.buildMainJS)(handoff);
|
|
156
161
|
yield (0, css_1.buildMainCss)(handoff);
|
|
157
|
-
// Build
|
|
158
|
-
yield (0, builder_2.
|
|
162
|
+
// Build patterns after components
|
|
163
|
+
yield (0, builder_2.processPatterns)(handoff);
|
|
159
164
|
const appPath = yield initializeProjectApp(handoff);
|
|
160
165
|
// Persist client configuration
|
|
161
166
|
yield (0, client_config_1.persistClientConfig)(handoff);
|
|
@@ -200,7 +205,7 @@ const watchApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
200
205
|
(0, watchers_1.watchRuntimeConfiguration)(handoff, state);
|
|
201
206
|
(0, watchers_1.watchGlobalEntries)(handoff, state, chokidarConfig);
|
|
202
207
|
(0, watchers_1.watchPages)(handoff, chokidarConfig);
|
|
203
|
-
(0, watchers_1.
|
|
208
|
+
(0, watchers_1.watchRuntimePatterns)(handoff, state);
|
|
204
209
|
});
|
|
205
210
|
exports.watchApp = watchApp;
|
|
206
211
|
/**
|
|
@@ -42,3 +42,12 @@ export declare function resolveComponentAffectedOutputPaths(componentId: string)
|
|
|
42
42
|
* Resolve affected output paths for multiple components (union).
|
|
43
43
|
*/
|
|
44
44
|
export declare function resolveComponentAffectedOutputPathsBatch(componentIds: string[]): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Resolve affected static output file paths for a pattern ISR update.
|
|
47
|
+
* Returns paths under out/ for the pattern API JSON and summary.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolvePatternAffectedOutputPaths(patternId: string): string[];
|
|
50
|
+
/**
|
|
51
|
+
* Resolve affected output paths for multiple patterns (union).
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolvePatternAffectedOutputPathsBatch(patternIds: string[]): string[];
|
|
@@ -10,6 +10,8 @@ exports.routePathToOutputPaths = routePathToOutputPaths;
|
|
|
10
10
|
exports.resolveAffectedOutputPaths = resolveAffectedOutputPaths;
|
|
11
11
|
exports.resolveComponentAffectedOutputPaths = resolveComponentAffectedOutputPaths;
|
|
12
12
|
exports.resolveComponentAffectedOutputPathsBatch = resolveComponentAffectedOutputPathsBatch;
|
|
13
|
+
exports.resolvePatternAffectedOutputPaths = resolvePatternAffectedOutputPaths;
|
|
14
|
+
exports.resolvePatternAffectedOutputPathsBatch = resolvePatternAffectedOutputPathsBatch;
|
|
13
15
|
/**
|
|
14
16
|
* ISR path resolver: computes which static output files (under out/) are affected
|
|
15
17
|
* for a given page path or "menu changed", for use with partial deploy.
|
|
@@ -211,3 +213,30 @@ function resolveComponentAffectedOutputPathsBatch(componentIds) {
|
|
|
211
213
|
}
|
|
212
214
|
return unique;
|
|
213
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Resolve affected static output file paths for a pattern ISR update.
|
|
218
|
+
* Returns paths under out/ for the pattern API JSON and summary.
|
|
219
|
+
*/
|
|
220
|
+
function resolvePatternAffectedOutputPaths(patternId) {
|
|
221
|
+
return [
|
|
222
|
+
`api/pattern/${patternId}.json`,
|
|
223
|
+
'api/patterns.json',
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Resolve affected output paths for multiple patterns (union).
|
|
228
|
+
*/
|
|
229
|
+
function resolvePatternAffectedOutputPathsBatch(patternIds) {
|
|
230
|
+
const out = ['api/patterns.json'];
|
|
231
|
+
for (const id of patternIds) {
|
|
232
|
+
out.push(`api/pattern/${id}.json`);
|
|
233
|
+
}
|
|
234
|
+
// ES5-compatible alternative to [...new Set(out)]
|
|
235
|
+
var unique = [];
|
|
236
|
+
for (var i = 0; i < out.length; i++) {
|
|
237
|
+
if (unique.indexOf(out[i]) === -1) {
|
|
238
|
+
unique.push(out[i]);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return unique;
|
|
242
|
+
}
|
|
@@ -40,9 +40,9 @@ export declare const getRuntimeComponentsPathsToWatch: (handoff: Handoff) => Map
|
|
|
40
40
|
*/
|
|
41
41
|
export declare const watchRuntimeComponents: (handoff: Handoff, state: WatcherState, runtimeComponentPathsToWatch: Map<string, keyof ComponentListObject["entries"]>) => void;
|
|
42
42
|
/**
|
|
43
|
-
* Watches runtime
|
|
43
|
+
* Watches runtime pattern config files for changes and triggers pattern rebuilds.
|
|
44
44
|
*/
|
|
45
|
-
export declare const
|
|
45
|
+
export declare const watchRuntimePatterns: (handoff: Handoff, state: WatcherState) => void;
|
|
46
46
|
/**
|
|
47
47
|
* Watches the runtime configuration for changes.
|
|
48
48
|
*/
|
|
@@ -35,14 +35,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.watchRuntimeConfiguration = exports.
|
|
38
|
+
exports.watchRuntimeConfiguration = exports.watchRuntimePatterns = exports.watchRuntimeComponents = exports.getRuntimeComponentsPathsToWatch = exports.mapEntryTypeToSegment = exports.watchGlobalEntries = exports.watchPages = exports.watchAppSource = exports.watchPublicDirectory = void 0;
|
|
39
39
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
40
40
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
41
41
|
const path_1 = __importDefault(require("path"));
|
|
42
42
|
const css_1 = require("../transformers/preview/component/css");
|
|
43
43
|
const javascript_1 = require("../transformers/preview/component/javascript");
|
|
44
44
|
const builder_1 = __importStar(require("../transformers/preview/component/builder"));
|
|
45
|
-
const builder_2 = require("../transformers/preview/
|
|
45
|
+
const builder_2 = require("../transformers/preview/pattern/builder");
|
|
46
46
|
const logger_1 = require("../utils/logger");
|
|
47
47
|
const client_config_1 = require("./client-config");
|
|
48
48
|
const paths_1 = require("./paths");
|
|
@@ -262,31 +262,31 @@ const watchRuntimeComponents = (handoff, state, runtimeComponentPathsToWatch) =>
|
|
|
262
262
|
};
|
|
263
263
|
exports.watchRuntimeComponents = watchRuntimeComponents;
|
|
264
264
|
/**
|
|
265
|
-
* Watches runtime
|
|
265
|
+
* Watches runtime pattern config files for changes and triggers pattern rebuilds.
|
|
266
266
|
*/
|
|
267
|
-
const
|
|
267
|
+
const watchRuntimePatterns = (handoff, state) => {
|
|
268
268
|
var _a, _b, _c, _d, _e;
|
|
269
|
-
const
|
|
270
|
-
const
|
|
269
|
+
const runtimePatterns = (_c = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.patterns) !== null && _c !== void 0 ? _c : {};
|
|
270
|
+
const patternConfigPaths = handoff.getConfigFilePaths().filter((configPath) => {
|
|
271
271
|
const dirName = path_1.default.basename(path_1.default.dirname(configPath));
|
|
272
|
-
return dirName in
|
|
272
|
+
return dirName in runtimePatterns;
|
|
273
273
|
});
|
|
274
|
-
// Also watch
|
|
275
|
-
const
|
|
276
|
-
if (
|
|
274
|
+
// Also watch pattern directories directly
|
|
275
|
+
const patternIds = Object.keys(runtimePatterns);
|
|
276
|
+
if (patternIds.length === 0 && patternConfigPaths.length === 0)
|
|
277
277
|
return;
|
|
278
|
-
const pathsToWatch =
|
|
279
|
-
// Add
|
|
280
|
-
for (const
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
pathsToWatch.push(
|
|
278
|
+
const pathsToWatch = patternConfigPaths.length > 0 ? patternConfigPaths : [];
|
|
279
|
+
// Add pattern config entry paths from the config
|
|
280
|
+
for (const patternId of patternIds) {
|
|
281
|
+
const pattern = runtimePatterns[patternId];
|
|
282
|
+
if (pattern.path && fs_extra_1.default.existsSync(pattern.path)) {
|
|
283
|
+
pathsToWatch.push(pattern.path);
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
// Watch the
|
|
287
|
-
if ((_e = (_d = handoff.config.entries) === null || _d === void 0 ? void 0 : _d.
|
|
288
|
-
for (const
|
|
289
|
-
const resolvedPath = path_1.default.resolve(handoff.workingPath,
|
|
286
|
+
// Watch the pattern entry directories from config
|
|
287
|
+
if ((_e = (_d = handoff.config.entries) === null || _d === void 0 ? void 0 : _d.patterns) === null || _e === void 0 ? void 0 : _e.length) {
|
|
288
|
+
for (const patternPath of handoff.config.entries.patterns) {
|
|
289
|
+
const resolvedPath = path_1.default.resolve(handoff.workingPath, patternPath);
|
|
290
290
|
if (fs_extra_1.default.existsSync(resolvedPath)) {
|
|
291
291
|
pathsToWatch.push(resolvedPath);
|
|
292
292
|
}
|
|
@@ -302,12 +302,12 @@ const watchRuntimePages = (handoff, state) => {
|
|
|
302
302
|
if (!state.debounce) {
|
|
303
303
|
state.debounce = true;
|
|
304
304
|
try {
|
|
305
|
-
logger_1.Logger.warn('
|
|
305
|
+
logger_1.Logger.warn('Pattern config changed. Rebuilding patterns...');
|
|
306
306
|
handoff.reload();
|
|
307
|
-
yield (0, builder_2.
|
|
307
|
+
yield (0, builder_2.processPatterns)(handoff);
|
|
308
308
|
}
|
|
309
309
|
catch (e) {
|
|
310
|
-
logger_1.Logger.error('Error processing
|
|
310
|
+
logger_1.Logger.error('Error processing patterns:', e);
|
|
311
311
|
}
|
|
312
312
|
finally {
|
|
313
313
|
state.debounce = false;
|
|
@@ -317,7 +317,7 @@ const watchRuntimePages = (handoff, state) => {
|
|
|
317
317
|
}
|
|
318
318
|
}));
|
|
319
319
|
};
|
|
320
|
-
exports.
|
|
320
|
+
exports.watchRuntimePatterns = watchRuntimePatterns;
|
|
321
321
|
/**
|
|
322
322
|
* Watches the runtime configuration for changes.
|
|
323
323
|
*/
|
package/dist/commands/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const fetch_1 = __importDefault(require("./fetch"));
|
|
|
14
14
|
const init_1 = __importDefault(require("./init"));
|
|
15
15
|
const component_1 = __importDefault(require("./isr/component"));
|
|
16
16
|
const pages_2 = __importDefault(require("./isr/pages"));
|
|
17
|
+
const pattern_1 = __importDefault(require("./isr/pattern"));
|
|
17
18
|
const component_2 = __importDefault(require("./make/component"));
|
|
18
19
|
const page_1 = __importDefault(require("./make/page"));
|
|
19
20
|
const template_1 = __importDefault(require("./make/template"));
|
|
@@ -36,6 +37,7 @@ exports.commands = [
|
|
|
36
37
|
init_1.default,
|
|
37
38
|
pages_2.default,
|
|
38
39
|
component_1.default,
|
|
40
|
+
pattern_1.default,
|
|
39
41
|
page_1.default,
|
|
40
42
|
component_2.default,
|
|
41
43
|
template_1.default,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandModule } from 'yargs';
|
|
2
|
+
import { SharedArgs } from '../types';
|
|
3
|
+
export interface IsrPatternArgs extends SharedArgs {
|
|
4
|
+
id?: string;
|
|
5
|
+
ids?: string[];
|
|
6
|
+
partial?: boolean;
|
|
7
|
+
deployDir?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const command: CommandModule<{}, IsrPatternArgs>;
|
|
10
|
+
export default command;
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const __1 = __importDefault(require("../../"));
|
|
16
|
+
const isr_paths_1 = require("../../app-builder/isr-paths");
|
|
17
|
+
const builder_1 = require("../../transformers/preview/pattern/builder");
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
const command = {
|
|
20
|
+
command: 'isr:pattern',
|
|
21
|
+
describe: 'ISR for pattern changes: rebuild one or more patterns, then rebuild app and optionally deploy only affected routes',
|
|
22
|
+
builder: (yargs) => {
|
|
23
|
+
return (0, utils_1.getSharedOptions)(yargs)
|
|
24
|
+
.option('id', {
|
|
25
|
+
describe: 'Pattern ID to rebuild (e.g. boilerplate)',
|
|
26
|
+
type: 'string',
|
|
27
|
+
})
|
|
28
|
+
.option('ids', {
|
|
29
|
+
describe: 'Comma-separated pattern IDs to rebuild',
|
|
30
|
+
type: 'string',
|
|
31
|
+
coerce: (arg) => (arg ? arg.split(',').map((p) => p.trim()) : []),
|
|
32
|
+
})
|
|
33
|
+
.option('partial', {
|
|
34
|
+
describe: 'Partial deploy: copy only affected pattern output files into existing site output',
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
default: false,
|
|
37
|
+
})
|
|
38
|
+
.option('deploy-dir', {
|
|
39
|
+
describe: 'Copy output to this directory instead of default site output',
|
|
40
|
+
type: 'string',
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
var _a;
|
|
45
|
+
const handoff = new __1.default(args.debug, args.force);
|
|
46
|
+
handoff.init();
|
|
47
|
+
const ids = args.id ? [args.id] : (_a = args.ids) !== null && _a !== void 0 ? _a : [];
|
|
48
|
+
if (ids.length === 0) {
|
|
49
|
+
throw new Error('Either --id or --ids is required');
|
|
50
|
+
}
|
|
51
|
+
for (const id of ids) {
|
|
52
|
+
yield (0, builder_1.processPatterns)(handoff, id);
|
|
53
|
+
}
|
|
54
|
+
const copyOnlyPaths = args.partial
|
|
55
|
+
? (0, isr_paths_1.resolvePatternAffectedOutputPathsBatch)(ids)
|
|
56
|
+
: undefined;
|
|
57
|
+
const buildOptions = (copyOnlyPaths === null || copyOnlyPaths === void 0 ? void 0 : copyOnlyPaths.length) || args.deployDir
|
|
58
|
+
? { copyOnlyPaths: (copyOnlyPaths === null || copyOnlyPaths === void 0 ? void 0 : copyOnlyPaths.length) ? copyOnlyPaths : undefined, deployDir: args.deployDir }
|
|
59
|
+
: undefined;
|
|
60
|
+
yield handoff.build(true, buildOptions);
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
exports.default = command;
|
package/dist/config/runtime.d.ts
CHANGED
|
@@ -30,10 +30,10 @@ export declare const initRuntimeConfig: (handoff: HandoffContext) => [runtimeCon
|
|
|
30
30
|
*/
|
|
31
31
|
export declare const getComponentsForPath: (searchPath: string) => string[];
|
|
32
32
|
/**
|
|
33
|
-
* Returns a list of
|
|
34
|
-
* Mirrors getComponentsForPath but for
|
|
33
|
+
* Returns a list of pattern directories for a given path.
|
|
34
|
+
* Mirrors getComponentsForPath but for pattern definitions.
|
|
35
35
|
*/
|
|
36
|
-
export declare const
|
|
36
|
+
export declare const getPatternsForPath: (searchPath: string) => string[];
|
|
37
37
|
/**
|
|
38
38
|
* Recursively converts all keys and string values in an object to lowercase.
|
|
39
39
|
*/
|
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.getPatternsForPath = 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");
|
|
@@ -24,7 +24,7 @@ const initRuntimeConfig = (handoff) => {
|
|
|
24
24
|
scss: undefined,
|
|
25
25
|
js: undefined,
|
|
26
26
|
components: {},
|
|
27
|
-
|
|
27
|
+
patterns: {},
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
if (!!((_a = handoff.config.entries) === null || _a === void 0 ? void 0 : _a.scss)) {
|
|
@@ -90,45 +90,45 @@ const initRuntimeConfig = (handoff) => {
|
|
|
90
90
|
result.entries.components[component.id] = component;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
if ((_k = (_j = handoff.config.entries) === null || _j === void 0 ? void 0 : _j.
|
|
94
|
-
const
|
|
95
|
-
for (const
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const possibleConfigFiles = [`${
|
|
99
|
-
const configFileName = possibleConfigFiles.find((file) => fs_extra_1.default.existsSync(path_1.default.resolve(
|
|
93
|
+
if ((_k = (_j = handoff.config.entries) === null || _j === void 0 ? void 0 : _j.patterns) === null || _k === void 0 ? void 0 : _k.length) {
|
|
94
|
+
const patternPaths = handoff.config.entries.patterns.flatMap(exports.getPatternsForPath);
|
|
95
|
+
for (const patternPath of patternPaths) {
|
|
96
|
+
const resolvedPatternPath = path_1.default.resolve(handoff.workingPath, patternPath);
|
|
97
|
+
const patternBaseName = path_1.default.basename(resolvedPatternPath);
|
|
98
|
+
const possibleConfigFiles = [`${patternBaseName}.json`, `${patternBaseName}.js`, `${patternBaseName}.cjs`];
|
|
99
|
+
const configFileName = possibleConfigFiles.find((file) => fs_extra_1.default.existsSync(path_1.default.resolve(resolvedPatternPath, file)));
|
|
100
100
|
if (!configFileName) {
|
|
101
|
-
logger_1.Logger.warn(`Missing
|
|
101
|
+
logger_1.Logger.warn(`Missing pattern config: ${path_1.default.resolve(resolvedPatternPath, possibleConfigFiles.join(' or '))}`);
|
|
102
102
|
continue;
|
|
103
103
|
}
|
|
104
|
-
const
|
|
105
|
-
configFiles.push(
|
|
106
|
-
let
|
|
104
|
+
const resolvedPatternConfigPath = path_1.default.resolve(resolvedPatternPath, configFileName);
|
|
105
|
+
configFiles.push(resolvedPatternConfigPath);
|
|
106
|
+
let pattern;
|
|
107
107
|
try {
|
|
108
108
|
if (configFileName.endsWith('.json')) {
|
|
109
|
-
const
|
|
110
|
-
|
|
109
|
+
const patternJson = fs_extra_1.default.readFileSync(resolvedPatternConfigPath, 'utf8');
|
|
110
|
+
pattern = JSON.parse(patternJson);
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
|
-
delete require.cache[require.resolve(
|
|
114
|
-
const
|
|
115
|
-
|
|
113
|
+
delete require.cache[require.resolve(resolvedPatternConfigPath)];
|
|
114
|
+
const importedPattern = require(resolvedPatternConfigPath);
|
|
115
|
+
pattern = importedPattern.default || importedPattern;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
catch (err) {
|
|
119
|
-
logger_1.Logger.error(`Failed to read or parse
|
|
119
|
+
logger_1.Logger.error(`Failed to read or parse pattern config: ${resolvedPatternConfigPath}`, err);
|
|
120
120
|
continue;
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
pattern.id = patternBaseName;
|
|
123
123
|
// Validate that referenced components exist
|
|
124
|
-
if (
|
|
125
|
-
for (const componentId of
|
|
124
|
+
if (pattern.components) {
|
|
125
|
+
for (const componentId of pattern.components) {
|
|
126
126
|
if (!result.entries.components[componentId]) {
|
|
127
|
-
logger_1.Logger.warn(`
|
|
127
|
+
logger_1.Logger.warn(`Pattern '${pattern.id}' references unknown component '${componentId}'`);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
result.entries.
|
|
131
|
+
result.entries.patterns[pattern.id] = pattern;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
return [result, Array.from(configFiles)];
|
|
@@ -171,10 +171,10 @@ const getComponentsForPath = (searchPath) => {
|
|
|
171
171
|
};
|
|
172
172
|
exports.getComponentsForPath = getComponentsForPath;
|
|
173
173
|
/**
|
|
174
|
-
* Returns a list of
|
|
175
|
-
* Mirrors getComponentsForPath but for
|
|
174
|
+
* Returns a list of pattern directories for a given path.
|
|
175
|
+
* Mirrors getComponentsForPath but for pattern definitions.
|
|
176
176
|
*/
|
|
177
|
-
const
|
|
177
|
+
const getPatternsForPath = (searchPath) => {
|
|
178
178
|
const dirName = path_1.default.basename(searchPath);
|
|
179
179
|
const possibleConfigFiles = [`${dirName}.json`, `${dirName}.js`, `${dirName}.cjs`];
|
|
180
180
|
const hasOwnConfig = possibleConfigFiles.some((file) => fs_extra_1.default.existsSync(path_1.default.resolve(searchPath, file)));
|
|
@@ -190,7 +190,7 @@ const getPagesForPath = (searchPath) => {
|
|
|
190
190
|
}
|
|
191
191
|
return [searchPath];
|
|
192
192
|
};
|
|
193
|
-
exports.
|
|
193
|
+
exports.getPatternsForPath = getPatternsForPath;
|
|
194
194
|
/**
|
|
195
195
|
* Recursively converts all keys and string values in an object to lowercase.
|
|
196
196
|
*/
|
package/dist/index.d.ts
CHANGED
package/dist/pipeline/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import 'dotenv/config';
|
|
|
2
2
|
import Handoff from '..';
|
|
3
3
|
export { readPrevJSONFile, zip, zipAssets } from './archive';
|
|
4
4
|
export { buildComponents } from './components';
|
|
5
|
-
export {
|
|
5
|
+
export { buildPatterns } from './patterns';
|
|
6
6
|
/**
|
|
7
7
|
* Run the entire Figma data pipeline:
|
|
8
8
|
* 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.buildPatterns = 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,8 @@ 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
|
|
30
|
-
Object.defineProperty(exports, "
|
|
29
|
+
var patterns_1 = require("./patterns");
|
|
30
|
+
Object.defineProperty(exports, "buildPatterns", { enumerable: true, get: function () { return patterns_1.buildPatterns; } });
|
|
31
31
|
/**
|
|
32
32
|
* Run the entire Figma data pipeline:
|
|
33
33
|
* 1. Validate runtime requirements
|
|
@@ -9,13 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
const builder_1 = require("../transformers/preview/
|
|
12
|
+
exports.buildPatterns = void 0;
|
|
13
|
+
const builder_1 = require("../transformers/preview/pattern/builder");
|
|
14
14
|
/**
|
|
15
|
-
* Builds
|
|
15
|
+
* Builds pattern previews by running the pattern processor.
|
|
16
16
|
* Must be called after buildComponents so component outputs exist.
|
|
17
17
|
*/
|
|
18
|
-
const
|
|
19
|
-
yield (0, builder_1.
|
|
18
|
+
const buildPatterns = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
yield (0, builder_1.processPatterns)(handoff);
|
|
20
20
|
});
|
|
21
|
-
exports.
|
|
21
|
+
exports.buildPatterns = buildPatterns;
|
|
@@ -64,7 +64,7 @@ function createSlotMetadata(key, argType, value) {
|
|
|
64
64
|
var _a, _b;
|
|
65
65
|
const controlType = typeof (argType === null || argType === void 0 ? void 0 : argType.control) === 'string' ? argType.control : (_a = argType === null || argType === void 0 ? void 0 : argType.control) === null || _a === void 0 ? void 0 : _a.type;
|
|
66
66
|
const type = inferSlotType(controlType, value);
|
|
67
|
-
|
|
67
|
+
const metadata = {
|
|
68
68
|
id: key,
|
|
69
69
|
name: (argType === null || argType === void 0 ? void 0 : argType.name) || (0, lodash_1.startCase)(key),
|
|
70
70
|
description: (argType === null || argType === void 0 ? void 0 : argType.description) || '',
|
|
@@ -75,6 +75,11 @@ function createSlotMetadata(key, argType, value) {
|
|
|
75
75
|
required: !!(argType === null || argType === void 0 ? void 0 : argType.required),
|
|
76
76
|
},
|
|
77
77
|
};
|
|
78
|
+
// Capture select/radio options so the Playground can render a proper dropdown
|
|
79
|
+
if (Array.isArray(argType === null || argType === void 0 ? void 0 : argType.options) && argType.options.length > 0) {
|
|
80
|
+
metadata.options = argType.options;
|
|
81
|
+
}
|
|
82
|
+
return metadata;
|
|
78
83
|
}
|
|
79
84
|
function getStoryEntries(moduleExports) {
|
|
80
85
|
return Object.entries(moduleExports).filter(([key, value]) => {
|
|
@@ -119,15 +124,17 @@ function safeRenderToHtml(meta, story, args) {
|
|
|
119
124
|
return `<div style="padding:1rem;color:#b91c1c;font-family:monospace;font-size:13px">Render error: ${String(error)}</div>`;
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
|
-
function createHtmlDocument(componentId, previewTitle, renderedHtml) {
|
|
123
|
-
var _a
|
|
127
|
+
function createHtmlDocument(componentId, previewTitle, renderedHtml, previewCss) {
|
|
128
|
+
var _a;
|
|
129
|
+
const basePath = (_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : '';
|
|
130
|
+
const previewCssLink = previewCss ? `\n <link rel="stylesheet" href="${previewCss}" />` : '';
|
|
124
131
|
return `<!DOCTYPE html>
|
|
125
132
|
<html lang="en">
|
|
126
133
|
<head>
|
|
127
134
|
<meta charset="UTF-8" />
|
|
128
|
-
<link rel="stylesheet" href="${
|
|
129
|
-
<link rel="stylesheet" href="${
|
|
130
|
-
<link rel="stylesheet" href="${
|
|
135
|
+
<link rel="stylesheet" href="${basePath}/api/component/main.css" />
|
|
136
|
+
<link rel="stylesheet" href="${basePath}/api/component/${componentId}.css" />
|
|
137
|
+
<link rel="stylesheet" href="${basePath}/assets/css/preview.css" />${previewCssLink}
|
|
131
138
|
<title>${previewTitle}</title>
|
|
132
139
|
</head>
|
|
133
140
|
<body>
|
|
@@ -154,7 +161,7 @@ function csfRenderPlugin(componentData, _documentationComponents, handoff) {
|
|
|
154
161
|
},
|
|
155
162
|
generateBundle(_, bundle) {
|
|
156
163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
var _a, _b, _c, _d, _e, _f;
|
|
164
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
158
165
|
for (const [fileName, chunkInfo] of Object.entries(bundle)) {
|
|
159
166
|
if (chunkInfo.type === 'chunk' && fileName.includes(PLUGIN_CONSTANTS.SCRIPT_ID)) {
|
|
160
167
|
delete bundle[fileName];
|
|
@@ -246,7 +253,7 @@ function csfRenderPlugin(componentData, _documentationComponents, handoff) {
|
|
|
246
253
|
for (const [storyKey, storyValue] of stories) {
|
|
247
254
|
const preview = componentData.previews[storyKey];
|
|
248
255
|
const rendered = safeRenderToHtml(meta, storyValue, preview.values || {});
|
|
249
|
-
const html = yield (0, html_1.formatHtml)(createHtmlDocument(componentId, preview.title, rendered));
|
|
256
|
+
const html = yield (0, html_1.formatHtml)(createHtmlDocument(componentId, preview.title, rendered, (_g = (_f = componentData.options) === null || _f === void 0 ? void 0 : _f.preview) === null || _g === void 0 ? void 0 : _g.css));
|
|
250
257
|
const fileName = `${componentId}-${storyKey}.html`;
|
|
251
258
|
this.emitFile({
|
|
252
259
|
type: 'asset',
|
|
@@ -262,7 +269,7 @@ function csfRenderPlugin(componentData, _documentationComponents, handoff) {
|
|
|
262
269
|
lastHtml = html;
|
|
263
270
|
}
|
|
264
271
|
// Emit standalone client module for Playground live rendering
|
|
265
|
-
const firstStoryKey = (
|
|
272
|
+
const firstStoryKey = (_h = stories[0]) === null || _h === void 0 ? void 0 : _h[0];
|
|
266
273
|
if (firstStoryKey) {
|
|
267
274
|
try {
|
|
268
275
|
const clientModuleSource = (0, build_1.generateCsfClientComponentSource)(templatePath, firstStoryKey);
|
|
@@ -63,6 +63,7 @@ function processComponentInstances(componentData, documentationComponents) {
|
|
|
63
63
|
*/
|
|
64
64
|
function renderHandlebarsTemplate(template, componentData, previewData, injectFieldWrappers) {
|
|
65
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
var _a, _b;
|
|
66
67
|
// Register Handlebars helpers with current injection state
|
|
67
68
|
(0, handlebars_2.registerHandlebarsHelpers)({ id: componentData.id, properties: componentData.properties || {} }, injectFieldWrappers);
|
|
68
69
|
const context = (0, handlebars_2.createHandlebarsContext)({
|
|
@@ -71,6 +72,7 @@ function renderHandlebarsTemplate(template, componentData, previewData, injectFi
|
|
|
71
72
|
title: componentData.title
|
|
72
73
|
}, previewData, {
|
|
73
74
|
includeSharedStyles: Boolean(componentData.sharedStyles),
|
|
75
|
+
previewCss: (_b = (_a = componentData.options) === null || _a === void 0 ? void 0 : _a.preview) === null || _b === void 0 ? void 0 : _b.css,
|
|
74
76
|
});
|
|
75
77
|
const compiled = handlebars_1.default.compile(template)(context);
|
|
76
78
|
return yield (0, html_1.formatHtmlWithWrapper)(compiled);
|