@suronai/cli 0.1.31 → 0.1.32
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/package.json +1 -1
- package/src/commands/init.js +49 -34
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -15,6 +15,12 @@ export const initCommand = new Command("init")
|
|
|
15
15
|
|
|
16
16
|
console.log("\n" + c.bold(" suron init") + " — " + c.dim(cwd) + "\n");
|
|
17
17
|
|
|
18
|
+
if (existsSync(join(cwd, ".suron.json"))) {
|
|
19
|
+
console.error(" " + c.red("✗") + " .suron.json already exists — this app is already initialised.");
|
|
20
|
+
console.error(" To restore a lost config, run: " + c.bold("suron recover") + "\n");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
if (!existsSync(join(cwd, ".env"))) {
|
|
19
25
|
console.error(" " + c.red("✗") + " .env not found in current directory");
|
|
20
26
|
console.error(" Create a .env file with your secrets, then run: suron init\n");
|
|
@@ -213,15 +219,53 @@ async function patchEntryPoint(cwd, isEsm) {
|
|
|
213
219
|
|
|
214
220
|
const lines = src.split("\n");
|
|
215
221
|
|
|
216
|
-
//
|
|
217
|
-
|
|
222
|
+
// Two-pass scan:
|
|
223
|
+
// Pass 1 — lines containing "dotenv" (import or require)
|
|
224
|
+
// Pass 2 — bare config() / config({...}) call lines that don't contain "dotenv"
|
|
225
|
+
// (these appear after the import was already on a separate line)
|
|
226
|
+
const toReplace = [];
|
|
227
|
+
const seenIndices = new Set();
|
|
228
|
+
|
|
218
229
|
for (let i = 0; i < lines.length; i++) {
|
|
230
|
+
const trimmed = lines[i].trim();
|
|
231
|
+
const indent = lines[i].match(/^(\s*)/)[1];
|
|
232
|
+
|
|
219
233
|
if (lines[i].includes("dotenv")) {
|
|
220
|
-
|
|
234
|
+
seenIndices.add(i);
|
|
235
|
+
let replacement = null;
|
|
236
|
+
if (isEsm) {
|
|
237
|
+
if (trimmed.startsWith("import")) {
|
|
238
|
+
replacement = indent + trimmed.replace(/(from\s+)['"]dotenv(?:\/config)?['"]/, '$1"@suronai/sdk"');
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
if (trimmed.includes("require")) {
|
|
242
|
+
replacement = indent + "const { config } = require(\"@suronai/sdk\");\n" + indent + "await config();";
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
toReplace.push({ index: i, content: lines[i], replacement });
|
|
221
246
|
}
|
|
222
247
|
}
|
|
223
248
|
|
|
224
|
-
|
|
249
|
+
// Pass 2: bare config() call — only in ESM where the import and call are separate lines
|
|
250
|
+
if (isEsm) {
|
|
251
|
+
for (let i = 0; i < lines.length; i++) {
|
|
252
|
+
if (seenIndices.has(i)) continue;
|
|
253
|
+
const trimmed = lines[i].trim();
|
|
254
|
+
const indent = lines[i].match(/^(\s*)/)[1];
|
|
255
|
+
// Matches: config() / config({}) / config({ ... }) — with or without semicolon
|
|
256
|
+
if (/^config\s*\(.*\);?$/.test(trimmed) && !trimmed.startsWith("//")) {
|
|
257
|
+
toReplace.push({
|
|
258
|
+
index: i,
|
|
259
|
+
content: lines[i],
|
|
260
|
+
replacement: indent + trimmed.replace(/^config\s*\(/, "await config("),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Sort by line number so the diff preview is in file order
|
|
265
|
+
toReplace.sort((a, b) => a.index - b.index);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (toReplace.length === 0) {
|
|
225
269
|
console.log("\n Add to your app entry point:\n");
|
|
226
270
|
printSnippet(isEsm);
|
|
227
271
|
return;
|
|
@@ -232,36 +276,7 @@ async function patchEntryPoint(cwd, isEsm) {
|
|
|
232
276
|
console.log(" " + c.yellow("▶") + " Found dotenv in " + c.dim(relEntry) + ":");
|
|
233
277
|
console.log();
|
|
234
278
|
|
|
235
|
-
|
|
236
|
-
// We preserve the original line's leading whitespace (indent) and only
|
|
237
|
-
// swap out the dotenv-specific part — nothing else on the line is touched.
|
|
238
|
-
const replacements = dotenvLines.map(({ index, content }) => {
|
|
239
|
-
const trimmed = content.trim();
|
|
240
|
-
const indent = content.match(/^(\s*)/)[1];
|
|
241
|
-
let replacement = null;
|
|
242
|
-
|
|
243
|
-
if (isEsm) {
|
|
244
|
-
// import { config } from "dotenv" → import { config } from "@suronai/sdk"
|
|
245
|
-
// Preserves the quote style and anything else on the line.
|
|
246
|
-
if (trimmed.startsWith("import") && trimmed.includes("dotenv")) {
|
|
247
|
-
replacement = indent + trimmed.replace(/(from\s+)['"]dotenv['"]/, '$1"@suronai/sdk"');
|
|
248
|
-
}
|
|
249
|
-
// config(); → await config();
|
|
250
|
-
// Only matches lines that are purely a config() call, nothing else.
|
|
251
|
-
else if (/^config\s*\(\s*\);?$/.test(trimmed)) {
|
|
252
|
-
replacement = indent + trimmed.replace(/^config\s*\(/, "await config(");
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
// require("dotenv").config() → const { config } = require("@suronai/sdk"); await config();
|
|
256
|
-
if (trimmed.includes("require") && trimmed.includes("dotenv")) {
|
|
257
|
-
replacement = indent + "const { config } = require(\"@suronai/sdk\");\n" + indent + "await config();";
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// If we found a dotenv line but don't know how to replace it, show it
|
|
262
|
-
// with a warning so the user knows to handle it manually.
|
|
263
|
-
return { index, content, replacement };
|
|
264
|
-
});
|
|
279
|
+
const replacements = toReplace;
|
|
265
280
|
|
|
266
281
|
// Show the diff preview
|
|
267
282
|
for (const { content, replacement } of replacements) {
|