@madojs/mado 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/AGENTS.md +24 -26
  2. package/CHANGELOG.md +95 -0
  3. package/README.md +22 -47
  4. package/TODO.md +52 -48
  5. package/dist/src/component.d.ts +2 -1
  6. package/dist/src/component.js +5 -2
  7. package/dist/src/component.js.map +1 -1
  8. package/dist/src/each.d.ts +1 -1
  9. package/dist/src/each.js +1 -1
  10. package/dist/src/each.js.map +1 -1
  11. package/dist/src/html/bindings.js +3 -3
  12. package/dist/src/html/bindings.js.map +1 -1
  13. package/dist/src/index.d.ts +11 -6
  14. package/dist/src/index.js +5 -3
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/lazy.d.ts +1 -1
  17. package/dist/src/lazy.js +1 -1
  18. package/dist/src/lazy.js.map +1 -1
  19. package/dist/src/page.d.ts +17 -21
  20. package/dist/src/page.js +7 -12
  21. package/dist/src/page.js.map +1 -1
  22. package/dist/src/router/manifest.d.ts +1 -1
  23. package/dist/src/router/manifest.js +21 -13
  24. package/dist/src/router/manifest.js.map +1 -1
  25. package/dist/src/router/match.d.ts +2 -2
  26. package/dist/src/router/match.js +3 -3
  27. package/dist/src/router/match.js.map +1 -1
  28. package/dist/src/router/navigation.js +1 -1
  29. package/dist/src/router/navigation.js.map +1 -1
  30. package/dist/src/vite/index.d.ts +10 -0
  31. package/dist/src/vite/index.js +33 -0
  32. package/dist/src/vite/index.js.map +1 -0
  33. package/docs/en/00-the-mado-way.md +25 -12
  34. package/docs/en/01-routing.md +90 -142
  35. package/docs/en/02-project-layout.md +59 -53
  36. package/docs/en/03-static-bake.md +5 -6
  37. package/docs/en/05-why-mado.md +6 -6
  38. package/docs/en/06-for-backenders.md +18 -22
  39. package/docs/en/08-llm-zero-history-test.md +9 -14
  40. package/docs/en/09-shadow-vs-light-dom.md +28 -36
  41. package/docs/en/10-app-architecture.md +158 -96
  42. package/docs/en/11-layouts.md +22 -24
  43. package/docs/en/12-auth-and-api.md +89 -182
  44. package/docs/en/13-deployment.md +18 -22
  45. package/docs/en/14-testing.md +4 -4
  46. package/docs/en/16-bake-cookbook.md +11 -12
  47. package/docs/en/18-api-freeze-map.md +6 -4
  48. package/docs/en/20-v1-stability.md +1 -1
  49. package/docs/fr/00-the-mado-way.md +55 -90
  50. package/docs/fr/01-routing.md +70 -152
  51. package/docs/fr/02-project-layout.md +61 -42
  52. package/docs/fr/03-static-bake.md +1 -1
  53. package/docs/fr/05-why-mado.md +6 -6
  54. package/docs/fr/06-for-backenders.md +7 -7
  55. package/docs/fr/08-llm-zero-history-test.md +21 -48
  56. package/docs/fr/09-shadow-vs-light-dom.md +43 -162
  57. package/docs/fr/10-app-architecture.md +110 -33
  58. package/docs/fr/11-layouts.md +24 -12
  59. package/docs/fr/12-auth-and-api.md +63 -22
  60. package/docs/fr/13-deployment.md +7 -10
  61. package/docs/fr/14-testing.md +1 -1
  62. package/docs/fr/16-bake-cookbook.md +2 -2
  63. package/docs/fr/18-api-freeze-map.md +1 -1
  64. package/docs/fr/20-v1-stability.md +1 -1
  65. package/docs/recipes/nginx/README.md +13 -0
  66. package/docs/ru/00-the-mado-way.md +53 -75
  67. package/docs/ru/01-routing.md +68 -143
  68. package/docs/ru/02-project-layout.md +61 -41
  69. package/docs/ru/03-static-bake.md +2 -2
  70. package/docs/ru/05-why-mado.md +6 -6
  71. package/docs/ru/06-for-backenders.md +7 -7
  72. package/docs/ru/08-llm-zero-history-test.md +9 -14
  73. package/docs/ru/09-shadow-vs-light-dom.md +43 -178
  74. package/docs/ru/10-app-architecture.md +115 -63
  75. package/docs/ru/11-layouts.md +24 -24
  76. package/docs/ru/12-auth-and-api.md +57 -35
  77. package/docs/ru/13-deployment.md +7 -11
  78. package/docs/ru/14-testing.md +1 -1
  79. package/docs/ru/16-bake-cookbook.md +12 -6
  80. package/docs/ru/18-api-freeze-map.md +5 -3
  81. package/docs/ru/20-v1-stability.md +1 -1
  82. package/docs/uk/00-the-mado-way.md +70 -44
  83. package/docs/uk/01-routing.md +41 -47
  84. package/docs/uk/02-project-layout.md +68 -41
  85. package/docs/uk/03-static-bake.md +1 -2
  86. package/docs/uk/06-for-backenders.md +3 -3
  87. package/docs/uk/08-llm-zero-history-test.md +22 -24
  88. package/docs/uk/09-shadow-vs-light-dom.md +37 -86
  89. package/docs/uk/10-app-architecture.md +72 -31
  90. package/docs/uk/11-layouts.md +25 -12
  91. package/docs/uk/12-auth-and-api.md +58 -22
  92. package/docs/uk/13-deployment.md +4 -3
  93. package/docs/uk/14-testing.md +1 -1
  94. package/docs/uk/18-api-freeze-map.md +1 -1
  95. package/docs/uk/20-v1-stability.md +1 -1
  96. package/llms.txt +14 -15
  97. package/package.json +18 -11
  98. package/scripts/_config.mjs +15 -161
  99. package/scripts/bake.mjs +74 -63
  100. package/scripts/cli/generate.mjs +348 -0
  101. package/scripts/cli/help.mjs +27 -0
  102. package/scripts/cli/index.mjs +79 -0
  103. package/scripts/cli/init.mjs +153 -0
  104. package/scripts/cli/release.mjs +152 -0
  105. package/scripts/cli/run.mjs +96 -0
  106. package/scripts/cli.mjs +2 -621
  107. package/scripts/package-smoke.mjs +4 -1
  108. package/scripts/preview.mjs +13 -37
  109. package/scripts/size-budget.mjs +5 -2
  110. package/scripts/vite.default.mjs +11 -0
  111. package/starters/default/.editorconfig +12 -0
  112. package/starters/default/README.md +74 -0
  113. package/starters/default/eslint.config.mjs +256 -0
  114. package/starters/default/index.html +13 -0
  115. package/starters/default/package.json +30 -0
  116. package/starters/default/public/favicon.svg +4 -0
  117. package/starters/default/src/app.routes.ts +39 -0
  118. package/starters/default/src/layouts/app-shell.layout.ts +35 -0
  119. package/starters/default/src/layouts/auth-shell.layout.ts +17 -0
  120. package/starters/default/src/main.ts +16 -0
  121. package/starters/default/src/modules/auth/_contracts/auth-api.types.ts +17 -0
  122. package/starters/default/src/modules/auth/auth.connector.ts +45 -0
  123. package/starters/default/src/modules/auth/auth.guard.ts +22 -0
  124. package/starters/default/src/modules/auth/auth.public.ts +9 -0
  125. package/starters/default/src/modules/auth/auth.routes.ts +8 -0
  126. package/starters/default/src/modules/auth/auth.service.ts +71 -0
  127. package/starters/default/src/modules/auth/auth.types.ts +15 -0
  128. package/starters/default/src/modules/auth/login.page.ts +62 -0
  129. package/starters/default/src/modules/billing/_contracts/stripe.types.ts +17 -0
  130. package/starters/default/src/modules/billing/api/stripe.connector.ts +71 -0
  131. package/starters/default/src/modules/billing/billing.public.ts +5 -0
  132. package/starters/default/src/modules/billing/billing.routes.ts +9 -0
  133. package/starters/default/src/modules/billing/billing.types.ts +15 -0
  134. package/starters/default/src/modules/billing/components/invoice-status-badge.component.ts +43 -0
  135. package/starters/default/src/modules/billing/data/invoices.resource.ts +35 -0
  136. package/starters/default/src/modules/billing/pages/invoice-detail.page.ts +70 -0
  137. package/starters/default/src/modules/billing/pages/invoices-list.page.ts +73 -0
  138. package/starters/default/src/modules/home/home.page.ts +34 -0
  139. package/starters/default/src/modules/home/not-found.page.ts +11 -0
  140. package/starters/default/src/shared/http/http-client.ts +86 -0
  141. package/starters/default/src/shared/http/http-error.ts +37 -0
  142. package/starters/default/src/shared/http/interceptors.ts +59 -0
  143. package/starters/default/src/shared/lib/format-date.ts +19 -0
  144. package/starters/default/src/shared/styles/content.css +70 -0
  145. package/starters/default/src/shared/styles/reset.css +32 -0
  146. package/starters/default/src/shared/styles/shell.css +57 -0
  147. package/starters/default/src/shared/styles/tokens.css +44 -0
  148. package/starters/default/src/shared/ui/x-button.component.ts +49 -0
  149. package/starters/default/src/shared/ui/x-spinner.component.ts +22 -0
  150. package/starters/default/src/styles.d.ts +1 -0
  151. package/starters/default/src/vite-env.d.ts +1 -0
  152. package/starters/default/tsconfig.json +24 -0
  153. package/starters/default/vite.config.ts +9 -0
  154. package/MADO_V1_PLAN.md +0 -179
  155. package/ROADMAP.md +0 -178
  156. package/dist/src/html.d.ts +0 -18
  157. package/dist/src/html.js +0 -17
  158. package/dist/src/html.js.map +0 -1
  159. package/dist/src/router.d.ts +0 -13
  160. package/dist/src/router.js +0 -13
  161. package/dist/src/router.js.map +0 -1
  162. package/scripts/bundle.mjs +0 -212
  163. package/scripts/llm-zero-history-smoke.mjs +0 -93
  164. package/scripts/new.mjs +0 -80
  165. package/scripts/showcase-regression.mjs +0 -392
  166. package/server/serve.mjs +0 -455
  167. package/starters/admin/README.md +0 -63
  168. package/starters/admin/index.html +0 -28
  169. package/starters/admin/mado.config.json +0 -22
  170. package/starters/admin/package.json +0 -24
  171. package/starters/admin/public/favicon.svg +0 -4
  172. package/starters/admin/src/components/x-button.ts +0 -82
  173. package/starters/admin/src/components/x-input.ts +0 -105
  174. package/starters/admin/src/layouts/app.ts +0 -101
  175. package/starters/admin/src/layouts/auth.ts +0 -41
  176. package/starters/admin/src/lib/api.ts +0 -184
  177. package/starters/admin/src/lib/auth.ts +0 -83
  178. package/starters/admin/src/main.ts +0 -15
  179. package/starters/admin/src/pages/admin/dashboard.ts +0 -48
  180. package/starters/admin/src/pages/admin/order-detail.ts +0 -80
  181. package/starters/admin/src/pages/admin/orders.ts +0 -117
  182. package/starters/admin/src/pages/home.ts +0 -34
  183. package/starters/admin/src/pages/login.ts +0 -70
  184. package/starters/admin/src/pages/not-found.ts +0 -12
  185. package/starters/admin/src/routes.ts +0 -40
  186. package/starters/admin/src/styles/global.ts +0 -86
  187. package/starters/admin/tsconfig.json +0 -15
  188. package/starters/crud/README.md +0 -33
  189. package/starters/crud/index.html +0 -28
  190. package/starters/crud/mado.config.json +0 -20
  191. package/starters/crud/package.json +0 -24
  192. package/starters/crud/src/components/app-shell.ts +0 -56
  193. package/starters/crud/src/components/ticket-detail.ts +0 -33
  194. package/starters/crud/src/components/ticket-form.ts +0 -69
  195. package/starters/crud/src/components/ticket-list.ts +0 -66
  196. package/starters/crud/src/lib/api.ts +0 -76
  197. package/starters/crud/src/main.ts +0 -9
  198. package/starters/crud/src/pages/home.ts +0 -34
  199. package/starters/crud/src/pages/not-found.ts +0 -12
  200. package/starters/crud/src/pages/ticket-detail.ts +0 -7
  201. package/starters/crud/src/pages/ticket-new.ts +0 -7
  202. package/starters/crud/src/pages/tickets.ts +0 -7
  203. package/starters/crud/src/routes.ts +0 -11
  204. package/starters/crud/src/styles/global.ts +0 -155
  205. package/starters/crud/tsconfig.json +0 -15
  206. package/starters/minimal/README.md +0 -21
  207. package/starters/minimal/index.html +0 -28
  208. package/starters/minimal/mado.config.json +0 -20
  209. package/starters/minimal/package.json +0 -24
  210. package/starters/minimal/src/components/app-counter.ts +0 -31
  211. package/starters/minimal/src/main.ts +0 -9
  212. package/starters/minimal/src/pages/home.ts +0 -35
  213. package/starters/minimal/src/pages/not-found.ts +0 -14
  214. package/starters/minimal/src/routes.ts +0 -8
  215. package/starters/minimal/src/styles/global.ts +0 -60
  216. package/starters/minimal/tsconfig.json +0 -15
  217. package/templates/page-detail.ts +0 -63
  218. package/templates/page-form.ts +0 -94
  219. package/templates/page-list.ts +0 -79
@@ -1,63 +0,0 @@
1
- /**
2
- * Template: detail page by :id (loads one entity).
3
- *
4
- * Add to routes.ts:
5
- * '/__name__/:id': () => import('./pages/__name__-detail.js'),
6
- */
7
-
8
- import {
9
- page,
10
- component,
11
- html,
12
- css,
13
- resource,
14
- jsonFetcher,
15
- } from "@madojs/mado";
16
-
17
- interface Entity {
18
- id: number;
19
- name: string;
20
- }
21
-
22
- component(
23
- "x-__name__-detail",
24
- ({ host }) => {
25
- // id comes from data-id; page() sets it from params.
26
- const idAttr = () => host.dataset.id ?? "";
27
-
28
- const item = resource<Entity>(
29
- () => `/api/__name__/${idAttr()}`,
30
- jsonFetcher(),
31
- { staleTime: 60_000 },
32
- );
33
-
34
- return () => html`
35
- <section>
36
- ${() =>
37
- item.loading()
38
- ? html`<p><i>loading…</i></p>`
39
- : item.error()
40
- ? html`<p class="err">${item.error()!.message}</p>`
41
- : item.data()
42
- ? html`
43
- <h1>${item.data()!.name}</h1>
44
- <p>id: ${item.data()!.id}</p>
45
- `
46
- : null}
47
- <a href="/__name__" data-link>← back to list</a>
48
- </section>
49
- `;
50
- },
51
- {
52
- styles: css`
53
- :host { display: block; }
54
- .err { color: #c00; }
55
- `,
56
- },
57
- );
58
-
59
- export default page<{ id: string }>({
60
- title: ({ id }) => `__Name__ #${id}`,
61
- view: ({ params }) =>
62
- html`<x-__name__-detail data-id=${params.id}></x-__name__-detail>`,
63
- });
@@ -1,94 +0,0 @@
1
- /**
2
- * Template: create/edit form page.
3
- */
4
-
5
- import {
6
- page,
7
- component,
8
- html,
9
- css,
10
- signal,
11
- useForm,
12
- mutation,
13
- } from "@madojs/mado";
14
-
15
- interface Values {
16
- name: string;
17
- email: string;
18
- [k: string]: string | number | boolean | undefined;
19
- }
20
-
21
- component(
22
- "x-__name__-page",
23
- () => {
24
- const f = useForm<Values>({
25
- name: { required: true, minLength: 2, default: "" },
26
- email: { required: true, type: "email", default: "" },
27
- });
28
-
29
- const save = mutation<Values, Values>(async (v) => {
30
- const r = await fetch("/api/__name__", {
31
- method: "POST",
32
- headers: { "content-type": "application/json" },
33
- body: JSON.stringify(v),
34
- });
35
- if (!r.ok) throw new Error(`HTTP ${r.status}`);
36
- return (await r.json()) as Values;
37
- });
38
-
39
- const done = signal(false);
40
-
41
- const submit = f.onSubmit(async (v) => {
42
- await save.run(v);
43
- done.set(true);
44
- f.reset();
45
- });
46
-
47
- const err = (name: keyof Values) => () =>
48
- f.touched()[name as string] && f.errors()[name as string]
49
- ? html`<small class="err">${f.errors()[name as string]}</small>`
50
- : null;
51
-
52
- return () => html`
53
- <section>
54
- <h1>__Name__</h1>
55
- <form @submit=${submit} novalidate>
56
- <label>
57
- Name
58
- <input name="name" .value=${() => f.values().name ?? ""}
59
- @input=${f.onInput} @blur=${f.onBlur} />
60
- ${err("name")}
61
- </label>
62
- <label>
63
- Email
64
- <input name="email" type="email" .value=${() => f.values().email ?? ""}
65
- @input=${f.onInput} @blur=${f.onBlur} />
66
- ${err("email")}
67
- </label>
68
- <button type="submit"
69
- ?disabled=${() => !f.isValid() || f.submitting() || save.loading()}>
70
- ${() => (save.loading() || f.submitting() ? "saving…" : "save")}
71
- </button>
72
- ${() => (save.error() ? html`<p class="err">${save.error()!.message}</p>` : null)}
73
- ${() => (done() ? html`<p class="ok">saved</p>` : null)}
74
- </form>
75
- </section>
76
- `;
77
- },
78
- {
79
- styles: css`
80
- :host { display: block; }
81
- label { display: block; margin: .5rem 0; }
82
- input { display: block; margin-top: .25rem; padding: .25rem .5rem;
83
- border: 1px solid #999; border-radius: 4px; min-width: 14rem; }
84
- .err { color: #c00; }
85
- .ok { color: #060; }
86
- button:disabled { opacity: .5; }
87
- `,
88
- },
89
- );
90
-
91
- export default page({
92
- title: "__Name__",
93
- view: () => html`<x-__name__-page></x-__name__-page>`,
94
- });
@@ -1,79 +0,0 @@
1
- /**
2
- * Template: list page with URL filter and pagination.
3
- * Copy into src/pages/ and rename.
4
- */
5
-
6
- import {
7
- page,
8
- component,
9
- html,
10
- css,
11
- each,
12
- resource,
13
- queryParam,
14
- jsonFetcher,
15
- } from "@madojs/mado";
16
-
17
- interface Item {
18
- id: number;
19
- name: string;
20
- }
21
-
22
- component(
23
- "x-__name__-page",
24
- () => {
25
- const search = queryParam("q", "");
26
- const pageQ = queryParam("page", "1");
27
- const limit = 20;
28
-
29
- const items = resource<Item[]>(
30
- () =>
31
- `/api/__name__?q=${encodeURIComponent(search())}&page=${pageQ()}&limit=${limit}`,
32
- jsonFetcher(),
33
- { staleTime: 30_000 },
34
- );
35
-
36
- return () => html`
37
- <section>
38
- <h1>__Name__</h1>
39
- <input
40
- placeholder="search..."
41
- .value=${search}
42
- @input=${(e: Event) =>
43
- search.set((e.target as HTMLInputElement).value)}
44
- />
45
- ${() => (items.loading() ? html`<p><i>loading…</i></p>` : null)}
46
- ${() =>
47
- items.error()
48
- ? html`<p class="err">${items.error()!.message}</p>`
49
- : null}
50
- <ul>
51
- ${() =>
52
- each(
53
- items.data() ?? [],
54
- (it) => it.id,
55
- (it) => html`<li>${it.name}</li>`,
56
- )}
57
- </ul>
58
- <nav>
59
- <button @click=${() =>
60
- pageQ.set(String(Math.max(1, +pageQ() - 1)))}>‹</button>
61
- <span>${pageQ}</span>
62
- <button @click=${() => pageQ.set(String(+pageQ() + 1))}>›</button>
63
- </nav>
64
- </section>
65
- `;
66
- },
67
- {
68
- styles: css`
69
- :host { display: block; }
70
- .err { color: #c00; }
71
- ul { padding-left: 1.2rem; }
72
- `,
73
- },
74
- );
75
-
76
- export default page({
77
- title: "__Name__",
78
- view: () => html`<x-__name__-page></x-__name__-page>`,
79
- });