@suronai/cli 0.1.18 → 0.1.20

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suronai/cli",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "CLI for Suron — suron login, init, whoami, rotate",
5
5
  "type": "module",
6
6
  "bin": {
@@ -89,12 +89,14 @@ export const initCommand = new Command("init")
89
89
 
90
90
  // ── Install SDK ───────────────────────────────────────────────────────────
91
91
  const pkgJsonPath = join(cwd, "package.json");
92
+ let isEsm = false;
92
93
 
93
94
  if (existsSync(pkgJsonPath)) {
94
95
  let alreadyInstalled = false;
95
96
  try {
96
97
  const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
97
98
  alreadyInstalled = !!(pkg.dependencies?.["@suronai/sdk"] || pkg.devDependencies?.["@suronai/sdk"]);
99
+ isEsm = pkg.type === "module";
98
100
  } catch { /* ignore */ }
99
101
 
100
102
  if (!alreadyInstalled) {
@@ -108,6 +110,9 @@ export const initCommand = new Command("init")
108
110
  }
109
111
  }
110
112
 
113
+ // ── Auto-patch entry point ────────────────────────────────────────────────
114
+ await patchEntryPoint(cwd, isEsm);
115
+
111
116
  // ── Done ──────────────────────────────────────────────────────────────────
112
117
  console.log();
113
118
  console.log(" " + c.green("✓") + " .env encrypted " + c.dim("(safe to commit)"));
@@ -115,10 +120,6 @@ export const initCommand = new Command("init")
115
120
  console.log(" " + c.green("✓") + " .suron.json written " + c.dim("(safe to commit)"));
116
121
  console.log(" " + c.green("✓") + " @suronai/sdk installed");
117
122
  console.log();
118
- console.log(" Add to your app entry point:\n");
119
- console.log(" " + c.cyan("import") + " { vault } from " + c.green("'@suronai/sdk'"));
120
- console.log(" " + c.cyan("await") + " vault()");
121
- console.log();
122
123
  });
123
124
 
124
125
  /** @param {string} cwd @returns {string} */
@@ -143,3 +144,109 @@ function pmAddCmd(pm) {
143
144
  function sanitiseName(name) {
144
145
  return name.toLowerCase().replace(/[^a-z0-9]/g, "");
145
146
  }
147
+
148
+ /**
149
+ * Looks for a dotenv bootstrap in the project entry point and offers
150
+ * to replace it with the Suron equivalent.
151
+ *
152
+ * Detects both ESM and CJS patterns:
153
+ * ESM: import { config } from "dotenv"; config();
154
+ * CJS: require("dotenv").config();
155
+ *
156
+ * Replaces with the correct form based on the project type:
157
+ * ESM: import { Suron } from "@suronai/sdk"; await Suron();
158
+ * CJS: const { Suron } = require("@suronai/sdk"); await Suron();
159
+ *
160
+ * @param {string} cwd
161
+ * @param {boolean} isEsm
162
+ */
163
+ async function patchEntryPoint(cwd, isEsm) {
164
+ // Candidates in priority order
165
+ const candidates = isEsm
166
+ ? ["index.js", "index.mjs", "src/index.js", "src/index.mjs"]
167
+ : ["index.js", "index.cjs", "src/index.js", "src/index.cjs"];
168
+
169
+ let entryPath = null;
170
+ for (const rel of candidates) {
171
+ const abs = join(cwd, rel);
172
+ if (existsSync(abs)) { entryPath = abs; break; }
173
+ }
174
+
175
+ if (!entryPath) {
176
+ // No entry point found — just print the manual snippet
177
+ console.log(" Add to your app entry point:\n");
178
+ printSnippet(isEsm);
179
+ return;
180
+ }
181
+
182
+ let src;
183
+ try { src = readFileSync(entryPath, "utf-8"); } catch { return; }
184
+
185
+ // Build regex patterns for both dotenv styles
186
+ const esmPattern = /^import\s+\{\s*config\s*\}\s+from\s+["']dotenv["'];?\s*\n?config\(\);?/m;
187
+ const cjsPattern = /^(?:const\s+)?require\(["']dotenv["']\)\.config\(\);?/m;
188
+ const pattern = isEsm ? esmPattern : cjsPattern;
189
+
190
+ const match = src.match(pattern);
191
+
192
+ if (!match) {
193
+ // dotenv not found — print manual snippet
194
+ console.log("\n Add to your app entry point:\n");
195
+ printSnippet(isEsm);
196
+ return;
197
+ }
198
+
199
+ // dotenv detected — ask user
200
+ const relEntry = entryPath.replace(cwd + "\\", "").replace(cwd + "/", "");
201
+ console.log();
202
+ console.log(" " + c.yellow("▶") + " Found " + c.cyan("dotenv") + " in " + c.dim(relEntry));
203
+ console.log();
204
+ console.log(" " + c.dim("Will replace:"));
205
+ console.log(" " + c.red("-") + " " + c.dim(match[0].replace(/\n/g, "\n - ")));
206
+ console.log(" " + c.dim("With:"));
207
+ if (isEsm) {
208
+ console.log(" " + c.green("+") + " " + c.cyan("import") + " { Suron } from " + c.green("'@suronai/sdk'"));
209
+ console.log(" " + c.green("+") + " " + c.cyan("await") + " Suron()");
210
+ } else {
211
+ console.log(" " + c.green("+") + " const { Suron } = " + c.cyan("require") + "(" + c.green("'@suronai/sdk'") + ")");
212
+ console.log(" " + c.green("+") + " " + c.cyan("await") + " Suron()");
213
+ }
214
+ console.log();
215
+
216
+ const answer = await prompt(" Replace? [" + c.green("Y") + "/n] › ");
217
+ const confirmed = answer === "" || /^y(es)?$/i.test(answer);
218
+
219
+ if (!confirmed) {
220
+ console.log(" " + c.dim("Skipped.") + " Add manually:\n");
221
+ printSnippet(isEsm);
222
+ return;
223
+ }
224
+
225
+ // Perform the replacement
226
+ const replacement = isEsm
227
+ ? `import { Suron } from '@suronai/sdk';\nawait Suron();`
228
+ : `const { Suron } = require('@suronai/sdk');\nawait Suron();`;
229
+
230
+ const patched = src.replace(pattern, replacement);
231
+
232
+ try {
233
+ writeFileSync(entryPath, patched, "utf-8");
234
+ console.log(" " + c.green("✓") + " " + c.dim(relEntry) + " patched");
235
+ } catch (err) {
236
+ console.error(" " + c.red("✗") + " Could not write " + relEntry + ": " + err.message);
237
+ console.log(" Add manually:\n");
238
+ printSnippet(isEsm);
239
+ }
240
+ }
241
+
242
+ /** @param {boolean} isEsm */
243
+ function printSnippet(isEsm) {
244
+ if (isEsm) {
245
+ console.log(" " + c.cyan("import") + " { Suron } from " + c.green("'@suronai/sdk'"));
246
+ console.log(" " + c.cyan("await") + " Suron()");
247
+ } else {
248
+ console.log(" const { Suron } = " + c.cyan("require") + "(" + c.green("'@suronai/sdk'") + ")");
249
+ console.log(" " + c.cyan("await") + " Suron()");
250
+ }
251
+ console.log();
252
+ }