odoro 1.0.1 → 1.0.3

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 (54) hide show
  1. package/README.md +73 -0
  2. package/dist/build-KI7IEVRJ.js +4 -0
  3. package/dist/{chunk-R6PMAMXA.js → chunk-2EE5QUCW.js} +16 -3
  4. package/dist/{chunk-CJIUP7A3.js → chunk-FJYUQALD.js} +1 -1
  5. package/dist/cli.js +4 -4
  6. package/dist/{create-LTT3SAWT.js → create-VUSKHXBN.js} +109 -65
  7. package/dist/index.js +2 -2
  8. package/dist/{package-LK46RV2I.js → package-2JOBLFXE.js} +3 -2
  9. package/dist/registry/index.d.ts +2 -2
  10. package/dist/{server-ATGFRVSW.js → server-DXOQAPVX.js} +1 -1
  11. package/package.json +3 -2
  12. package/templates/react-ts/_variantes/avec-moteur/src/{sections/Fond.tsx → fond.tsx} +13 -13
  13. package/templates/react-ts/_variantes/sans-libs/src/App.tsx +363 -23
  14. package/templates/{react-ts-server/_variantes/sans-libs/client/src/sections/Fond.tsx → react-ts/_variantes/sans-libs/src/fond.tsx} +1 -1
  15. package/templates/react-ts/_variantes/sans-libs/src/styles.css +115 -38
  16. package/templates/react-ts/_variantes/sans-routeur/src/App.tsx +427 -22
  17. package/templates/react-ts/index.html +11 -0
  18. package/templates/react-ts/public/favicon.svg +2 -3
  19. package/templates/react-ts/src/App.tsx +585 -57
  20. package/templates/{react-ts-server/client/src/sections/Fond.tsx → react-ts/src/fond.tsx} +9 -9
  21. package/templates/react-ts/src/router.tsx +72 -0
  22. package/templates/react-ts-server/_variantes/avec-moteur/client/src/{sections/Fond.tsx → fond.tsx} +13 -13
  23. package/templates/react-ts-server/_variantes/sans-libs/client/src/App.tsx +363 -23
  24. package/templates/{react-ts/_variantes/sans-libs/src/sections/Fond.tsx → react-ts-server/_variantes/sans-libs/client/src/fond.tsx} +1 -1
  25. package/templates/react-ts-server/_variantes/sans-libs/client/src/styles.css +115 -38
  26. package/templates/react-ts-server/_variantes/sans-routeur/client/src/App.tsx +427 -22
  27. package/templates/react-ts-server/client/index.html +11 -0
  28. package/templates/react-ts-server/client/public/favicon.svg +2 -3
  29. package/templates/react-ts-server/client/src/App.tsx +585 -57
  30. package/templates/{react-ts/src/sections/Fond.tsx → react-ts-server/client/src/fond.tsx} +9 -9
  31. package/templates/react-ts-server/client/src/router.tsx +72 -0
  32. package/dist/build-GIPMPYJ3.js +0 -4
  33. package/templates/react-ts/_variantes/sans-libs/src/composants/Marque.tsx +0 -37
  34. package/templates/react-ts/_variantes/sans-libs/src/sections/Cloture.tsx +0 -60
  35. package/templates/react-ts/_variantes/sans-libs/src/sections/Hero.tsx +0 -92
  36. package/templates/react-ts/_variantes/sans-libs/src/sections/Piliers.tsx +0 -44
  37. package/templates/react-ts/src/composants/Marque.tsx +0 -50
  38. package/templates/react-ts/src/routes/About.tsx +0 -43
  39. package/templates/react-ts/src/routes/Home.tsx +0 -28
  40. package/templates/react-ts/src/routes/NotFound.tsx +0 -14
  41. package/templates/react-ts/src/sections/Cloture.tsx +0 -69
  42. package/templates/react-ts/src/sections/Hero.tsx +0 -119
  43. package/templates/react-ts/src/sections/Piliers.tsx +0 -68
  44. package/templates/react-ts-server/_variantes/sans-libs/client/src/composants/Marque.tsx +0 -37
  45. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Cloture.tsx +0 -60
  46. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Hero.tsx +0 -92
  47. package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Piliers.tsx +0 -44
  48. package/templates/react-ts-server/client/src/composants/Marque.tsx +0 -50
  49. package/templates/react-ts-server/client/src/routes/About.tsx +0 -43
  50. package/templates/react-ts-server/client/src/routes/Home.tsx +0 -28
  51. package/templates/react-ts-server/client/src/routes/NotFound.tsx +0 -14
  52. package/templates/react-ts-server/client/src/sections/Cloture.tsx +0 -69
  53. package/templates/react-ts-server/client/src/sections/Hero.tsx +0 -119
  54. package/templates/react-ts-server/client/src/sections/Piliers.tsx +0 -68
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # odoro
2
+
3
+ The Odoro engine: a development server with hot reload, a production build, and
4
+ the component registry client.
5
+
6
+ ```sh
7
+ npm create odoro@latest
8
+ ```
9
+
10
+ That single command scaffolds a project and installs everything below. This
11
+ package is what it installs.
12
+
13
+ ## Commands
14
+
15
+ | Command | What it does |
16
+ | ---------------- | --------------------------------------------------------- |
17
+ | `odoro dev` | Development server with hot module replacement. |
18
+ | `odoro build` | Production build into `dist/`. |
19
+ | `odoro preview` | Serves `dist/` the way a static host would. |
20
+ | `odoro create` | Scaffolds a project — same thing as `npm create odoro`. |
21
+ | `odoro init` | Writes `odoro.json` so `odoro add` knows where to write. |
22
+ | `odoro add <id>` | Copies a registry component into your project. |
23
+ | `odoro list` | Prints the registry catalogue. |
24
+ | `odoro diff` | Compares what is installed with what the registry serves. |
25
+ | `odoro doctor` | Checks that the project is in a fit state. |
26
+
27
+ Run `odoro --help` for the full list, including the database commands.
28
+
29
+ ## Configuration
30
+
31
+ ```ts
32
+ // odoro.config.ts
33
+ import { defineConfig } from 'odoro'
34
+
35
+ export default defineConfig({
36
+ alias: { '@': 'src' },
37
+ server: { port: 5180 },
38
+ })
39
+ ```
40
+
41
+ ## The registry is not a dependency
42
+
43
+ `odoro add text/count-up` **copies the source into your project**. The code is
44
+ then yours: read it, change it, delete it. Nothing updates behind your back, and
45
+ there is no package to keep in step.
46
+
47
+ ```sh
48
+ odoro add text/count-up
49
+ # + src/odoro/hooks/useInView.ts
50
+ # + src/odoro/text/CountUp.tsx
51
+ ```
52
+
53
+ Entries that need an npm package say so, and `odoro add` tells you which one is
54
+ missing before you find out at build time.
55
+
56
+ ## Hot reload keeps your state
57
+
58
+ Editing a component swaps its code without unmounting the tree: a counter's
59
+ value, the text in a field, the open tab all survive the edit. A stylesheet is
60
+ swapped without a reload.
61
+
62
+ A module that exports something other than components reloads the page, and that
63
+ is correct — nothing would let us propagate the change safely.
64
+
65
+ ## Links
66
+
67
+ - Documentation — <https://odoro.dev/docs>
68
+ - Component registry — <https://odoro.dev/docs/registry>
69
+ - Source — <https://github.com/ODORO-CLI/OdoroKit>
70
+
71
+ ## Licence
72
+
73
+ UNLICENSED. Copyright (c) BouBouw. See `LICENSE`.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ export { buildProject, reportBuild } from './chunk-FJYUQALD.js';
3
+ import './chunk-2EE5QUCW.js';
4
+ import './chunk-JMEHF3KN.js';
@@ -34,7 +34,9 @@ async function fournisseurDe(root) {
34
34
  // `generate` enumere les classes du palier courant. Absent d'un paquet
35
35
  // plus ancien : le champ reste alors indefini, et le developpement
36
36
  // retombe sur la feuille telle qu'elle est livree.
37
- ...typeof generate === "function" ? { classesConnues: () => new Set(generate("core").classNames) } : {}
37
+ ...typeof generate === "function" ? {
38
+ classesConnues: () => new Set(generate("core").classNames)
39
+ } : {}
38
40
  };
39
41
  } catch {
40
42
  return void 0;
@@ -720,6 +722,11 @@ async function applyReactRefresh(code, file) {
720
722
  // La carte de source produite par la compilation precedente est reprise et
721
723
  // fusionnee : sans cela, les numeros de ligne du debogueur designeraient le
722
724
  // code instrumente plutot que la source.
725
+ //
726
+ // `true` demande a Babel de lire la carte inline du code recu. Il l'accepte
727
+ // — verifie : la source reprise est bien le fichier d'origine — mais les
728
+ // types de la 7.x ne decrivent que la forme objet. L'annotation est
729
+ // incomplete, pas la valeur.
723
730
  inputSourceMap: true,
724
731
  sourceMaps: "inline",
725
732
  // `skipEnvCheck` leve un garde-fou destine aux configurations globales,
@@ -934,7 +941,9 @@ async function startDevServer(config) {
934
941
  const fournisseur = await fournisseurDe(config.root);
935
942
  const utilitaires = fournisseur?.classesConnues === void 0 ? void 0 : fournisseur.renderUtilitairesPour(fournisseur.classesConnues());
936
943
  if (utilitaires !== void 0) {
937
- info(`utilitaires de developpement : ${String(Math.round(utilitaires.length / 1024))} Ko`);
944
+ info(
945
+ `utilitaires de developpement : ${String(Math.round(utilitaires.length / 1024))} Ko`
946
+ );
938
947
  }
939
948
  const entries = extractEntries(await readFile(indexFile, "utf8"), config.root);
940
949
  const specifiers = await scanDependencies(config, entries);
@@ -1005,7 +1014,11 @@ async function startDevServer(config) {
1005
1014
  };
1006
1015
  const serveHtml = async (response) => {
1007
1016
  const html = await readFile(indexFile, "utf8");
1008
- send(response, injectClient(html, utilitaires !== void 0), MIME[".html"]);
1017
+ send(
1018
+ response,
1019
+ injectClient(html, utilitaires !== void 0),
1020
+ MIME[".html"]
1021
+ );
1009
1022
  };
1010
1023
  const forward = (incoming, response, target) => {
1011
1024
  const url2 = new URL(incoming.url ?? "/", target);
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { extractEntries, applyAlias, isBareSpecifier, fournisseurDe } from './chunk-R6PMAMXA.js';
2
+ import { extractEntries, applyAlias, isBareSpecifier, fournisseurDe } from './chunk-2EE5QUCW.js';
3
3
  import { info, colors, size, success, duration } from './chunk-JMEHF3KN.js';
4
4
  import { existsSync } from 'fs';
5
5
  import { readFile, rm, mkdir, writeFile, cp, stat } from 'fs/promises';
package/dist/cli.js CHANGED
@@ -131,7 +131,7 @@ function rootFrom(flags, positional) {
131
131
  async function run(argv) {
132
132
  const { command, positional, flags } = parseArgs(argv);
133
133
  if (flags["version"] === true) {
134
- const manifest = await import('./package-LK46RV2I.js');
134
+ const manifest = await import('./package-2JOBLFXE.js');
135
135
  console.log(manifest.default.version);
136
136
  return 0;
137
137
  }
@@ -142,7 +142,7 @@ async function run(argv) {
142
142
  switch (command) {
143
143
  case "create":
144
144
  case "new": {
145
- const { createCommand } = await import('./create-LTT3SAWT.js');
145
+ const { createCommand } = await import('./create-VUSKHXBN.js');
146
146
  const options = {};
147
147
  if (positional[0] !== void 0) options.name = positional[0];
148
148
  if (typeof flags["template"] === "string") options.template = flags["template"];
@@ -156,13 +156,13 @@ async function run(argv) {
156
156
  return createCommand(options);
157
157
  }
158
158
  case "dev": {
159
- const { startDevServer } = await import('./server-ATGFRVSW.js');
159
+ const { startDevServer } = await import('./server-DXOQAPVX.js');
160
160
  const config = await loadConfig(rootFrom(flags, positional), overridesFrom(flags));
161
161
  await startDevServer(config);
162
162
  return new Promise(() => void 0);
163
163
  }
164
164
  case "build": {
165
- const { buildProject, reportBuild } = await import('./build-GIPMPYJ3.js');
165
+ const { buildProject, reportBuild } = await import('./build-KI7IEVRJ.js');
166
166
  const config = await loadConfig(rootFrom(flags, positional), overridesFrom(flags));
167
167
  const output = await buildProject(config);
168
168
  reportBuild(output, process.cwd());
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { writeDatabaseUrl, assertEnvIgnored, PROVIDER_PENDING, checkDatabaseUrl } from './chunk-3SZIN6VG.js';
3
- import { execSync } from 'child_process';
3
+ import { execSync, spawn } from 'child_process';
4
4
  import { existsSync, statSync, readdirSync, readFileSync } from 'fs';
5
5
  import { resolve, basename, dirname, join } from 'path';
6
6
  import * as prompts from '@clack/prompts';
@@ -12,35 +12,35 @@ import { fileURLToPath } from 'url';
12
12
  var MODULES = [
13
13
  {
14
14
  id: "libs",
15
- label: "Bibliotheques",
16
- hint: "style, jetons, interface et animations",
15
+ label: "Libraries",
16
+ hint: "styles, tokens, UI and motion",
17
17
  defaut: true,
18
18
  paquet: "@odoro-cli/libs"
19
19
  },
20
20
  {
21
21
  id: "router",
22
- label: "Routeur",
23
- hint: "vient avec les bibliotheques \u2014 cable les pages",
22
+ label: "Router",
23
+ hint: "ships with the libraries \u2014 wires up the pages",
24
24
  defaut: true
25
25
  },
26
26
  {
27
27
  id: "icons",
28
- label: "Icones",
29
- hint: "cinq familles, importables une a une",
28
+ label: "Icons",
29
+ hint: "five families, imported one by one",
30
30
  defaut: true,
31
31
  paquet: "@odoro-cli/icons"
32
32
  },
33
33
  {
34
34
  id: "engine",
35
- label: "Moteur",
36
- hint: "WebGL, surfaces et politique de mouvement",
35
+ label: "Engine",
36
+ hint: "WebGL, surfaces and motion policy",
37
37
  defaut: false,
38
38
  paquet: "@odoro-cli/engine"
39
39
  },
40
40
  {
41
41
  id: "registre",
42
- label: "Registre de composants",
43
- hint: "copies par `odoro add` \u2014 entraine le moteur",
42
+ label: "Component registry",
43
+ hint: "copied by `odoro add` \u2014 pulls in the engine",
44
44
  defaut: false
45
45
  }
46
46
  ];
@@ -54,13 +54,13 @@ function resoudre(selection) {
54
54
  if (choisis.has("router") && !choisis.has("libs")) {
55
55
  choisis.delete("router");
56
56
  avertissements.push(
57
- "Le routeur vient des bibliotheques (@odoro-cli/libs/router) : sans elles, il est retire."
57
+ "The router lives in the libraries (@odoro-cli/libs/router) \u2014 without them it is dropped."
58
58
  );
59
59
  }
60
60
  if (choisis.has("registre") && !choisis.has("engine")) {
61
61
  choisis.add("engine");
62
62
  avertissements.push(
63
- "Presque toutes les entrees du registre importent @odoro-cli/engine : le moteur est ajoute."
63
+ "Almost every registry entry imports @odoro-cli/engine, so the engine was added."
64
64
  );
65
65
  }
66
66
  return { modules: MODULE_IDS.filter((id) => choisis.has(id)), avertissements };
@@ -84,11 +84,13 @@ function gardeLesRoutes(modules) {
84
84
  }
85
85
  function lireModules(valeur) {
86
86
  const brut = valeur.split(",").map((part) => part.trim()).filter((part) => part !== "");
87
- if (brut.length === 1 && brut[0] === "aucun") return { modules: [] };
87
+ if (brut.length === 1 && (brut[0] === "none" || brut[0] === "aucun")) {
88
+ return { modules: [] };
89
+ }
88
90
  const inconnu = brut.find((part) => !MODULE_IDS.includes(part));
89
91
  if (inconnu !== void 0) {
90
92
  return {
91
- erreur: `Module inconnu : "${inconnu}". Disponibles : ${MODULE_IDS.join(", ")}, ou "aucun".`
93
+ erreur: `Unknown module: "${inconnu}". Available: ${MODULE_IDS.join(", ")}, or "none".`
92
94
  };
93
95
  }
94
96
  return { modules: brut };
@@ -232,8 +234,8 @@ async function scaffold(options) {
232
234
  const files = [];
233
235
  await copyDirectory(source, options.target, files);
234
236
  if (!gardeLesRoutes(modules)) {
235
- for (const dossier of ["src/routes", "client/src/routes"]) {
236
- await rm(join(options.target, dossier), { recursive: true, force: true });
237
+ for (const fichier of ["src/router.tsx", "client/src/router.tsx"]) {
238
+ await rm(join(options.target, fichier), { force: true });
237
239
  }
238
240
  }
239
241
  const poses = [];
@@ -246,37 +248,38 @@ async function scaffold(options) {
246
248
  options.version ?? cliVersion(),
247
249
  modules
248
250
  );
251
+ const retires = /* @__PURE__ */ new Set(["src/router.tsx", "client/src/router.tsx"]);
249
252
  const listes = /* @__PURE__ */ new Set([
250
- ...files.filter(
251
- (f) => !f.startsWith("src/routes/") && !f.startsWith("client/src/routes/")
252
- ),
253
+ ...files.filter((f) => gardeLesRoutes(modules) || !retires.has(f)),
253
254
  ...poses
254
255
  ]);
255
256
  return { files: [...listes].sort() };
256
257
  }
257
258
 
258
259
  // src/commands/create.ts
260
+ var DERNIERES_LIGNES = 8;
261
+ var LARGEUR_LIGNE = 64;
259
262
  var TEMPLATE_LABELS = {
260
- "react-ts": "Application monopage \u2014 React, TypeScript, routeur et animations Odoro",
261
- "react-ts-server": "Client et serveur \u2014 la meme application, plus un socle @odoro-cli/server modulaire et un Dockerfile"
263
+ "react-ts": "Single-page app \u2014 React, TypeScript, Odoro router and motion",
264
+ "react-ts-server": "Client and server \u2014 the same app, plus a modular @odoro-cli/server base and a Dockerfile"
262
265
  };
263
266
  async function askDatabase() {
264
267
  const choice = ensure(
265
268
  await prompts.select({
266
- message: "Base de donnees",
269
+ message: "Database",
267
270
  initialValue: "url",
268
271
  options: [
269
272
  {
270
273
  value: "provider",
271
- label: "Fournisseur Odoro",
272
- hint: "provisionnement automatique \u2014 bientot"
274
+ label: "Odoro provider",
275
+ hint: "automatic provisioning \u2014 coming soon"
273
276
  },
274
277
  {
275
278
  value: "url",
276
- label: "URL PostgreSQL existante",
277
- hint: "Neon, Supabase, RDS, la votre"
279
+ label: "Existing PostgreSQL URL",
280
+ hint: "Neon, Supabase, RDS, your own"
278
281
  },
279
- { value: "later", label: "Configurer plus tard", hint: ".env.example seul" }
282
+ { value: "later", label: "Set up later", hint: ".env.example only" }
280
283
  ]
281
284
  })
282
285
  );
@@ -292,7 +295,7 @@ async function askDatabase() {
292
295
  }
293
296
  const url = ensure(
294
297
  await prompts.text({
295
- message: "URL PostgreSQL",
298
+ message: "PostgreSQL URL",
296
299
  placeholder: "postgres://utilisateur:motdepasse@hote:5432/base?sslmode=require",
297
300
  validate: (value) => checkDatabaseUrl(value ?? "")
298
301
  })
@@ -317,7 +320,7 @@ async function askModules(options) {
317
320
  if (options.yes === true) return MODULES_PAR_DEFAUT;
318
321
  const choisis = ensure(
319
322
  await prompts.multiselect({
320
- message: "Que met-on dans le projet ?",
323
+ message: "What goes in the project?",
321
324
  initialValues: [...MODULES_PAR_DEFAUT],
322
325
  required: false,
323
326
  options: MODULES.map((m) => ({ value: m.id, label: m.label, hint: m.hint }))
@@ -329,9 +332,55 @@ function annoncer(resolution) {
329
332
  for (const mot of resolution.avertissements) prompts.log.warn(mot);
330
333
  return resolution.modules;
331
334
  }
335
+ async function installerDependances(target, manager) {
336
+ const [commande, ...args] = installCommand(manager).split(" ");
337
+ if (commande === void 0) return false;
338
+ const barre = prompts.spinner({ indicator: "timer" });
339
+ barre.start(`Installing dependencies with ${manager}`);
340
+ const fin = [];
341
+ const garder = (bloc) => {
342
+ for (const ligne of bloc.split("\n")) {
343
+ const propre = ligne.trim();
344
+ if (propre === "" || !/[a-z0-9]/i.test(propre)) continue;
345
+ fin.push(propre);
346
+ if (fin.length > DERNIERES_LIGNES) fin.shift();
347
+ barre.message(`${manager} \xB7 ${propre.slice(0, LARGEUR_LIGNE)}`);
348
+ }
349
+ };
350
+ const code = await new Promise((resolve_) => {
351
+ const processus = spawn(commande, args, {
352
+ cwd: target,
353
+ shell: process.platform === "win32"
354
+ });
355
+ processus.stdout?.setEncoding("utf8").on("data", garder);
356
+ processus.stderr?.setEncoding("utf8").on("data", garder);
357
+ processus.on("error", () => {
358
+ resolve_(-1);
359
+ });
360
+ processus.on("close", (sortie) => {
361
+ resolve_(sortie ?? -1);
362
+ });
363
+ });
364
+ if (code === 0) {
365
+ barre.stop(`Dependencies installed with ${manager}`);
366
+ return true;
367
+ }
368
+ barre.stop(`${manager} install failed`, 1);
369
+ for (const ligne of fin) prompts.log.error(colors.dim(ligne));
370
+ return false;
371
+ }
372
+ function versionCli() {
373
+ try {
374
+ const manifeste = join(dirname(templatesRoot()), "package.json");
375
+ const { version } = JSON.parse(readFileSync(manifeste, "utf8"));
376
+ return version;
377
+ } catch {
378
+ return "?";
379
+ }
380
+ }
332
381
  function ensure(value) {
333
382
  if (prompts.isCancel(value)) {
334
- prompts.cancel("Creation annulee.");
383
+ prompts.cancel("Cancelled.");
335
384
  process.exit(0);
336
385
  }
337
386
  return value;
@@ -340,10 +389,12 @@ async function createCommand(options) {
340
389
  const root = templatesRoot();
341
390
  const templates = availableTemplates(root);
342
391
  const defaultTemplate = templates[0] ?? "react-ts";
343
- prompts.intro(colors.bold(colors.magenta(" odoro ")));
392
+ prompts.intro(
393
+ `${colors.bgBlue(colors.black(" ODORO "))} ${colors.dim(`v${versionCli()}`)}`
394
+ );
344
395
  const rawName = options.name ?? (options.yes === true ? "odoro-app" : ensure(
345
396
  await prompts.text({
346
- message: "Nom du projet",
397
+ message: "Project name",
347
398
  placeholder: "mon-site",
348
399
  defaultValue: "odoro-app",
349
400
  validate: (value) => value === "" ? void 0 : validatePackageName(toPackageName(value))
@@ -361,17 +412,17 @@ async function createCommand(options) {
361
412
  if (state === "occupe" && overwrite === void 0) {
362
413
  if (options.yes === true) {
363
414
  prompts.cancel(
364
- `Le dossier "${basename(target)}" n'est pas vide. Precisez --overwrite ou --merge.`
415
+ `Folder "${basename(target)}" is not empty. Pass --overwrite or --merge.`
365
416
  );
366
417
  return 1;
367
418
  }
368
419
  const choice = ensure(
369
420
  await prompts.select({
370
- message: `Le dossier "${basename(target)}" n'est pas vide.`,
421
+ message: `Folder "${basename(target)}" is not empty.`,
371
422
  options: [
372
- { value: "annuler", label: "Annuler" },
373
- { value: "fusionner", label: "Fusionner \u2014 ecrase les fichiers de meme nom" },
374
- { value: "ecraser", label: "Vider le dossier puis creer le projet" }
423
+ { value: "annuler", label: "Cancel" },
424
+ { value: "fusionner", label: "Merge \u2014 overwrites files of the same name" },
425
+ { value: "ecraser", label: "Empty the folder, then create the project" }
375
426
  ]
376
427
  })
377
428
  );
@@ -393,9 +444,7 @@ async function createCommand(options) {
393
444
  })
394
445
  ));
395
446
  if (!templates.includes(template)) {
396
- prompts.cancel(
397
- `Template inconnu : "${template}". Disponibles : ${templates.join(", ")}.`
398
- );
447
+ prompts.cancel(`Unknown template: "${template}". Available: ${templates.join(", ")}.`);
399
448
  return 1;
400
449
  }
401
450
  const modules = await askModules(options);
@@ -403,28 +452,28 @@ async function createCommand(options) {
403
452
  const detected = detectPackageManager();
404
453
  const manager = options.pm ?? (options.yes === true ? detected : ensure(
405
454
  await prompts.select({
406
- message: "Gestionnaire de paquets",
455
+ message: "Package manager",
407
456
  initialValue: detected,
408
457
  options: PACKAGE_MANAGERS.map((name) => ({
409
458
  value: name,
410
459
  label: name,
411
- hint: name === detected ? "detecte" : void 0
460
+ hint: name === detected ? "detected" : void 0
412
461
  }))
413
462
  })
414
463
  ));
415
464
  if (!PACKAGE_MANAGERS.includes(manager)) {
416
- prompts.cancel(`Gestionnaire inconnu : "${manager}".`);
465
+ prompts.cancel(`Unknown package manager: "${manager}".`);
417
466
  return 1;
418
467
  }
419
468
  const database = template === "react-ts-server" && options.yes !== true ? await askDatabase() : void 0;
420
- const withGit = options.git ?? (options.yes === true ? true : ensure(await prompts.confirm({ message: "Initialiser un depot git ?" })));
469
+ const withGit = options.git ?? (options.yes === true ? true : ensure(await prompts.confirm({ message: "Initialize a git repository?" })));
421
470
  const withInstall = options.install ?? (options.yes === true ? true : ensure(
422
471
  await prompts.confirm({
423
- message: `Installer les dependances avec ${manager} ?`
472
+ message: `Install dependencies with ${manager}?`
424
473
  })
425
474
  ));
426
475
  const spinner2 = prompts.spinner();
427
- spinner2.start("Creation du projet");
476
+ spinner2.start("Writing files");
428
477
  const scaffoldOptions = {
429
478
  target,
430
479
  template,
@@ -434,18 +483,20 @@ async function createCommand(options) {
434
483
  if (overwrite !== void 0) scaffoldOptions.overwrite = overwrite;
435
484
  scaffoldOptions.modules = modules;
436
485
  const { files } = await scaffold(scaffoldOptions);
437
- spinner2.stop(`${files.length} fichiers ecrits dans ${colors.cyan(basename(target))}`);
486
+ spinner2.stop(
487
+ `${String(files.length)} files written to ${colors.cyan(basename(target))}`
488
+ );
438
489
  if (withGit && !existsSync(resolve(target, ".git"))) {
439
490
  try {
440
491
  execSync("git init -q", { cwd: target, stdio: "ignore" });
441
- prompts.log.success("Depot git initialise.");
492
+ prompts.log.success("Git repository initialized.");
442
493
  } catch {
443
- prompts.log.warn("git est introuvable : depot non initialise.");
494
+ prompts.log.warn("git was not found \u2014 repository not initialized.");
444
495
  }
445
496
  }
446
497
  if (database?.url !== void 0) {
447
498
  await writeDatabaseUrl(target, database.url);
448
- prompts.log.success("URL de base ecrite dans .env");
499
+ prompts.log.success("Database URL written to .env");
449
500
  const risque = await assertEnvIgnored(target);
450
501
  if (risque !== void 0) prompts.log.warn(risque);
451
502
  }
@@ -455,30 +506,23 @@ async function createCommand(options) {
455
506
  const code = await initCommand({ root: target, yes: true });
456
507
  if (code !== 0) {
457
508
  prompts.log.warn(
458
- "Le registre n a pas pu etre configure. Relancez `odoro init` dans le projet."
509
+ "The registry could not be configured. Run `odoro init` in the project."
459
510
  );
460
511
  }
461
512
  }
462
- if (withInstall) {
463
- const install = prompts.spinner();
464
- install.start(`Installation avec ${manager}`);
465
- try {
466
- execSync(installCommand(manager), { cwd: target, stdio: "ignore" });
467
- install.stop("Dependances installees.");
468
- } catch {
469
- install.stop("Installation echouee \u2014 a relancer a la main.");
470
- }
471
- }
513
+ const installe = withInstall ? await installerDependances(target, manager) : false;
472
514
  const steps = [
473
515
  `cd ${basename(target)}`,
474
- ...withInstall ? [] : [installCommand(manager)],
516
+ // Si l'installation a echoue, la commande revient dans les etapes : le
517
+ // projet est ecrit, il ne lui manque que ses dependances.
518
+ ...installe ? [] : [installCommand(manager)],
475
519
  // `odoro.json` vient d'etre ecrit : ce qui reste a montrer, c'est la
476
520
  // commande qui s'en sert.
477
521
  ...modules.includes("registre") ? ["odoro add text/count-up"] : [],
478
522
  runCommand(manager, "dev")
479
523
  ];
480
- prompts.note(steps.join("\n"), "Prochaines etapes");
481
- prompts.outro(colors.green("Bon developpement."));
524
+ prompts.note(steps.join("\n"), "Next steps");
525
+ prompts.outro(colors.green("Happy building."));
482
526
  return 0;
483
527
  }
484
528
 
package/dist/index.js CHANGED
@@ -2,6 +2,6 @@
2
2
  export { startPreviewServer } from './chunk-34ES2ICQ.js';
3
3
  export { defineConfig, loadConfig } from './chunk-DL3NPC4H.js';
4
4
  import './chunk-T6RLHSCW.js';
5
- export { buildProject, reportBuild } from './chunk-CJIUP7A3.js';
6
- export { ModuleGraph, depFileName, detectSelfAccepting, optimizeDeps, scanDependencies, startDevServer } from './chunk-R6PMAMXA.js';
5
+ export { buildProject, reportBuild } from './chunk-FJYUQALD.js';
6
+ export { ModuleGraph, depFileName, detectSelfAccepting, optimizeDeps, scanDependencies, startDevServer } from './chunk-2EE5QUCW.js';
7
7
  import './chunk-JMEHF3KN.js';
@@ -2,7 +2,7 @@
2
2
  // package.json
3
3
  var package_default = {
4
4
  name: "odoro",
5
- version: "1.0.1",
5
+ version: "1.0.3",
6
6
  type: "module",
7
7
  license: "UNLICENSED",
8
8
  author: "BouBouw",
@@ -44,13 +44,14 @@ var package_default = {
44
44
  prepublishOnly: "pnpm run build"
45
45
  },
46
46
  dependencies: {
47
- "@babel/core": "^8.0.1",
47
+ "@babel/core": "^7.29.7",
48
48
  "@clack/prompts": "^0.11.0",
49
49
  esbuild: "^0.28.2",
50
50
  picocolors: "^1.1.1",
51
51
  "react-refresh": "^0.18.0"
52
52
  },
53
53
  devDependencies: {
54
+ "@types/babel__core": "^7.20.5",
54
55
  "@types/node": "^22.18.8",
55
56
  tsup: "^8.5.0",
56
57
  typescript: "^5.9.3",
@@ -94,10 +94,10 @@ declare const baseSchema: z.ZodMiniObject<{
94
94
  }>]>>;
95
95
  notes: z.ZodMiniOptional<z.ZodMiniString<string>>;
96
96
  fallback: z.ZodMiniOptional<z.ZodMiniEnum<{
97
+ none: "none";
97
98
  poster: "poster";
98
99
  gradient: "gradient";
99
100
  static: "static";
100
- none: "none";
101
101
  }>>;
102
102
  }, z.core.$strip>;
103
103
  }, z.core.$strip>;
@@ -165,10 +165,10 @@ declare const metaSchema: z.ZodMiniObject<{
165
165
  }>]>>;
166
166
  notes: z.ZodMiniOptional<z.ZodMiniString<string>>;
167
167
  fallback: z.ZodMiniOptional<z.ZodMiniEnum<{
168
+ none: "none";
168
169
  poster: "poster";
169
170
  gradient: "gradient";
170
171
  static: "static";
171
- none: "none";
172
172
  }>>;
173
173
  }, z.core.$strip>;
174
174
  }, z.core.$strip>;
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export { extractEntries, injectClient, startDevServer } from './chunk-R6PMAMXA.js';
2
+ export { extractEntries, injectClient, startDevServer } from './chunk-2EE5QUCW.js';
3
3
  import './chunk-JMEHF3KN.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odoro",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "author": "BouBouw",
@@ -35,13 +35,14 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@babel/core": "^8.0.1",
38
+ "@babel/core": "^7.29.7",
39
39
  "@clack/prompts": "^0.11.0",
40
40
  "esbuild": "^0.28.2",
41
41
  "picocolors": "^1.1.1",
42
42
  "react-refresh": "^0.18.0"
43
43
  },
44
44
  "devDependencies": {
45
+ "@types/babel__core": "^7.20.5",
45
46
  "@types/node": "^22.18.8",
46
47
  "tsup": "^8.5.0",
47
48
  "typescript": "^5.9.3",