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
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ import { guessAliasPaths } from './chunk-T6RLHSCW.js';
3
+ import { existsSync } from 'fs';
4
+ import { readFile, mkdir, writeFile, rm } from 'fs/promises';
5
+ import { join, resolve } from 'path';
6
+ import { pathToFileURL } from 'url';
7
+ import { build } from 'esbuild';
8
+
9
+ var LINE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/;
10
+ var REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g;
11
+ function parseEnvDetailed(text) {
12
+ const values = {};
13
+ const literals = /* @__PURE__ */ new Set();
14
+ const lines = text.split(/\r?\n/);
15
+ for (let index = 0; index < lines.length; index += 1) {
16
+ const line = lines[index];
17
+ if (line === void 0) continue;
18
+ if (line.trim() === "" || line.trimStart().startsWith("#")) continue;
19
+ const found = LINE.exec(line);
20
+ const key = found?.[1];
21
+ if (key === void 0) continue;
22
+ const raw = (found?.[2] ?? "").trim();
23
+ const quote = raw[0];
24
+ if (quote !== '"' && quote !== "'" && quote !== "`") {
25
+ const comment = raw.search(/\s#/);
26
+ values[key] = comment === -1 ? raw : raw.slice(0, comment).trimEnd();
27
+ continue;
28
+ }
29
+ let body = raw.slice(1);
30
+ while (body.length === 0 || !body.endsWith(quote)) {
31
+ const next = lines[index + 1];
32
+ if (next === void 0) break;
33
+ index += 1;
34
+ body = `${body}
35
+ ${next}`;
36
+ }
37
+ const content = body.endsWith(quote) ? body.slice(0, -1) : body;
38
+ if (quote === "'") {
39
+ values[key] = content;
40
+ literals.add(key);
41
+ continue;
42
+ }
43
+ values[key] = content.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
44
+ }
45
+ return { values, literals };
46
+ }
47
+ function expand(values, environment, literals) {
48
+ const rendered = {};
49
+ for (const [key, value] of Object.entries(values)) {
50
+ if (literals.has(key)) {
51
+ rendered[key] = value;
52
+ continue;
53
+ }
54
+ rendered[key] = value.replace(REFERENCE, (whole, braced, bare) => {
55
+ const name = braced ?? bare;
56
+ if (name === void 0) return whole;
57
+ return rendered[name] ?? values[name] ?? environment[name] ?? "";
58
+ });
59
+ }
60
+ return rendered;
61
+ }
62
+ function envFilesFor(mode) {
63
+ return [".env", ".env.local", `.env.${mode}`, `.env.${mode}.local`];
64
+ }
65
+ async function loadEnv(directory, mode, prefix) {
66
+ const stacked = {};
67
+ const literals = /* @__PURE__ */ new Set();
68
+ const files = [];
69
+ for (const name of envFilesFor(mode)) {
70
+ const path = join(directory, name);
71
+ if (!existsSync(path)) continue;
72
+ files.push(name);
73
+ const read = parseEnvDetailed(await readFile(path, "utf8"));
74
+ Object.assign(stacked, read.values);
75
+ for (const key of Object.keys(read.values)) {
76
+ if (read.literals.has(key)) literals.add(key);
77
+ else literals.delete(key);
78
+ }
79
+ }
80
+ const all = expand(stacked, process.env, literals);
81
+ for (const [key, value] of Object.entries(process.env)) {
82
+ if (value !== void 0 && key in all) all[key] = value;
83
+ }
84
+ const client = {};
85
+ for (const [key, value] of Object.entries(all)) {
86
+ if (key.startsWith(prefix)) client[key] = value;
87
+ }
88
+ for (const [key, value] of Object.entries(process.env)) {
89
+ if (value !== void 0 && key.startsWith(prefix)) client[key] = value;
90
+ }
91
+ return { all, client, files };
92
+ }
93
+ function clientEnv(variables, mode, base) {
94
+ return {
95
+ MODE: mode,
96
+ // `DEV` and `PROD` cannot be deduced from the mode name alone: a `staging`
97
+ // mode builds as production and must behave like it.
98
+ DEV: mode === "development",
99
+ PROD: mode !== "development",
100
+ BASE_URL: base,
101
+ ...variables
102
+ };
103
+ }
104
+ function defineConfig(config) {
105
+ return config;
106
+ }
107
+ var CONFIG_FILES = ["odoro.config.ts", "odoro.config.js", "odoro.config.mjs"];
108
+ async function importConfigFile(file, root) {
109
+ const directory = join(root, "node_modules", ".odoro");
110
+ const output = join(directory, `config.${Date.now().toString(36)}.mjs`);
111
+ await mkdir(directory, { recursive: true });
112
+ try {
113
+ const result = await build({
114
+ entryPoints: [file],
115
+ bundle: true,
116
+ format: "esm",
117
+ platform: "node",
118
+ target: "node20",
119
+ write: false,
120
+ // Only the project code is inlined; its dependencies stay external,
121
+ // otherwise the whole node_modules would have to be resolved to read
122
+ // three lines.
123
+ packages: "external",
124
+ // `packages: 'external'` is not enough: a `baseUrl` in the
125
+ // `tsconfig.json` makes bare imports be looked up from the project root,
126
+ // where `odoro.json` — the registry file — is found before the package.
127
+ // The import then stops being a package import, the rule above no longer
128
+ // applies, and the build fails on a `defineConfig` missing from a
129
+ // configuration file.
130
+ //
131
+ // Naming it explicitly puts it out of reach of that resolution. The list
132
+ // matters for projects already created: they still carry a `baseUrl`, and
133
+ // their tsconfig cannot be rewritten.
134
+ external: ["odoro"]
135
+ });
136
+ const code = result.outputFiles[0]?.text;
137
+ if (code === void 0) {
138
+ throw new Error(`[odoro] Configuration "${file}" produced no code.`);
139
+ }
140
+ await writeFile(output, code, "utf8");
141
+ const module = await import(pathToFileURL(output).href);
142
+ if (module.default === void 0) {
143
+ throw new Error(`[odoro] Configuration "${file}" must have a default export.`);
144
+ }
145
+ return module.default;
146
+ } finally {
147
+ await rm(output, { force: true });
148
+ }
149
+ }
150
+ function resolvePrerender(requested, root) {
151
+ if (requested === void 0 || requested === false) return void 0;
152
+ const raw = requested === true ? {} : Array.isArray(requested) ? { routes: requested } : requested;
153
+ return {
154
+ routes: raw.routes ?? [],
155
+ entry: resolve(root, raw.entry ?? "src/entry-server.tsx")
156
+ };
157
+ }
158
+ async function loadConfig(root, overrides = {}, defaultMode = "production") {
159
+ const absoluteRoot = resolve(root);
160
+ let file;
161
+ let loaded = {};
162
+ for (const candidate of CONFIG_FILES) {
163
+ const path = join(absoluteRoot, candidate);
164
+ if (existsSync(path)) {
165
+ file = path;
166
+ loaded = await importConfigFile(path, absoluteRoot);
167
+ break;
168
+ }
169
+ }
170
+ const merged = {
171
+ ...loaded,
172
+ ...overrides,
173
+ server: { ...loaded.server, ...overrides.server },
174
+ build: { ...loaded.build, ...overrides.build },
175
+ alias: { ...loaded.alias, ...overrides.alias },
176
+ define: { ...loaded.define, ...overrides.define }
177
+ };
178
+ const base = merged.base ?? "/";
179
+ const projectRoot = merged.root === void 0 ? absoluteRoot : resolve(absoluteRoot, merged.root);
180
+ const mode = merged.mode ?? defaultMode;
181
+ const envPrefix = merged.envPrefix ?? "ODORO_";
182
+ const envDir = merged.envDir === void 0 ? projectRoot : resolve(projectRoot, merged.envDir);
183
+ const environment = await loadEnv(envDir, mode, envPrefix);
184
+ for (const [key, value] of Object.entries(environment.all)) {
185
+ process.env[key] ??= value;
186
+ }
187
+ const https = merged.server?.https;
188
+ return {
189
+ root: projectRoot,
190
+ base: base.endsWith("/") ? base : `${base}/`,
191
+ publicDir: resolve(projectRoot, merged.publicDir ?? "public"),
192
+ outDir: resolve(projectRoot, merged.build?.outDir ?? "dist"),
193
+ server: {
194
+ port: merged.server?.port ?? 5180,
195
+ host: merged.server?.host ?? "localhost",
196
+ proxy: merged.server?.proxy ?? {},
197
+ https: https === void 0 ? void 0 : { ...https },
198
+ strictPort: merged.server?.strictPort ?? false,
199
+ open: merged.server?.open ?? false
200
+ },
201
+ build: {
202
+ outDir: merged.build?.outDir ?? "dist",
203
+ minify: merged.build?.minify ?? true,
204
+ sourcemap: merged.build?.sourcemap ?? true,
205
+ target: merged.build?.target ?? "es2022",
206
+ // On by default: a stylesheet holding every possible class is a
207
+ // generation accident, not an intention.
208
+ prune: merged.build?.prune ?? true,
209
+ safelist: merged.build?.safelist ?? [],
210
+ // On by default: the manifest only costs a file of a few lines, and
211
+ // preloading removes a cascade of requests nobody sees on a local machine
212
+ // and everybody suffers elsewhere.
213
+ manifest: merged.build?.manifest ?? true,
214
+ preload: merged.build?.preload ?? true,
215
+ prerender: resolvePrerender(merged.build?.prerender, projectRoot)
216
+ },
217
+ // The aliases declared in `tsconfig.json` are picked up automatically.
218
+ // Without that, a project following `odoro init` — which infers its prefix
219
+ // from the tsconfig — would have to redeclare the same alias here for the
220
+ // server to resolve it. Two places for the same truth, and an error that
221
+ // only shows up on the first import.
222
+ //
223
+ // The configuration wins: it is what you write to fix a case the inference
224
+ // does not catch.
225
+ alias: { ...await guessAliasPaths(projectRoot), ...merged.alias },
226
+ define: merged.define ?? {},
227
+ envPrefix,
228
+ envDir,
229
+ mode,
230
+ env: environment.all,
231
+ envClient: clientEnv(
232
+ environment.client,
233
+ mode,
234
+ base.endsWith("/") ? base : `${base}/`
235
+ ),
236
+ plugins: merged.plugins ?? [],
237
+ configFile: file
238
+ };
239
+ }
240
+
241
+ export { clientEnv, defineConfig, loadConfig, loadEnv };