@madojs/mado 0.10.0 → 0.11.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/AGENTS.md +24 -26
- package/CHANGELOG.md +98 -0
- package/README.md +18 -45
- package/TODO.md +52 -48
- package/dist/src/component.d.ts +2 -1
- package/dist/src/component.js +5 -2
- package/dist/src/component.js.map +1 -1
- package/dist/src/each.d.ts +1 -1
- package/dist/src/each.js +1 -1
- package/dist/src/each.js.map +1 -1
- package/dist/src/html/template.js +10 -0
- package/dist/src/html/template.js.map +1 -1
- package/dist/src/index.d.ts +11 -6
- package/dist/src/index.js +5 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/lazy.d.ts +1 -1
- package/dist/src/lazy.js +1 -1
- package/dist/src/lazy.js.map +1 -1
- package/dist/src/page.d.ts +17 -21
- package/dist/src/page.js +7 -12
- package/dist/src/page.js.map +1 -1
- package/dist/src/router/manifest.d.ts +1 -1
- package/dist/src/router/manifest.js +21 -13
- package/dist/src/router/manifest.js.map +1 -1
- package/dist/src/router/match.d.ts +2 -2
- package/dist/src/router/match.js +3 -3
- package/dist/src/router/match.js.map +1 -1
- package/dist/src/router/navigation.js +1 -1
- package/dist/src/router/navigation.js.map +1 -1
- package/dist/src/vite/index.d.ts +10 -0
- package/dist/src/vite/index.js +33 -0
- package/dist/src/vite/index.js.map +1 -0
- package/docs/en/00-the-mado-way.md +25 -12
- package/docs/en/01-routing.md +90 -142
- package/docs/en/02-project-layout.md +59 -52
- package/docs/en/03-static-bake.md +5 -6
- package/docs/en/05-why-mado.md +6 -6
- package/docs/en/06-for-backenders.md +18 -22
- package/docs/en/08-llm-zero-history-test.md +9 -14
- package/docs/en/09-shadow-vs-light-dom.md +28 -36
- package/docs/en/10-app-architecture.md +158 -96
- package/docs/en/11-layouts.md +22 -24
- package/docs/en/12-auth-and-api.md +89 -182
- package/docs/en/13-deployment.md +25 -26
- package/docs/en/14-testing.md +4 -4
- package/docs/en/16-bake-cookbook.md +17 -10
- package/docs/en/18-api-freeze-map.md +6 -4
- package/docs/en/20-v1-stability.md +1 -1
- package/docs/fr/00-the-mado-way.md +55 -90
- package/docs/fr/01-routing.md +70 -152
- package/docs/fr/02-project-layout.md +74 -48
- package/docs/fr/03-static-bake.md +1 -1
- package/docs/fr/05-why-mado.md +6 -6
- package/docs/fr/06-for-backenders.md +7 -7
- package/docs/fr/08-llm-zero-history-test.md +21 -48
- package/docs/fr/09-shadow-vs-light-dom.md +43 -162
- package/docs/fr/10-app-architecture.md +110 -33
- package/docs/fr/11-layouts.md +24 -12
- package/docs/fr/12-auth-and-api.md +63 -22
- package/docs/fr/13-deployment.md +30 -12
- package/docs/fr/14-testing.md +1 -1
- package/docs/fr/16-bake-cookbook.md +57 -4
- package/docs/fr/18-api-freeze-map.md +1 -1
- package/docs/fr/20-v1-stability.md +1 -1
- package/docs/recipes/nginx/README.md +13 -0
- package/docs/ru/00-the-mado-way.md +53 -75
- package/docs/ru/01-routing.md +68 -143
- package/docs/ru/02-project-layout.md +75 -48
- package/docs/ru/03-static-bake.md +2 -2
- package/docs/ru/05-why-mado.md +6 -6
- package/docs/ru/06-for-backenders.md +7 -7
- package/docs/ru/08-llm-zero-history-test.md +9 -14
- package/docs/ru/09-shadow-vs-light-dom.md +43 -178
- package/docs/ru/10-app-architecture.md +115 -63
- package/docs/ru/11-layouts.md +24 -24
- package/docs/ru/12-auth-and-api.md +57 -35
- package/docs/ru/13-deployment.md +19 -13
- package/docs/ru/14-testing.md +1 -1
- package/docs/ru/16-bake-cookbook.md +48 -8
- package/docs/ru/18-api-freeze-map.md +5 -3
- package/docs/ru/20-v1-stability.md +1 -1
- package/docs/uk/00-the-mado-way.md +70 -44
- package/docs/uk/01-routing.md +41 -47
- package/docs/uk/02-project-layout.md +68 -41
- package/docs/uk/03-static-bake.md +1 -2
- package/docs/uk/06-for-backenders.md +3 -3
- package/docs/uk/08-llm-zero-history-test.md +22 -24
- package/docs/uk/09-shadow-vs-light-dom.md +37 -86
- package/docs/uk/10-app-architecture.md +72 -31
- package/docs/uk/11-layouts.md +25 -12
- package/docs/uk/12-auth-and-api.md +58 -22
- package/docs/uk/13-deployment.md +4 -3
- package/docs/uk/14-testing.md +1 -1
- package/docs/uk/18-api-freeze-map.md +1 -1
- package/docs/uk/20-v1-stability.md +1 -1
- package/llms.txt +14 -15
- package/package.json +18 -11
- package/scripts/_config.mjs +15 -161
- package/scripts/bake.mjs +71 -58
- package/scripts/cli/generate.mjs +348 -0
- package/scripts/cli/help.mjs +27 -0
- package/scripts/cli/index.mjs +79 -0
- package/scripts/cli/init.mjs +153 -0
- package/scripts/cli/release.mjs +152 -0
- package/scripts/cli/run.mjs +96 -0
- package/scripts/cli.mjs +2 -560
- package/scripts/package-smoke.mjs +4 -1
- package/scripts/preview.mjs +17 -61
- package/scripts/size-budget.mjs +5 -2
- package/scripts/vite.default.mjs +11 -0
- package/starters/default/.editorconfig +12 -0
- package/starters/default/README.md +74 -0
- package/starters/default/eslint.config.mjs +256 -0
- package/starters/default/index.html +13 -0
- package/starters/default/package.json +30 -0
- package/starters/default/public/favicon.svg +4 -0
- package/starters/default/src/app.routes.ts +39 -0
- package/starters/default/src/layouts/app-shell.layout.ts +35 -0
- package/starters/default/src/layouts/auth-shell.layout.ts +17 -0
- package/starters/default/src/main.ts +16 -0
- package/starters/default/src/modules/auth/_contracts/auth-api.types.ts +17 -0
- package/starters/default/src/modules/auth/auth.connector.ts +45 -0
- package/starters/default/src/modules/auth/auth.guard.ts +22 -0
- package/starters/default/src/modules/auth/auth.public.ts +9 -0
- package/starters/default/src/modules/auth/auth.routes.ts +8 -0
- package/starters/default/src/modules/auth/auth.service.ts +71 -0
- package/starters/default/src/modules/auth/auth.types.ts +15 -0
- package/starters/default/src/modules/auth/login.page.ts +62 -0
- package/starters/default/src/modules/billing/_contracts/stripe.types.ts +17 -0
- package/starters/default/src/modules/billing/api/stripe.connector.ts +71 -0
- package/starters/default/src/modules/billing/billing.public.ts +5 -0
- package/starters/default/src/modules/billing/billing.routes.ts +9 -0
- package/starters/default/src/modules/billing/billing.types.ts +15 -0
- package/starters/default/src/modules/billing/components/invoice-status-badge.component.ts +43 -0
- package/starters/default/src/modules/billing/data/invoices.resource.ts +35 -0
- package/starters/default/src/modules/billing/pages/invoice-detail.page.ts +70 -0
- package/starters/default/src/modules/billing/pages/invoices-list.page.ts +73 -0
- package/starters/default/src/modules/home/home.page.ts +34 -0
- package/starters/default/src/modules/home/not-found.page.ts +11 -0
- package/starters/default/src/shared/http/http-client.ts +86 -0
- package/starters/default/src/shared/http/http-error.ts +37 -0
- package/starters/default/src/shared/http/interceptors.ts +59 -0
- package/starters/default/src/shared/lib/format-date.ts +19 -0
- package/starters/default/src/shared/styles/content.css +70 -0
- package/starters/default/src/shared/styles/reset.css +32 -0
- package/starters/default/src/shared/styles/shell.css +57 -0
- package/starters/default/src/shared/styles/tokens.css +44 -0
- package/starters/default/src/shared/ui/x-button.component.ts +49 -0
- package/starters/default/src/shared/ui/x-spinner.component.ts +22 -0
- package/starters/default/src/styles.d.ts +1 -0
- package/starters/default/src/vite-env.d.ts +1 -0
- package/starters/default/tsconfig.json +24 -0
- package/starters/default/vite.config.ts +9 -0
- package/MADO_V1_PLAN.md +0 -179
- package/ROADMAP.md +0 -178
- package/dist/src/html.d.ts +0 -18
- package/dist/src/html.js +0 -17
- package/dist/src/html.js.map +0 -1
- package/dist/src/router.d.ts +0 -13
- package/dist/src/router.js +0 -13
- package/dist/src/router.js.map +0 -1
- package/scripts/bundle.mjs +0 -212
- package/scripts/llm-zero-history-smoke.mjs +0 -93
- package/scripts/new.mjs +0 -80
- package/scripts/showcase-regression.mjs +0 -392
- package/server/serve.mjs +0 -455
- package/starters/admin/README.md +0 -63
- package/starters/admin/index.html +0 -28
- package/starters/admin/mado.config.json +0 -22
- package/starters/admin/package.json +0 -24
- package/starters/admin/public/favicon.svg +0 -4
- package/starters/admin/src/components/x-button.ts +0 -82
- package/starters/admin/src/components/x-input.ts +0 -105
- package/starters/admin/src/layouts/app.ts +0 -101
- package/starters/admin/src/layouts/auth.ts +0 -41
- package/starters/admin/src/lib/api.ts +0 -184
- package/starters/admin/src/lib/auth.ts +0 -83
- package/starters/admin/src/main.ts +0 -15
- package/starters/admin/src/pages/admin/dashboard.ts +0 -48
- package/starters/admin/src/pages/admin/order-detail.ts +0 -80
- package/starters/admin/src/pages/admin/orders.ts +0 -117
- package/starters/admin/src/pages/home.ts +0 -34
- package/starters/admin/src/pages/login.ts +0 -70
- package/starters/admin/src/pages/not-found.ts +0 -12
- package/starters/admin/src/routes.ts +0 -40
- package/starters/admin/src/styles/global.ts +0 -86
- package/starters/admin/tsconfig.json +0 -15
- package/starters/crud/README.md +0 -33
- package/starters/crud/index.html +0 -28
- package/starters/crud/mado.config.json +0 -20
- package/starters/crud/package.json +0 -24
- package/starters/crud/src/components/app-shell.ts +0 -56
- package/starters/crud/src/components/ticket-detail.ts +0 -33
- package/starters/crud/src/components/ticket-form.ts +0 -69
- package/starters/crud/src/components/ticket-list.ts +0 -66
- package/starters/crud/src/lib/api.ts +0 -76
- package/starters/crud/src/main.ts +0 -9
- package/starters/crud/src/pages/home.ts +0 -34
- package/starters/crud/src/pages/not-found.ts +0 -12
- package/starters/crud/src/pages/ticket-detail.ts +0 -7
- package/starters/crud/src/pages/ticket-new.ts +0 -7
- package/starters/crud/src/pages/tickets.ts +0 -7
- package/starters/crud/src/routes.ts +0 -11
- package/starters/crud/src/styles/global.ts +0 -155
- package/starters/crud/tsconfig.json +0 -15
- package/starters/minimal/README.md +0 -21
- package/starters/minimal/index.html +0 -28
- package/starters/minimal/mado.config.json +0 -20
- package/starters/minimal/package.json +0 -24
- package/starters/minimal/src/components/app-counter.ts +0 -31
- package/starters/minimal/src/main.ts +0 -9
- package/starters/minimal/src/pages/home.ts +0 -35
- package/starters/minimal/src/pages/not-found.ts +0 -14
- package/starters/minimal/src/routes.ts +0 -8
- package/starters/minimal/src/styles/global.ts +0 -60
- package/starters/minimal/tsconfig.json +0 -15
- package/templates/page-detail.ts +0 -63
- package/templates/page-form.ts +0 -94
- package/templates/page-list.ts +0 -79
|
@@ -1,35 +1,76 @@
|
|
|
1
1
|
# Auth et API
|
|
2
2
|
|
|
3
|
-
Le starter
|
|
3
|
+
Le starter par défaut est la recette recommandée. La mécanique HTTP vit dans
|
|
4
|
+
`src/shared/http/`, l'état auth dans `src/modules/auth/`.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
```txt
|
|
7
|
+
src/shared/http/
|
|
8
|
+
http-client.ts
|
|
9
|
+
http-error.ts
|
|
10
|
+
interceptors.ts
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
src/modules/auth/
|
|
13
|
+
auth.connector.ts
|
|
14
|
+
auth.service.ts
|
|
15
|
+
auth.guard.ts
|
|
16
|
+
auth.routes.ts
|
|
17
|
+
auth.public.ts
|
|
18
|
+
_contracts/
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Flow pour un business module :
|
|
22
|
+
|
|
23
|
+
```txt
|
|
24
|
+
connector -> resource/mutation -> page
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Les pages n'importent pas de DTOs et n'appellent pas `fetch()` directement. Les
|
|
28
|
+
connectors n'importent pas la réactivité Mado ou l'UI.
|
|
10
29
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- les routes protégées utilisent un group guard.
|
|
30
|
+
## Auth Service
|
|
31
|
+
|
|
32
|
+
Auth state est un ES module singleton :
|
|
15
33
|
|
|
16
34
|
```ts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
const _user = signal<User | null>(null);
|
|
36
|
+
const _token = signal<string | null>(null);
|
|
37
|
+
|
|
38
|
+
export const user = () => _user();
|
|
39
|
+
export const isAuthed = computed(() => _user() !== null);
|
|
22
40
|
```
|
|
23
41
|
|
|
24
|
-
|
|
42
|
+
Exposez seulement la surface nécessaire via `auth.public.ts`.
|
|
25
43
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
## Guards
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
export function requireAuth(): boolean | string {
|
|
48
|
+
if (isAuthed()) return true;
|
|
49
|
+
return "/login";
|
|
31
50
|
}
|
|
32
51
|
```
|
|
33
52
|
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
Use in `src/app.routes.ts`:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
"/billing": layout({
|
|
57
|
+
layout: () => import("./layouts/app-shell.layout"),
|
|
58
|
+
guard: requireAuth,
|
|
59
|
+
routes: billingRoutes,
|
|
60
|
+
}),
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Dev Proxy
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
plugins: [mado()],
|
|
68
|
+
server: {
|
|
69
|
+
proxy: { "/api": "http://localhost:3000" },
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Rule: `shared/http` connaît HTTP, connectors connaissent un système externe,
|
|
75
|
+
resources connaissent les cache keys, pages connaissent l'UI, `*.public.ts` est
|
|
76
|
+
la surface cross-module.
|
package/docs/fr/13-deployment.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Déploiement
|
|
2
2
|
|
|
3
|
-
Une commande, un artefact :
|
|
3
|
+
Une commande, un artefact déployable :
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
mado release
|
|
@@ -10,30 +10,48 @@ Résultat :
|
|
|
10
10
|
|
|
11
11
|
```txt
|
|
12
12
|
out/
|
|
13
|
-
├── index.html
|
|
14
|
-
├── assets/
|
|
15
|
-
├──
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
├── index.html ← shell SPA ou HTML baked pour /
|
|
14
|
+
├── assets/ ← assets Vite hashés
|
|
15
|
+
│ ├── *.gz ← gzip précompressé
|
|
16
|
+
│ └── *.br ← brotli précompressé
|
|
17
|
+
├── <route>/index.html ← HTML baked pour les hébergeurs statiques
|
|
18
|
+
├── sitemap.xml ← sitemap à la racine du site
|
|
19
|
+
├── _redirects ← fallback SPA Cloudflare Pages / Netlify
|
|
20
|
+
└── _headers ← règles de cache
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
Déploie `out/` sur nginx, Cloudflare Pages, Netlify, S3/CloudFront ou GitHub
|
|
21
|
-
Pages.
|
|
24
|
+
Pages. Ne déploie pas `dist/` : c'est un output interne.
|
|
25
|
+
|
|
26
|
+
## Preview
|
|
22
27
|
|
|
23
28
|
```bash
|
|
24
29
|
mado release
|
|
25
30
|
mado preview
|
|
26
31
|
```
|
|
27
32
|
|
|
28
|
-
`mado preview` sert `out/` comme un hébergeur statique :
|
|
29
|
-
fallback SPA ensuite.
|
|
33
|
+
`mado preview` sert le `out/` final comme un hébergeur statique : fichiers réels
|
|
34
|
+
d'abord (`/<route>/index.html` si la route est baked), fallback SPA ensuite.
|
|
35
|
+
Preview vérifie exactement ce qui sera déployé.
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
## VPS + nginx
|
|
32
38
|
|
|
33
39
|
```bash
|
|
34
40
|
mado release
|
|
35
41
|
rsync -avz --delete out/ user@server:/var/www/myapp/
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
pour HTML, et fallback SPA pour les deep
|
|
44
|
+
La recette nginx optionnelle vit dans `docs/recipes/nginx/`. Elle gère le cache
|
|
45
|
+
immutable pour `/assets/*`, no-cache pour HTML, et le fallback SPA pour les deep
|
|
46
|
+
links.
|
|
47
|
+
|
|
48
|
+
## Cloudflare / Netlify
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
mado release
|
|
52
|
+
npx wrangler pages deploy out --project-name=myapp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`_redirects` et `_headers` sont générés automatiquement si tu n'en fournis pas.
|
|
56
|
+
Les routes baked sont promues en vrais fichiers (`out/<route>/index.html`), donc
|
|
57
|
+
l'hébergeur statique les sert avant le fallback SPA.
|
package/docs/fr/14-testing.md
CHANGED
|
@@ -22,7 +22,7 @@ globalThis.document = window.document;
|
|
|
22
22
|
globalThis.Node = window.Node;
|
|
23
23
|
globalThis.HTMLElement = window.HTMLElement;
|
|
24
24
|
|
|
25
|
-
const { html, render } = await import("../dist/src/html.js");
|
|
25
|
+
const { html, render } = await import("../dist/src/html/template.js");
|
|
26
26
|
|
|
27
27
|
test("renders", () => {
|
|
28
28
|
const root = document.createElement("div");
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
# Bake
|
|
1
|
+
# Bake Cookbook
|
|
2
2
|
|
|
3
3
|
`mado bake` rend certaines routes en HTML statique. C'est pour le SEO et un
|
|
4
4
|
premier rendu rapide, pas pour SSR + hydration.
|
|
5
5
|
|
|
6
|
+
## Page Minimale
|
|
7
|
+
|
|
6
8
|
```ts
|
|
7
9
|
export default page({
|
|
8
10
|
head: () => ({ title: "Products", description: "Catalog" }),
|
|
@@ -21,15 +23,66 @@ export default page({
|
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
Dans les vues baked, préfère les tableaux simples (`items.map(...)`). Les
|
|
24
|
-
directives runtime comme `each()` sont pour le navigateur.
|
|
26
|
+
directives runtime comme keyed `each()` sont pour le navigateur.
|
|
27
|
+
|
|
28
|
+
## Routes Dynamiques
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
export default page<{ slug: string }>({
|
|
32
|
+
head: ({ slug }, data) => ({ title: data.title, canonical: `/blog/${slug}` }),
|
|
33
|
+
view: ({ data }) => html`<article>${unsafeHTML(data.html)}</article>`,
|
|
34
|
+
bake: {
|
|
35
|
+
paths: async () => (await api.posts()).map((p) => ({ slug: p.slug })),
|
|
36
|
+
data: ({ slug }) => api.post(slug),
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Utilise `unsafeHTML()` seulement pour du HTML fiable ou déjà nettoyé.
|
|
42
|
+
|
|
43
|
+
## Route Manifest
|
|
44
|
+
|
|
45
|
+
`mado bake` a besoin du manifest source :
|
|
25
46
|
|
|
26
47
|
```ts
|
|
27
48
|
export const manifest = {
|
|
28
49
|
"/": () => import("./pages/home.js"),
|
|
29
50
|
"/blog/:slug": () => import("./pages/blog-post.js"),
|
|
30
51
|
};
|
|
52
|
+
|
|
31
53
|
export default routes(manifest);
|
|
32
54
|
```
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
## Output
|
|
57
|
+
|
|
58
|
+
Standalone `mado bake` écrit les pages baked dans `out/baked/` par défaut.
|
|
59
|
+
`mado release` utilise le shell de production bundlé, garde cette copie
|
|
60
|
+
`out/baked/` pour inspection, promeut le HTML dans les vrais chemins de route
|
|
61
|
+
dans `out/`, et copie le sitemap vers `out/sitemap.xml`.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
mado release
|
|
65
|
+
tree out
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Le dossier déployable est `out/`, pas `dist/`.
|
|
69
|
+
|
|
70
|
+
## Client Boot
|
|
71
|
+
|
|
72
|
+
Le HTML baked marque `#app` avec `data-mado-baked`. Ce n'est pas de
|
|
73
|
+
l'hydration : au démarrage, `render()` remplace le DOM baked par les bindings
|
|
74
|
+
vivants de l'application.
|
|
75
|
+
|
|
76
|
+
## Valeurs Non Supportées
|
|
77
|
+
|
|
78
|
+
Bake échoue volontairement au lieu d'écrire `[object Object]`. Si une vue baked
|
|
79
|
+
signale une directive non supportée :
|
|
80
|
+
|
|
81
|
+
- remplace `each()` par `items.map(...)` dans le markup baked ;
|
|
82
|
+
- garde les widgets interactifs dans des routes client-only ;
|
|
83
|
+
- assure-toi que chaque valeur peut être sérialisée en HTML statique.
|
|
84
|
+
|
|
85
|
+
## Canonical Links
|
|
86
|
+
|
|
87
|
+
Passe `--base-url` pour que les liens canonical et le sitemap pointent vers la
|
|
88
|
+
production.
|
|
@@ -27,7 +27,7 @@ Ces noms sont publics et protégés par SemVer une fois v1 publiée :
|
|
|
27
27
|
- Templates et directives : `html`, `render`, `each`, `list`, `unsafeHTML`,
|
|
28
28
|
`ref`, `classMap`, `styleMap`.
|
|
29
29
|
- Composants et CSS : `component`, `css`, `cssVars`.
|
|
30
|
-
- Routage et pages : `routes`, `router`, `page`, `layout`,
|
|
30
|
+
- Routage et pages : `routes`, `router`, `page`, `layout`,
|
|
31
31
|
`navigate`, `queryParam`, `prefetchPath`.
|
|
32
32
|
- Data : `resource`, `mutation`, `invalidate`, `jsonFetcher`, `HttpError`.
|
|
33
33
|
- Formulaires : `useForm`.
|
|
@@ -26,7 +26,7 @@ Après v1, Mado considère comme protégés par SemVer :
|
|
|
26
26
|
`ctx.onDispose`.
|
|
27
27
|
- Les contrats router/page/resource/form documentés dans les docs anglaises.
|
|
28
28
|
- Les noms de commandes CLI et leur intention générale (`build`, `dev`,
|
|
29
|
-
`release`, `bake`, `
|
|
29
|
+
`release`, `bake`, `preview`, `init`, `new`).
|
|
30
30
|
|
|
31
31
|
Casser cela nécessite une version majeure.
|
|
32
32
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Nginx Container Recipe
|
|
2
|
+
|
|
3
|
+
Optional static deployment recipe for a generated Mado app.
|
|
4
|
+
|
|
5
|
+
Copy this directory into your app as `docker/`, then build from the app root:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
docker build -f docker/Containerfile -t myapp .
|
|
9
|
+
docker run --rm -p 8080:80 myapp
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The container runs `npm run release` and serves the resulting `out/` directory
|
|
13
|
+
with nginx. This is a recipe, not a framework runtime requirement.
|
|
@@ -2,105 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
> Один правильный путь. Жёсткие контракты. Никакой магии.
|
|
4
4
|
|
|
5
|
-
Mado — фреймворк для команд, которые строят админки, внутренние инструменты
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
нарушаешь — типы и линтер скажут об этом сразу.
|
|
5
|
+
Mado — фреймворк для команд, которые строят админки, внутренние инструменты и
|
|
6
|
+
business SPA. Такие приложения должны быть простыми в разработке и скучными в
|
|
7
|
+
поддержке. Поэтому Mado задает соглашения, а не предлагает пять равноценных
|
|
8
|
+
стилей.
|
|
10
9
|
|
|
11
10
|
## Принципы
|
|
12
11
|
|
|
13
|
-
1. **Один способ.**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
1. **Один способ.** Если пишешь что-то необычное, сначала проверь, нет ли уже
|
|
13
|
+
каноничного helper/API.
|
|
14
|
+
2. **Явность над магией.** Никаких file-system scanners, implicit globals и
|
|
15
|
+
скрытых side effects.
|
|
16
|
+
3. **Платформа сначала.** Web Components, History API, `<form>`, `fetch` и
|
|
17
|
+
Shadow DOM остаются платформой, а не прячутся под тяжелыми абстракциями.
|
|
18
|
+
4. **Strict types.** `tsc --strict --noUncheckedIndexedAccess` всегда.
|
|
19
|
+
5. **No runtime dependencies.** Dev/build tooling допустим, runtime Mado
|
|
20
|
+
остается нативным.
|
|
18
21
|
|
|
19
|
-
##
|
|
22
|
+
## Структура проекта
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
+
```txt
|
|
24
25
|
src/
|
|
25
|
-
├──
|
|
26
|
-
├──
|
|
27
|
-
├──
|
|
28
|
-
├──
|
|
29
|
-
|
|
30
|
-
└──
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// src/components/user-card.ts
|
|
39
|
-
import { component, html, css } from "@madojs/mado";
|
|
40
|
-
|
|
41
|
-
component(
|
|
42
|
-
"x-user-card",
|
|
43
|
-
() => {
|
|
44
|
-
return () => html`<div class="card"><slot /></div>`;
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
styles: css`
|
|
48
|
-
.card {
|
|
49
|
-
padding: 1rem;
|
|
50
|
-
}
|
|
51
|
-
`,
|
|
52
|
-
},
|
|
53
|
-
);
|
|
26
|
+
├── main.ts ← boot: global CSS/providers + render router
|
|
27
|
+
├── app.routes.ts ← readable app map, exports `manifest` + default routes()
|
|
28
|
+
├── layouts/ ← app-zone wrappers (`page({ view: ({ child }) => ... })`)
|
|
29
|
+
├── shared/ ← UI bricks, http client, pure lib, global CSS
|
|
30
|
+
└── modules/ ← bounded contexts
|
|
31
|
+
└── billing/
|
|
32
|
+
├── billing.routes.ts
|
|
33
|
+
├── billing.public.ts
|
|
34
|
+
├── billing.types.ts
|
|
35
|
+
├── pages/
|
|
36
|
+
├── data/
|
|
37
|
+
├── api/
|
|
38
|
+
└── _contracts/
|
|
54
39
|
```
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Один способ загрузки данных
|
|
41
|
+
Default starter — каноничная версия этой формы. Если docs и старые примеры
|
|
42
|
+
расходятся, starter и `docs/10-app-architecture.md` главнее.
|
|
59
43
|
|
|
60
|
-
|
|
44
|
+
## Один компонент = один файл
|
|
61
45
|
|
|
62
46
|
```ts
|
|
63
|
-
|
|
64
|
-
const user = resource(() => `/api/users/${id()}`, jsonFetcher());
|
|
47
|
+
import { component, css, html } from "@madojs/mado";
|
|
65
48
|
|
|
66
|
-
|
|
67
|
-
|
|
49
|
+
component("x-user-card", () => () => html`<div class="card"><slot></slot></div>`, {
|
|
50
|
+
styles: css`
|
|
51
|
+
.card { padding: 1rem; }
|
|
52
|
+
`,
|
|
53
|
+
});
|
|
68
54
|
```
|
|
69
55
|
|
|
70
|
-
|
|
56
|
+
Import component file registers the element. Import it where the tag is used.
|
|
71
57
|
|
|
72
|
-
|
|
58
|
+
## Один способ описать страницу
|
|
73
59
|
|
|
74
60
|
```ts
|
|
75
|
-
|
|
76
|
-
import { page, html, resource, jsonFetcher } from "@madojs/mado";
|
|
61
|
+
import { html, page, resource, jsonFetcher } from "@madojs/mado";
|
|
77
62
|
|
|
78
63
|
export default page({
|
|
79
64
|
title: ({ id }) => `User #${id}`,
|
|
80
|
-
view: ({ params }) =>
|
|
65
|
+
view: ({ params }) => {
|
|
66
|
+
const user = resource(() => `/api/users/${params.id}`, jsonFetcher());
|
|
67
|
+
return html`...`;
|
|
68
|
+
},
|
|
81
69
|
});
|
|
82
70
|
```
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
### Один способ объявить роуты
|
|
87
|
-
|
|
88
|
-
См. [`01-routing.md`](./01-routing.md).
|
|
72
|
+
Page-local signals, resources and forms live inside `view()`. Module-wide state
|
|
73
|
+
belongs in `*.service.ts`.
|
|
89
74
|
|
|
90
75
|
## Чего НЕ делаем
|
|
91
76
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
- ❌ Не подключаем pkg без обсуждения. Каждая зависимость — обязательство.
|
|
98
|
-
|
|
99
|
-
## Когда сомневаешься
|
|
100
|
-
|
|
101
|
-
Если ты задаёшься вопросом "а как тут лучше?" — это сигнал, что:
|
|
102
|
-
|
|
103
|
-
1. Либо есть встроенный хелпер, который ты не знаешь (загляни в `docs/`).
|
|
104
|
-
2. Либо это новая ситуация — её надо обсудить и **зафиксировать** в этом документе как ещё одно соглашение.
|
|
77
|
+
- Не используем JSX/Vue/Svelte syntax.
|
|
78
|
+
- Не пишем custom elements без дефиса.
|
|
79
|
+
- Не читаем signals через `.value`; signal читается как function.
|
|
80
|
+
- Не используем `innerHTML` напрямую.
|
|
81
|
+
- Не добавляем runtime packages без обсуждения.
|
|
105
82
|
|
|
106
|
-
|
|
83
|
+
Когда сомневаешься, лучше записать один честный рецепт в docs, чем добавить
|
|
84
|
+
новый primitive в core.
|