generator-white-label 5.0.1 → 9.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.
- package/.editorconfig +15 -0
- package/.yarnrc.yml +6 -0
- package/CLI.md +82 -0
- package/LICENSE +9 -0
- package/PACKAGE_MANAGERS.md +35 -0
- package/README.md +232 -124
- package/app/404.tsx +28 -0
- package/app/README.md +92 -8
- package/app/assets/data/view/global.json +7 -47
- package/app/assets/data/view/index.json +9 -1
- package/app/assets/script/index.tsx +13 -0
- package/app/assets/script/tasks/TaskApplication.ts +77 -0
- package/app/assets/script/tasks/TaskMediator.ts +15 -0
- package/app/assets/script/tasks/TaskModel.ts +32 -0
- package/app/assets/script/tasks/TaskRouter.ts +30 -0
- package/app/assets/script/tasks/TaskView.tsx +24 -0
- package/app/assets/style/global.css +111 -0
- package/app/assets/style/print.css +8 -0
- package/app/assets/view/CodeBlock.tsx +17 -0
- package/app/assets/view/examples/tasks/TaskExample.tsx +63 -0
- package/app/assets/view/examples/tasks/task-state.ts +46 -0
- package/app/assets/view/layout/SiteFooter.tsx +11 -0
- package/app/assets/view/layout/SiteHeader.tsx +23 -0
- package/app/assets/view/page-data.ts +14 -0
- package/app/assets/view/sections/GettingStartedSection.tsx +27 -0
- package/app/assets/view/sections/HeroSection.tsx +21 -0
- package/app/assets/view/sections/LiveExampleSection.tsx +29 -0
- package/app/assets/view/sections/PackageDocsSection.tsx +69 -0
- package/app/assets/view/sections/SourceGuideSection.tsx +28 -0
- package/app/index.tsx +54 -0
- package/cli/index.ts +118 -0
- package/dist/app/404.d.ts +1 -0
- package/dist/app/404.js +6 -0
- package/dist/app/404.js.map +1 -0
- package/dist/app/assets/script/index.d.ts +8 -2
- package/dist/app/assets/script/index.js +11 -1
- package/dist/app/assets/script/index.js.map +1 -1
- package/dist/app/assets/script/tasks/TaskApplication.d.ts +20 -0
- package/dist/app/assets/script/tasks/TaskApplication.js +63 -0
- package/dist/app/assets/script/tasks/TaskApplication.js.map +1 -0
- package/dist/app/assets/script/tasks/TaskMediator.d.ts +10 -0
- package/dist/app/assets/script/tasks/TaskMediator.js +5 -0
- package/dist/app/assets/script/tasks/TaskMediator.js.map +1 -0
- package/dist/app/assets/script/tasks/TaskModel.d.ts +13 -0
- package/dist/app/assets/script/tasks/TaskModel.js +33 -0
- package/dist/app/assets/script/tasks/TaskModel.js.map +1 -0
- package/dist/app/assets/script/tasks/TaskRouter.d.ts +12 -0
- package/dist/app/assets/script/tasks/TaskRouter.js +28 -0
- package/dist/app/assets/script/tasks/TaskRouter.js.map +1 -0
- package/dist/app/assets/script/tasks/TaskView.d.ts +9 -0
- package/dist/app/assets/script/tasks/TaskView.js +24 -0
- package/dist/app/assets/script/tasks/TaskView.js.map +1 -0
- package/dist/app/assets/view/CodeBlock.d.ts +11 -0
- package/dist/app/assets/view/CodeBlock.js +12 -0
- package/dist/app/assets/view/CodeBlock.js.map +1 -0
- package/dist/app/assets/view/examples/tasks/TaskExample.d.ts +11 -0
- package/dist/app/assets/view/examples/tasks/TaskExample.js +16 -0
- package/dist/app/assets/view/examples/tasks/TaskExample.js.map +1 -0
- package/dist/app/assets/view/examples/tasks/task-state.d.ts +22 -0
- package/dist/app/assets/view/examples/tasks/task-state.js +30 -0
- package/dist/app/assets/view/examples/tasks/task-state.js.map +1 -0
- package/dist/app/assets/view/layout/SiteFooter.d.ts +2 -0
- package/dist/app/assets/view/layout/SiteFooter.js +6 -0
- package/dist/app/assets/view/layout/SiteFooter.js.map +1 -0
- package/dist/app/assets/view/layout/SiteHeader.d.ts +8 -0
- package/dist/app/assets/view/layout/SiteHeader.js +12 -0
- package/dist/app/assets/view/layout/SiteHeader.js.map +1 -0
- package/dist/app/assets/view/page-data.d.ts +16 -0
- package/dist/app/assets/view/page-data.js +2 -0
- package/dist/app/assets/view/page-data.js.map +1 -0
- package/dist/app/assets/view/sections/GettingStartedSection.d.ts +2 -0
- package/dist/app/assets/view/sections/GettingStartedSection.js +11 -0
- package/dist/app/assets/view/sections/GettingStartedSection.js.map +1 -0
- package/dist/app/assets/view/sections/HeroSection.d.ts +8 -0
- package/dist/app/assets/view/sections/HeroSection.js +12 -0
- package/dist/app/assets/view/sections/HeroSection.js.map +1 -0
- package/dist/app/assets/view/sections/LiveExampleSection.d.ts +6 -0
- package/dist/app/assets/view/sections/LiveExampleSection.js +13 -0
- package/dist/app/assets/view/sections/LiveExampleSection.js.map +1 -0
- package/dist/app/assets/view/sections/PackageDocsSection.d.ts +2 -0
- package/dist/app/assets/view/sections/PackageDocsSection.js +31 -0
- package/dist/app/assets/view/sections/PackageDocsSection.js.map +1 -0
- package/dist/app/assets/view/sections/SourceGuideSection.d.ts +7 -0
- package/dist/app/assets/view/sections/SourceGuideSection.js +11 -0
- package/dist/app/assets/view/sections/SourceGuideSection.js.map +1 -0
- package/dist/app/index.d.ts +8 -0
- package/dist/app/index.js +22 -0
- package/dist/app/index.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.js +98 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/scaffold/index.d.ts +64 -0
- package/dist/scaffold/index.js +125 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scripts/build.d.ts +5 -13
- package/dist/scripts/build.js +48 -79
- package/dist/scripts/build.js.map +1 -1
- package/dist/server/handler.d.ts +7 -0
- package/dist/server/handler.js +67 -0
- package/dist/server/handler.js.map +1 -0
- package/package.json +78 -40
- package/pnpm-workspace.yaml +4 -0
- package/scaffold/AGENTS.md +18 -0
- package/scaffold/index.ts +139 -0
- package/scaffold/no-jsx/README.md +73 -0
- package/scaffold/no-jsx/app/404.ts +10 -0
- package/scaffold/no-jsx/app/assets/script/index.ts +7 -0
- package/scaffold/no-jsx/app/assets/script/tasks/TaskView.ts +19 -0
- package/scaffold/no-jsx/app/assets/view/examples/tasks/TaskExample.ts +39 -0
- package/scaffold/no-jsx/app/index.ts +58 -0
- package/scripts/build.ts +55 -86
- package/server/handler.ts +75 -0
- package/template-test/site.test.js +235 -0
- package/tsconfig.site.json +6 -5
- package/tsconfig.site.no-jsx.json +24 -0
- package/app/404.hbs +0 -20
- package/app/assets/data/coutries.json +0 -992
- package/app/assets/data/states.json +0 -204
- package/app/assets/data/view/toolkit/colors.json +0 -17
- package/app/assets/data/view/toolkit/components.json +0 -39
- package/app/assets/data/view/toolkit/elements.json +0 -119
- package/app/assets/data/view/toolkit/grids.json +0 -17
- package/app/assets/data/view/toolkit/icons.json +0 -17
- package/app/assets/data/view/toolkit/index.json +0 -17
- package/app/assets/data/view/toolkit/type.json +0 -17
- package/app/assets/font/opensans/LICENSE.txt +0 -202
- package/app/assets/font/opensans/opensans-bold-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-bolditalic-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-extrabold-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-extrabolditalic-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-italic-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-light-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-lightitalic-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-regular-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-semibold-webfont.woff2 +0 -0
- package/app/assets/font/opensans/opensans-semibolditalic-webfont.woff2 +0 -0
- package/app/assets/font/opensans/stylesheet.css +0 -120
- package/app/assets/image/apple-touch-icon.png +0 -0
- package/app/assets/image/demo/fallback.avif +0 -0
- package/app/assets/image/demo/fallback.jpg +0 -0
- package/app/assets/image/demo/fallback.webp +0 -0
- package/app/assets/image/demo/large.avif +0 -0
- package/app/assets/image/demo/large.webp +0 -0
- package/app/assets/image/demo/small.avif +0 -0
- package/app/assets/image/demo/small.webp +0 -0
- package/app/assets/image/favicon.png +0 -0
- package/app/assets/image/graphic-css3.svg +0 -30
- package/app/assets/image/graphic-html5.svg +0 -29
- package/app/assets/markup/element/a.hbs +0 -29
- package/app/assets/markup/element/button.hbs +0 -30
- package/app/assets/markup/element/div.hbs +0 -11
- package/app/assets/markup/element/head.hbs +0 -78
- package/app/assets/markup/element/iframe.hbs +0 -20
- package/app/assets/markup/element/img.hbs +0 -30
- package/app/assets/markup/element/input.hbs +0 -43
- package/app/assets/markup/element/label.hbs +0 -14
- package/app/assets/markup/element/legend.hbs +0 -5
- package/app/assets/markup/element/meta.hbs +0 -11
- package/app/assets/markup/element/nav.hbs +0 -13
- package/app/assets/markup/element/p.hbs +0 -8
- package/app/assets/markup/element/picture.hbs +0 -58
- package/app/assets/markup/element/script.hbs +0 -3
- package/app/assets/markup/element/select.hbs +0 -35
- package/app/assets/markup/element/span.hbs +0 -8
- package/app/assets/markup/element/svg.hbs +0 -11
- package/app/assets/markup/element/table.hbs +0 -50
- package/app/assets/markup/element/textarea.hbs +0 -24
- package/app/assets/markup/element/ul.hbs +0 -13
- package/app/assets/markup/modal/modal-example-1.handlebars +0 -8
- package/app/assets/markup/toolkit/accessibility-skip-to-element-1.handlebars +0 -1
- package/app/assets/markup/toolkit/accessibility-speaker-1.handlebars +0 -1
- package/app/assets/markup/toolkit/anchor-1.handlebars +0 -1
- package/app/assets/markup/toolkit/button-1.handlebars +0 -1
- package/app/assets/markup/toolkit/footer-1.handlebars +0 -3
- package/app/assets/markup/toolkit/header-1.handlebars +0 -1
- package/app/assets/markup/toolkit/heading-1.handlebars +0 -1
- package/app/assets/markup/toolkit/heading-2.handlebars +0 -1
- package/app/assets/markup/toolkit/heading-3.handlebars +0 -1
- package/app/assets/markup/toolkit/heading-4.handlebars +0 -1
- package/app/assets/markup/toolkit/image-1.handlebars +0 -1
- package/app/assets/markup/toolkit/input-checkbox-1.handlebars +0 -1
- package/app/assets/markup/toolkit/input-error-1.handlebars +0 -8
- package/app/assets/markup/toolkit/input-radio-1.handlebars +0 -1
- package/app/assets/markup/toolkit/input-text-1.handlebars +0 -1
- package/app/assets/markup/toolkit/label-1.handlebars +0 -1
- package/app/assets/markup/toolkit/legend-1.handlebars +0 -1
- package/app/assets/markup/toolkit/list-1.handlebars +0 -1
- package/app/assets/markup/toolkit/modal-1.handlebars +0 -4
- package/app/assets/markup/toolkit/nav-1.handlebars +0 -1
- package/app/assets/markup/toolkit/picture-1.handlebars +0 -1
- package/app/assets/markup/toolkit/select-1.handlebars +0 -1
- package/app/assets/markup/toolkit/table-1.handlebars +0 -1
- package/app/assets/markup/toolkit/text-1.handlebars +0 -1
- package/app/assets/markup/toolkit/textarea-1.handlebars +0 -1
- package/app/assets/markup/toolkit/youtube-player-1.handlebars +0 -1
- package/app/assets/script/api/facebook.ts +0 -41
- package/app/assets/script/api/youtube.ts +0 -22
- package/app/assets/script/index.ts +0 -2
- package/app/assets/script/mediator/global.ts +0 -4
- package/app/assets/script/model/singletons/countries.ts +0 -5
- package/app/assets/script/model/singletons/global.ts +0 -5
- package/app/assets/script/model/singletons/states.ts +0 -5
- package/app/assets/script/model/user.ts +0 -4
- package/app/assets/script/toolkit.ts +0 -11
- package/app/assets/script/types.d.ts +0 -6
- package/app/assets/script/utility/ajax.ts +0 -15
- package/app/assets/script/utility/form.ts +0 -119
- package/app/assets/script/utility/regex.ts +0 -26
- package/app/assets/script/utility/share.ts +0 -77
- package/app/assets/script/utility/string.ts +0 -148
- package/app/assets/script/view/default.tsx +0 -14
- package/app/assets/script/view/toolkit/youtube-player-1.ts +0 -33
- package/app/assets/style/base/_toolkit.scss +0 -39
- package/app/assets/style/base/colors/_colors.scss +0 -18
- package/app/assets/style/base/components/_modal-1.scss +0 -80
- package/app/assets/style/base/components/_sticky-1.scss +0 -19
- package/app/assets/style/base/components/_tabpanel-1.scss +0 -115
- package/app/assets/style/base/components/_tabpanel-2.scss +0 -64
- package/app/assets/style/base/components/_tabpanel-base-1.scss +0 -13
- package/app/assets/style/base/components/_youtube-player-1.scss +0 -16
- package/app/assets/style/base/elements/_anchors.scss +0 -27
- package/app/assets/style/base/elements/_buttons.scss +0 -25
- package/app/assets/style/base/elements/_fieldsets.scss +0 -9
- package/app/assets/style/base/elements/_images.scss +0 -8
- package/app/assets/style/base/elements/_inputs.scss +0 -78
- package/app/assets/style/base/elements/_labels.scss +0 -16
- package/app/assets/style/base/elements/_landmarks.scss +0 -3
- package/app/assets/style/base/elements/_legends.scss +0 -11
- package/app/assets/style/base/elements/_lists.scss +0 -15
- package/app/assets/style/base/elements/_pictures.scss +0 -4
- package/app/assets/style/base/elements/_tables.scss +0 -39
- package/app/assets/style/base/layouts/_staggered-1.scss +0 -29
- package/app/assets/style/base/type/_fonts.scss +0 -125
- package/app/assets/style/base/type/_headings.scss +0 -36
- package/app/assets/style/base/type/_text.scss +0 -9
- package/app/assets/style/base/utilities/_accessibility.scss +0 -55
- package/app/assets/style/base/utilities/_functions.scss +0 -98
- package/app/assets/style/base/utilities/_scroll.scss +0 -11
- package/app/assets/style/base/utilities/_type.scss +0 -13
- package/app/assets/style/global.scss +0 -123
- package/app/assets/style/print.scss +0 -6
- package/app/assets/style/toolkit.scss +0 -387
- package/app/index.hbs +0 -21
- package/app/robots.txt +0 -1
- package/app/toolkit/colors.hbs +0 -102
- package/app/toolkit/components.hbs +0 -261
- package/app/toolkit/elements.hbs +0 -497
- package/app/toolkit/grids.hbs +0 -413
- package/app/toolkit/icons.hbs +0 -87
- package/app/toolkit/index.hbs +0 -144
- package/app/toolkit/type.hbs +0 -120
- package/dist/app/assets/data/coutries.json +0 -992
- package/dist/app/assets/data/states.json +0 -204
- package/dist/app/assets/script/api/facebook.d.ts +0 -8
- package/dist/app/assets/script/api/facebook.js +0 -42
- package/dist/app/assets/script/api/facebook.js.map +0 -1
- package/dist/app/assets/script/api/youtube.d.ts +0 -8
- package/dist/app/assets/script/api/youtube.js +0 -22
- package/dist/app/assets/script/api/youtube.js.map +0 -1
- package/dist/app/assets/script/mediator/global.d.ts +0 -4
- package/dist/app/assets/script/mediator/global.js +0 -4
- package/dist/app/assets/script/mediator/global.js.map +0 -1
- package/dist/app/assets/script/model/singletons/countries.d.ts +0 -4
- package/dist/app/assets/script/model/singletons/countries.js +0 -5
- package/dist/app/assets/script/model/singletons/countries.js.map +0 -1
- package/dist/app/assets/script/model/singletons/global.d.ts +0 -4
- package/dist/app/assets/script/model/singletons/global.js +0 -5
- package/dist/app/assets/script/model/singletons/global.js.map +0 -1
- package/dist/app/assets/script/model/singletons/states.d.ts +0 -4
- package/dist/app/assets/script/model/singletons/states.js +0 -5
- package/dist/app/assets/script/model/singletons/states.js.map +0 -1
- package/dist/app/assets/script/model/user.d.ts +0 -4
- package/dist/app/assets/script/model/user.js +0 -6
- package/dist/app/assets/script/model/user.js.map +0 -1
- package/dist/app/assets/script/toolkit.d.ts +0 -1
- package/dist/app/assets/script/toolkit.js +0 -7
- package/dist/app/assets/script/toolkit.js.map +0 -1
- package/dist/app/assets/script/utility/ajax.d.ts +0 -8
- package/dist/app/assets/script/utility/ajax.js +0 -17
- package/dist/app/assets/script/utility/ajax.js.map +0 -1
- package/dist/app/assets/script/utility/form.d.ts +0 -64
- package/dist/app/assets/script/utility/form.js +0 -111
- package/dist/app/assets/script/utility/form.js.map +0 -1
- package/dist/app/assets/script/utility/regex.d.ts +0 -14
- package/dist/app/assets/script/utility/regex.js +0 -27
- package/dist/app/assets/script/utility/regex.js.map +0 -1
- package/dist/app/assets/script/utility/share.d.ts +0 -68
- package/dist/app/assets/script/utility/share.js +0 -81
- package/dist/app/assets/script/utility/share.js.map +0 -1
- package/dist/app/assets/script/utility/string.d.ts +0 -64
- package/dist/app/assets/script/utility/string.js +0 -135
- package/dist/app/assets/script/utility/string.js.map +0 -1
- package/dist/app/assets/script/view/default.d.ts +0 -11
- package/dist/app/assets/script/view/default.js +0 -15
- package/dist/app/assets/script/view/default.js.map +0 -1
- package/dist/app/assets/script/view/toolkit/youtube-player-1.d.ts +0 -23
- package/dist/app/assets/script/view/toolkit/youtube-player-1.js +0 -34
- package/dist/app/assets/script/view/toolkit/youtube-player-1.js.map +0 -1
- package/dist/generators/app/index.d.ts +0 -18
- package/dist/generators/app/index.js +0 -59
- package/dist/generators/app/index.js.map +0 -1
- package/generators/app/index.js +0 -2
- 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
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, including destination safety. 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
|
+
Project creation accepts a missing or existing **empty** directory. A non-empty destination is rejected before scaffold files are copied or written.
|
|
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 is the default.
|
|
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()` uses the same destination-safety rule as the CLI: missing and empty directories are allowed; non-empty directories are rejected before project content is written.
|
|
73
|
+
|
|
74
|
+
## Read the implementation
|
|
75
|
+
|
|
76
|
+
The source is intentionally small enough to teach the design:
|
|
77
|
+
|
|
78
|
+
- `scaffold/index.ts` — project creation and destination-safety boundary
|
|
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,303 @@
|
|
|
1
|
-
# white-label
|
|
1
|
+
# generator-white-label
|
|
2
2
|
|
|
3
|
-
`white-label` is a
|
|
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
|
-
|
|
5
|
+
[Documentation](https://whitelabeljs.org/docs/generator/) · [API reference](https://whitelabeljs.org/api/#generator) · [Demo site](https://whitelabeljs.org/)
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
+
## A simple View click event
|
|
64
|
+
|
|
65
|
+
Use View lifecycle hooks to add and remove browser listeners with the same callback reference:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import View from 'white-label-view';
|
|
69
|
+
|
|
70
|
+
class ButtonView extends View {
|
|
71
|
+
handleClick = () => {
|
|
72
|
+
console.log('Clicked');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
addListeners() {
|
|
76
|
+
this.element.addEventListener('click', this.handleClick);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
removeListeners() {
|
|
81
|
+
this.element.removeEventListener('click', this.handleClick);
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`addListeners()` runs when the View mounts. `removeListeners()` runs before replacement or destruction, so the listener lifecycle stays owned by the View.
|
|
88
|
+
|
|
89
|
+
## Read the source
|
|
90
|
+
|
|
91
|
+
For the default JSX scaffold, a useful reading order is:
|
|
92
|
+
|
|
93
|
+
1. [`app/index.tsx`](app/index.tsx) — page composition.
|
|
94
|
+
2. [`app/assets/view/sections/LiveExampleSection.tsx`](app/assets/view/sections/LiveExampleSection.tsx) — static composition around an interactive feature.
|
|
95
|
+
3. [`app/assets/view/examples/tasks/TaskExample.tsx`](app/assets/view/examples/tasks/TaskExample.tsx) — shared JSX rendering.
|
|
96
|
+
4. [`app/assets/script/tasks/TaskApplication.ts`](app/assets/script/tasks/TaskApplication.ts) — explicit dependency wiring.
|
|
97
|
+
5. `TaskRouter`, `TaskMediator`, `TaskModel`, and `TaskView` — one responsibility at a time.
|
|
98
|
+
6. [`server/handler.ts`](server/handler.ts) — provider-neutral `Request`/`Response` serverless composition.
|
|
99
|
+
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.
|
|
100
|
+
|
|
101
|
+
The `--no-jsx` scaffold mirrors the same structure with `.ts` files and HTML-string render functions.
|
|
102
|
+
|
|
103
|
+
Comments focus on why boundaries exist instead of narrating obvious TypeScript.
|
|
10
104
|
|
|
11
|
-
- `
|
|
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.
|
|
105
|
+
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.
|
|
18
106
|
|
|
19
|
-
|
|
107
|
+
A useful rule when extending the project is:
|
|
20
108
|
|
|
21
|
-
|
|
109
|
+
> Introduce an abstraction when it gives a concern a clear home, not merely to create another layer.
|
|
22
110
|
|
|
23
|
-
##
|
|
111
|
+
## Create a project
|
|
24
112
|
|
|
25
|
-
|
|
26
|
-
- npm 10 or newer
|
|
113
|
+
Requirement:
|
|
27
114
|
|
|
28
|
-
|
|
115
|
+
- Node.js `^22.18.0` or `>=24.11.0`
|
|
29
116
|
|
|
30
|
-
Install
|
|
117
|
+
Install the CLI globally with your preferred package manager, or run the package directly.
|
|
118
|
+
|
|
119
|
+
With npm:
|
|
31
120
|
|
|
32
121
|
```sh
|
|
33
|
-
|
|
34
|
-
mkdir my-site
|
|
35
|
-
cd my-site
|
|
36
|
-
yo white-label
|
|
122
|
+
npx generator-white-label create my-project
|
|
37
123
|
```
|
|
38
124
|
|
|
39
|
-
|
|
125
|
+
With Yarn:
|
|
40
126
|
|
|
41
127
|
```sh
|
|
42
|
-
|
|
43
|
-
npm test
|
|
128
|
+
yarn dlx generator-white-label create my-project
|
|
44
129
|
```
|
|
45
130
|
|
|
46
|
-
|
|
131
|
+
With pnpm:
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
pnpm dlx generator-white-label create my-project
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
A global install also exposes the `white-label` command:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
npm install --global generator-white-label
|
|
141
|
+
white-label create my-project
|
|
142
|
+
```
|
|
47
143
|
|
|
48
|
-
|
|
144
|
+
After generation, use npm, Yarn, or pnpm consistently within the project:
|
|
49
145
|
|
|
50
146
|
```sh
|
|
51
|
-
|
|
147
|
+
cd my-project
|
|
148
|
+
npm install && npm test
|
|
149
|
+
# or: yarn install && yarn test
|
|
150
|
+
# or: pnpm install && pnpm test
|
|
52
151
|
```
|
|
53
152
|
|
|
54
|
-
|
|
153
|
+
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.
|
|
55
154
|
|
|
56
|
-
|
|
155
|
+
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.
|
|
156
|
+
|
|
157
|
+
For explicit or non-interactive use:
|
|
57
158
|
|
|
58
159
|
```sh
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
--production=true
|
|
160
|
+
white-label create my-project --jsx
|
|
161
|
+
white-label create my-project --no-jsx
|
|
162
|
+
|
|
163
|
+
npx generator-white-label create my-project --jsx
|
|
164
|
+
npx generator-white-label create my-project --no-jsx
|
|
65
165
|
```
|
|
66
166
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
| `--version` | Current Unix timestamp | Directory name used for versioned assets. |
|
|
73
|
-
| `--production` | `false` | Minifies CSS and JavaScript when set to `true`. |
|
|
167
|
+
The same `--jsx` and `--no-jsx` options work through `yarn dlx` and `pnpm dlx`.
|
|
168
|
+
|
|
169
|
+
If no interactive answer is available and neither flag is supplied, JSX is the default.
|
|
170
|
+
|
|
171
|
+
The generator refuses to layer a scaffold over an existing non-empty destination. This protection is enforced by the shared `createProject()` engine, so it applies to both the CLI and programmatic use. An existing empty directory is allowed; a missing directory is created as part of generation.
|
|
74
172
|
|
|
75
|
-
|
|
173
|
+
See [`CLI.md`](CLI.md) for the CLI contract and [`PACKAGE_MANAGERS.md`](PACKAGE_MANAGERS.md) for package-manager compatibility details.
|
|
76
174
|
|
|
77
|
-
##
|
|
175
|
+
## Programmatic API
|
|
78
176
|
|
|
79
|
-
|
|
177
|
+
Project creation has one implementation:
|
|
80
178
|
|
|
81
|
-
```
|
|
82
|
-
{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
179
|
+
```js
|
|
180
|
+
import {createProject} from 'generator-white-label';
|
|
181
|
+
|
|
182
|
+
// Resolves after the scaffold files and package manifest have been written.
|
|
183
|
+
await createProject({
|
|
184
|
+
destination: new URL('./my-project', import.meta.url).pathname,
|
|
185
|
+
jsx: false
|
|
186
|
+
});
|
|
87
187
|
```
|
|
88
188
|
|
|
89
|
-
|
|
189
|
+
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`.
|
|
190
|
+
|
|
191
|
+
`createProject(options)` returns `Promise<void>`. A successful call resolves with `undefined`; file-system failures reject the promise instead of returning a status value. If the destination already exists and contains files, it rejects before copying or writing project content.
|
|
192
|
+
|
|
193
|
+
`createProject()` is the canonical creation API. The CLI and future integrations are adapters around it rather than separate generation systems. Keeping overwrite policy here prevents adapters from accidentally bypassing the same safety boundary.
|
|
194
|
+
|
|
195
|
+
This is the same design principle used throughout White Label: one responsibility, one implementation, explicit adapters at environment boundaries.
|
|
196
|
+
|
|
197
|
+
## Source layout
|
|
198
|
+
|
|
199
|
+
| Path | Purpose |
|
|
200
|
+
| --- | --- |
|
|
201
|
+
| `scaffold/index.ts` | Canonical `createProject()` implementation and destination-safety boundary |
|
|
202
|
+
| `scaffold/no-jsx/` | Plain-TypeScript template equivalents |
|
|
203
|
+
| `cli/index.ts` | First-party command-line adapter |
|
|
204
|
+
| `app/*.tsx` | Default JSX top-level static pages |
|
|
205
|
+
| `app/assets/view/` | Default JSX views and page sections |
|
|
206
|
+
| `app/assets/script/tasks/` | Model/View/Mediator/Router example |
|
|
207
|
+
| `server/handler.ts` | Provider-neutral serverless `Request` → `Response` example |
|
|
208
|
+
| `scripts/build.ts` | Static rendering and asset build for `.ts` and `.tsx` pages |
|
|
209
|
+
| `test/` | Executable contracts and integration tests |
|
|
210
|
+
| `template-test/` | Generated-project validation, including serverless portability budgets |
|
|
211
|
+
|
|
212
|
+
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.
|
|
213
|
+
|
|
214
|
+
## Template choice: JSX or no JSX
|
|
215
|
+
|
|
216
|
+
JSX is optional. When enabled, TypeScript uses the White Label JSX runtime:
|
|
90
217
|
|
|
91
218
|
```json
|
|
92
219
|
{
|
|
93
|
-
"
|
|
94
|
-
|
|
220
|
+
"compilerOptions": {
|
|
221
|
+
"jsx": "react-jsx",
|
|
222
|
+
"jsxImportSource": "white-label-view"
|
|
223
|
+
}
|
|
95
224
|
}
|
|
96
225
|
```
|
|
97
226
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
## Responsive images
|
|
227
|
+
A page remains an ordinary function:
|
|
101
228
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
}}
|
|
229
|
+
```tsx
|
|
230
|
+
export default function Page(data: Record<string, unknown>) {
|
|
231
|
+
return <main><h1>{String(data.title)}</h1></main>;
|
|
232
|
+
}
|
|
117
233
|
```
|
|
118
234
|
|
|
119
|
-
|
|
235
|
+
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
236
|
|
|
121
|
-
|
|
237
|
+
For larger pages, compose focused views instead of growing one renderer indefinitely.
|
|
122
238
|
|
|
123
|
-
|
|
239
|
+
White Label JSX HTML-escapes ordinary child text and ordinary attribute values by default, rejects intrinsic `on*` event-handler attributes, and uses runtime-owned identity for trusted JSX/raw values. That escaping is not a general-purpose sanitizer for URL or CSS semantics. Plain-TypeScript templates and third-party engines likewise remain responsible for their own contextual escaping, sanitization, raw-output features, and configuration. See [Template engines and JSX options](https://whitelabeljs.org/docs/view/#template-engines) for the tested matrix and trust boundaries.
|
|
124
240
|
|
|
125
|
-
|
|
126
|
-
npm run build
|
|
127
|
-
npm run typecheck
|
|
128
|
-
npm test
|
|
129
|
-
npm run coverage
|
|
130
|
-
npm run audit
|
|
131
|
-
```
|
|
241
|
+
## Progressive enhancement
|
|
132
242
|
|
|
133
|
-
|
|
243
|
+
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
244
|
|
|
135
|
-
|
|
245
|
+
The principle is intentional:
|
|
136
246
|
|
|
137
|
-
|
|
247
|
+
```text
|
|
248
|
+
HTML owns semantics.
|
|
249
|
+
JavaScript enhances behavior.
|
|
250
|
+
```
|
|
138
251
|
|
|
139
|
-
##
|
|
252
|
+
## Serverless and function runtimes
|
|
140
253
|
|
|
141
|
-
|
|
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.
|
|
254
|
+
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
255
|
|
|
147
|
-
|
|
256
|
+
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
257
|
|
|
149
|
-
|
|
258
|
+
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
259
|
|
|
151
|
-
|
|
152
|
-
// app/assets/script/profile.ts
|
|
153
|
-
import User from './model/user.js';
|
|
260
|
+
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
261
|
|
|
155
|
-
|
|
156
|
-
console.log(profile.get().name);
|
|
157
|
-
```
|
|
262
|
+
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 document Node as their supported server runtime; verify a specific edge provider before deployment.
|
|
158
263
|
|
|
159
|
-
|
|
264
|
+
## Build and verify
|
|
160
265
|
|
|
161
|
-
The
|
|
266
|
+
The repository keeps npm as its canonical maintenance/audit path and committed lockfile. Generated projects support npm, Yarn, and pnpm.
|
|
162
267
|
|
|
163
|
-
|
|
268
|
+
Development build:
|
|
164
269
|
|
|
165
|
-
|
|
270
|
+
```sh
|
|
271
|
+
npm run build -- --version=local
|
|
272
|
+
python3 -m http.server 8080 --directory _deploy
|
|
273
|
+
```
|
|
166
274
|
|
|
167
|
-
|
|
275
|
+
Production build:
|
|
168
276
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
|
277
|
+
```sh
|
|
278
|
+
npm run build -- \
|
|
279
|
+
--version=production \
|
|
280
|
+
--production=true \
|
|
281
|
+
--site-url=https://www.example.com
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Verification:
|
|
182
285
|
|
|
183
286
|
```sh
|
|
184
|
-
npm
|
|
185
|
-
npm run typecheck
|
|
287
|
+
npm run lint
|
|
186
288
|
npm test
|
|
187
289
|
npm run coverage
|
|
290
|
+
npm run audit
|
|
188
291
|
npm pack --dry-run
|
|
189
292
|
```
|
|
190
293
|
|
|
191
|
-
|
|
294
|
+
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. CI also checks the documented Node 22.18 minimum, the primary Node 24 line, packed CLI/programmatic API installation, and generated-project compatibility across npm, Yarn, and pnpm.
|
|
295
|
+
|
|
296
|
+
## White Label ecosystem
|
|
192
297
|
|
|
193
|
-
|
|
298
|
+
- [`white-label-model`](https://github.com/bshack/white-label-model) — observable state.
|
|
299
|
+
- [`white-label-view`](https://github.com/bshack/white-label-view) — rendering, DOM lifecycle, optional JSX, and a template-engine-agnostic rendering contract.
|
|
300
|
+
- [`white-label-mediator`](https://github.com/bshack/white-label-mediator) — application events.
|
|
301
|
+
- [`white-label-router`](https://github.com/bshack/white-label-router) — routing and URL state.
|
|
194
302
|
|
|
195
|
-
|
|
303
|
+
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
|
+
}
|