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.
- package/README.md +73 -0
- package/dist/build-KI7IEVRJ.js +4 -0
- package/dist/{chunk-R6PMAMXA.js → chunk-2EE5QUCW.js} +16 -3
- package/dist/{chunk-CJIUP7A3.js → chunk-FJYUQALD.js} +1 -1
- package/dist/cli.js +4 -4
- package/dist/{create-LTT3SAWT.js → create-VUSKHXBN.js} +109 -65
- package/dist/index.js +2 -2
- package/dist/{package-LK46RV2I.js → package-2JOBLFXE.js} +3 -2
- package/dist/registry/index.d.ts +2 -2
- package/dist/{server-ATGFRVSW.js → server-DXOQAPVX.js} +1 -1
- package/package.json +3 -2
- package/templates/react-ts/_variantes/avec-moteur/src/{sections/Fond.tsx → fond.tsx} +13 -13
- package/templates/react-ts/_variantes/sans-libs/src/App.tsx +363 -23
- package/templates/{react-ts-server/_variantes/sans-libs/client/src/sections/Fond.tsx → react-ts/_variantes/sans-libs/src/fond.tsx} +1 -1
- package/templates/react-ts/_variantes/sans-libs/src/styles.css +115 -38
- package/templates/react-ts/_variantes/sans-routeur/src/App.tsx +427 -22
- package/templates/react-ts/index.html +11 -0
- package/templates/react-ts/public/favicon.svg +2 -3
- package/templates/react-ts/src/App.tsx +585 -57
- package/templates/{react-ts-server/client/src/sections/Fond.tsx → react-ts/src/fond.tsx} +9 -9
- package/templates/react-ts/src/router.tsx +72 -0
- package/templates/react-ts-server/_variantes/avec-moteur/client/src/{sections/Fond.tsx → fond.tsx} +13 -13
- package/templates/react-ts-server/_variantes/sans-libs/client/src/App.tsx +363 -23
- package/templates/{react-ts/_variantes/sans-libs/src/sections/Fond.tsx → react-ts-server/_variantes/sans-libs/client/src/fond.tsx} +1 -1
- package/templates/react-ts-server/_variantes/sans-libs/client/src/styles.css +115 -38
- package/templates/react-ts-server/_variantes/sans-routeur/client/src/App.tsx +427 -22
- package/templates/react-ts-server/client/index.html +11 -0
- package/templates/react-ts-server/client/public/favicon.svg +2 -3
- package/templates/react-ts-server/client/src/App.tsx +585 -57
- package/templates/{react-ts/src/sections/Fond.tsx → react-ts-server/client/src/fond.tsx} +9 -9
- package/templates/react-ts-server/client/src/router.tsx +72 -0
- package/dist/build-GIPMPYJ3.js +0 -4
- package/templates/react-ts/_variantes/sans-libs/src/composants/Marque.tsx +0 -37
- package/templates/react-ts/_variantes/sans-libs/src/sections/Cloture.tsx +0 -60
- package/templates/react-ts/_variantes/sans-libs/src/sections/Hero.tsx +0 -92
- package/templates/react-ts/_variantes/sans-libs/src/sections/Piliers.tsx +0 -44
- package/templates/react-ts/src/composants/Marque.tsx +0 -50
- package/templates/react-ts/src/routes/About.tsx +0 -43
- package/templates/react-ts/src/routes/Home.tsx +0 -28
- package/templates/react-ts/src/routes/NotFound.tsx +0 -14
- package/templates/react-ts/src/sections/Cloture.tsx +0 -69
- package/templates/react-ts/src/sections/Hero.tsx +0 -119
- package/templates/react-ts/src/sections/Piliers.tsx +0 -68
- package/templates/react-ts-server/_variantes/sans-libs/client/src/composants/Marque.tsx +0 -37
- package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Cloture.tsx +0 -60
- package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Hero.tsx +0 -92
- package/templates/react-ts-server/_variantes/sans-libs/client/src/sections/Piliers.tsx +0 -44
- package/templates/react-ts-server/client/src/composants/Marque.tsx +0 -50
- package/templates/react-ts-server/client/src/routes/About.tsx +0 -43
- package/templates/react-ts-server/client/src/routes/Home.tsx +0 -28
- package/templates/react-ts-server/client/src/routes/NotFound.tsx +0 -14
- package/templates/react-ts-server/client/src/sections/Cloture.tsx +0 -69
- package/templates/react-ts-server/client/src/sections/Hero.tsx +0 -119
- 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`.
|
|
@@ -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" ? {
|
|
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(
|
|
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(
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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: "
|
|
16
|
-
hint: "
|
|
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: "
|
|
23
|
-
hint: "
|
|
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: "
|
|
29
|
-
hint: "
|
|
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: "
|
|
36
|
-
hint: "WebGL, surfaces
|
|
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: "
|
|
43
|
-
hint: "
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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] === "
|
|
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: `
|
|
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
|
|
236
|
-
await rm(join(options.target,
|
|
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": "
|
|
261
|
-
"react-ts-server": "Client
|
|
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: "
|
|
269
|
+
message: "Database",
|
|
267
270
|
initialValue: "url",
|
|
268
271
|
options: [
|
|
269
272
|
{
|
|
270
273
|
value: "provider",
|
|
271
|
-
label: "
|
|
272
|
-
hint: "
|
|
274
|
+
label: "Odoro provider",
|
|
275
|
+
hint: "automatic provisioning \u2014 coming soon"
|
|
273
276
|
},
|
|
274
277
|
{
|
|
275
278
|
value: "url",
|
|
276
|
-
label: "
|
|
277
|
-
hint: "Neon, Supabase, RDS,
|
|
279
|
+
label: "Existing PostgreSQL URL",
|
|
280
|
+
hint: "Neon, Supabase, RDS, your own"
|
|
278
281
|
},
|
|
279
|
-
{ value: "later", label: "
|
|
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
|
|
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: "
|
|
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("
|
|
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(
|
|
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: "
|
|
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
|
-
`
|
|
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: `
|
|
421
|
+
message: `Folder "${basename(target)}" is not empty.`,
|
|
371
422
|
options: [
|
|
372
|
-
{ value: "annuler", label: "
|
|
373
|
-
{ value: "fusionner", label: "
|
|
374
|
-
{ value: "ecraser", label: "
|
|
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: "
|
|
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 ? "
|
|
460
|
+
hint: name === detected ? "detected" : void 0
|
|
412
461
|
}))
|
|
413
462
|
})
|
|
414
463
|
));
|
|
415
464
|
if (!PACKAGE_MANAGERS.includes(manager)) {
|
|
416
|
-
prompts.cancel(`
|
|
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: "
|
|
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: `
|
|
472
|
+
message: `Install dependencies with ${manager}?`
|
|
424
473
|
})
|
|
425
474
|
));
|
|
426
475
|
const spinner2 = prompts.spinner();
|
|
427
|
-
spinner2.start("
|
|
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(
|
|
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("
|
|
492
|
+
prompts.log.success("Git repository initialized.");
|
|
442
493
|
} catch {
|
|
443
|
-
prompts.log.warn("git
|
|
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
|
|
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
|
-
"
|
|
509
|
+
"The registry could not be configured. Run `odoro init` in the project."
|
|
459
510
|
);
|
|
460
511
|
}
|
|
461
512
|
}
|
|
462
|
-
|
|
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
|
-
|
|
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"), "
|
|
481
|
-
prompts.outro(colors.green("
|
|
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-
|
|
6
|
-
export { ModuleGraph, depFileName, detectSelfAccepting, optimizeDeps, scanDependencies, startDevServer } from './chunk-
|
|
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.
|
|
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": "^
|
|
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",
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -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>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "odoro",
|
|
3
|
-
"version": "1.0.
|
|
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": "^
|
|
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",
|