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.
Files changed (174) hide show
  1. package/Changelog.md +6 -3
  2. package/config/docs/system.md +0 -2
  3. package/dist/app/components/Component/Cards.jsx +32 -0
  4. package/dist/app-builder/build.d.ts +1 -6
  5. package/dist/app-builder/build.js +34 -54
  6. package/dist/app-builder/index.d.ts +0 -1
  7. package/dist/app-builder/index.js +1 -9
  8. package/dist/app-builder/watchers.d.ts +1 -5
  9. package/dist/app-builder/watchers.js +9 -68
  10. package/dist/cache/build-cache.js +25 -10
  11. package/dist/cli.js +1 -1
  12. package/dist/commands/index.js +2 -16
  13. package/dist/config/runtime.d.ts +0 -5
  14. package/dist/config/runtime.js +4 -67
  15. package/dist/index.d.ts +1 -4
  16. package/dist/index.js +2 -2
  17. package/dist/pipeline/index.d.ts +0 -1
  18. package/dist/pipeline/index.js +1 -3
  19. package/dist/transformers/plugins/csf-render.js +1 -18
  20. package/dist/transformers/plugins/handlebars-previews.js +12 -1
  21. package/dist/transformers/plugins/ssr-render.js +0 -14
  22. package/dist/transformers/preview/component/builder.js +16 -1
  23. package/dist/transformers/utils/build.d.ts +0 -18
  24. package/dist/transformers/utils/build.js +0 -108
  25. package/dist/transformers/utils/html.js +15 -3
  26. package/dist/types/config.d.ts +0 -19
  27. package/dist/utils/path.d.ts +15 -0
  28. package/dist/utils/path.js +31 -0
  29. package/docs/api.md +279 -0
  30. package/docs/api_spec.yml +0 -0
  31. package/docs/cli.md +52 -66
  32. package/docs/props.md +34 -0
  33. package/package.json +6 -10
  34. package/src/app/components/Component/ComponentLists.tsx +5 -4
  35. package/src/app/components/Navigation/MainNav.tsx +3 -5
  36. package/src/app/components/Navigation/SideNav.tsx +4 -7
  37. package/src/app/components/SideNav/Custom.tsx +5 -3
  38. package/src/app/components/ui/mobile-nav.tsx +10 -7
  39. package/src/app/components/util/index.ts +11 -64
  40. package/src/app/lib/utils.ts +13 -0
  41. package/src/app/next.config.mjs +31 -15
  42. package/src/app/pages/system/component/[component]/index.tsx +15 -8
  43. package/src/app/pages/system/component/index.tsx +10 -87
  44. package/src/app/pages/system/index.tsx +5 -24
  45. package/src/app/pages/system/tokens/components/[component]/index.tsx +14 -1
  46. package/src/app/pages/system/tokens/index.tsx +10 -85
  47. package/src/app/tsconfig.json +1 -1
  48. package/src/app-builder/README.md +1 -1
  49. package/src/app-builder/build.ts +37 -70
  50. package/src/app-builder/index.ts +0 -9
  51. package/src/app-builder/watchers.ts +9 -67
  52. package/src/cache/README.md +2 -2
  53. package/src/cache/build-cache.ts +29 -11
  54. package/src/cli.ts +1 -1
  55. package/src/commands/index.ts +0 -14
  56. package/src/config/runtime.ts +0 -76
  57. package/src/index.ts +3 -3
  58. package/src/pipeline/README.md +1 -0
  59. package/src/pipeline/index.ts +0 -1
  60. package/src/transformers/README.md +3 -2
  61. package/src/transformers/plugins/csf-render.ts +0 -17
  62. package/src/transformers/plugins/handlebars-previews.ts +13 -1
  63. package/src/transformers/plugins/ssr-render.ts +8 -17
  64. package/src/transformers/preview/component/builder.ts +17 -1
  65. package/src/transformers/utils/build.ts +0 -112
  66. package/src/transformers/utils/html.ts +16 -3
  67. package/src/types/README.md +2 -1
  68. package/src/types/config.ts +0 -21
  69. package/src/utils/path.ts +29 -0
  70. package/tsconfig.json +1 -1
  71. package/config/docs/playground.md +0 -14
  72. package/config/docs/system/alert.md +0 -30
  73. package/config/docs/system/button.md +0 -34
  74. package/config/docs/system/checkbox.md +0 -30
  75. package/config/docs/system/input.md +0 -31
  76. package/config/docs/system/modal.md +0 -32
  77. package/config/docs/system/pagination.md +0 -30
  78. package/config/docs/system/radio.md +0 -30
  79. package/config/docs/system/select.md +0 -30
  80. package/config/docs/system/switch.md +0 -30
  81. package/config/docs/system/tooltip.md +0 -30
  82. package/dist/app/components/Component/Cards.js +0 -17
  83. package/dist/app-builder/isr-paths.d.ts +0 -44
  84. package/dist/app-builder/isr-paths.js +0 -213
  85. package/dist/commands/isr/component.d.ts +0 -10
  86. package/dist/commands/isr/component.js +0 -63
  87. package/dist/commands/isr/pages.d.ts +0 -11
  88. package/dist/commands/isr/pages.js +0 -64
  89. package/dist/commands/platform/init.d.ts +0 -6
  90. package/dist/commands/platform/init.js +0 -231
  91. package/dist/commands/platform/login.d.ts +0 -6
  92. package/dist/commands/platform/login.js +0 -108
  93. package/dist/commands/platform/logout.d.ts +0 -6
  94. package/dist/commands/platform/logout.js +0 -88
  95. package/dist/commands/platform/pull.d.ts +0 -8
  96. package/dist/commands/platform/pull.js +0 -112
  97. package/dist/commands/platform/push.d.ts +0 -8
  98. package/dist/commands/platform/push.js +0 -428
  99. package/dist/pipeline/pages.d.ts +0 -6
  100. package/dist/pipeline/pages.js +0 -21
  101. package/dist/platform/client.d.ts +0 -122
  102. package/dist/platform/client.js +0 -228
  103. package/dist/platform/credentials.d.ts +0 -40
  104. package/dist/platform/credentials.js +0 -91
  105. package/dist/platform/sync.d.ts +0 -68
  106. package/dist/platform/sync.js +0 -349
  107. package/dist/transformers/preview/page/api.d.ts +0 -8
  108. package/dist/transformers/preview/page/api.js +0 -74
  109. package/dist/transformers/preview/page/builder.d.ts +0 -7
  110. package/dist/transformers/preview/page/builder.js +0 -173
  111. package/dist/transformers/preview/page/types.d.ts +0 -38
  112. package/dist/transformers/preview/page/types.js +0 -2
  113. package/docs/components.md +0 -107
  114. package/docs/isr.md +0 -113
  115. package/docs/pages.md +0 -152
  116. package/docs/rest.yml +0 -590
  117. package/docs/rest_api.md +0 -78
  118. package/eslint.config.mjs +0 -18
  119. package/handoff.config.js +0 -90
  120. package/src/app/components/Page/PageLists.tsx +0 -218
  121. package/src/app/components/Page/types.ts +0 -19
  122. package/src/app/components/Playground/ComponentCard.tsx +0 -78
  123. package/src/app/components/Playground/ComponentLibrary.tsx +0 -99
  124. package/src/app/components/Playground/EditContext.tsx +0 -159
  125. package/src/app/components/Playground/EditSheet.tsx +0 -80
  126. package/src/app/components/Playground/MediaBrowser.tsx +0 -56
  127. package/src/app/components/Playground/PlaygroundBuilder.tsx +0 -160
  128. package/src/app/components/Playground/PlaygroundContext.tsx +0 -276
  129. package/src/app/components/Playground/Preview.tsx +0 -174
  130. package/src/app/components/Playground/SortableItem.tsx +0 -45
  131. package/src/app/components/Playground/TemplateManager.tsx +0 -81
  132. package/src/app/components/Playground/Wizard/ApiKeySettings.tsx +0 -125
  133. package/src/app/components/Playground/Wizard/WizardDialog.tsx +0 -228
  134. package/src/app/components/Playground/Wizard/llm-client.ts +0 -87
  135. package/src/app/components/Playground/Wizard/prompt-builder.ts +0 -78
  136. package/src/app/components/Playground/Wizard/response-parser.ts +0 -81
  137. package/src/app/components/Playground/fields/ButtonField.tsx +0 -24
  138. package/src/app/components/Playground/fields/Field.tsx +0 -112
  139. package/src/app/components/Playground/fields/FieldLabel.tsx +0 -20
  140. package/src/app/components/Playground/fields/ImageField.tsx +0 -92
  141. package/src/app/components/Playground/fields/LinkField.tsx +0 -24
  142. package/src/app/components/Playground/fields/RichTextField.tsx +0 -34
  143. package/src/app/components/Playground/fields/TextField.tsx +0 -13
  144. package/src/app/components/Playground/types.ts +0 -30
  145. package/src/app/components/ui/dialog.tsx +0 -80
  146. package/src/app/components/ui/textarea.tsx +0 -19
  147. package/src/app/pages/playground/index.tsx +0 -30
  148. package/src/app/pages/system/page/[page]/index.tsx +0 -300
  149. package/src/app/pages/system/page/index.tsx +0 -124
  150. package/src/app-builder/isr-paths.ts +0 -209
  151. package/src/commands/isr/component.ts +0 -68
  152. package/src/commands/isr/pages.ts +0 -68
  153. package/src/commands/platform/init.ts +0 -229
  154. package/src/commands/platform/login.ts +0 -96
  155. package/src/commands/platform/logout.ts +0 -63
  156. package/src/commands/platform/pull.ts +0 -98
  157. package/src/commands/platform/push.ts +0 -469
  158. package/src/pipeline/pages.ts +0 -10
  159. package/src/platform/client.ts +0 -335
  160. package/src/platform/credentials.ts +0 -106
  161. package/src/platform/sync.ts +0 -428
  162. package/src/transformers/preview/page/api.ts +0 -65
  163. package/src/transformers/preview/page/builder.ts +0 -200
  164. package/src/transformers/preview/page/types.ts +0 -37
  165. package/test_components/example/example.js +0 -110
  166. package/test_components/example/style.scss +0 -56
  167. package/test_components/example/template.hbs +0 -19
  168. package/test_components/example-csf/example-csf.js +0 -16
  169. package/test_components/example-csf/style.scss +0 -52
  170. package/test_components/example-csf/template.stories.tsx +0 -97
  171. package/test_components/example-react/example-react.js +0 -69
  172. package/test_components/example-react/style.scss +0 -56
  173. package/test_components/example-react/template.tsx +0 -49
  174. package/test_pages/boilerplate/boilerplate.json +0 -73
package/Changelog.md CHANGED
@@ -6,10 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to
7
7
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
- ## \[1.2.0]
9
+ ## \[1.1.1] - 2026-03-12
10
10
 
11
- * Upgrade to Next16
12
- * Add pagination data structure to arrays
11
+ This patch release focuses on Windows stabilization and consistency across environments.
12
+
13
+ It includes targeted fixes to reduce platform-specific issues in local development and documentation rendering, especially around path handling, routing/navigation behavior, and runtime update detection. These changes aim to make behavior on Windows align more closely with Mac and Linux, with no intended breaking changes.
14
+
15
+ Also includes a fallback for components with empty previews definitions, preventing preview generation failures during builds.
13
16
 
14
17
  ## \[1.1.0] - 2026-03-05
15
18
 
@@ -16,6 +16,4 @@ menu:
16
16
  tokens: true
17
17
  - title: Components
18
18
  components: true
19
- - title: Pages
20
- pages: true
21
19
  ---
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const lucide_react_1 = require("lucide-react");
7
+ const react_1 = __importDefault(require("react"));
8
+ const PracticeLine = ({ line, type }) => (<li className="flex items-start gap-3">
9
+ {type === 'positive' ? (<lucide_react_1.Check className="mt-[5px] h-3 w-3 shrink-0 text-emerald-600" strokeWidth={3}/>) : type === 'negative' ? (<lucide_react_1.X className="mt-[5px] h-3 w-3 shrink-0 text-gray-400" strokeWidth={3}/>) : (<span className="mt-[5px] h-3 w-3 shrink-0"/>)}
10
+ <p className="text-sm">{line}</p>
11
+ </li>);
12
+ const CardItem = ({ card }) => {
13
+ // Split content by newlines and render each line as a separate item
14
+ const lines = card.content.split('\n').filter((line) => line.trim());
15
+ return (<ul className="space-y-3 text-emerald-800">
16
+ {lines.map((line, index) => (<PracticeLine line={line} type={card.type} key={`do-rule-${index}`}/>))}
17
+ </ul>);
18
+ };
19
+ const Cards = ({ cards, maxCardsPerRow = 2, className = '' }) => {
20
+ if (!cards || cards.length === 0) {
21
+ return null;
22
+ }
23
+ return (<div className="grid grid-cols-[repeat(auto-fit,minmax(100%,1fr))] gap-6 sm:grid-cols-[repeat(auto-fit,minmax(300px,1fr))]">
24
+ {cards.map((card, index) => (<div key={`card-${index}`} className="relative rounded-lg border bg-gray-50 p-8 text-gray-600 dark:bg-gray-800">
25
+ <h2 className="mb-3 font-normal text-gray-700">
26
+ {card.title}
27
+ </h2>
28
+ <CardItem card={card}/>
29
+ </div>))}
30
+ </div>);
31
+ };
32
+ exports.default = Cards;
@@ -1,13 +1,8 @@
1
1
  import Handoff from '..';
2
2
  /**
3
3
  * Build the Next.js documentation application.
4
- * @param copyOnlyPaths - If set, do not remove output dir; copy only these paths (relative to out/) into existing output (merge).
5
- * @param deployDir - If set, copy output to this directory instead of default (workingPath/sitesDirectory/projectId).
6
4
  */
7
- declare const buildApp: (handoff: Handoff, skipComponents?: boolean, options?: {
8
- copyOnlyPaths?: string[];
9
- deployDir?: string;
10
- }) => Promise<void>;
5
+ declare const buildApp: (handoff: Handoff, skipComponents?: boolean) => Promise<void>;
11
6
  /**
12
7
  * Watch the Next.js application.
13
8
  * Starts a custom dev server with Handoff-specific watchers and hot-reloading.
@@ -17,16 +17,15 @@ 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 pages_1 = require("../pipeline/pages");
21
- const builder_1 = __importDefault(require("../transformers/preview/component/builder"));
22
20
  const css_1 = require("../transformers/preview/component/css");
23
21
  const javascript_1 = require("../transformers/preview/component/javascript");
22
+ const builder_1 = __importDefault(require("../transformers/preview/component/builder"));
24
23
  const logger_1 = require("../utils/logger");
25
24
  const client_config_1 = require("./client-config");
26
25
  const paths_1 = require("./paths");
27
- const builder_2 = require("../transformers/preview/page/builder");
28
26
  const watchers_1 = require("./watchers");
29
27
  const websocket_1 = require("./websocket");
28
+ const escapeForSingleQuotedJsString = (value) => value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
30
29
  /**
31
30
  * Performs cleanup of the application directory by removing the existing app directory if it exists.
32
31
  */
@@ -59,8 +58,7 @@ const initializeProjectApp = (handoff) => __awaiter(void 0, void 0, void 0, func
59
58
  yield fs_extra_1.default.copy(customThemePath, destPath, { overwrite: true });
60
59
  logger_1.Logger.success(`Custom theme.css loaded`);
61
60
  }
62
- // Prepare project app configuration
63
- // Warning: Regex replacement is fragile and depends on exact formatting in next.config.mjs
61
+ // Prepare project app configuration using stable placeholder replacement.
64
62
  const handoffProjectId = handoff.getProjectId();
65
63
  const handoffAppBasePath = (_a = handoff.config.app.base_path) !== null && _a !== void 0 ? _a : '';
66
64
  const handoffWorkingPath = path_1.default.resolve(handoff.workingPath);
@@ -69,38 +67,42 @@ const initializeProjectApp = (handoff) => __awaiter(void 0, void 0, void 0, func
69
67
  const nextConfigPath = path_1.default.resolve(srcPath, 'next.config.mjs');
70
68
  const targetPath = path_1.default.resolve(appPath, 'next.config.mjs');
71
69
  const handoffWebsocketPort = (_c = (_b = handoff.config.app.ports) === null || _b === void 0 ? void 0 : _b.websocket) !== null && _c !== void 0 ? _c : 3001;
72
- const nextConfigContent = (yield fs_extra_1.default.readFile(nextConfigPath, 'utf-8'))
73
- .replace(/basePath:\s+''/g, `basePath: '${handoffAppBasePath}'`)
74
- .replace(/HANDOFF_PROJECT_ID:\s+''/g, `HANDOFF_PROJECT_ID: '${handoffProjectId}'`)
75
- .replace(/HANDOFF_APP_BASE_PATH:\s+''/g, `HANDOFF_APP_BASE_PATH: '${handoffAppBasePath}'`)
76
- .replace(/HANDOFF_WORKING_PATH:\s+''/g, `HANDOFF_WORKING_PATH: '${handoffWorkingPath}'`)
77
- .replace(/HANDOFF_MODULE_PATH:\s+''/g, `HANDOFF_MODULE_PATH: '${handoffModulePath}'`)
78
- .replace(/HANDOFF_EXPORT_PATH:\s+''/g, `HANDOFF_EXPORT_PATH: '${handoffExportPath}'`)
79
- .replace(/HANDOFF_WEBSOCKET_PORT:\s+''/g, `HANDOFF_WEBSOCKET_PORT: '${handoffWebsocketPort}'`)
80
- .replace(/%HANDOFF_MODULE_PATH%/g, handoffModulePath);
70
+ const escapedAppBasePath = escapeForSingleQuotedJsString(handoffAppBasePath);
71
+ const escapedProjectId = escapeForSingleQuotedJsString(handoffProjectId);
72
+ const escapedWorkingPath = escapeForSingleQuotedJsString(handoffWorkingPath);
73
+ const escapedModulePath = escapeForSingleQuotedJsString(handoffModulePath);
74
+ const escapedExportPath = escapeForSingleQuotedJsString(handoffExportPath);
75
+ const escapedWebsocketPort = escapeForSingleQuotedJsString(String(handoffWebsocketPort));
76
+ const placeholderValues = {
77
+ '%HANDOFF_PROJECT_ID%': escapedProjectId,
78
+ '%HANDOFF_APP_BASE_PATH%': escapedAppBasePath,
79
+ '%HANDOFF_WORKING_PATH%': escapedWorkingPath,
80
+ '%HANDOFF_MODULE_PATH%': escapedModulePath,
81
+ '%HANDOFF_EXPORT_PATH%': escapedExportPath,
82
+ '%HANDOFF_WEBSOCKET_PORT%': escapedWebsocketPort,
83
+ };
84
+ let nextConfigContent = yield fs_extra_1.default.readFile(nextConfigPath, 'utf-8');
85
+ for (const [placeholder, value] of Object.entries(placeholderValues)) {
86
+ nextConfigContent = nextConfigContent.split(placeholder).join(value);
87
+ }
81
88
  yield fs_extra_1.default.writeFile(targetPath, nextConfigContent);
82
89
  return appPath;
83
90
  });
84
91
  /**
85
92
  * Build the Next.js documentation application.
86
- * @param copyOnlyPaths - If set, do not remove output dir; copy only these paths (relative to out/) into existing output (merge).
87
- * @param deployDir - If set, copy output to this directory instead of default (workingPath/sitesDirectory/projectId).
88
93
  */
89
- const buildApp = (handoff, skipComponents, options) => __awaiter(void 0, void 0, void 0, function* () {
94
+ const buildApp = (handoff, skipComponents) => __awaiter(void 0, void 0, void 0, function* () {
90
95
  skipComponents = skipComponents !== null && skipComponents !== void 0 ? skipComponents : false;
91
- const copyOnlyPaths = options === null || options === void 0 ? void 0 : options.copyOnlyPaths;
92
- const deployDir = options === null || options === void 0 ? void 0 : options.deployDir;
93
96
  // Perform cleanup
94
97
  yield cleanupAppDirectory(handoff);
95
98
  // Build components
96
99
  if (!skipComponents) {
97
100
  yield (0, components_1.buildComponents)(handoff);
98
101
  }
99
- // Build pages (must run after components so rendered outputs exist)
100
- yield (0, pages_1.buildPages)(handoff);
101
102
  // Prepare app
102
103
  const appPath = yield initializeProjectApp(handoff);
103
104
  yield (0, client_config_1.persistClientConfig)(handoff);
105
+ // Build app
104
106
  const buildResult = cross_spawn_1.default.sync('npx', ['next', 'build'], {
105
107
  cwd: appPath,
106
108
  stdio: 'inherit',
@@ -113,35 +115,16 @@ const buildApp = (handoff, skipComponents, options) => __awaiter(void 0, void 0,
113
115
  }
114
116
  throw new Error(errorMsg);
115
117
  }
116
- // Resolve output directory: explicit deployDir or default under working path
117
- const outputRoot = deployDir
118
- ? path_1.default.resolve(deployDir)
119
- : path_1.default.resolve(handoff.workingPath, handoff.sitesDirectory);
120
- const output = deployDir ? outputRoot : path_1.default.resolve(outputRoot, handoff.getProjectId());
121
- if (!deployDir) {
122
- yield fs_extra_1.default.ensureDir(path_1.default.resolve(handoff.workingPath, handoff.sitesDirectory));
123
- }
124
- if (copyOnlyPaths && copyOnlyPaths.length > 0) {
125
- // Partial deploy: merge only the listed paths into existing output
126
- yield fs_extra_1.default.ensureDir(output);
127
- const outDir = path_1.default.resolve(appPath, 'out');
128
- for (const relativePath of copyOnlyPaths) {
129
- const src = path_1.default.join(outDir, relativePath);
130
- const dest = path_1.default.join(output, relativePath);
131
- if (fs_extra_1.default.existsSync(src)) {
132
- yield fs_extra_1.default.ensureDir(path_1.default.dirname(dest));
133
- yield fs_extra_1.default.copy(src, dest, { overwrite: true });
134
- }
135
- }
136
- }
137
- else {
138
- // Full deploy: replace output with full out
139
- if (fs_extra_1.default.existsSync(output)) {
140
- yield fs_extra_1.default.remove(output);
141
- }
142
- yield fs_extra_1.default.ensureDir(output);
143
- yield fs_extra_1.default.copy(path_1.default.resolve(appPath, 'out'), output);
118
+ // Ensure output root directory exists
119
+ const outputRoot = path_1.default.resolve(handoff.workingPath, handoff.sitesDirectory);
120
+ yield fs_extra_1.default.ensureDir(outputRoot);
121
+ // Clean the project output directory (if exists)
122
+ const output = path_1.default.resolve(outputRoot, handoff.getProjectId());
123
+ if (fs_extra_1.default.existsSync(output)) {
124
+ yield fs_extra_1.default.remove(output);
144
125
  }
126
+ // Copy the build files into the project output directory
127
+ yield fs_extra_1.default.copy(path_1.default.resolve(appPath, 'out'), output);
145
128
  });
146
129
  /**
147
130
  * Watch the Next.js application.
@@ -154,8 +137,6 @@ const watchApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
154
137
  yield (0, builder_1.default)(handoff, undefined, undefined, { useCache: true });
155
138
  yield (0, javascript_1.buildMainJS)(handoff);
156
139
  yield (0, css_1.buildMainCss)(handoff);
157
- // Build pages after components
158
- yield (0, builder_2.processPages)(handoff);
159
140
  const appPath = yield initializeProjectApp(handoff);
160
141
  // Persist client configuration
161
142
  yield (0, client_config_1.persistClientConfig)(handoff);
@@ -170,7 +151,7 @@ const watchApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
170
151
  // create empty directory
171
152
  yield fs_extra_1.default.ensureDir(moduleOutput);
172
153
  }
173
- const nextProcess = (0, cross_spawn_1.default)('npx', ['next', 'dev', '--port', String(port)], {
154
+ const nextProcess = (0, cross_spawn_1.default)('npx', ['next', 'dev', '--turbopack', '--port', String(port)], {
174
155
  cwd: appPath,
175
156
  stdio: 'inherit',
176
157
  env: Object.assign(Object.assign({}, process.env), { NODE_ENV: 'development' }),
@@ -200,7 +181,6 @@ const watchApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
200
181
  (0, watchers_1.watchRuntimeConfiguration)(handoff, state);
201
182
  (0, watchers_1.watchGlobalEntries)(handoff, state, chokidarConfig);
202
183
  (0, watchers_1.watchPages)(handoff, chokidarConfig);
203
- (0, watchers_1.watchRuntimePages)(handoff, state);
204
184
  });
205
185
  exports.watchApp = watchApp;
206
186
  /**
@@ -219,7 +199,7 @@ const devApp = (handoff) => __awaiter(void 0, void 0, void 0, function* () {
219
199
  // Persist client configuration
220
200
  yield (0, client_config_1.persistClientConfig)(handoff);
221
201
  // Run
222
- const devResult = cross_spawn_1.default.sync('npx', ['next', 'dev', '--port', String((_b = (_a = handoff.config.app.ports) === null || _a === void 0 ? void 0 : _a.app) !== null && _b !== void 0 ? _b : 3000)], {
202
+ const devResult = cross_spawn_1.default.sync('npx', ['next', 'dev', '--turbopack', '--port', String((_b = (_a = handoff.config.app.ports) === null || _a === void 0 ? void 0 : _a.app) !== null && _b !== void 0 ? _b : 3000)], {
223
203
  cwd: appPath,
224
204
  stdio: 'inherit',
225
205
  env: Object.assign(Object.assign({}, process.env), { NODE_ENV: 'development' }),
@@ -1,3 +1,2 @@
1
1
  export { buildComponents } from '../pipeline/components';
2
2
  export { default, devApp, watchApp } from './build';
3
- export { getL1StaticPathSegments, getL2StaticPathSegments, normalizeRoutePath, resolveAffectedOutputPaths, resolveComponentAffectedOutputPaths, resolveComponentAffectedOutputPathsBatch, routePathToOutputPaths, } from './isr-paths';
@@ -3,18 +3,10 @@ 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.routePathToOutputPaths = exports.resolveComponentAffectedOutputPathsBatch = exports.resolveComponentAffectedOutputPaths = exports.resolveAffectedOutputPaths = exports.normalizeRoutePath = exports.getL2StaticPathSegments = exports.getL1StaticPathSegments = exports.watchApp = exports.devApp = exports.default = exports.buildComponents = void 0;
6
+ exports.watchApp = exports.devApp = exports.default = exports.buildComponents = void 0;
7
7
  var components_1 = require("../pipeline/components");
8
8
  Object.defineProperty(exports, "buildComponents", { enumerable: true, get: function () { return components_1.buildComponents; } });
9
9
  var build_1 = require("./build");
10
10
  Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(build_1).default; } });
11
11
  Object.defineProperty(exports, "devApp", { enumerable: true, get: function () { return build_1.devApp; } });
12
12
  Object.defineProperty(exports, "watchApp", { enumerable: true, get: function () { return build_1.watchApp; } });
13
- var isr_paths_1 = require("./isr-paths");
14
- Object.defineProperty(exports, "getL1StaticPathSegments", { enumerable: true, get: function () { return isr_paths_1.getL1StaticPathSegments; } });
15
- Object.defineProperty(exports, "getL2StaticPathSegments", { enumerable: true, get: function () { return isr_paths_1.getL2StaticPathSegments; } });
16
- Object.defineProperty(exports, "normalizeRoutePath", { enumerable: true, get: function () { return isr_paths_1.normalizeRoutePath; } });
17
- Object.defineProperty(exports, "resolveAffectedOutputPaths", { enumerable: true, get: function () { return isr_paths_1.resolveAffectedOutputPaths; } });
18
- Object.defineProperty(exports, "resolveComponentAffectedOutputPaths", { enumerable: true, get: function () { return isr_paths_1.resolveComponentAffectedOutputPaths; } });
19
- Object.defineProperty(exports, "resolveComponentAffectedOutputPathsBatch", { enumerable: true, get: function () { return isr_paths_1.resolveComponentAffectedOutputPathsBatch; } });
20
- Object.defineProperty(exports, "routePathToOutputPaths", { enumerable: true, get: function () { return isr_paths_1.routePathToOutputPaths; } });
@@ -34,15 +34,11 @@ export declare const mapEntryTypeToSegment: (type: keyof ComponentListObject["en
34
34
  *
35
35
  * @returns A Map of paths to watch and their entry types
36
36
  */
37
- export declare const getRuntimeComponentsPathsToWatch: (handoff: Handoff) => Map<string, "js" | "scss" | "template">;
37
+ export declare const getRuntimeComponentsPathsToWatch: (handoff: Handoff) => Map<string, "template" | "js" | "scss">;
38
38
  /**
39
39
  * Watches runtime components for changes.
40
40
  */
41
41
  export declare const watchRuntimeComponents: (handoff: Handoff, state: WatcherState, runtimeComponentPathsToWatch: Map<string, keyof ComponentListObject["entries"]>) => void;
42
- /**
43
- * Watches runtime page config files for changes and triggers page rebuilds.
44
- */
45
- export declare const watchRuntimePages: (handoff: Handoff, state: WatcherState) => void;
46
42
  /**
47
43
  * Watches the runtime configuration for changes.
48
44
  */
@@ -35,15 +35,15 @@ 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.watchRuntimePages = exports.watchRuntimeComponents = exports.getRuntimeComponentsPathsToWatch = exports.mapEntryTypeToSegment = exports.watchGlobalEntries = exports.watchPages = exports.watchAppSource = exports.watchPublicDirectory = void 0;
38
+ exports.watchRuntimeConfiguration = 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/page/builder");
46
45
  const logger_1 = require("../utils/logger");
46
+ const path_2 = require("../utils/path");
47
47
  const client_config_1 = require("./client-config");
48
48
  const paths_1 = require("./paths");
49
49
  /**
@@ -146,11 +146,6 @@ const watchGlobalEntries = (handoff, state, chokidarConfig) => {
146
146
  const pathsToWatch = [...scssPathsToWatch, ...jsPathsToWatch];
147
147
  if (pathsToWatch.length === 0)
148
148
  return;
149
- const isPathInside = (filePath, parentPath) => {
150
- const normalizedFilePath = path_1.default.resolve(filePath);
151
- const normalizedParentPath = path_1.default.resolve(parentPath);
152
- return normalizedFilePath === normalizedParentPath || normalizedFilePath.startsWith(`${normalizedParentPath}${path_1.default.sep}`);
153
- };
154
149
  chokidar_1.default.watch(pathsToWatch, chokidarConfig).on('all', (event, file) => __awaiter(void 0, void 0, void 0, function* () {
155
150
  switch (event) {
156
151
  case 'add':
@@ -160,8 +155,8 @@ const watchGlobalEntries = (handoff, state, chokidarConfig) => {
160
155
  state.debounce = true;
161
156
  try {
162
157
  logger_1.Logger.warn('Global entry changed. Rebuilding bundles and components...');
163
- const shouldRebuildMainCss = !!scssEntry && scssPathsToWatch.some((watchPath) => isPathInside(file, watchPath));
164
- const shouldRebuildMainJs = !!jsEntry && jsPathsToWatch.some((watchPath) => isPathInside(file, watchPath));
158
+ const shouldRebuildMainCss = !!scssEntry && scssPathsToWatch.some((watchPath) => (0, path_2.isPathInside)(file, watchPath));
159
+ const shouldRebuildMainJs = !!jsEntry && jsPathsToWatch.some((watchPath) => (0, path_2.isPathInside)(file, watchPath));
165
160
  if (shouldRebuildMainCss) {
166
161
  yield (0, css_1.buildMainCss)(handoff);
167
162
  }
@@ -229,11 +224,14 @@ const watchRuntimeComponents = (handoff, state, runtimeComponentPathsToWatch) =>
229
224
  }
230
225
  if (runtimeComponentPathsToWatch.size > 0) {
231
226
  const pathsToWatch = Array.from(runtimeComponentPathsToWatch.keys());
227
+ const runtimeComponentEntryTypeByPath = new Map(Array.from(runtimeComponentPathsToWatch.entries()).map(([watchPath, entryType]) => [(0, path_2.normalizePathForCompare)(watchPath), entryType]));
228
+ const configFileSet = new Set(handoff.getConfigFilePaths().map((configPath) => (0, path_2.normalizePathForCompare)(configPath)));
232
229
  state.runtimeComponentsWatcher = chokidar_1.default.watch(pathsToWatch, {
233
230
  ignoreInitial: true,
234
231
  });
235
232
  state.runtimeComponentsWatcher.on('all', (event, file) => __awaiter(void 0, void 0, void 0, function* () {
236
- if (handoff.getConfigFilePaths().includes(file)) {
233
+ const normalizedFile = (0, path_2.normalizePathForCompare)(file);
234
+ if (configFileSet.has(normalizedFile)) {
237
235
  return;
238
236
  }
239
237
  switch (event) {
@@ -243,7 +241,7 @@ const watchRuntimeComponents = (handoff, state, runtimeComponentPathsToWatch) =>
243
241
  if (!state.debounce) {
244
242
  state.debounce = true;
245
243
  try {
246
- const entryType = runtimeComponentPathsToWatch.get(file);
244
+ const entryType = runtimeComponentEntryTypeByPath.get(normalizedFile);
247
245
  const segmentToUpdate = entryType ? (0, exports.mapEntryTypeToSegment)(entryType) : undefined;
248
246
  const componentDir = path_1.default.basename(path_1.default.dirname(file));
249
247
  yield (0, builder_1.default)(handoff, componentDir, segmentToUpdate);
@@ -261,63 +259,6 @@ const watchRuntimeComponents = (handoff, state, runtimeComponentPathsToWatch) =>
261
259
  }
262
260
  };
263
261
  exports.watchRuntimeComponents = watchRuntimeComponents;
264
- /**
265
- * Watches runtime page config files for changes and triggers page rebuilds.
266
- */
267
- const watchRuntimePages = (handoff, state) => {
268
- var _a, _b, _c, _d, _e;
269
- const runtimePages = (_c = (_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.pages) !== null && _c !== void 0 ? _c : {};
270
- const pageConfigPaths = handoff.getConfigFilePaths().filter((configPath) => {
271
- const dirName = path_1.default.basename(path_1.default.dirname(configPath));
272
- return dirName in runtimePages;
273
- });
274
- // Also watch page directories directly
275
- const pageIds = Object.keys(runtimePages);
276
- if (pageIds.length === 0 && pageConfigPaths.length === 0)
277
- return;
278
- const pathsToWatch = pageConfigPaths.length > 0 ? pageConfigPaths : [];
279
- // Add page config entry paths from the config
280
- for (const pageId of pageIds) {
281
- const page = runtimePages[pageId];
282
- if (page.path && fs_extra_1.default.existsSync(page.path)) {
283
- pathsToWatch.push(page.path);
284
- }
285
- }
286
- // Watch the page entry directories from config
287
- if ((_e = (_d = handoff.config.entries) === null || _d === void 0 ? void 0 : _d.pages) === null || _e === void 0 ? void 0 : _e.length) {
288
- for (const pagePath of handoff.config.entries.pages) {
289
- const resolvedPath = path_1.default.resolve(handoff.workingPath, pagePath);
290
- if (fs_extra_1.default.existsSync(resolvedPath)) {
291
- pathsToWatch.push(resolvedPath);
292
- }
293
- }
294
- }
295
- if (pathsToWatch.length === 0)
296
- return;
297
- chokidar_1.default.watch(pathsToWatch, { ignoreInitial: true }).on('all', (event, file) => __awaiter(void 0, void 0, void 0, function* () {
298
- switch (event) {
299
- case 'add':
300
- case 'change':
301
- case 'unlink':
302
- if (!state.debounce) {
303
- state.debounce = true;
304
- try {
305
- logger_1.Logger.warn('Page config changed. Rebuilding pages...');
306
- handoff.reload();
307
- yield (0, builder_2.processPages)(handoff);
308
- }
309
- catch (e) {
310
- logger_1.Logger.error('Error processing pages:', e);
311
- }
312
- finally {
313
- state.debounce = false;
314
- }
315
- }
316
- break;
317
- }
318
- }));
319
- };
320
- exports.watchRuntimePages = watchRuntimePages;
321
262
  /**
322
263
  * Watches the runtime configuration for changes.
323
264
  */
@@ -27,6 +27,7 @@ exports.pruneRemovedComponents = pruneRemovedComponents;
27
27
  const fs_extra_1 = __importDefault(require("fs-extra"));
28
28
  const path_1 = __importDefault(require("path"));
29
29
  const logger_1 = require("../utils/logger");
30
+ const path_2 = require("../utils/path");
30
31
  const file_state_1 = require("./file-state");
31
32
  /** Current cache format version - bump when structure changes */
32
33
  const CACHE_VERSION = '1.0.0';
@@ -142,23 +143,17 @@ function getComponentFilePaths(handoff, componentId) {
142
143
  }
143
144
  const files = [];
144
145
  let templateDir;
145
- // Find the config file path for this component
146
- const configPaths = handoff.getConfigFilePaths();
147
- for (const configPath of configPaths) {
148
- // Check if this config path belongs to this component
149
- if (configPath.includes(componentId)) {
150
- files.push(configPath);
151
- break;
152
- }
153
- }
154
- // Add entry files
146
+ const componentDirs = new Set();
147
+ // Add entry files and infer component directories from resolved entry paths
155
148
  const entries = runtimeComponent.entries;
156
149
  if (entries) {
157
150
  if (entries.js) {
158
151
  files.push(entries.js);
152
+ componentDirs.add((0, path_2.normalizePathForCompare)(path_1.default.dirname(entries.js)));
159
153
  }
160
154
  if (entries.scss) {
161
155
  files.push(entries.scss);
156
+ componentDirs.add((0, path_2.normalizePathForCompare)(path_1.default.dirname(entries.scss)));
162
157
  }
163
158
  // Handle both 'template' (singular) and 'templates' (plural) entry types
164
159
  const templatePath = entries.template || entries.templates;
@@ -167,17 +162,37 @@ function getComponentFilePaths(handoff, componentId) {
167
162
  const stat = fs_extra_1.default.statSync(templatePath);
168
163
  if (stat.isDirectory()) {
169
164
  templateDir = templatePath;
165
+ componentDirs.add((0, path_2.normalizePathForCompare)(templatePath));
170
166
  }
171
167
  else {
172
168
  files.push(templatePath);
169
+ componentDirs.add((0, path_2.normalizePathForCompare)(path_1.default.dirname(templatePath)));
173
170
  }
174
171
  }
175
172
  catch (_d) {
176
173
  // File doesn't exist, still add to track
177
174
  files.push(templatePath);
175
+ componentDirs.add((0, path_2.normalizePathForCompare)(path_1.default.dirname(templatePath)));
178
176
  }
179
177
  }
180
178
  }
179
+ // Find the config file path for this component using exact config filename + directory matching.
180
+ const configPaths = handoff.getConfigFilePaths();
181
+ const expectedConfigFileNames = new Set([`${componentId}.json`, `${componentId}.js`, `${componentId}.cjs`]);
182
+ const matchingConfigPath = configPaths.find((configPath) => {
183
+ const configFileName = path_1.default.basename(configPath);
184
+ if (!expectedConfigFileNames.has(configFileName)) {
185
+ return false;
186
+ }
187
+ if (componentDirs.size === 0) {
188
+ return true;
189
+ }
190
+ const configDir = (0, path_2.normalizePathForCompare)(path_1.default.dirname(configPath));
191
+ return componentDirs.has(configDir);
192
+ });
193
+ if (matchingConfigPath) {
194
+ files.push(matchingConfigPath);
195
+ }
181
196
  return { files, templateDir };
182
197
  }
183
198
  /**
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ class HandoffCliError extends Error {
19
19
  * Show the help message
20
20
  */
21
21
  const showVersion = () => {
22
- return 'Handoff App - 1.1.0-0';
22
+ return 'Handoff App - 1.1.1';
23
23
  };
24
24
  /**
25
25
  * Define a CLI error
@@ -12,16 +12,9 @@ const pages_1 = __importDefault(require("./eject/pages"));
12
12
  const theme_1 = __importDefault(require("./eject/theme"));
13
13
  const fetch_1 = __importDefault(require("./fetch"));
14
14
  const init_1 = __importDefault(require("./init"));
15
- const component_1 = __importDefault(require("./isr/component"));
16
- const pages_2 = __importDefault(require("./isr/pages"));
17
- const component_2 = __importDefault(require("./make/component"));
15
+ const component_1 = __importDefault(require("./make/component"));
18
16
  const page_1 = __importDefault(require("./make/page"));
19
17
  const template_1 = __importDefault(require("./make/template"));
20
- const init_2 = __importDefault(require("./platform/init"));
21
- const login_1 = __importDefault(require("./platform/login"));
22
- const logout_1 = __importDefault(require("./platform/logout"));
23
- const pull_1 = __importDefault(require("./platform/pull"));
24
- const push_1 = __importDefault(require("./platform/push"));
25
18
  const scaffold_1 = __importDefault(require("./scaffold"));
26
19
  const start_1 = __importDefault(require("./start"));
27
20
  const components_2 = __importDefault(require("./validate/components"));
@@ -34,16 +27,9 @@ exports.commands = [
34
27
  theme_1.default,
35
28
  fetch_1.default,
36
29
  init_1.default,
37
- pages_2.default,
38
- component_1.default,
39
30
  page_1.default,
40
- component_2.default,
31
+ component_1.default,
41
32
  template_1.default,
42
- login_1.default,
43
- init_2.default,
44
- pull_1.default,
45
- push_1.default,
46
- logout_1.default,
47
33
  scaffold_1.default,
48
34
  start_1.default,
49
35
  components_2.default,
@@ -29,11 +29,6 @@ export declare const initRuntimeConfig: (handoff: HandoffContext) => [runtimeCon
29
29
  * @returns An array of string paths to component directories.
30
30
  */
31
31
  export declare const getComponentsForPath: (searchPath: string) => string[];
32
- /**
33
- * Returns a list of page directories for a given path.
34
- * Mirrors getComponentsForPath but for page definitions.
35
- */
36
- export declare const getPagesForPath: (searchPath: string) => string[];
37
32
  /**
38
33
  * Recursively converts all keys and string values in an object to lowercase.
39
34
  */