generator-white-label 5.0.1 → 8.0.0

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 (299) hide show
  1. package/.editorconfig +15 -0
  2. package/.yarnrc.yml +6 -0
  3. package/CLI.md +82 -0
  4. package/LICENSE +9 -0
  5. package/PACKAGE_MANAGERS.md +35 -0
  6. package/README.md +204 -124
  7. package/app/404.tsx +28 -0
  8. package/app/README.md +66 -8
  9. package/app/assets/data/view/global.json +7 -47
  10. package/app/assets/data/view/index.json +9 -1
  11. package/app/assets/script/index.tsx +13 -0
  12. package/app/assets/script/tasks/TaskApplication.ts +77 -0
  13. package/app/assets/script/tasks/TaskMediator.ts +20 -0
  14. package/app/assets/script/tasks/TaskModel.ts +32 -0
  15. package/app/assets/script/tasks/TaskRouter.ts +30 -0
  16. package/app/assets/script/tasks/TaskView.tsx +24 -0
  17. package/app/assets/style/global.css +111 -0
  18. package/app/assets/style/print.css +8 -0
  19. package/app/assets/view/CodeBlock.tsx +17 -0
  20. package/app/assets/view/examples/tasks/TaskExample.tsx +63 -0
  21. package/app/assets/view/examples/tasks/task-state.ts +46 -0
  22. package/app/assets/view/layout/SiteFooter.tsx +11 -0
  23. package/app/assets/view/layout/SiteHeader.tsx +23 -0
  24. package/app/assets/view/page-data.ts +14 -0
  25. package/app/assets/view/sections/GettingStartedSection.tsx +27 -0
  26. package/app/assets/view/sections/HeroSection.tsx +21 -0
  27. package/app/assets/view/sections/LiveExampleSection.tsx +29 -0
  28. package/app/assets/view/sections/PackageDocsSection.tsx +69 -0
  29. package/app/assets/view/sections/SourceGuideSection.tsx +28 -0
  30. package/app/index.tsx +54 -0
  31. package/cli/index.ts +117 -0
  32. package/dist/app/404.d.ts +1 -0
  33. package/dist/app/404.js +6 -0
  34. package/dist/app/404.js.map +1 -0
  35. package/dist/app/assets/script/index.d.ts +8 -2
  36. package/dist/app/assets/script/index.js +11 -1
  37. package/dist/app/assets/script/index.js.map +1 -1
  38. package/dist/app/assets/script/tasks/TaskApplication.d.ts +20 -0
  39. package/dist/app/assets/script/tasks/TaskApplication.js +63 -0
  40. package/dist/app/assets/script/tasks/TaskApplication.js.map +1 -0
  41. package/dist/app/assets/script/tasks/TaskMediator.d.ts +15 -0
  42. package/dist/app/assets/script/tasks/TaskMediator.js +5 -0
  43. package/dist/app/assets/script/tasks/TaskMediator.js.map +1 -0
  44. package/dist/app/assets/script/tasks/TaskModel.d.ts +13 -0
  45. package/dist/app/assets/script/tasks/TaskModel.js +33 -0
  46. package/dist/app/assets/script/tasks/TaskModel.js.map +1 -0
  47. package/dist/app/assets/script/tasks/TaskRouter.d.ts +12 -0
  48. package/dist/app/assets/script/tasks/TaskRouter.js +28 -0
  49. package/dist/app/assets/script/tasks/TaskRouter.js.map +1 -0
  50. package/dist/app/assets/script/tasks/TaskView.d.ts +9 -0
  51. package/dist/app/assets/script/tasks/TaskView.js +24 -0
  52. package/dist/app/assets/script/tasks/TaskView.js.map +1 -0
  53. package/dist/app/assets/view/CodeBlock.d.ts +11 -0
  54. package/dist/app/assets/view/CodeBlock.js +12 -0
  55. package/dist/app/assets/view/CodeBlock.js.map +1 -0
  56. package/dist/app/assets/view/examples/tasks/TaskExample.d.ts +11 -0
  57. package/dist/app/assets/view/examples/tasks/TaskExample.js +16 -0
  58. package/dist/app/assets/view/examples/tasks/TaskExample.js.map +1 -0
  59. package/dist/app/assets/view/examples/tasks/task-state.d.ts +22 -0
  60. package/dist/app/assets/view/examples/tasks/task-state.js +30 -0
  61. package/dist/app/assets/view/examples/tasks/task-state.js.map +1 -0
  62. package/dist/app/assets/view/layout/SiteFooter.d.ts +2 -0
  63. package/dist/app/assets/view/layout/SiteFooter.js +6 -0
  64. package/dist/app/assets/view/layout/SiteFooter.js.map +1 -0
  65. package/dist/app/assets/view/layout/SiteHeader.d.ts +8 -0
  66. package/dist/app/assets/view/layout/SiteHeader.js +12 -0
  67. package/dist/app/assets/view/layout/SiteHeader.js.map +1 -0
  68. package/dist/app/assets/view/page-data.d.ts +16 -0
  69. package/dist/app/assets/view/page-data.js +2 -0
  70. package/dist/app/assets/view/page-data.js.map +1 -0
  71. package/dist/app/assets/view/sections/GettingStartedSection.d.ts +2 -0
  72. package/dist/app/assets/view/sections/GettingStartedSection.js +11 -0
  73. package/dist/app/assets/view/sections/GettingStartedSection.js.map +1 -0
  74. package/dist/app/assets/view/sections/HeroSection.d.ts +8 -0
  75. package/dist/app/assets/view/sections/HeroSection.js +12 -0
  76. package/dist/app/assets/view/sections/HeroSection.js.map +1 -0
  77. package/dist/app/assets/view/sections/LiveExampleSection.d.ts +6 -0
  78. package/dist/app/assets/view/sections/LiveExampleSection.js +13 -0
  79. package/dist/app/assets/view/sections/LiveExampleSection.js.map +1 -0
  80. package/dist/app/assets/view/sections/PackageDocsSection.d.ts +2 -0
  81. package/dist/app/assets/view/sections/PackageDocsSection.js +31 -0
  82. package/dist/app/assets/view/sections/PackageDocsSection.js.map +1 -0
  83. package/dist/app/assets/view/sections/SourceGuideSection.d.ts +7 -0
  84. package/dist/app/assets/view/sections/SourceGuideSection.js +11 -0
  85. package/dist/app/assets/view/sections/SourceGuideSection.js.map +1 -0
  86. package/dist/app/index.d.ts +8 -0
  87. package/dist/app/index.js +22 -0
  88. package/dist/app/index.js.map +1 -0
  89. package/dist/cli/index.d.ts +13 -0
  90. package/dist/cli/index.js +97 -0
  91. package/dist/cli/index.js.map +1 -0
  92. package/dist/scaffold/index.d.ts +64 -0
  93. package/dist/scaffold/index.js +109 -0
  94. package/dist/scaffold/index.js.map +1 -0
  95. package/dist/scripts/build.d.ts +5 -13
  96. package/dist/scripts/build.js +48 -79
  97. package/dist/scripts/build.js.map +1 -1
  98. package/package.json +77 -40
  99. package/pnpm-workspace.yaml +4 -0
  100. package/scaffold/index.ts +127 -0
  101. package/scaffold/no-jsx/README.md +47 -0
  102. package/scaffold/no-jsx/app/404.ts +10 -0
  103. package/scaffold/no-jsx/app/assets/script/index.ts +7 -0
  104. package/scaffold/no-jsx/app/assets/script/tasks/TaskView.ts +19 -0
  105. package/scaffold/no-jsx/app/assets/view/examples/tasks/TaskExample.ts +39 -0
  106. package/scaffold/no-jsx/app/index.ts +58 -0
  107. package/scripts/build.ts +55 -86
  108. package/server/handler.ts +75 -0
  109. package/template-test/site.test.js +233 -0
  110. package/tsconfig.site.json +6 -5
  111. package/tsconfig.site.no-jsx.json +24 -0
  112. package/app/404.hbs +0 -20
  113. package/app/assets/data/coutries.json +0 -992
  114. package/app/assets/data/states.json +0 -204
  115. package/app/assets/data/view/toolkit/colors.json +0 -17
  116. package/app/assets/data/view/toolkit/components.json +0 -39
  117. package/app/assets/data/view/toolkit/elements.json +0 -119
  118. package/app/assets/data/view/toolkit/grids.json +0 -17
  119. package/app/assets/data/view/toolkit/icons.json +0 -17
  120. package/app/assets/data/view/toolkit/index.json +0 -17
  121. package/app/assets/data/view/toolkit/type.json +0 -17
  122. package/app/assets/font/opensans/LICENSE.txt +0 -202
  123. package/app/assets/font/opensans/opensans-bold-webfont.woff2 +0 -0
  124. package/app/assets/font/opensans/opensans-bolditalic-webfont.woff2 +0 -0
  125. package/app/assets/font/opensans/opensans-extrabold-webfont.woff2 +0 -0
  126. package/app/assets/font/opensans/opensans-extrabolditalic-webfont.woff2 +0 -0
  127. package/app/assets/font/opensans/opensans-italic-webfont.woff2 +0 -0
  128. package/app/assets/font/opensans/opensans-light-webfont.woff2 +0 -0
  129. package/app/assets/font/opensans/opensans-lightitalic-webfont.woff2 +0 -0
  130. package/app/assets/font/opensans/opensans-regular-webfont.woff2 +0 -0
  131. package/app/assets/font/opensans/opensans-semibold-webfont.woff2 +0 -0
  132. package/app/assets/font/opensans/opensans-semibolditalic-webfont.woff2 +0 -0
  133. package/app/assets/font/opensans/stylesheet.css +0 -120
  134. package/app/assets/image/apple-touch-icon.png +0 -0
  135. package/app/assets/image/demo/fallback.avif +0 -0
  136. package/app/assets/image/demo/fallback.jpg +0 -0
  137. package/app/assets/image/demo/fallback.webp +0 -0
  138. package/app/assets/image/demo/large.avif +0 -0
  139. package/app/assets/image/demo/large.webp +0 -0
  140. package/app/assets/image/demo/small.avif +0 -0
  141. package/app/assets/image/demo/small.webp +0 -0
  142. package/app/assets/image/favicon.png +0 -0
  143. package/app/assets/image/graphic-css3.svg +0 -30
  144. package/app/assets/image/graphic-html5.svg +0 -29
  145. package/app/assets/markup/element/a.hbs +0 -29
  146. package/app/assets/markup/element/button.hbs +0 -30
  147. package/app/assets/markup/element/div.hbs +0 -11
  148. package/app/assets/markup/element/head.hbs +0 -78
  149. package/app/assets/markup/element/iframe.hbs +0 -20
  150. package/app/assets/markup/element/img.hbs +0 -30
  151. package/app/assets/markup/element/input.hbs +0 -43
  152. package/app/assets/markup/element/label.hbs +0 -14
  153. package/app/assets/markup/element/legend.hbs +0 -5
  154. package/app/assets/markup/element/meta.hbs +0 -11
  155. package/app/assets/markup/element/nav.hbs +0 -13
  156. package/app/assets/markup/element/p.hbs +0 -8
  157. package/app/assets/markup/element/picture.hbs +0 -58
  158. package/app/assets/markup/element/script.hbs +0 -3
  159. package/app/assets/markup/element/select.hbs +0 -35
  160. package/app/assets/markup/element/span.hbs +0 -8
  161. package/app/assets/markup/element/svg.hbs +0 -11
  162. package/app/assets/markup/element/table.hbs +0 -50
  163. package/app/assets/markup/element/textarea.hbs +0 -24
  164. package/app/assets/markup/element/ul.hbs +0 -13
  165. package/app/assets/markup/modal/modal-example-1.handlebars +0 -8
  166. package/app/assets/markup/toolkit/accessibility-skip-to-element-1.handlebars +0 -1
  167. package/app/assets/markup/toolkit/accessibility-speaker-1.handlebars +0 -1
  168. package/app/assets/markup/toolkit/anchor-1.handlebars +0 -1
  169. package/app/assets/markup/toolkit/button-1.handlebars +0 -1
  170. package/app/assets/markup/toolkit/footer-1.handlebars +0 -3
  171. package/app/assets/markup/toolkit/header-1.handlebars +0 -1
  172. package/app/assets/markup/toolkit/heading-1.handlebars +0 -1
  173. package/app/assets/markup/toolkit/heading-2.handlebars +0 -1
  174. package/app/assets/markup/toolkit/heading-3.handlebars +0 -1
  175. package/app/assets/markup/toolkit/heading-4.handlebars +0 -1
  176. package/app/assets/markup/toolkit/image-1.handlebars +0 -1
  177. package/app/assets/markup/toolkit/input-checkbox-1.handlebars +0 -1
  178. package/app/assets/markup/toolkit/input-error-1.handlebars +0 -8
  179. package/app/assets/markup/toolkit/input-radio-1.handlebars +0 -1
  180. package/app/assets/markup/toolkit/input-text-1.handlebars +0 -1
  181. package/app/assets/markup/toolkit/label-1.handlebars +0 -1
  182. package/app/assets/markup/toolkit/legend-1.handlebars +0 -1
  183. package/app/assets/markup/toolkit/list-1.handlebars +0 -1
  184. package/app/assets/markup/toolkit/modal-1.handlebars +0 -4
  185. package/app/assets/markup/toolkit/nav-1.handlebars +0 -1
  186. package/app/assets/markup/toolkit/picture-1.handlebars +0 -1
  187. package/app/assets/markup/toolkit/select-1.handlebars +0 -1
  188. package/app/assets/markup/toolkit/table-1.handlebars +0 -1
  189. package/app/assets/markup/toolkit/text-1.handlebars +0 -1
  190. package/app/assets/markup/toolkit/textarea-1.handlebars +0 -1
  191. package/app/assets/markup/toolkit/youtube-player-1.handlebars +0 -1
  192. package/app/assets/script/api/facebook.ts +0 -41
  193. package/app/assets/script/api/youtube.ts +0 -22
  194. package/app/assets/script/index.ts +0 -2
  195. package/app/assets/script/mediator/global.ts +0 -4
  196. package/app/assets/script/model/singletons/countries.ts +0 -5
  197. package/app/assets/script/model/singletons/global.ts +0 -5
  198. package/app/assets/script/model/singletons/states.ts +0 -5
  199. package/app/assets/script/model/user.ts +0 -4
  200. package/app/assets/script/toolkit.ts +0 -11
  201. package/app/assets/script/types.d.ts +0 -6
  202. package/app/assets/script/utility/ajax.ts +0 -15
  203. package/app/assets/script/utility/form.ts +0 -119
  204. package/app/assets/script/utility/regex.ts +0 -26
  205. package/app/assets/script/utility/share.ts +0 -77
  206. package/app/assets/script/utility/string.ts +0 -148
  207. package/app/assets/script/view/default.tsx +0 -14
  208. package/app/assets/script/view/toolkit/youtube-player-1.ts +0 -33
  209. package/app/assets/style/base/_toolkit.scss +0 -39
  210. package/app/assets/style/base/colors/_colors.scss +0 -18
  211. package/app/assets/style/base/components/_modal-1.scss +0 -80
  212. package/app/assets/style/base/components/_sticky-1.scss +0 -19
  213. package/app/assets/style/base/components/_tabpanel-1.scss +0 -115
  214. package/app/assets/style/base/components/_tabpanel-2.scss +0 -64
  215. package/app/assets/style/base/components/_tabpanel-base-1.scss +0 -13
  216. package/app/assets/style/base/components/_youtube-player-1.scss +0 -16
  217. package/app/assets/style/base/elements/_anchors.scss +0 -27
  218. package/app/assets/style/base/elements/_buttons.scss +0 -25
  219. package/app/assets/style/base/elements/_fieldsets.scss +0 -9
  220. package/app/assets/style/base/elements/_images.scss +0 -8
  221. package/app/assets/style/base/elements/_inputs.scss +0 -78
  222. package/app/assets/style/base/elements/_labels.scss +0 -16
  223. package/app/assets/style/base/elements/_landmarks.scss +0 -3
  224. package/app/assets/style/base/elements/_legends.scss +0 -11
  225. package/app/assets/style/base/elements/_lists.scss +0 -15
  226. package/app/assets/style/base/elements/_pictures.scss +0 -4
  227. package/app/assets/style/base/elements/_tables.scss +0 -39
  228. package/app/assets/style/base/layouts/_staggered-1.scss +0 -29
  229. package/app/assets/style/base/type/_fonts.scss +0 -125
  230. package/app/assets/style/base/type/_headings.scss +0 -36
  231. package/app/assets/style/base/type/_text.scss +0 -9
  232. package/app/assets/style/base/utilities/_accessibility.scss +0 -55
  233. package/app/assets/style/base/utilities/_functions.scss +0 -98
  234. package/app/assets/style/base/utilities/_scroll.scss +0 -11
  235. package/app/assets/style/base/utilities/_type.scss +0 -13
  236. package/app/assets/style/global.scss +0 -123
  237. package/app/assets/style/print.scss +0 -6
  238. package/app/assets/style/toolkit.scss +0 -387
  239. package/app/index.hbs +0 -21
  240. package/app/robots.txt +0 -1
  241. package/app/toolkit/colors.hbs +0 -102
  242. package/app/toolkit/components.hbs +0 -261
  243. package/app/toolkit/elements.hbs +0 -497
  244. package/app/toolkit/grids.hbs +0 -413
  245. package/app/toolkit/icons.hbs +0 -87
  246. package/app/toolkit/index.hbs +0 -144
  247. package/app/toolkit/type.hbs +0 -120
  248. package/dist/app/assets/data/coutries.json +0 -992
  249. package/dist/app/assets/data/states.json +0 -204
  250. package/dist/app/assets/script/api/facebook.d.ts +0 -8
  251. package/dist/app/assets/script/api/facebook.js +0 -42
  252. package/dist/app/assets/script/api/facebook.js.map +0 -1
  253. package/dist/app/assets/script/api/youtube.d.ts +0 -8
  254. package/dist/app/assets/script/api/youtube.js +0 -22
  255. package/dist/app/assets/script/api/youtube.js.map +0 -1
  256. package/dist/app/assets/script/mediator/global.d.ts +0 -4
  257. package/dist/app/assets/script/mediator/global.js +0 -4
  258. package/dist/app/assets/script/mediator/global.js.map +0 -1
  259. package/dist/app/assets/script/model/singletons/countries.d.ts +0 -4
  260. package/dist/app/assets/script/model/singletons/countries.js +0 -5
  261. package/dist/app/assets/script/model/singletons/countries.js.map +0 -1
  262. package/dist/app/assets/script/model/singletons/global.d.ts +0 -4
  263. package/dist/app/assets/script/model/singletons/global.js +0 -5
  264. package/dist/app/assets/script/model/singletons/global.js.map +0 -1
  265. package/dist/app/assets/script/model/singletons/states.d.ts +0 -4
  266. package/dist/app/assets/script/model/singletons/states.js +0 -5
  267. package/dist/app/assets/script/model/singletons/states.js.map +0 -1
  268. package/dist/app/assets/script/model/user.d.ts +0 -4
  269. package/dist/app/assets/script/model/user.js +0 -6
  270. package/dist/app/assets/script/model/user.js.map +0 -1
  271. package/dist/app/assets/script/toolkit.d.ts +0 -1
  272. package/dist/app/assets/script/toolkit.js +0 -7
  273. package/dist/app/assets/script/toolkit.js.map +0 -1
  274. package/dist/app/assets/script/utility/ajax.d.ts +0 -8
  275. package/dist/app/assets/script/utility/ajax.js +0 -17
  276. package/dist/app/assets/script/utility/ajax.js.map +0 -1
  277. package/dist/app/assets/script/utility/form.d.ts +0 -64
  278. package/dist/app/assets/script/utility/form.js +0 -111
  279. package/dist/app/assets/script/utility/form.js.map +0 -1
  280. package/dist/app/assets/script/utility/regex.d.ts +0 -14
  281. package/dist/app/assets/script/utility/regex.js +0 -27
  282. package/dist/app/assets/script/utility/regex.js.map +0 -1
  283. package/dist/app/assets/script/utility/share.d.ts +0 -68
  284. package/dist/app/assets/script/utility/share.js +0 -81
  285. package/dist/app/assets/script/utility/share.js.map +0 -1
  286. package/dist/app/assets/script/utility/string.d.ts +0 -64
  287. package/dist/app/assets/script/utility/string.js +0 -135
  288. package/dist/app/assets/script/utility/string.js.map +0 -1
  289. package/dist/app/assets/script/view/default.d.ts +0 -11
  290. package/dist/app/assets/script/view/default.js +0 -15
  291. package/dist/app/assets/script/view/default.js.map +0 -1
  292. package/dist/app/assets/script/view/toolkit/youtube-player-1.d.ts +0 -23
  293. package/dist/app/assets/script/view/toolkit/youtube-player-1.js +0 -34
  294. package/dist/app/assets/script/view/toolkit/youtube-player-1.js.map +0 -1
  295. package/dist/generators/app/index.d.ts +0 -18
  296. package/dist/generators/app/index.js +0 -59
  297. package/dist/generators/app/index.js.map +0 -1
  298. package/generators/app/index.js +0 -2
  299. package/generators/app/index.ts +0 -61
package/.editorconfig ADDED
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 4
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.{json,yml,yaml}]
12
+ indent_size = 2
13
+
14
+ [*.md]
15
+ trim_trailing_whitespace = false
package/.yarnrc.yml ADDED
@@ -0,0 +1,6 @@
1
+ nodeLinker: node-modules
2
+ npmPreapprovedPackages:
3
+ - "white-label-mediator"
4
+ - "white-label-model"
5
+ - "white-label-router"
6
+ - "white-label-view"
package/CLI.md ADDED
@@ -0,0 +1,82 @@
1
+ # White Label CLI
2
+
3
+ White Label has one project-creation engine and a thin command-line adapter.
4
+
5
+ ```text
6
+ CLI ──────> createProject() ──────> project
7
+ Node API ─┘
8
+ ```
9
+
10
+ `createProject()` owns the scaffold. The CLI translates command-line input into that API.
11
+
12
+ ## Create a project
13
+
14
+ With a globally installed CLI:
15
+
16
+ ```sh
17
+ white-label create my-project
18
+ ```
19
+
20
+ Or run the package directly with the package manager you prefer:
21
+
22
+ ```sh
23
+ npx generator-white-label create my-project
24
+ yarn dlx generator-white-label create my-project
25
+ pnpm dlx generator-white-label create my-project
26
+ ```
27
+
28
+ The CLI creates into a new or existing **empty** directory. It refuses a non-empty destination so a mistyped path cannot overwrite existing project files.
29
+
30
+ Then install and test the generated project with npm, Yarn, or pnpm:
31
+
32
+ ```sh
33
+ cd my-project
34
+ npm install && npm test
35
+ # or: yarn install && yarn test
36
+ # or: pnpm install && pnpm test
37
+ ```
38
+
39
+ When run interactively, the CLI asks whether page and view templates should use JSX/TSX. JSX is optional: choose **Yes** for White Label's first-party JSX syntax such as `<section>...</section>`, or **No** for plain TypeScript functions that return HTML strings. Both choices produce the same working starter application and features.
40
+
41
+ Choose **No** when you want plain string templates or plan to use a third-party renderer. Install that renderer in the generated application and call it from the View `template` function; White Label does not require an adapter. See [Template engines and JSX options](https://whitelabeljs.org/docs/view/#template-engines) for the tested third-party engines and rendering contract.
42
+
43
+ For scripts and non-interactive use, choose explicitly:
44
+
45
+ ```sh
46
+ white-label create my-project --jsx
47
+ white-label create my-project --no-jsx
48
+
49
+ npx generator-white-label create my-project --jsx
50
+ npx generator-white-label create my-project --no-jsx
51
+ ```
52
+
53
+ The same `--jsx` and `--no-jsx` flags work through `yarn dlx` and `pnpm dlx`.
54
+
55
+ If no choice can be asked interactively and neither flag is supplied, JSX remains the default for backward compatibility.
56
+
57
+ Run `white-label --help` for usage. See [`PACKAGE_MANAGERS.md`](PACKAGE_MANAGERS.md) for package-manager compatibility details.
58
+
59
+ ## Use the API
60
+
61
+ ```js
62
+ import {createProject} from 'generator-white-label';
63
+
64
+ await createProject({
65
+ destination: '/absolute/path/to/my-project',
66
+ jsx: false
67
+ });
68
+ ```
69
+
70
+ Set `jsx: true` for JSX/TSX templates or `jsx: false` for plain TypeScript and HTML strings. Use `jsx: false` as the starting point when another template engine should own rendering. Omitting `jsx` defaults to `true`.
71
+
72
+ `createProject()` is the lower-level programmatic API and does not apply the CLI's non-empty-directory guard. Applications using it directly own destination-policy decisions.
73
+
74
+ ## Read the implementation
75
+
76
+ The source is intentionally small enough to teach the design:
77
+
78
+ - `scaffold/index.ts` — project creation
79
+ - `cli/index.ts` — command-line adapter
80
+ - `test/` — executable contracts
81
+
82
+ Creation behavior belongs in one place. Future integrations should call `createProject()` rather than copy templates or reimplement generation logic.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 bshack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # Package manager support
2
+
3
+ `generator-white-label` and the projects it creates support npm, Yarn, and pnpm.
4
+
5
+ ## Run the generator
6
+
7
+ ```sh
8
+ npx generator-white-label create my-project
9
+ yarn dlx generator-white-label create my-project
10
+ pnpm dlx generator-white-label create my-project
11
+ ```
12
+
13
+ The same `--jsx` and `--no-jsx` options are available through every invocation path. JSX is optional: use `--jsx` for the first-party White Label JSX runtime, or `--no-jsx` for plain TypeScript templates and as the starting point for a third-party template engine.
14
+
15
+ See [Template engines and JSX options](https://whitelabeljs.org/docs/view/#template-engines) for tested third-party renderers and the View rendering contract.
16
+
17
+ ## Work with a generated project
18
+
19
+ After generation, use the package manager you prefer:
20
+
21
+ ```sh
22
+ npm install && npm test
23
+ yarn install && yarn test
24
+ pnpm install && pnpm test
25
+ ```
26
+
27
+ Generated manifests require the supported Node.js runtime but do not require a specific package manager. Nested scripts use Node's `--run` support instead of invoking npm internally.
28
+
29
+ Generated projects use exact npm versions for the four first-party White Label packages. They also carry narrow install-script approvals for the dependencies that actually need lifecycle builds: `esbuild`, `@parcel/watcher`, and `white-label-view`. npm uses pinned `allowScripts` entries, Yarn uses pinned `dependenciesMeta` build permissions, and pnpm uses `onlyBuiltDependencies`.
30
+
31
+ Yarn's package-age security gate is left enabled for ordinary dependencies. The generated `.yarnrc.yml` preapproves only `white-label-mediator`, `white-label-model`, `white-label-router`, and `white-label-view` so a newly published White Label release can be installed immediately without disabling Yarn's protection for the rest of the dependency graph.
32
+
33
+ ## Repository development
34
+
35
+ The committed `package-lock.json` remains the generator repository's canonical dependency lockfile and npm remains the maintenance/audit path used by primary CI. Compatibility CI packs the real generator artifact and verifies its API and CLI under npm, Yarn, and pnpm. Alternate lockfiles are not committed merely for compatibility testing.
package/README.md CHANGED
@@ -1,195 +1,275 @@
1
- # white-label
1
+ # generator-white-label
2
2
 
3
- `white-label` is a Yeoman generator and build system for creating static websites. It provides a working project structure with Handlebars templates, Sass styles, Bootstrap, responsive images, and TypeScript sources compiled to bundled JavaScript.
3
+ `generator-white-label` is a framework-independent TypeScript project generator for small, accessible, SEO-friendly sites with progressive enhancement, composable White Label primitives, and a provider-neutral Node.js function example.
4
4
 
5
- Use it when you want a small, understandable static-site foundation that you can brand and extend without adopting a full application framework.
5
+ [Documentation](https://whitelabeljs.org/docs/generator/) · [API reference](https://whitelabeljs.org/api/#generator) · [Demo site](https://whitelabeljs.org/)
6
6
 
7
- ## What it builds
7
+ The project is also its own teaching tool. The landing page, README, source, and tests are meant to be read together:
8
8
 
9
- The project separates source files by responsibility:
9
+ ```text
10
+ understand → see → build → verify
11
+ ```
12
+
13
+ White Label does not prescribe a framework. It provides focused pieces that can be composed where useful and omitted where they are not.
14
+
15
+ ## The idea
16
+
17
+ A typical interactive feature can be understood as a flow of responsibilities:
18
+
19
+ ```text
20
+ URL / user action
21
+
22
+ Router
23
+
24
+ Mediator
25
+
26
+ Model
27
+
28
+ View
29
+
30
+ DOM
31
+ ```
32
+
33
+ These are responsibilities, not mandatory layers. Static content can stay plain JSX or plain TypeScript HTML strings. A feature that does not need routing does not need a router.
34
+
35
+ - [`white-label-router`](https://github.com/bshack/white-label-router) turns location into application intent.
36
+ - [`white-label-mediator`](https://github.com/bshack/white-label-mediator) coordinates application events.
37
+ - [`white-label-model`](https://github.com/bshack/white-label-model) owns observable state.
38
+ - [`white-label-view`](https://github.com/bshack/white-label-view) owns rendering and DOM lifecycle.
39
+ - [`white-label-view/jsx-runtime`](https://github.com/bshack/white-label-view) provides optional escaped JSX without React or another template engine.
40
+
41
+ The goal is simple boundaries with explicit composition.
42
+
43
+ ## Learn from the generated application
44
+
45
+ The generated landing page demonstrates the same architecture it documents.
46
+
47
+ Its static sections use either JSX functions or equivalent plain TypeScript HTML-string functions, depending on the generator choice. The task example then shows all four packages working together:
48
+
49
+ ```text
50
+ TaskRouter
51
+ ↓ route intent
52
+ TaskMediator
53
+ ↓ state operation
54
+ TaskModel
55
+ ↓ observable state
56
+ TaskView
57
+ ↓ render
58
+ DOM
59
+ ```
60
+
61
+ Both generated variants provide the same application behavior and progressive enhancement. The only difference is template syntax.
62
+
63
+ ## Read the source
10
64
 
11
- - `app/*.hbs` contains pages.
12
- - `app/assets/markup` contains reusable Handlebars partials.
13
- - `app/assets/data/view` contains global and page-specific JSON data.
14
- - `app/assets/style` contains Sass entry points and partials.
15
- - `app/assets/script` contains TypeScript and TSX entry points.
16
- - `app/assets/image` and `app/assets/font` contain static assets.
17
- - `scripts/build.ts` turns those sources into a deployable `_deploy` directory.
65
+ For the default JSX scaffold, a useful reading order is:
18
66
 
19
- The build renders Handlebars pages, compiles Sass, bundles JavaScript with esbuild, copies static assets, and writes the deployment configuration to `assets/data/config.json`. `global.css` includes the complete compiled Bootstrap CSS followed by the project's styles.
67
+ 1. [`app/index.tsx`](app/index.tsx) page composition.
68
+ 2. [`app/assets/view/sections/LiveExampleSection.tsx`](app/assets/view/sections/LiveExampleSection.tsx) — static composition around an interactive feature.
69
+ 3. [`app/assets/view/examples/tasks/TaskExample.tsx`](app/assets/view/examples/tasks/TaskExample.tsx) — shared JSX rendering.
70
+ 4. [`app/assets/script/tasks/TaskApplication.ts`](app/assets/script/tasks/TaskApplication.ts) — explicit dependency wiring.
71
+ 5. `TaskRouter`, `TaskMediator`, `TaskModel`, and `TaskView` — one responsibility at a time.
72
+ 6. [`server/handler.ts`](server/handler.ts) — provider-neutral `Request`/`Response` serverless composition.
73
+ 7. [`test/app.test.js`](test/app.test.js) and [`template-test/site.test.js`](template-test/site.test.js) — browser and generated-project contracts.
20
74
 
21
- Generated formatting utilities use native `Intl` and `Date` APIs, so new projects do not need Lodash, Moment, or Numeral for the included examples.
75
+ The `--no-jsx` scaffold mirrors the same structure with `.ts` files and HTML-string render functions.
22
76
 
23
- ## Requirements
77
+ Comments focus on why boundaries exist instead of narrating obvious TypeScript.
24
78
 
25
- - Node.js 20 or newer
26
- - npm 10 or newer
79
+ When documenting public APIs, examples use comments where they clarify intent, lifecycle, side effects, or non-obvious behavior. Public method documentation should also state the return value—including meaningful boolean/status values, chaining returns, `undefined`, promises, and relevant thrown/rejected errors.
27
80
 
28
- ## Generate a new site
81
+ A useful rule when extending the project is:
29
82
 
30
- Install Yeoman and the generator, then run it in an empty project directory:
83
+ > Introduce an abstraction when it gives a concern a clear home, not merely to create another layer.
84
+
85
+ ## Create a project
86
+
87
+ Requirement:
88
+
89
+ - Node.js `^22.18.0` or `>=24.11.0`
90
+
91
+ Install the CLI globally with your preferred package manager, or run the package directly.
92
+
93
+ With npm:
31
94
 
32
95
  ```sh
33
- npm install --global yo generator-white-label
34
- mkdir my-site
35
- cd my-site
36
- yo white-label
96
+ npx generator-white-label create my-project
37
97
  ```
38
98
 
39
- The generator copies the `app` and `scripts` directories and creates a project `package.json`. It intentionally does not install dependencies automatically, so you can review that manifest first:
99
+ With Yarn:
40
100
 
41
101
  ```sh
42
- npm install
43
- npm test
102
+ yarn dlx generator-white-label create my-project
44
103
  ```
45
104
 
46
- ## Build the site
105
+ With pnpm:
47
106
 
48
- A build with defaults is enough for local inspection:
107
+ ```sh
108
+ pnpm dlx generator-white-label create my-project
109
+ ```
110
+
111
+ A global install also exposes the `white-label` command:
49
112
 
50
113
  ```sh
51
- npm run build
114
+ npm install --global generator-white-label
115
+ white-label create my-project
52
116
  ```
53
117
 
54
- The generated site is written to `_deploy`. Each asset build is placed under `_deploy/release/<version>/assets`; when no version is supplied, the build uses the current Unix timestamp.
118
+ After generation, use npm, Yarn, or pnpm consistently within the project:
119
+
120
+ ```sh
121
+ cd my-project
122
+ npm install && npm test
123
+ # or: yarn install && yarn test
124
+ # or: pnpm install && pnpm test
125
+ ```
55
126
 
56
- For a deployment build, pass explicit values after `--`:
127
+ Interactive creation asks whether templates should use JSX/TSX. JSX is optional: choose **Yes** for White Label's first-party JSX syntax such as `<section>...</section>`, or **No** for plain TypeScript functions that return HTML strings. Both choices generate the same functional starter application.
128
+
129
+ Choose the no-JSX path when another template engine should own rendering. Install that engine in the generated application and call it from the View `template` function; no White Label adapter is required. White Label View currently tests Handlebars, Eta, EJS, Mustache, Nunjucks, and Pug in both browser and server rendering. See [Template engines and JSX options](https://whitelabeljs.org/docs/view/#template-engines) for tested versions, examples, the rendering contract, and security guidance.
130
+
131
+ For explicit or non-interactive use:
57
132
 
58
133
  ```sh
59
- npm run build -- \
60
- --www=https://www.example.com \
61
- --cdn=https://cdn.example.com \
62
- --service=https://api.example.com \
63
- --version=2026.09.06 \
64
- --production=true
134
+ white-label create my-project --jsx
135
+ white-label create my-project --no-jsx
136
+
137
+ npx generator-white-label create my-project --jsx
138
+ npx generator-white-label create my-project --no-jsx
65
139
  ```
66
140
 
67
- | Option | Default | Purpose |
68
- | --- | --- | --- |
69
- | `--www` | `/` | Public website base URL exposed to templates and configuration. |
70
- | `--cdn` | `/` | Asset base URL exposed to templates and configuration. |
71
- | `--service` | `/service-endpoint` | Backend service URL exposed to the site. |
72
- | `--version` | Current Unix timestamp | Directory name used for versioned assets. |
73
- | `--production` | `false` | Minifies CSS and JavaScript when set to `true`. |
141
+ The same `--jsx` and `--no-jsx` options work through `yarn dlx` and `pnpm dlx`.
142
+
143
+ If no interactive answer is available and neither flag is supplied, JSX is the default for backward compatibility.
74
144
 
75
- The version may contain only letters, numbers, dots, underscores, and hyphens. This prevents it from escaping the deployment directory.
145
+ See [`CLI.md`](CLI.md) for the CLI contract and [`PACKAGE_MANAGERS.md`](PACKAGE_MANAGERS.md) for package-manager compatibility details.
76
146
 
77
- ## Add a page
147
+ ## Programmatic API
78
148
 
79
- Create `app/about.hbs`:
149
+ Project creation has one implementation:
80
150
 
81
- ```handlebars
82
- {{> element/head}}
83
- <main>
84
- <h1>{{title}}</h1>
85
- <p>{{introduction}}</p>
86
- </main>
151
+ ```js
152
+ import {createProject} from 'generator-white-label';
153
+
154
+ // Resolves after the scaffold files and package manifest have been written.
155
+ await createProject({
156
+ destination: new URL('./my-project', import.meta.url).pathname,
157
+ jsx: false
158
+ });
87
159
  ```
88
160
 
89
- Then create matching data at `app/assets/data/view/about.json`:
161
+ Set `jsx: true` for JSX/TSX templates or `jsx: false` for plain TypeScript and HTML strings. Use `jsx: false` as the starting point for a third-party template engine. Omitting `jsx` defaults to `true`.
162
+
163
+ `createProject(options)` returns `Promise<void>`. A successful call resolves with `undefined`; file-system failures reject the promise instead of returning a status value.
164
+
165
+ `createProject()` is the canonical creation API. The CLI and future integrations are adapters around it rather than separate generation systems.
166
+
167
+ This is the same design principle used throughout White Label: one responsibility, one implementation, explicit adapters at environment boundaries.
168
+
169
+ ## Source layout
170
+
171
+ | Path | Purpose |
172
+ | --- | --- |
173
+ | `scaffold/index.ts` | Canonical `createProject()` implementation |
174
+ | `scaffold/no-jsx/` | Plain-TypeScript template equivalents |
175
+ | `cli/index.ts` | First-party command-line adapter |
176
+ | `app/*.tsx` | Default JSX top-level static pages |
177
+ | `app/assets/view/` | Default JSX views and page sections |
178
+ | `app/assets/script/tasks/` | Model/View/Mediator/Router example |
179
+ | `server/handler.ts` | Provider-neutral serverless `Request` → `Response` example |
180
+ | `scripts/build.ts` | Static rendering and asset build for `.ts` and `.tsx` pages |
181
+ | `test/` | Executable contracts and integration tests |
182
+ | `template-test/` | Generated-project validation, including serverless portability budgets |
183
+
184
+ No React, Bootstrap, Sass, Eta, Handlebars, Mustache, Nunjucks, Pug, web fonts, cloud SDK, or browser-side template framework is required. Third-party template engines and provider adapters remain optional application dependencies.
185
+
186
+ ## Template choice: JSX or no JSX
187
+
188
+ JSX is optional. When enabled, TypeScript uses the White Label JSX runtime:
90
189
 
91
190
  ```json
92
191
  {
93
- "title": "About us",
94
- "introduction": "A short description of the organization."
192
+ "compilerOptions": {
193
+ "jsx": "react-jsx",
194
+ "jsxImportSource": "white-label-view"
195
+ }
95
196
  }
96
197
  ```
97
198
 
98
- Global data from `app/assets/data/view/global.json`, page data, and build options are merged before the template is rendered. Page-specific values take precedence over global values, and build options take precedence over both.
199
+ A page remains an ordinary function:
99
200
 
100
- ## Responsive images
101
-
102
- The included `picture` partial supports AVIF and WebP sources at each responsive breakpoint, with an ordinary image as the final fallback:
103
-
104
- ```handlebars
105
- {{> element/picture
106
- imageFallback='assets/image/hero/fallback.jpg'
107
- imageSmallAvif='assets/image/hero/small.avif'
108
- imageSmallWebp='assets/image/hero/small.webp'
109
- imageLargeAvif='assets/image/hero/large.avif'
110
- imageLargeWebp='assets/image/hero/large.webp'
111
- width='2048'
112
- height='1600'
113
- loading='lazy'
114
- decoding='async'
115
- alt='A human-readable description of the image'
116
- }}
201
+ ```tsx
202
+ export default function Page(data: Record<string, unknown>) {
203
+ return <main><h1>{String(data.title)}</h1></main>;
204
+ }
117
205
  ```
118
206
 
119
- Browsers choose the first supported source whose media query matches. Browsers without AVIF or WebP support use `imageFallback`. Supplying width and height also reserves layout space and helps avoid content movement while the image loads.
207
+ With `--no-jsx`, the equivalent page is ordinary TypeScript returning an HTML string instead. The application architecture and generated features remain the same. That no-JSX scaffold is also the intended starting point when Handlebars, Eta, EJS, Mustache, Nunjucks, Pug, or another renderer should remain the project's template convention.
120
208
 
121
- ## Development checks
209
+ For larger pages, compose focused views instead of growing one renderer indefinitely.
122
210
 
123
- Run the same basic checks before proposing a change:
211
+ JSX expressions are escaped by default. In plain-TypeScript templates or third-party engines, applications own the engine's escaping and raw-output configuration. See [Template engines and JSX options](https://whitelabeljs.org/docs/view/#template-engines) for the tested matrix and trust boundaries.
124
212
 
125
- ```sh
126
- npm run build
127
- npm run typecheck
128
- npm test
129
- npm run coverage
130
- npm run audit
131
- ```
213
+ ## Progressive enhancement
132
214
 
133
- ## Version 4 migration notes
215
+ The generated project renders meaningful HTML during the build. Interactive task filters are real links first and are enhanced with History API navigation after initialization.
134
216
 
135
- Version 4 intentionally replaced the unsupported Gulp 3, Babel 6, PhantomJS, Karma, Bower, and legacy plugin pipeline. It also replaced Foundation with Bootstrap 5.3.8 and migrated the grid markup to Bootstrap `row` and responsive `col-*` classes. Projects upgrading from an older major version should treat the build tooling, supported Node.js versions, CSS framework, and generated markup as breaking changes.
217
+ The principle is intentional:
136
218
 
137
- Version 4.1 removes Lodash, Moment, and Numeral from generated projects. If application code added its own imports from those packages, either retain the dependency in that application or migrate those calls before upgrading.
219
+ ```text
220
+ HTML owns semantics.
221
+ JavaScript enhances behavior.
222
+ ```
138
223
 
139
- ## Related packages
224
+ ## Serverless and function runtimes
140
225
 
141
- - [`white-label-model`](https://github.com/bshack/white-label-model) provides event-emitting models and collections.
142
- - [`white-label-view`](https://github.com/bshack/white-label-view) renders templates and manages delegated DOM events.
143
- - [`white-label-router`](https://github.com/bshack/white-label-router) provides History API navigation.
144
- - [`white-label-mediator`](https://github.com/bshack/white-label-mediator) provides shared application messaging.
145
- - [`white-label-service`](https://github.com/bshack/white-label-service) provides an authenticated JSON service backed by MySQL.
226
+ Every generated project includes `server/handler.ts`, a provider-neutral example built around the Web `Request` and `Response` APIs. It composes Router, Mediator, Model, and `white-label-view/server` without Express or a provider SDK.
146
227
 
147
- ## TypeScript development and version 5.0.0 migration
228
+ Mutable White Label instances are created inside `handleRequest()`. This is intentional: serverless hosts can reuse a warm process for many requests, so mutable module-level Model/View/Router/Mediator instances can leak request data or listeners. Immutable configuration can still be shared at module scope when its lifetime is intentionally process-wide.
148
229
 
149
- Implementation code now uses strict TypeScript. Builds emit JavaScript, source maps with embedded source, and `.d.ts` declarations into `dist`. JavaScript callers can still use the package without compiling TypeScript themselves. JSDoc comments describe parameters, return values, lifecycle behavior, and validation at the implementation, and are retained in declarations.
230
+ Cloud-specific adapters should stay at the boundary. Translate an AWS/Vercel/Netlify/Azure/etc. request into a Web `Request` when necessary, call `handleRequest()`, and translate the returned `Response` back only if the provider requires it.
150
231
 
151
- ```ts
152
- // app/assets/script/profile.ts
153
- import User from './model/user.js';
232
+ Generated-project tests exercise sequential warm invocations, concurrent requests, request-data escaping, execution without browser globals, and a browser/Web-target bundle smoke test. They also enforce a 100 kB minified serverless-composition bundle budget and a 750 ms fresh-process handler-import budget. These are regression guards, not universal latency guarantees.
154
233
 
155
- const profile = new User({name: 'Ada'});
156
- console.log(profile.get().name);
157
- ```
234
+ The Web-target bundle smoke test catches unresolved Node built-ins, but it does **not** claim blanket Cloudflare/Deno/edge-provider compatibility. The published runtime packages still document Node as their supported server runtime; verify a specific edge provider before deployment.
158
235
 
159
- Write implementation files as `.ts`, or `.tsx` for React markup. Keep `.js` extensions on relative imports: TypeScript resolves them to source files and emits imports usable by Node. Every top-level script entry is bundled, except declaration-only `.d.ts` files. The build checks all sample modules, including modules not imported by an entry point.
236
+ ## Build and verify
160
237
 
161
- The generated project uses the current typed releases of `white-label-model` and `white-label-view`. The `types.d.ts` file declares only the optional SDK callbacks placed on `window`; package API types come directly from those dependencies.
238
+ The repository keeps npm as its canonical maintenance/audit path and committed lockfile. Generated projects support npm, Yarn, and pnpm.
162
239
 
163
- Version 5 is a major release because generated projects now contain TypeScript and use a two-stage TypeScript/esbuild pipeline. Use Node.js 24 for development and CI. Existing generated sites are not changed automatically: migrate their script files, copy the new build configuration, and resolve strict type errors before deploying. The small `generators/app/index.js` file is only Yeoman's discovery bridge to compiled TypeScript.
240
+ Development build:
164
241
 
165
- The generated project includes its own README. Full Bootstrap CSS remains included. Old inactive Gulp and Karma configuration has been removed; all historical share-URL assertions now run in the active Node test suite.
242
+ ```sh
243
+ npm run build -- --version=local
244
+ python3 -m http.server 8080 --directory _deploy
245
+ ```
166
246
 
167
- ### Sample utility reference
247
+ Production build:
168
248
 
169
- | Module | Functionality and example |
170
- | --- | --- |
171
- | `utility/ajax.ts` | `getScript('/sdk.js')` appends an asynchronous script; call it only when needed. |
172
- | `utility/form.ts` | Read multiselect values, select or find an option, decorate/split metadata, and build named options: `buildOptions([{id: 1, name: 'Ada'}], 1)`. Metadata helpers mutate their supplied arrays. |
173
- | `utility/string.ts` | Parse trusted HTML, read query values, format local dates, numbers and USD currency, and create phone/email links: `formatCurrency(12.5)` returns `$12.50`. `getQueryStringParamater` retains its historical spelling. |
174
- | `utility/share.ts` | Construct encoded Facebook, Twitter, LinkedIn and email URLs. Missing required values return `false`. Twitter retains its legacy 140-character rule; Google Plus support is a deprecated URL formatter for a discontinued service. |
175
- | `utility/regex.ts` | Legacy presentation-validation expressions for dates, passwords, phone numbers, ZIP codes, length and currency. These are not substitutes for server validation or a modern password policy. |
176
- | `model/user.ts` | An extendable observable object model. Country/state singletons contain the bundled JSON data. The global model starts with local URL defaults; the build separately writes deployment settings to `assets/data/config.json`. |
177
- | `api/facebook.ts`, `api/youtube.ts` | Optional SDK adapters that emit readiness events through the shared mediator. They are tested with local browser doubles, not live provider accounts. Review provider configuration before enabling them in a real site. |
178
- | `view/default.tsx` | A React greeting component: `<HelloMessage name="Ada" />`. |
179
- | `view/toolkit/youtube-player-1.ts` | An extension skeleton for a concrete player, with the legacy `removeListners` hook retained. |
180
-
181
- ### Verification and coverage
249
+ ```sh
250
+ npm run build -- \
251
+ --version=production \
252
+ --production=true \
253
+ --site-url=https://www.example.com
254
+ ```
255
+
256
+ Verification:
182
257
 
183
258
  ```sh
184
- npm ci --ignore-scripts
185
- npm run typecheck
259
+ npm run lint
186
260
  npm test
187
261
  npm run coverage
262
+ npm run audit
188
263
  npm pack --dry-run
189
264
  ```
190
265
 
191
- `npm test` builds the code, checks TypeScript consumer examples against the emitted declarations, and runs the tests. `npm run coverage` additionally enforces **100% statements, branches, functions, and lines for each implementation file**. Unexecuted implementation files count toward the result; declaration-only files contain no executable code and are excluded. Reports are written to `coverage`, including `lcov.info` for coverage viewers. CI runs the same gate and checks committed build output for drift.
266
+ Tests are part of the documentation. They demonstrate intended contracts while protecting behavior. Executable project source is held to 100% statement, branch, function, and line coverage.
267
+
268
+ ## White Label ecosystem
192
269
 
193
- Tests exercise the compiled JavaScript interface used by downstream callers. Coverage is an execution metric, not proof that all possible inputs or external integrations are correct. Tests for third-party SDKs use local doubles. No live provider requests are needed.
270
+ - [`white-label-model`](https://github.com/bshack/white-label-model) observable state.
271
+ - [`white-label-view`](https://github.com/bshack/white-label-view) — rendering, DOM lifecycle, optional JSX, and a template-engine-agnostic rendering contract.
272
+ - [`white-label-mediator`](https://github.com/bshack/white-label-mediator) — application events.
273
+ - [`white-label-router`](https://github.com/bshack/white-label-router) — routing and URL state.
194
274
 
195
- To undo this migration, revert its commit and run `npm ci` from the restored lockfile. No npm release, database migration, or production deployment is performed by these development changes.
275
+ The generated project imports the real packages rather than reproducing their behavior locally. That makes it both an example and an ecosystem integration test.
package/app/404.tsx ADDED
@@ -0,0 +1,28 @@
1
+ interface PageData {
2
+ cdn: string;
3
+ version: string;
4
+ www: string;
5
+ }
6
+
7
+ export default function NotFoundPage(data: Record<string, unknown>) {
8
+ const page = data as unknown as PageData;
9
+ return (
10
+ <html lang="en-US" dir="ltr">
11
+ <head>
12
+ <meta charset="utf-8" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
14
+ <meta name="robots" content="noindex,follow" />
15
+ <title>Page not found | White Label</title>
16
+ <link rel="stylesheet" href={`${page.cdn}release/${page.version}/assets/style/global.css`} />
17
+ </head>
18
+ <body>
19
+ <a className="skip-link" href="#main">Skip to the message</a>
20
+ <main id="main" tabindex="-1" className="mx-auto max-w-5xl px-4 py-24 sm:px-6 lg:px-8">
21
+ <h1 className="text-5xl font-extrabold tracking-tight">Page not found</h1>
22
+ <p className="mt-6 text-lg">The requested page does not exist.</p>
23
+ <p className="mt-6"><a className="font-bold underline" href={page.www}>Return to the White Label starter</a></p>
24
+ </main>
25
+ </body>
26
+ </html>
27
+ );
28
+ }