create-snapify-app 1.1.1 → 1.1.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.
|
@@ -58,11 +58,18 @@ async function main() {
|
|
|
58
58
|
}
|
|
59
59
|
if (!nonInteractive) {
|
|
60
60
|
console.log('\n PostgreSQL');
|
|
61
|
+
console.log(' (colle une URL Neon/Postgres, ou réponds o puis entre l’URL, ou n pour saisir hôte/port)');
|
|
61
62
|
const paste = await askYesNo('Coller une DATABASE_URL complète', false);
|
|
62
|
-
if (paste) {
|
|
63
|
-
databaseUrl =
|
|
63
|
+
if (paste && typeof paste === 'object' && paste.__databaseUrl) {
|
|
64
|
+
databaseUrl = paste.__databaseUrl;
|
|
65
|
+
ok('DATABASE_URL détectée');
|
|
66
|
+
} else if (paste) {
|
|
67
|
+
databaseUrl = await ask('DATABASE_URL (postgres://… ou postgresql://…)');
|
|
64
68
|
}
|
|
65
69
|
}
|
|
70
|
+
if (databaseUrl && !/^(postgres(ql)?:\/\/)/i.test(databaseUrl)) {
|
|
71
|
+
fail('DATABASE_URL invalide — doit commencer par postgres:// ou postgresql://');
|
|
72
|
+
}
|
|
66
73
|
if (!databaseUrl) {
|
|
67
74
|
const host = String(flags['db-host'] || (!nonInteractive ? await ask('Hôte', '127.0.0.1') : ''));
|
|
68
75
|
const port = String(flags['db-port'] || (!nonInteractive ? await ask('Port', '5432') : '5432'));
|
|
@@ -119,22 +126,39 @@ async function main() {
|
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
if (!skipInstall) {
|
|
122
|
-
|
|
123
|
-
const
|
|
129
|
+
// Windows : npm est npm.cmd — spawn sans shell échoue souvent sans message clair
|
|
130
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
131
|
+
const npmOpts = {
|
|
124
132
|
cwd: dest,
|
|
125
133
|
stdio: 'inherit',
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
shell: process.platform === 'win32',
|
|
135
|
+
env: { ...process.env, NODE_ENV: 'development', npm_config_fund: 'false' },
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
console.log('\n→ npm install…');
|
|
139
|
+
const install = spawnSync(npmCmd, ['install', '--no-audit', '--no-fund', '--legacy-peer-deps'], npmOpts);
|
|
140
|
+
if (install.error) {
|
|
141
|
+
fail(`npm install : ${install.error.message}`);
|
|
142
|
+
}
|
|
143
|
+
if (install.status !== 0) {
|
|
144
|
+
fail(
|
|
145
|
+
`npm install a échoué (code ${install.status}).\n` +
|
|
146
|
+
` Réessayez manuellement :\n` +
|
|
147
|
+
` cd ${dest}\n` +
|
|
148
|
+
` npm install --legacy-peer-deps`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
129
151
|
ok('Dépendances installées');
|
|
130
152
|
|
|
131
153
|
console.log('\n→ npm run build…');
|
|
132
|
-
const build = spawnSync(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
154
|
+
const build = spawnSync(npmCmd, ['run', 'build'], npmOpts);
|
|
155
|
+
if (build.error) fail(`npm run build : ${build.error.message}`);
|
|
156
|
+
if (build.status !== 0) {
|
|
157
|
+
fail(
|
|
158
|
+
`npm run build a échoué (code ${build.status}).\n` +
|
|
159
|
+
` Réessayez : cd ${dest} && npm run build`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
138
162
|
ok('Frontend compilé');
|
|
139
163
|
}
|
|
140
164
|
|
package/lib/prompt.mjs
CHANGED
|
@@ -57,7 +57,12 @@ export async function askSecret(question) {
|
|
|
57
57
|
/** @param {string} question @param {boolean} [fallback] */
|
|
58
58
|
export async function askYesNo(question, fallback = true) {
|
|
59
59
|
const def = fallback ? 'O/n' : 'o/N';
|
|
60
|
-
const answer = (await ask(`${question} [${def}]`, '')).
|
|
60
|
+
const answer = (await ask(`${question} [${def}]`, '')).trim();
|
|
61
61
|
if (!answer) return fallback;
|
|
62
|
-
|
|
62
|
+
const lower = answer.toLowerCase();
|
|
63
|
+
// Si l'utilisateur colle directement une URL postgres au lieu de o/N
|
|
64
|
+
if (/^(postgres(ql)?:\/\/)/i.test(answer)) {
|
|
65
|
+
return { __databaseUrl: answer };
|
|
66
|
+
}
|
|
67
|
+
return lower === 'o' || lower === 'oui' || lower === 'y' || lower === 'yes';
|
|
63
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-snapify-app",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Installe Snapify (CMS complet : backend + frontend) : npx create-snapify-app@latest",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "NOVALABS WEB DESIGN <contact@novalabs.tn> (https://novalabs.tn)",
|
package/template/package.json
CHANGED
|
@@ -92,10 +92,11 @@ async function main() {
|
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// Vérifie
|
|
95
|
+
// Vérifie version + tarball téléchargeable (évite métadonnées sans .tgz / 0.0.0-stage)
|
|
96
96
|
let confirmed = '';
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
let tarballOk = false;
|
|
98
|
+
for (let i = 0; i < 12; i++) {
|
|
99
|
+
await new Promise((r) => setTimeout(r, i === 0 ? 2000 : 3000));
|
|
99
100
|
try {
|
|
100
101
|
confirmed = execFileSync('npm', ['view', `${pkg.name}@${pkg.version}`, 'version'], {
|
|
101
102
|
cwd: ROOT,
|
|
@@ -106,15 +107,37 @@ async function main() {
|
|
|
106
107
|
} catch {
|
|
107
108
|
confirmed = '';
|
|
108
109
|
}
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
try {
|
|
111
|
+
const tarball = execFileSync('npm', ['view', `${pkg.name}@${pkg.version}`, 'dist.tarball'], {
|
|
112
|
+
cwd: ROOT,
|
|
113
|
+
encoding: 'utf8',
|
|
114
|
+
env: npmEnv,
|
|
115
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
116
|
+
}).trim();
|
|
117
|
+
if (tarball.startsWith('http')) {
|
|
118
|
+
const head = execFileSync('curl', ['-sS', '-o', '/dev/null', '-w', '%{http_code}', '-L', tarball], {
|
|
119
|
+
encoding: 'utf8',
|
|
120
|
+
}).trim();
|
|
121
|
+
tarballOk = head === '200';
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
tarballOk = false;
|
|
125
|
+
}
|
|
126
|
+
if (confirmed === pkg.version && tarballOk) break;
|
|
127
|
+
console.log(
|
|
128
|
+
`• Attente npm… (${i + 1}/12) version=${confirmed || '—'} tarball=${tarballOk ? 'ok' : '404'}`,
|
|
129
|
+
);
|
|
111
130
|
}
|
|
112
|
-
if (confirmed !== pkg.version) {
|
|
131
|
+
if (confirmed !== pkg.version || !tarballOk) {
|
|
113
132
|
throw new Error(
|
|
114
|
-
`
|
|
133
|
+
`Publication incomplète : ${pkg.name}@${pkg.version} version=${confirmed || 'absente'} tarball=${tarballOk ? 'ok' : '404'}. ` +
|
|
134
|
+
`Souvent un publish « staged » sans blob. Bump la version et republie avec --otp.`,
|
|
115
135
|
);
|
|
116
136
|
}
|
|
117
|
-
console.log(
|
|
137
|
+
console.log(
|
|
138
|
+
`✔ Publié et confirmé (tarball 200) : https://www.npmjs.com/package/${pkg.name}/v/${pkg.version}\n` +
|
|
139
|
+
` Install : npx create-snapify-app@${pkg.version}`,
|
|
140
|
+
);
|
|
118
141
|
}
|
|
119
142
|
|
|
120
143
|
main().catch((e) => {
|