odoro 1.0.8 → 2.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 (85) hide show
  1. package/README.md +94 -0
  2. package/client.d.ts +90 -16
  3. package/dist/build-LZAUDJST.js +5 -0
  4. package/dist/{chunk-34RGOZFA.js → chunk-4D56Z7G3.js} +49 -50
  5. package/dist/{chunk-JMEHF3KN.js → chunk-7ZB5MAM6.js} +4 -4
  6. package/dist/{chunk-LHZGX5ML.js → chunk-OMHEQVIW.js} +295 -160
  7. package/dist/{chunk-3SZIN6VG.js → chunk-P3DJITWE.js} +10 -10
  8. package/dist/{chunk-ZVL7EXJO.js → chunk-PRWVZ2SM.js} +22 -14
  9. package/dist/chunk-Q2KCMTB5.js +741 -0
  10. package/dist/chunk-QOVBLN7A.js +241 -0
  11. package/dist/chunk-WWTDEV4Y.js +604 -0
  12. package/dist/cli.d.ts +12 -13
  13. package/dist/cli.js +84 -63
  14. package/dist/{commands-4JRBD55Z.js → commands-EUGVLQWL.js} +44 -45
  15. package/dist/{commands-AHMXBWQQ.js → commands-GYA7NTCX.js} +124 -124
  16. package/dist/{create-CDKS7KZ3.js → create-QX5LEWMS.js} +158 -154
  17. package/dist/index.d.ts +603 -151
  18. package/dist/index.js +6 -6
  19. package/dist/{package-NBP5NDX6.js → package-T4Z7OBOH.js} +5 -5
  20. package/dist/preview-P4WY5GEY.js +4 -0
  21. package/dist/registry/index.d.ts +75 -76
  22. package/dist/registry/index.js +1 -1
  23. package/dist/{server-4UGN3SFS.js → server-2WP562EV.js} +3 -3
  24. package/package.json +5 -5
  25. package/templates/react-ts/README.md +71 -35
  26. package/templates/react-ts/_env.example +9 -0
  27. package/templates/react-ts/_variants/with-engine/src/background.tsx +118 -0
  28. package/templates/react-ts/_variants/without-libs/src/App.tsx +380 -0
  29. package/templates/react-ts/_variants/without-libs/src/background.tsx +24 -0
  30. package/templates/react-ts/_variants/without-libs/src/entry-server.tsx +39 -0
  31. package/templates/react-ts/_variants/without-libs/src/main.tsx +26 -0
  32. package/templates/{react-ts-server/_variantes/sans-libs/client → react-ts/_variants/without-libs}/src/styles.css +137 -137
  33. package/templates/react-ts/{_variantes/sans-routeur → _variants/without-router}/src/App.tsx +141 -141
  34. package/templates/react-ts/_variants/without-router/src/entry-server.tsx +39 -0
  35. package/templates/react-ts/index.html +4 -4
  36. package/templates/react-ts/odoro.config.ts +5 -0
  37. package/templates/react-ts/src/App.tsx +219 -209
  38. package/templates/react-ts/src/background.tsx +66 -0
  39. package/templates/react-ts/src/entry-server.tsx +85 -0
  40. package/templates/react-ts/src/main.tsx +13 -4
  41. package/templates/react-ts/src/router.tsx +65 -45
  42. package/templates/react-ts/src/styles.css +5 -5
  43. package/templates/react-ts-server/Dockerfile +9 -9
  44. package/templates/react-ts-server/README.md +97 -45
  45. package/templates/react-ts-server/_env.example +31 -33
  46. package/templates/react-ts-server/_variants/with-engine/client/src/background.tsx +118 -0
  47. package/templates/react-ts-server/_variants/without-libs/client/src/App.tsx +380 -0
  48. package/templates/react-ts-server/_variants/without-libs/client/src/background.tsx +24 -0
  49. package/templates/react-ts-server/_variants/without-libs/client/src/entry-server.tsx +39 -0
  50. package/templates/react-ts-server/_variants/without-libs/client/src/main.tsx +26 -0
  51. package/templates/{react-ts/_variantes/sans-libs → react-ts-server/_variants/without-libs/client}/src/styles.css +137 -137
  52. package/templates/react-ts-server/{_variantes/sans-routeur → _variants/without-router}/client/src/App.tsx +141 -141
  53. package/templates/react-ts-server/_variants/without-router/client/src/entry-server.tsx +39 -0
  54. package/templates/react-ts-server/client/index.html +4 -4
  55. package/templates/react-ts-server/client/src/App.tsx +228 -210
  56. package/templates/react-ts-server/client/src/account.tsx +267 -0
  57. package/templates/react-ts-server/client/src/auth.tsx +139 -0
  58. package/templates/react-ts-server/client/src/background.tsx +66 -0
  59. package/templates/react-ts-server/client/src/entry-server.tsx +92 -0
  60. package/templates/react-ts-server/client/src/main.tsx +17 -5
  61. package/templates/react-ts-server/client/src/router.tsx +77 -45
  62. package/templates/react-ts-server/client/src/styles.css +5 -5
  63. package/templates/react-ts-server/odoro.config.ts +7 -4
  64. package/templates/react-ts-server/package.json +2 -0
  65. package/templates/react-ts-server/scripts/dev.mjs +14 -14
  66. package/templates/react-ts-server/server/src/main.ts +119 -45
  67. package/templates/react-ts-server/server/src/modules/auth/index.ts +238 -0
  68. package/templates/react-ts-server/server/src/modules/auth/password.ts +122 -0
  69. package/templates/react-ts-server/server/src/modules/auth/store.ts +193 -0
  70. package/templates/react-ts-server/server/src/modules/health/index.ts +45 -46
  71. package/dist/build-JFQHODAT.js +0 -5
  72. package/dist/chunk-22KJTV2R.js +0 -380
  73. package/dist/chunk-DL3NPC4H.js +0 -113
  74. package/dist/chunk-TQUJ3MFS.js +0 -268
  75. package/dist/preview-7DKEAQOQ.js +0 -4
  76. package/templates/react-ts/_variantes/avec-moteur/src/fond.tsx +0 -118
  77. package/templates/react-ts/_variantes/sans-libs/src/App.tsx +0 -382
  78. package/templates/react-ts/_variantes/sans-libs/src/fond.tsx +0 -23
  79. package/templates/react-ts/_variantes/sans-libs/src/main.tsx +0 -17
  80. package/templates/react-ts/src/fond.tsx +0 -42
  81. package/templates/react-ts-server/_variantes/avec-moteur/client/src/fond.tsx +0 -118
  82. package/templates/react-ts-server/_variantes/sans-libs/client/src/App.tsx +0 -382
  83. package/templates/react-ts-server/_variantes/sans-libs/client/src/fond.tsx +0 -23
  84. package/templates/react-ts-server/_variantes/sans-libs/client/src/main.tsx +0 -17
  85. package/templates/react-ts-server/client/src/fond.tsx +0 -42
@@ -1,268 +0,0 @@
1
- #!/usr/bin/env node
2
- import { relative, resolve } from 'path';
3
- import { build } from 'esbuild';
4
-
5
- // src/shared/ecouter.ts
6
- var ESSAIS = 10;
7
- async function ecouter(server, port, host, essais = ESSAIS) {
8
- for (let decalage = 0; decalage < essais; decalage += 1) {
9
- const candidat = port + decalage;
10
- const pris = await new Promise((resolve2, reject) => {
11
- const surErreur = (cause) => {
12
- server.removeListener("listening", surEcoute);
13
- if (cause.code === "EADDRINUSE") {
14
- resolve2(true);
15
- return;
16
- }
17
- reject(cause);
18
- };
19
- const surEcoute = () => {
20
- server.removeListener("error", surErreur);
21
- resolve2(false);
22
- };
23
- server.once("error", surErreur);
24
- server.once("listening", surEcoute);
25
- server.listen(candidat, host);
26
- });
27
- if (!pris) {
28
- const adresse = server.address();
29
- const obtenu = typeof adresse === "object" && adresse !== null ? adresse.port : candidat;
30
- return decalage === 0 ? { port: obtenu } : { port: obtenu, demande: port };
31
- }
32
- }
33
- throw new Error(
34
- `[odoro] Aucun port libre entre ${String(port)} et ${String(port + essais - 1)}.`
35
- );
36
- }
37
- var DEPS_PREFIX = "/@deps/";
38
- var INTERNAL_PREFIX = "/@odoro/";
39
- var SOURCE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
40
- var STYLE_EXTENSIONS = [".css"];
41
- var ASSET_EXTENSIONS = [
42
- ".svg",
43
- ".png",
44
- ".jpg",
45
- ".jpeg",
46
- ".gif",
47
- ".webp",
48
- ".avif",
49
- ".ico",
50
- ".woff",
51
- ".woff2",
52
- ".mp4",
53
- ".webm"
54
- ];
55
- function depFileName(specifier) {
56
- return `${specifier.replace(/^@/, "").split("/").join("_")}.js`;
57
- }
58
- function isBareSpecifier(specifier) {
59
- return !specifier.startsWith(".") && !specifier.startsWith("/") && !specifier.startsWith("\\") && !/^[a-zA-Z]:[\\/]/.test(specifier) && !specifier.startsWith("data:") && !specifier.startsWith("http:") && !specifier.startsWith("https:");
60
- }
61
- function hasExtension(path, extensions) {
62
- const clean = path.split("?")[0] ?? path;
63
- return extensions.some((extension) => clean.toLowerCase().endsWith(extension));
64
- }
65
- function fileToUrl(file, root) {
66
- const relativePath = relative(root, file).split("\\").join("/");
67
- if (!relativePath.startsWith("..")) return `/${relativePath}`;
68
- return `/@fs/${file.split("\\").join("/").replace(/^\//, "")}`;
69
- }
70
- function urlToFile(url, root) {
71
- const path = (url.split("?")[0] ?? url).split("#")[0] ?? url;
72
- if (path.startsWith("/@fs/")) {
73
- const absolute = path.slice("/@fs/".length);
74
- return /^[a-zA-Z]:/.test(absolute) ? absolute : `/${absolute}`;
75
- }
76
- return resolve(root, `.${path}`);
77
- }
78
- function applyAlias(specifier, config) {
79
- for (const [prefix, target] of Object.entries(config.alias)) {
80
- if (specifier === prefix || specifier.startsWith(`${prefix}/`)) {
81
- return resolve(
82
- config.root,
83
- target,
84
- specifier.slice(prefix.length).replace(/^\//, "")
85
- );
86
- }
87
- }
88
- return specifier;
89
- }
90
- function externalizeImports(config, dependencies) {
91
- return {
92
- name: "odoro-externalize",
93
- setup(builder) {
94
- builder.onResolve({ filter: /.*/ }, async (args) => {
95
- if (args.kind === "entry-point") return null;
96
- if (args.pluginData?.resolving === true) {
97
- return null;
98
- }
99
- if (args.path.startsWith(INTERNAL_PREFIX) || args.path.startsWith(DEPS_PREFIX)) {
100
- return { path: args.path, external: true };
101
- }
102
- const aliased = applyAlias(args.path, config);
103
- const isFileLike = hasExtension(aliased, STYLE_EXTENSIONS) || hasExtension(aliased, ASSET_EXTENSIONS);
104
- if (isBareSpecifier(aliased) && !isFileLike) {
105
- return { path: `${DEPS_PREFIX}${depFileName(aliased)}`, external: true };
106
- }
107
- const resolved = await builder.resolve(aliased, {
108
- kind: "import-statement",
109
- resolveDir: args.resolveDir,
110
- importer: args.importer,
111
- pluginData: { resolving: true }
112
- });
113
- if (resolved.errors.length > 0) {
114
- return { path: args.path, external: true };
115
- }
116
- dependencies.add(resolved.path);
117
- const url = fileToUrl(resolved.path, config.root);
118
- return {
119
- path: hasExtension(url, ASSET_EXTENSIONS) ? `${url}?import` : url,
120
- external: true
121
- };
122
- });
123
- }
124
- };
125
- }
126
- async function transformModule(file, config, env) {
127
- const dependencies = /* @__PURE__ */ new Set();
128
- const result = await build({
129
- entryPoints: [file],
130
- bundle: true,
131
- write: false,
132
- format: "esm",
133
- platform: "browser",
134
- target: "es2022",
135
- sourcemap: "inline",
136
- jsx: "automatic",
137
- jsxDev: true,
138
- logLevel: "silent",
139
- absWorkingDir: config.root,
140
- define: {
141
- "import.meta.env": JSON.stringify(env),
142
- "process.env.NODE_ENV": JSON.stringify("development"),
143
- ...config.define
144
- },
145
- plugins: [externalizeImports(config, dependencies)]
146
- });
147
- const code = result.outputFiles[0]?.text;
148
- if (code === void 0) {
149
- throw new Error(`[odoro] La compilation de "${file}" n'a produit aucun code.`);
150
- }
151
- return { code, dependencies: [...dependencies] };
152
- }
153
- var IDENTIFIANT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
154
- var RESERVES = /* @__PURE__ */ new Set([
155
- "arguments",
156
- "await",
157
- "break",
158
- "case",
159
- "catch",
160
- "class",
161
- "const",
162
- "continue",
163
- "debugger",
164
- "default",
165
- "delete",
166
- "do",
167
- "else",
168
- "enum",
169
- "eval",
170
- "export",
171
- "extends",
172
- "false",
173
- "finally",
174
- "for",
175
- "function",
176
- "if",
177
- "implements",
178
- "import",
179
- "in",
180
- "instanceof",
181
- "interface",
182
- "let",
183
- "new",
184
- "null",
185
- "package",
186
- "private",
187
- "protected",
188
- "public",
189
- "return",
190
- "static",
191
- "super",
192
- "switch",
193
- "this",
194
- "throw",
195
- "true",
196
- "try",
197
- "typeof",
198
- "var",
199
- "void",
200
- "while",
201
- "with",
202
- "yield"
203
- ]);
204
- function wrapJson(json) {
205
- let valeur;
206
- try {
207
- valeur = JSON.parse(json);
208
- } catch {
209
- return 'throw new SyntaxError("JSON illisible")';
210
- }
211
- const lignes = ["export default " + json.trim()];
212
- if (typeof valeur === "object" && valeur !== null && !Array.isArray(valeur)) {
213
- for (const [cle, contenu] of Object.entries(valeur)) {
214
- if (!IDENTIFIANT.test(cle) || RESERVES.has(cle)) continue;
215
- lignes.push("export const " + cle + " = " + JSON.stringify(contenu));
216
- }
217
- }
218
- return lignes.join("\n");
219
- }
220
- var DESTINATIONS_RESSOURCE = /* @__PURE__ */ new Set([
221
- "script",
222
- "style",
223
- "image",
224
- "font",
225
- "audio",
226
- "video",
227
- "track",
228
- "manifest",
229
- "worker",
230
- "sharedworker",
231
- "serviceworker"
232
- ]);
233
- function estUneRessource(entetes) {
234
- const destination = entetes["sec-fetch-dest"];
235
- return typeof destination === "string" && DESTINATIONS_RESSOURCE.has(destination);
236
- }
237
- function feuilleDemandee(entetes, url) {
238
- if (url.includes("?direct")) return true;
239
- if (entetes["sec-fetch-dest"] === "style") return true;
240
- const accepte = entetes["accept"];
241
- return typeof accepte === "string" && accepte.includes("text/css");
242
- }
243
- function wrapStyle(url, css) {
244
- return `const id = ${JSON.stringify(`odoro-style:${url}`)}
245
- const css = ${JSON.stringify(css)}
246
-
247
- let element = document.querySelector(\`style[data-odoro-id="\${id}"]\`)
248
- if (element === null) {
249
- element = document.createElement('style')
250
- element.setAttribute('data-odoro-id', id)
251
- document.head.appendChild(element)
252
- }
253
- element.textContent = css
254
-
255
- import.meta.hot?.accept()
256
- import.meta.hot?.dispose(() => {
257
- // La feuille suivante recreera l'element : le retirer evite d'empiler les
258
- // regles mortes a chaque rechargement.
259
- element?.remove()
260
- })
261
- `;
262
- }
263
- function wrapAsset(url) {
264
- return `export default ${JSON.stringify(url)}
265
- `;
266
- }
267
-
268
- export { ASSET_EXTENSIONS, DEPS_PREFIX, INTERNAL_PREFIX, SOURCE_EXTENSIONS, STYLE_EXTENSIONS, applyAlias, depFileName, ecouter, estUneRessource, feuilleDemandee, fileToUrl, hasExtension, isBareSpecifier, transformModule, urlToFile, wrapAsset, wrapJson, wrapStyle };
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- export { startPreviewServer } from './chunk-ZVL7EXJO.js';
3
- import './chunk-TQUJ3MFS.js';
4
- import './chunk-JMEHF3KN.js';
@@ -1,118 +0,0 @@
1
- /**
2
- * Le fond decoratif, en surface WebGL.
3
- *
4
- * Cette version remplace le degrade statique parce que le moteur a ete retenu a
5
- * la creation. Le reste de la page est inchange : elle place `<Fond />` et ne
6
- * sait pas ce qu'il y a derriere.
7
- *
8
- * ## Ce que le moteur apporte, et qu'un degrade ne peut pas
9
- *
10
- * **Un arbitre.** La surface est demandee au gestionnaire du moteur, qui la
11
- * refuse si le navigateur n'a pas WebGL, si trop de contextes sont deja
12
- * ouverts, ou si l'appareil ne suivrait pas. Le refus est une valeur, pas une
13
- * exception : on affiche alors le degrade, et la page tient.
14
- *
15
- * **Le mouvement reduit.** Sous cette preference, rien n'est monte : le fond
16
- * n'apportait que son mouvement, et la carte graphique n'a pas a s'allumer pour
17
- * un visiteur qui a demande le calme.
18
- *
19
- * **Les couleurs du theme.** Les teintes sont lues dans les jetons, pas ecrites
20
- * dans le nuanceur. Une bascule clair / sombre les relit, et changer
21
- * `--o-palette-brand-500` repeint le fond sans toucher a ce fichier.
22
- *
23
- * ## Pourquoi des styles en ligne
24
- *
25
- * Ce fichier est pose quel que soit le reste : un projet qui a decoche les
26
- * bibliotheques n'a pas les classes `o-*`, et une classe absente ne peint rien
27
- * — le fond aurait alors une hauteur nulle, sans que rien ne le signale. Les
28
- * quelques regles de placement sont donc ecrites ou elles sont sures.
29
- *
30
- * @module
31
- */
32
-
33
- import {
34
- AURORA_FRAGMENT,
35
- readTokenColour,
36
- useMotionState,
37
- useShaderSurface,
38
- type ShaderColour,
39
- } from '@odoro-cli/engine'
40
- import { useEffect, useMemo, useState, type ReactElement } from 'react'
41
-
42
- /** Les jetons lus pour teinter la nappe. */
43
- const TEINTES = ['--o-palette-brand-500', '--o-palette-brand-300', '--o-theme-bg'] as const
44
-
45
- /** Le degrade servi tant que la surface n'est pas la — ou pour toujours. */
46
- function Degrade(): ReactElement {
47
- return (
48
- <div
49
- style={{
50
- position: 'absolute',
51
- inset: 0,
52
- opacity: 0.28,
53
- filter: 'blur(64px)',
54
- background:
55
- 'radial-gradient(60% 60% at 50% 0%, var(--o-palette-brand-500, #3b82f6), transparent)',
56
- }}
57
- />
58
- )
59
- }
60
-
61
- /** Une nappe animee derriere le haut de la page. */
62
- export function Fond(): ReactElement {
63
- const { quality, reduced } = useMotionState()
64
- const [hote, setHote] = useState<HTMLElement | null>(null)
65
- const [teintes, setTeintes] = useState<readonly ShaderColour[]>([])
66
-
67
- // Relues quand l'hote apparait et quand le theme bascule — ce dernier cas
68
- // passe par la politique de mouvement, qui se renouvelle a chaque etat.
69
- useEffect(() => {
70
- if (hote === null) return
71
- setTeintes(TEINTES.map((jeton) => readTokenColour(jeton, hote)))
72
- }, [hote, reduced, quality])
73
-
74
- const uniforms = useMemo(() => {
75
- const [a, b, c] = teintes
76
- if (a === undefined || b === undefined || c === undefined) return undefined
77
- // Le fond du theme domine, la marque n'est qu'un reflet : ces trois
78
- // couleurs vont dans un melange, et deux teintes de marque sur trois
79
- // donneraient une nappe pleine page plutot qu'un halo.
80
- return { uColorA: c, uColorB: c, uColorC: a, uSpeed: 0.1, uScale: 1.4, uOctaves: 3 }
81
- }, [teintes])
82
-
83
- const { ref, ready, refused } = useShaderSurface<HTMLDivElement>({
84
- fragment: AURORA_FRAGMENT,
85
- uniforms: uniforms ?? {},
86
- name: 'fond-accueil',
87
- })
88
-
89
- const repli = !ready || refused !== undefined || uniforms === undefined
90
-
91
- return (
92
- <div
93
- aria-hidden="true"
94
- ref={(element) => {
95
- setHote(element)
96
- ref.current = element
97
- }}
98
- style={{
99
- position: 'absolute',
100
- insetInline: 0,
101
- top: 0,
102
- height: '42rem',
103
- overflow: 'hidden',
104
- pointerEvents: 'none',
105
- // Un fond decoratif se remarque quand on le cherche, pas avant. A
106
- // pleine intensite la nappe passe devant le titre qu'elle est censee
107
- // porter ; a un cinquieme, elle le souligne.
108
- opacity: 0.2,
109
- // Le bas se dissout dans la page : une surface qui s'arrete net dessine
110
- // une ligne horizontale que rien ne justifie.
111
- maskImage: 'linear-gradient(to bottom, black 45%, transparent)',
112
- WebkitMaskImage: 'linear-gradient(to bottom, black 45%, transparent)',
113
- }}
114
- >
115
- {repli ? <Degrade /> : null}
116
- </div>
117
- )
118
- }