odoro 1.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/client.d.ts +90 -16
- package/dist/build-XJIP4GNT.js +5 -0
- package/dist/{chunk-34RGOZFA.js → chunk-4D56Z7G3.js} +49 -50
- package/dist/{chunk-JMEHF3KN.js → chunk-7ZB5MAM6.js} +4 -4
- package/dist/chunk-DF67LADH.js +735 -0
- package/dist/{chunk-LHZGX5ML.js → chunk-HS7NGZLM.js} +307 -196
- package/dist/chunk-LIKVHWB4.js +231 -0
- package/dist/chunk-QOVBLN7A.js +241 -0
- package/dist/chunk-RTWJ5GFB.js +729 -0
- package/dist/chunk-TONYIKCN.js +57 -0
- package/dist/cli.d.ts +12 -13
- package/dist/cli.js +86 -63
- package/dist/{commands-AHMXBWQQ.js → commands-GYA7NTCX.js} +124 -124
- package/dist/commands-UOWN3IK4.js +181 -0
- package/dist/{create-CYVSVDAD.js → create-B2TLV6XI.js} +198 -160
- package/dist/index.d.ts +603 -151
- package/dist/index.js +6 -6
- package/dist/{package-EIDLKAA6.js → package-3ZJOEXM4.js} +6 -5
- package/dist/preview-3IRG7MHV.js +4 -0
- package/dist/registry/index.d.ts +75 -76
- package/dist/registry/index.js +1 -1
- package/dist/{server-4UGN3SFS.js → server-ZB3P3EGS.js} +3 -3
- package/package.json +6 -5
- package/templates/react-ts/README.md +71 -35
- package/templates/react-ts/_env.example +9 -0
- package/templates/react-ts/_variants/with-engine/src/background.tsx +118 -0
- package/templates/react-ts/_variants/without-libs/src/App.tsx +380 -0
- package/templates/react-ts/_variants/without-libs/src/background.tsx +24 -0
- package/templates/react-ts/_variants/without-libs/src/entry-server.tsx +39 -0
- package/templates/react-ts/_variants/without-libs/src/main.tsx +26 -0
- package/templates/{react-ts-server/_variantes/sans-libs/client → react-ts/_variants/without-libs}/src/styles.css +137 -137
- package/templates/react-ts/{_variantes/sans-routeur → _variants/without-router}/src/App.tsx +141 -141
- package/templates/react-ts/_variants/without-router/src/entry-server.tsx +39 -0
- package/templates/react-ts/index.html +4 -4
- package/templates/react-ts/odoro.config.ts +5 -0
- package/templates/react-ts/src/App.tsx +219 -209
- package/templates/react-ts/src/background.tsx +66 -0
- package/templates/react-ts/src/entry-server.tsx +85 -0
- package/templates/react-ts/src/main.tsx +13 -4
- package/templates/react-ts/src/router.tsx +65 -45
- package/templates/react-ts/src/styles.css +5 -5
- package/templates/react-ts-server/Dockerfile +9 -9
- package/templates/react-ts-server/README.md +97 -45
- package/templates/react-ts-server/_env.example +31 -33
- package/templates/react-ts-server/_variants/with-engine/client/src/background.tsx +118 -0
- package/templates/react-ts-server/_variants/without-libs/client/src/App.tsx +380 -0
- package/templates/react-ts-server/_variants/without-libs/client/src/background.tsx +24 -0
- package/templates/react-ts-server/_variants/without-libs/client/src/entry-server.tsx +39 -0
- package/templates/react-ts-server/_variants/without-libs/client/src/main.tsx +26 -0
- package/templates/{react-ts/_variantes/sans-libs → react-ts-server/_variants/without-libs/client}/src/styles.css +137 -137
- package/templates/react-ts-server/{_variantes/sans-routeur → _variants/without-router}/client/src/App.tsx +141 -141
- package/templates/react-ts-server/_variants/without-router/client/src/entry-server.tsx +39 -0
- package/templates/react-ts-server/client/index.html +4 -4
- package/templates/react-ts-server/client/src/App.tsx +228 -210
- package/templates/react-ts-server/client/src/account.tsx +267 -0
- package/templates/react-ts-server/client/src/auth.tsx +139 -0
- package/templates/react-ts-server/client/src/background.tsx +66 -0
- package/templates/react-ts-server/client/src/entry-server.tsx +92 -0
- package/templates/react-ts-server/client/src/main.tsx +17 -5
- package/templates/react-ts-server/client/src/router.tsx +77 -45
- package/templates/react-ts-server/client/src/styles.css +5 -5
- package/templates/react-ts-server/odoro.config.ts +7 -4
- package/templates/react-ts-server/package.json +2 -0
- package/templates/react-ts-server/scripts/dev.mjs +14 -14
- package/templates/react-ts-server/server/src/main.ts +119 -45
- package/templates/react-ts-server/server/src/modules/auth/index.ts +238 -0
- package/templates/react-ts-server/server/src/modules/auth/password.ts +122 -0
- package/templates/react-ts-server/server/src/modules/auth/store.ts +193 -0
- package/templates/react-ts-server/server/src/modules/health/index.ts +45 -46
- package/dist/build-JFQHODAT.js +0 -5
- package/dist/chunk-22KJTV2R.js +0 -380
- package/dist/chunk-3SZIN6VG.js +0 -64
- package/dist/chunk-DL3NPC4H.js +0 -113
- package/dist/chunk-TQUJ3MFS.js +0 -268
- package/dist/chunk-ZVL7EXJO.js +0 -66
- package/dist/commands-4JRBD55Z.js +0 -245
- package/dist/preview-7DKEAQOQ.js +0 -4
- package/templates/react-ts/_variantes/avec-moteur/src/fond.tsx +0 -118
- package/templates/react-ts/_variantes/sans-libs/src/App.tsx +0 -382
- package/templates/react-ts/_variantes/sans-libs/src/fond.tsx +0 -23
- package/templates/react-ts/_variantes/sans-libs/src/main.tsx +0 -17
- package/templates/react-ts/src/fond.tsx +0 -66
- package/templates/react-ts-server/_variantes/avec-moteur/client/src/fond.tsx +0 -118
- package/templates/react-ts-server/_variantes/sans-libs/client/src/App.tsx +0 -382
- package/templates/react-ts-server/_variantes/sans-libs/client/src/fond.tsx +0 -23
- package/templates/react-ts-server/_variantes/sans-libs/client/src/main.tsx +0 -17
- package/templates/react-ts-server/client/src/fond.tsx +0 -66
package/dist/chunk-DL3NPC4H.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { guessAliasPaths } from './chunk-T6RLHSCW.js';
|
|
3
|
-
import { mkdir, writeFile, rm } from 'fs/promises';
|
|
4
|
-
import { existsSync } from 'fs';
|
|
5
|
-
import { resolve, join } from 'path';
|
|
6
|
-
import { pathToFileURL } from 'url';
|
|
7
|
-
import { build } from 'esbuild';
|
|
8
|
-
|
|
9
|
-
function defineConfig(config) {
|
|
10
|
-
return config;
|
|
11
|
-
}
|
|
12
|
-
var CONFIG_FILES = ["odoro.config.ts", "odoro.config.js", "odoro.config.mjs"];
|
|
13
|
-
async function importConfigFile(file, root) {
|
|
14
|
-
const directory = join(root, "node_modules", ".odoro");
|
|
15
|
-
const output = join(directory, `config.${Date.now().toString(36)}.mjs`);
|
|
16
|
-
await mkdir(directory, { recursive: true });
|
|
17
|
-
try {
|
|
18
|
-
const result = await build({
|
|
19
|
-
entryPoints: [file],
|
|
20
|
-
bundle: true,
|
|
21
|
-
format: "esm",
|
|
22
|
-
platform: "node",
|
|
23
|
-
target: "node20",
|
|
24
|
-
write: false,
|
|
25
|
-
// Seul le code du projet est inline ; ses dependances restent externes,
|
|
26
|
-
// sans quoi il faudrait resoudre tout node_modules pour lire trois lignes.
|
|
27
|
-
packages: "external",
|
|
28
|
-
// `packages: 'external'` ne suffit pas : un `baseUrl` dans le
|
|
29
|
-
// `tsconfig.json` fait chercher les imports nus depuis la racine du
|
|
30
|
-
// projet, ou `odoro.json` — le fichier du registre — est trouve avant le
|
|
31
|
-
// paquet. L'import cesse alors d'etre un import de paquet, la regle
|
|
32
|
-
// ci-dessus ne s'applique plus, et la compilation echoue sur un
|
|
33
|
-
// `defineConfig` introuvable dans un fichier de configuration.
|
|
34
|
-
//
|
|
35
|
-
// Le nommer explicitement le met hors d'atteinte de cette resolution. La
|
|
36
|
-
// liste vaut pour les projets deja crees : eux portent encore un
|
|
37
|
-
// `baseUrl`, et on ne peut pas reecrire leur tsconfig.
|
|
38
|
-
external: ["odoro"]
|
|
39
|
-
});
|
|
40
|
-
const code = result.outputFiles[0]?.text;
|
|
41
|
-
if (code === void 0) {
|
|
42
|
-
throw new Error(`[odoro] La configuration "${file}" n'a produit aucun code.`);
|
|
43
|
-
}
|
|
44
|
-
await writeFile(output, code, "utf8");
|
|
45
|
-
const module = await import(pathToFileURL(output).href);
|
|
46
|
-
if (module.default === void 0) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`[odoro] La configuration "${file}" doit avoir un export par defaut.`
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
return module.default;
|
|
52
|
-
} finally {
|
|
53
|
-
await rm(output, { force: true });
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async function loadConfig(root, overrides = {}) {
|
|
57
|
-
const absoluteRoot = resolve(root);
|
|
58
|
-
let file;
|
|
59
|
-
let loaded = {};
|
|
60
|
-
for (const candidate of CONFIG_FILES) {
|
|
61
|
-
const path = join(absoluteRoot, candidate);
|
|
62
|
-
if (existsSync(path)) {
|
|
63
|
-
file = path;
|
|
64
|
-
loaded = await importConfigFile(path, absoluteRoot);
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
const merged = {
|
|
69
|
-
...loaded,
|
|
70
|
-
...overrides,
|
|
71
|
-
server: { ...loaded.server, ...overrides.server },
|
|
72
|
-
build: { ...loaded.build, ...overrides.build },
|
|
73
|
-
alias: { ...loaded.alias, ...overrides.alias },
|
|
74
|
-
define: { ...loaded.define, ...overrides.define }
|
|
75
|
-
};
|
|
76
|
-
const base = merged.base ?? "/";
|
|
77
|
-
const projectRoot = merged.root === void 0 ? absoluteRoot : resolve(absoluteRoot, merged.root);
|
|
78
|
-
return {
|
|
79
|
-
root: projectRoot,
|
|
80
|
-
base: base.endsWith("/") ? base : `${base}/`,
|
|
81
|
-
publicDir: resolve(projectRoot, merged.publicDir ?? "public"),
|
|
82
|
-
outDir: resolve(projectRoot, merged.build?.outDir ?? "dist"),
|
|
83
|
-
server: {
|
|
84
|
-
port: merged.server?.port ?? 5180,
|
|
85
|
-
host: merged.server?.host ?? "localhost",
|
|
86
|
-
proxy: merged.server?.proxy ?? {}
|
|
87
|
-
},
|
|
88
|
-
build: {
|
|
89
|
-
outDir: merged.build?.outDir ?? "dist",
|
|
90
|
-
minify: merged.build?.minify ?? true,
|
|
91
|
-
sourcemap: merged.build?.sourcemap ?? true,
|
|
92
|
-
target: merged.build?.target ?? "es2022",
|
|
93
|
-
// Actif par defaut : une feuille qui contient toutes les classes
|
|
94
|
-
// possibles est un accident de generation, pas une intention.
|
|
95
|
-
elaguer: merged.build?.elaguer ?? true,
|
|
96
|
-
safelist: merged.build?.safelist ?? []
|
|
97
|
-
},
|
|
98
|
-
// Les alias declares dans `tsconfig.json` sont repris d'office. Sans
|
|
99
|
-
// cela, un projet qui suit `odoro init` — lequel deduit son prefixe du
|
|
100
|
-
// tsconfig — aurait a redeclarer le meme alias ici pour que le serveur
|
|
101
|
-
// sache le resoudre. Deux endroits pour la meme verite, et une erreur
|
|
102
|
-
// qui n'apparait qu'au premier import.
|
|
103
|
-
//
|
|
104
|
-
// La configuration l'emporte : c'est elle qu'on ecrit pour corriger un
|
|
105
|
-
// cas que la deduction n'attrape pas.
|
|
106
|
-
alias: { ...await guessAliasPaths(projectRoot), ...merged.alias },
|
|
107
|
-
define: merged.define ?? {},
|
|
108
|
-
envPrefix: merged.envPrefix ?? "ODORO_",
|
|
109
|
-
configFile: file
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export { defineConfig, loadConfig };
|
package/dist/chunk-TQUJ3MFS.js
DELETED
|
@@ -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 };
|
package/dist/chunk-ZVL7EXJO.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { estUneRessource, ecouter } from './chunk-TQUJ3MFS.js';
|
|
3
|
-
import { warn, success, info, colors } from './chunk-JMEHF3KN.js';
|
|
4
|
-
import { existsSync, statSync, createReadStream } from 'fs';
|
|
5
|
-
import { createServer } from 'http';
|
|
6
|
-
import { normalize, join, extname } from 'path';
|
|
7
|
-
|
|
8
|
-
var MIME = {
|
|
9
|
-
".html": "text/html; charset=utf-8",
|
|
10
|
-
".js": "text/javascript; charset=utf-8",
|
|
11
|
-
".css": "text/css; charset=utf-8",
|
|
12
|
-
".json": "application/json; charset=utf-8",
|
|
13
|
-
".svg": "image/svg+xml",
|
|
14
|
-
".png": "image/png",
|
|
15
|
-
".jpg": "image/jpeg",
|
|
16
|
-
".webp": "image/webp",
|
|
17
|
-
".ico": "image/x-icon",
|
|
18
|
-
".woff2": "font/woff2",
|
|
19
|
-
".map": "application/json; charset=utf-8",
|
|
20
|
-
".txt": "text/plain; charset=utf-8",
|
|
21
|
-
".md": "text/markdown; charset=utf-8",
|
|
22
|
-
".markdown": "text/markdown; charset=utf-8"
|
|
23
|
-
};
|
|
24
|
-
async function startPreviewServer(config, port = config.server.port + 1) {
|
|
25
|
-
if (!existsSync(config.outDir)) {
|
|
26
|
-
throw new Error(`[odoro] Rien a previsualiser : lancez "odoro build" d'abord.`);
|
|
27
|
-
}
|
|
28
|
-
const server = createServer((incoming, response) => {
|
|
29
|
-
const path = (incoming.url ?? "/").split("?")[0] ?? "/";
|
|
30
|
-
const relativePath = normalize(decodeURIComponent(path)).split(/[\\/]/).filter(Boolean).join("/");
|
|
31
|
-
const candidate = join(config.outDir, relativePath);
|
|
32
|
-
const dansLeDossier = ["index.html", "index.md"].map((nom) => join(candidate, nom)).find((chemin) => existsSync(chemin) && statSync(chemin).isFile());
|
|
33
|
-
const existant = existsSync(candidate) && statSync(candidate).isFile() ? candidate : dansLeDossier;
|
|
34
|
-
if (existant === void 0 && (extname(relativePath) !== "" || estUneRessource(incoming.headers))) {
|
|
35
|
-
response.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
36
|
-
response.end(`Introuvable : /${relativePath}`);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const file = existant ?? join(config.outDir, "index.html");
|
|
40
|
-
if (!file.startsWith(config.outDir)) {
|
|
41
|
-
response.writeHead(403, { "Content-Type": "text/plain" });
|
|
42
|
-
response.end("Interdit");
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const type = MIME[extname(file).toLowerCase()] ?? "application/octet-stream";
|
|
46
|
-
const immutable = relativePath.startsWith("assets/");
|
|
47
|
-
response.writeHead(200, {
|
|
48
|
-
"Content-Type": type,
|
|
49
|
-
"Cache-Control": immutable ? "public, max-age=31536000, immutable" : "no-cache"
|
|
50
|
-
});
|
|
51
|
-
createReadStream(file).pipe(response);
|
|
52
|
-
});
|
|
53
|
-
const { port: obtenu, demande } = await ecouter(server, port, config.server.host);
|
|
54
|
-
if (demande !== void 0) {
|
|
55
|
-
warn(`port ${String(demande)} occupe \u2014 l apercu ecoute sur ${String(obtenu)}`);
|
|
56
|
-
}
|
|
57
|
-
const url = `http://${config.server.host}:${String(obtenu)}${config.base}`;
|
|
58
|
-
success("previsualisation du build de production");
|
|
59
|
-
info(` ${colors.cyan(url)}`);
|
|
60
|
-
return {
|
|
61
|
-
url,
|
|
62
|
-
close: () => new Promise((done) => server.close(() => done()))
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export { startPreviewServer };
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { writeDatabaseUrl, assertEnvIgnored } from './chunk-3SZIN6VG.js';
|
|
3
|
-
import { info, success, colors, warn, error } from './chunk-JMEHF3KN.js';
|
|
4
|
-
import { randomBytes } from 'crypto';
|
|
5
|
-
import { readFile, mkdir, writeFile, chmod } from 'fs/promises';
|
|
6
|
-
import { platform, homedir } from 'os';
|
|
7
|
-
import { dirname, join } from 'path';
|
|
8
|
-
|
|
9
|
-
function configPath(env = processEnv()) {
|
|
10
|
-
const xdg = env["XDG_CONFIG_HOME"];
|
|
11
|
-
if (xdg !== void 0 && xdg.length > 0) return join(xdg, "odoro", "config.json");
|
|
12
|
-
if (platform() === "win32") {
|
|
13
|
-
const appData = env["APPDATA"];
|
|
14
|
-
if (appData !== void 0 && appData.length > 0) {
|
|
15
|
-
return join(appData, "odoro", "config.json");
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return join(homedir(), ".config", "odoro", "config.json");
|
|
19
|
-
}
|
|
20
|
-
function processEnv() {
|
|
21
|
-
return process.env;
|
|
22
|
-
}
|
|
23
|
-
async function readUserConfig(path = configPath()) {
|
|
24
|
-
try {
|
|
25
|
-
return JSON.parse(await readFile(path, "utf8"));
|
|
26
|
-
} catch {
|
|
27
|
-
return {};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function writeUserConfig(config, path = configPath()) {
|
|
31
|
-
await mkdir(dirname(path), { recursive: true });
|
|
32
|
-
await writeFile(path, `${JSON.stringify(config, null, 2)}
|
|
33
|
-
`, "utf8");
|
|
34
|
-
if (platform() === "win32") return { path, restricted: false };
|
|
35
|
-
try {
|
|
36
|
-
await chmod(path, 384);
|
|
37
|
-
return { path, restricted: true };
|
|
38
|
-
} catch {
|
|
39
|
-
return { path, restricted: false };
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async function storeToken(apiUrl, token, path = configPath()) {
|
|
43
|
-
const current = await readUserConfig(path);
|
|
44
|
-
return await writeUserConfig(
|
|
45
|
-
{
|
|
46
|
-
...current,
|
|
47
|
-
tokens: { ...current.tokens, [apiUrl]: token },
|
|
48
|
-
defaultApiUrl: current.defaultApiUrl ?? apiUrl
|
|
49
|
-
},
|
|
50
|
-
path
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
async function findToken(apiUrl, path = configPath(), env = processEnv()) {
|
|
54
|
-
const fromEnv = env["ODORO_TOKEN"];
|
|
55
|
-
if (fromEnv !== void 0 && fromEnv.length > 0) return fromEnv;
|
|
56
|
-
const config = await readUserConfig(path);
|
|
57
|
-
return config.tokens?.[apiUrl];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// src/db/sdk.ts
|
|
61
|
-
var SDK_PACKAGE = "@odoro-cli/cloud-sdk";
|
|
62
|
-
async function loadSdk() {
|
|
63
|
-
try {
|
|
64
|
-
const specifier = SDK_PACKAGE;
|
|
65
|
-
const sdk = await import(specifier);
|
|
66
|
-
return { ok: true, sdk };
|
|
67
|
-
} catch {
|
|
68
|
-
return {
|
|
69
|
-
ok: false,
|
|
70
|
-
reason: `Cette commande a besoin de ${SDK_PACKAGE}, qui n'est pas installe.
|
|
71
|
-
|
|
72
|
-
npm install --save-dev ${SDK_PACKAGE}
|
|
73
|
-
|
|
74
|
-
Il n'est pas fourni avec odoro : ce binaire est telecharge a chaque
|
|
75
|
-
creation de projet, et la plupart n'emploient pas la plateforme.`
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// src/db/commands.ts
|
|
81
|
-
var DEFAULT_API_URL = "https://db.odoro.dev";
|
|
82
|
-
function idempotencyKey() {
|
|
83
|
-
return randomBytes(24).toString("hex");
|
|
84
|
-
}
|
|
85
|
-
async function connect(options) {
|
|
86
|
-
const apiUrl = options.apiUrl ?? DEFAULT_API_URL;
|
|
87
|
-
const load = await loadSdk();
|
|
88
|
-
if (!load.ok) {
|
|
89
|
-
error(load.reason);
|
|
90
|
-
return void 0;
|
|
91
|
-
}
|
|
92
|
-
const token = await findToken(apiUrl);
|
|
93
|
-
if (token === void 0) {
|
|
94
|
-
error(
|
|
95
|
-
`Aucun jeton pour ${apiUrl}.
|
|
96
|
-
|
|
97
|
-
odoro db:login
|
|
98
|
-
|
|
99
|
-
Ou fournissez-le par la variable ODORO_TOKEN, ce que fait une
|
|
100
|
-
integration continue.`
|
|
101
|
-
);
|
|
102
|
-
return void 0;
|
|
103
|
-
}
|
|
104
|
-
return { client: load.sdk.createClient({ baseUrl: apiUrl, token }), sdk: load.sdk };
|
|
105
|
-
}
|
|
106
|
-
async function loginCommand(options) {
|
|
107
|
-
const apiUrl = options.apiUrl ?? DEFAULT_API_URL;
|
|
108
|
-
const prompts = await import('@clack/prompts');
|
|
109
|
-
const value = await prompts.password({
|
|
110
|
-
message: `Jeton pour ${apiUrl}`,
|
|
111
|
-
validate: (input) => input.startsWith("odk_") ? void 0 : "Un jeton commence par odk_live_ ou odk_test_"
|
|
112
|
-
});
|
|
113
|
-
if (prompts.isCancel(value)) {
|
|
114
|
-
info("Annule.");
|
|
115
|
-
return 0;
|
|
116
|
-
}
|
|
117
|
-
const report = await storeToken(apiUrl, value);
|
|
118
|
-
success(`Jeton enregistre dans ${colors.dim(report.path)}`);
|
|
119
|
-
if (!report.restricted) {
|
|
120
|
-
warn(
|
|
121
|
-
"Les droits restrictifs du fichier n ont pas pu etre poses sur ce systeme : verifiez que ce dossier n est pas partage ni synchronise."
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
return 0;
|
|
125
|
-
}
|
|
126
|
-
async function statusCommand(options) {
|
|
127
|
-
const connection = await connect(options);
|
|
128
|
-
if (connection === void 0) return 1;
|
|
129
|
-
const { databases } = await connection.client.databases.list(
|
|
130
|
-
options.env === void 0 ? {} : { environmentId: options.env }
|
|
131
|
-
);
|
|
132
|
-
if (databases.length === 0) {
|
|
133
|
-
info("Aucune base. `odoro db:create` en provisionne une.");
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
for (const base of databases) {
|
|
137
|
-
const etat = base.state === "ready" ? colors.green(base.state) : base.state === "failed" || base.state === "quarantined" ? colors.red(base.state) : colors.dim(base.state);
|
|
138
|
-
console.log(` ${base.id} ${etat} ${colors.dim(base.region)}`);
|
|
139
|
-
}
|
|
140
|
-
return 0;
|
|
141
|
-
}
|
|
142
|
-
async function createCommand(options) {
|
|
143
|
-
const connection = await connect(options);
|
|
144
|
-
if (connection === void 0) return 1;
|
|
145
|
-
const environmentId = options.env;
|
|
146
|
-
if (environmentId === void 0) {
|
|
147
|
-
error("Precisez l environnement : `odoro db:create --env production`.");
|
|
148
|
-
return 1;
|
|
149
|
-
}
|
|
150
|
-
const prompts = await import('@clack/prompts');
|
|
151
|
-
const spinner = prompts.spinner();
|
|
152
|
-
spinner.start("Provisionnement");
|
|
153
|
-
const abort = new AbortController();
|
|
154
|
-
const onInterrupt = () => abort.abort();
|
|
155
|
-
process.once("SIGINT", onInterrupt);
|
|
156
|
-
try {
|
|
157
|
-
const fini = await connection.client.databases.createAndWait(
|
|
158
|
-
{ idempotencyKey: idempotencyKey(), environmentId, region: "eu-central-1" },
|
|
159
|
-
{ signal: abort.signal }
|
|
160
|
-
);
|
|
161
|
-
spinner.stop("Base provisionnee");
|
|
162
|
-
const databaseId = fini.subject;
|
|
163
|
-
if (databaseId === void 0) {
|
|
164
|
-
warn(
|
|
165
|
-
"L operation a abouti sans nommer la base creee. `odoro db:status` la montrera."
|
|
166
|
-
);
|
|
167
|
-
return 0;
|
|
168
|
-
}
|
|
169
|
-
const { connectionString } = await connection.client.credentials.rotate({
|
|
170
|
-
databaseId
|
|
171
|
-
});
|
|
172
|
-
await writeDatabaseUrl(options.root, connectionString);
|
|
173
|
-
success("DATABASE_URL ecrite dans .env");
|
|
174
|
-
const risque = await assertEnvIgnored(options.root);
|
|
175
|
-
if (risque !== void 0) warn(risque);
|
|
176
|
-
return 0;
|
|
177
|
-
} catch (cause) {
|
|
178
|
-
spinner.stop("Provisionnement interrompu");
|
|
179
|
-
if (abort.signal.aborted) {
|
|
180
|
-
info(
|
|
181
|
-
"Attente abandonnee. Le provisionnement continue : `odoro db:status` en montrera l aboutissement."
|
|
182
|
-
);
|
|
183
|
-
return 0;
|
|
184
|
-
}
|
|
185
|
-
error(describe(cause, connection.sdk));
|
|
186
|
-
return 1;
|
|
187
|
-
} finally {
|
|
188
|
-
process.off("SIGINT", onInterrupt);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async function branchCommand(options) {
|
|
192
|
-
const connection = await connect(options);
|
|
193
|
-
if (connection === void 0) return 1;
|
|
194
|
-
if (options.from === void 0 || options.name === void 0) {
|
|
195
|
-
error("Usage : `odoro db:branch --from production --name preview-42`");
|
|
196
|
-
return 1;
|
|
197
|
-
}
|
|
198
|
-
const prompts = await import('@clack/prompts');
|
|
199
|
-
const spinner = prompts.spinner();
|
|
200
|
-
spinner.start(`Branche depuis ${options.from}`);
|
|
201
|
-
try {
|
|
202
|
-
const fini = await connection.client.databases.branchAndWait({
|
|
203
|
-
idempotencyKey: idempotencyKey(),
|
|
204
|
-
parentEnvironmentId: options.from,
|
|
205
|
-
name: options.name,
|
|
206
|
-
// Sans regle declaree, la plateforme refuse. On ne devine pas a sa
|
|
207
|
-
// place : une regle inventee ici anonymiserait la mauvaise colonne, ou
|
|
208
|
-
// aucune.
|
|
209
|
-
anonymization: []
|
|
210
|
-
});
|
|
211
|
-
spinner.stop("Branche creee");
|
|
212
|
-
info(`Base : ${fini.subject ?? "voir odoro db:status"}`);
|
|
213
|
-
return 0;
|
|
214
|
-
} catch (cause) {
|
|
215
|
-
spinner.stop("Branche refusee");
|
|
216
|
-
error(describe(cause, connection.sdk));
|
|
217
|
-
return 1;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function describe(cause, sdk) {
|
|
221
|
-
if (sdk.isApiError(cause, "VALIDATION")) {
|
|
222
|
-
const errors = cause.options?.errors;
|
|
223
|
-
return [
|
|
224
|
-
"La demande a ete refusee :",
|
|
225
|
-
...(errors ?? []).map(({ field, message }) => ` ${field} \u2014 ${message}`)
|
|
226
|
-
].join("\n");
|
|
227
|
-
}
|
|
228
|
-
if (sdk.isApiError(cause, "RATE_LIMIT")) {
|
|
229
|
-
return "Trop de demandes. Les routes qui provisionnent sont volontairement limitees : chaque creation coute.";
|
|
230
|
-
}
|
|
231
|
-
if (sdk.isApiError(cause, "UNAUTHORIZED")) {
|
|
232
|
-
return `Jeton refuse. \`odoro db:login\` en enregistre un autre.`;
|
|
233
|
-
}
|
|
234
|
-
return cause instanceof Error ? cause.message : String(cause);
|
|
235
|
-
}
|
|
236
|
-
var DB_HELP = [
|
|
237
|
-
" db:login Enregistre un jeton de plateforme",
|
|
238
|
-
" db:status Liste les bases du projet",
|
|
239
|
-
" db:create --env <e> Provisionne une base et ecrit .env",
|
|
240
|
-
" db:branch --from <e> --name <n>",
|
|
241
|
-
" Cree une previsualisation par branche",
|
|
242
|
-
` (necessite ${SDK_PACKAGE})`
|
|
243
|
-
].join("\n");
|
|
244
|
-
|
|
245
|
-
export { DB_HELP, branchCommand, createCommand, loginCommand, statusCommand };
|
package/dist/preview-7DKEAQOQ.js
DELETED