@askdb/studio 0.2.0-beta.4 → 0.2.0-beta.41

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.
Files changed (49) hide show
  1. package/README.md +33 -29
  2. package/bin/askdb-studio.js +3 -1
  3. package/dist/bin.d.ts +1 -1
  4. package/dist/bin.d.ts.map +1 -1
  5. package/dist/bin.js +24 -3
  6. package/dist/bin.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +72 -15
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client/assets/index-Bl9jqOjj.css +2 -0
  11. package/dist/client/assets/index-CGC5sKu1.js +100 -0
  12. package/dist/client/index.html +2 -2
  13. package/dist/execute-registry.d.ts +89 -0
  14. package/dist/execute-registry.d.ts.map +1 -0
  15. package/dist/execute-registry.js +445 -0
  16. package/dist/execute-registry.js.map +1 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/introspection.d.ts +35 -0
  22. package/dist/introspection.d.ts.map +1 -0
  23. package/dist/introspection.js +106 -0
  24. package/dist/introspection.js.map +1 -0
  25. package/dist/package-manager.d.ts +44 -0
  26. package/dist/package-manager.d.ts.map +1 -0
  27. package/dist/package-manager.js +86 -0
  28. package/dist/package-manager.js.map +1 -0
  29. package/dist/prisma-install.d.ts +7 -0
  30. package/dist/prisma-install.d.ts.map +1 -0
  31. package/dist/prisma-install.js +7 -0
  32. package/dist/prisma-install.js.map +1 -0
  33. package/dist/request-guard.d.ts +44 -0
  34. package/dist/request-guard.d.ts.map +1 -0
  35. package/dist/request-guard.js +170 -0
  36. package/dist/request-guard.js.map +1 -0
  37. package/dist/server.d.ts +22 -4
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +1123 -148
  40. package/dist/server.js.map +1 -1
  41. package/dist/setup.d.ts +77 -0
  42. package/dist/setup.d.ts.map +1 -0
  43. package/dist/setup.js +511 -0
  44. package/dist/setup.js.map +1 -0
  45. package/dist/shared/api.d.ts +176 -3
  46. package/dist/shared/api.d.ts.map +1 -1
  47. package/package.json +81 -30
  48. package/dist/client/assets/index-Bsn2S5X2.css +0 -2
  49. package/dist/client/assets/index-C_RfRKkd.js +0 -8
package/dist/setup.js ADDED
@@ -0,0 +1,511 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import { basename, delimiter, dirname, join, resolve, isAbsolute, relative } from "node:path";
5
+ import { getBuiltinAiProviderSetup } from "@askdb/ai";
6
+ import { ASKDB_AI_PROVIDERS, bootstrapAskDbEnv, discoverAskDbConfigPath, getAskDbRuntimeConfig, } from "@askdb/config";
7
+ import { renderAskDbAiConfigScaffold } from "@askdb/config/scaffold";
8
+ import { formatInstallCommand, lockfilePackageManager, packageManagerAddArgs, packageManagerSpawnSpec, supportedBuildApprovals, } from "./package-manager.js";
9
+ import { PRISMA_BUILD_APPROVALS } from "./prisma-install.js";
10
+ /**
11
+ * Key/model env var names to scaffold for a provider, from `@askdb/ai`'s built-in
12
+ * provider table — the same source `askdb init` uses, so the two cannot drift.
13
+ */
14
+ function aiDefaults(provider) {
15
+ if (!ASKDB_AI_PROVIDERS.includes(provider))
16
+ return undefined;
17
+ return getBuiltinAiProviderSetup(provider);
18
+ }
19
+ const CONNECTION_ENV_DEFAULTS = {
20
+ postgres: "DATABASE_URL",
21
+ mysql: "DATABASE_URL",
22
+ sqlserver: "DATABASE_URL",
23
+ };
24
+ const EXECUTE_CONNECTION_ENV_DEFAULTS = {
25
+ postgres: "DATABASE_URL",
26
+ mysql: "DATABASE_URL",
27
+ sqlserver: "DATABASE_URL",
28
+ };
29
+ const EXECUTE_PROVIDERS = ["postgres", "mysql", "sqlite", "sqlserver"];
30
+ const ENV_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
31
+ // C0 controls, DEL, and the JS line/paragraph separators — never legitimate in a project path.
32
+ const CONTROL_CHAR_PATTERN = /[\u0000-\u001f\u007f\u2028\u2029]/;
33
+ /**
34
+ * Render a value as a TypeScript string literal for the generated
35
+ * `askdb.config.ts`. Every interpolated value goes through this — the file is
36
+ * later executed (via jiti) by Studio and the CLI, so a raw `"${value}"` would
37
+ * let a quote in a path inject code.
38
+ */
39
+ function tsString(value) {
40
+ return JSON.stringify(value);
41
+ }
42
+ const DB_URL_PLACEHOLDER = {
43
+ postgres: "postgresql://<USERNAME>:<PASSWORD>@<DATABASE_HOST>:<DATABASE_PORT>/<DATABASE_NAME>",
44
+ mysql: "mysql://<USERNAME>:<PASSWORD>@<DATABASE_HOST>:<DATABASE_PORT>/<DATABASE_NAME>",
45
+ sqlserver: "Data Source=<DATABASE_HOST>,<DATABASE_PORT>;Initial Catalog=<DATABASE_NAME>;User ID=<USERNAME>;Password=<PASSWORD>;Trust Server Certificate=True;Authentication=SqlPassword;",
46
+ };
47
+ /** Live-introspection driver per engine — mirrors `DB_DRIVER_PACKAGES` in `apps/cli/src/init.ts`. */
48
+ const DB_DRIVER_PACKAGES = {
49
+ postgres: "pg",
50
+ mysql: "mysql2",
51
+ sqlite: "better-sqlite3",
52
+ sqlserver: "mssql",
53
+ };
54
+ function pushEnvVar(envVars, entry) {
55
+ if (envVars.some((v) => v.name === entry.name))
56
+ return;
57
+ envVars.push(entry);
58
+ }
59
+ /** Mirrors `renderRagSection` in `apps/cli/src/init.ts` — keep the two in sync. */
60
+ function renderRagSection(ragStore, pgvectorEnv) {
61
+ switch (ragStore) {
62
+ case "file":
63
+ return ` rag: {
64
+ embedder: "mock",
65
+ store: "file",
66
+ storeConfig: { file: {} },
67
+ },`;
68
+ case "memory":
69
+ return ` rag: {
70
+ embedder: "mock",
71
+ store: "memory",
72
+ storeConfig: { memory: {} },
73
+ },`;
74
+ case "pgvector":
75
+ return ` rag: {
76
+ embedder: "mock",
77
+ store: "pgvector",
78
+ storeConfig: {
79
+ pgvector: {
80
+ databaseUrl: env(${tsString(pgvectorEnv ?? "ASKDB_PGVECTOR_URL")}),
81
+ },
82
+ },
83
+ },`;
84
+ }
85
+ }
86
+ /**
87
+ * Write `askdb.config.ts` (and `.env.example`) into `cwd`. Accepts env var
88
+ * NAMES only — secret values never travel through this endpoint. Refuses to
89
+ * overwrite an existing config. Templates mirror `askdb init`'s output.
90
+ */
91
+ export function writeSetupConfig(cwd, input) {
92
+ const existing = discoverAskDbConfigPath(cwd);
93
+ if (existing) {
94
+ throw new SetupError(409, `A config already exists at ${existing}. Edit it directly instead.`);
95
+ }
96
+ const schemaOut = validateRelativePath(input.schemaOut ?? "./askdb", "schemaOut");
97
+ // `aiDefaults` only accepts ids listed in `ASKDB_AI_PROVIDERS`, so `constructor`/`__proto__`
98
+ // can't masquerade as a provider — the provider name is emitted as an object key in the
99
+ // generated config.
100
+ const providerDefaults = aiDefaults(input.aiProvider);
101
+ if (!providerDefaults)
102
+ throw new SetupError(400, `Unknown AI provider: ${JSON.stringify(input.aiProvider)}`);
103
+ const aiKeyEnv = validateEnvName(input.aiKeyEnv ?? providerDefaults.keyEnv, "aiKeyEnv");
104
+ const aiModelEnv = input.aiModelEnv ? validateEnvName(input.aiModelEnv, "aiModelEnv") : undefined;
105
+ // The `ai` block comes from `@askdb/config/scaffold`, shared with `askdb init`.
106
+ const aiScaffold = renderAskDbAiConfigScaffold({
107
+ provider: input.aiProvider,
108
+ keyEnv: aiKeyEnv,
109
+ ...(aiModelEnv ? { modelEnv: aiModelEnv } : {}),
110
+ });
111
+ const envVars = aiScaffold.envVars.map((v) => ({
112
+ ...v,
113
+ requiredForIntrospection: false,
114
+ }));
115
+ let introspectionSection;
116
+ switch (input.database) {
117
+ case "postgres":
118
+ case "mysql":
119
+ case "sqlserver": {
120
+ const connectionEnv = validateEnvName(input.connectionEnv ?? CONNECTION_ENV_DEFAULTS[input.database], "connectionEnv");
121
+ envVars.push({
122
+ name: connectionEnv,
123
+ purpose: `${input.database} connection URL (introspection only)`,
124
+ requiredForIntrospection: true,
125
+ exampleValue: DB_URL_PLACEHOLDER[input.database],
126
+ });
127
+ introspectionSection = ` introspection: {
128
+ provider: ${tsString(input.database)},
129
+ providerConfig: {
130
+ ${input.database}: {
131
+ databaseUrl: env(${tsString(connectionEnv)}),
132
+ },
133
+ },
134
+ outputDir: ${tsString(schemaOut)},
135
+ },`;
136
+ break;
137
+ }
138
+ case "sqlite": {
139
+ const file = validateRelativePath(input.sqliteFile ?? "./data.db", "sqliteFile");
140
+ introspectionSection = ` introspection: {
141
+ provider: "sqlite",
142
+ providerConfig: {
143
+ sqlite: {
144
+ file: ${tsString(file)},
145
+ },
146
+ },
147
+ outputDir: ${tsString(schemaOut)},
148
+ },`;
149
+ break;
150
+ }
151
+ case "prisma": {
152
+ const schemaLine = input.prismaSchema
153
+ ? `\n schemaPath: ${tsString(validateRelativePath(input.prismaSchema, "prismaSchema"))},`
154
+ : "";
155
+ introspectionSection = ` introspection: {
156
+ provider: "prisma",
157
+ providerConfig: {
158
+ prisma: {${schemaLine}
159
+ },
160
+ },
161
+ outputDir: ${tsString(schemaOut)},
162
+ },`;
163
+ break;
164
+ }
165
+ default:
166
+ throw new SetupError(400, `Unknown database: ${String(input.database)}`);
167
+ }
168
+ const ragStore = input.ragStore ?? "file";
169
+ let pgvectorEnv;
170
+ if (ragStore === "pgvector") {
171
+ pgvectorEnv = validateEnvName(input.pgvectorEnv ?? "ASKDB_PGVECTOR_URL", "pgvectorEnv");
172
+ pushEnvVar(envVars, {
173
+ name: pgvectorEnv,
174
+ purpose: "pgvector connection URL",
175
+ requiredForIntrospection: false,
176
+ exampleValue: "postgresql://<USERNAME>:<PASSWORD>@<DATABASE_HOST>:<DATABASE_PORT>/<DATABASE_NAME>",
177
+ });
178
+ }
179
+ const ragSection = renderRagSection(ragStore, pgvectorEnv);
180
+ let studioSection = null;
181
+ let studioExecuteProvider;
182
+ if (input.studioExecute) {
183
+ studioExecuteProvider =
184
+ input.studioExecuteProvider ?? (input.database !== "prisma" ? input.database : undefined);
185
+ if (!studioExecuteProvider) {
186
+ throw new SetupError(400, "`studioExecuteProvider` is required when `studioExecute` is enabled and `database` is \"prisma\".");
187
+ }
188
+ if (!EXECUTE_PROVIDERS.includes(studioExecuteProvider)) {
189
+ throw new SetupError(400, `Unknown studioExecuteProvider: ${JSON.stringify(studioExecuteProvider)}`);
190
+ }
191
+ if (studioExecuteProvider === "sqlite") {
192
+ const file = validateRelativePath(input.studioExecuteSqliteFile ?? input.sqliteFile ?? "./data.db", "studioExecuteSqliteFile");
193
+ studioSection = ` studio: {
194
+ execute: {
195
+ enabled: true,
196
+ provider: "sqlite",
197
+ file: ${tsString(file)},
198
+ },
199
+ },`;
200
+ }
201
+ else {
202
+ const execConnectionEnv = validateEnvName(input.studioExecuteConnectionEnv ?? EXECUTE_CONNECTION_ENV_DEFAULTS[studioExecuteProvider], "studioExecuteConnectionEnv");
203
+ pushEnvVar(envVars, {
204
+ name: execConnectionEnv,
205
+ purpose: `${studioExecuteProvider} connection URL (Studio execute)`,
206
+ requiredForIntrospection: false,
207
+ exampleValue: DB_URL_PLACEHOLDER[studioExecuteProvider],
208
+ });
209
+ studioSection = ` studio: {
210
+ execute: {
211
+ enabled: true,
212
+ provider: ${tsString(studioExecuteProvider)},
213
+ databaseUrl: env(${tsString(execConnectionEnv)}),
214
+ },
215
+ },`;
216
+ }
217
+ }
218
+ const sections = [aiScaffold.source, introspectionSection, ragSection, studioSection].filter((s) => s !== null);
219
+ const config = `import { defineConfig, env, type AskDbConfig } from "@askdb/config";
220
+
221
+ export default defineConfig({
222
+ ${sections.join("\n")}
223
+ } satisfies AskDbConfig);
224
+ `;
225
+ const configPath = join(cwd, "askdb.config.ts");
226
+ writeFileSync(configPath, config, "utf8");
227
+ let envExamplePath = join(cwd, ".env.example");
228
+ if (existsSync(envExamplePath)) {
229
+ envExamplePath = null; // don't clobber an existing example file
230
+ }
231
+ else {
232
+ const example = [
233
+ "# AskDB environment — copy to .env and fill in real values.",
234
+ "# .env is read by Studio, the CLI, and the HTTP API; never commit it.",
235
+ ...envVars.map((v) => v.exampleValue ? `${v.name}=${v.exampleValue}` : `${v.name}= # ${v.purpose}`),
236
+ "",
237
+ ].join("\n");
238
+ writeFileSync(envExamplePath, example, "utf8");
239
+ }
240
+ // The config imports `@askdb/config`, so the project needs it (plus the
241
+ // live-introspection driver and, if enabled, the Studio execute driver)
242
+ // installed — same as `askdb init` does.
243
+ const deps = ensureProjectDependencies(cwd, input.database, studioExecuteProvider);
244
+ // Install the runtime snapshot from the file we just wrote so the rest of
245
+ // the server (and the introspection step) sees the new config immediately.
246
+ // Skipped when dependencies are still missing, or when the config can't
247
+ // load yet (e.g. `.env` isn't filled in — pgvector's `databaseUrl` must
248
+ // resolve at load time, unlike introspection URLs) — probeSetupState
249
+ // retries later and surfaces the load error.
250
+ if (!deps.manualInstallCommand) {
251
+ try {
252
+ bootstrapAskDbEnv({ cwd });
253
+ }
254
+ catch {
255
+ // probeSetupState re-attempts this after the caller fills in `.env`.
256
+ }
257
+ }
258
+ return {
259
+ configPath,
260
+ envExamplePath,
261
+ envVars,
262
+ installed: deps.installed,
263
+ manualInstallCommand: deps.manualInstallCommand,
264
+ packageJsonCreated: deps.packageJsonCreated,
265
+ };
266
+ }
267
+ /**
268
+ * Make sure the project can load the config we just wrote: `@askdb/config` +
269
+ * `dotenv` must be resolvable from the project, and live engines need their
270
+ * introspection driver. Mirrors `askdb init`'s install plan. Falls back to a
271
+ * manual command when the project looks like a workspace root or the install
272
+ * fails — never mutates a monorepo root implicitly.
273
+ */
274
+ function ensureProjectDependencies(cwd, database, studioExecuteProvider) {
275
+ const missing = [];
276
+ if (!isInstalledFor(cwd, "@askdb/config")) {
277
+ missing.push(`@askdb/config@${resolveConfigSpec()}`);
278
+ }
279
+ const allowBuilds = [];
280
+ // `@askdb/prisma` is an optional peer of Studio (#259). It depends on Prisma, whose
281
+ // `@prisma/engines` postinstall pnpm 11 refuses to run until it's approved, and then
282
+ // exits 1. A Prisma project approves it anyway, so the install does it here.
283
+ // `askdb init` does the same (`apps/cli/src/init.ts`).
284
+ if (database === "prisma" && !isInstalledFor(cwd, "@askdb/prisma")) {
285
+ missing.push(`@askdb/prisma@${resolvePrismaSpec()}`);
286
+ allowBuilds.push(...PRISMA_BUILD_APPROVALS);
287
+ }
288
+ const driversNeeded = new Set();
289
+ if (DB_DRIVER_PACKAGES[database])
290
+ driversNeeded.add(database);
291
+ if (studioExecuteProvider && DB_DRIVER_PACKAGES[studioExecuteProvider])
292
+ driversNeeded.add(studioExecuteProvider);
293
+ for (const db of driversNeeded) {
294
+ const driver = DB_DRIVER_PACKAGES[db];
295
+ if (driver && !isInstalledFor(cwd, driver) && !missing.includes(driver)) {
296
+ missing.push(driver);
297
+ }
298
+ }
299
+ if (missing.length === 0) {
300
+ return { installed: null, manualInstallCommand: null, packageJsonCreated: false };
301
+ }
302
+ let packageJsonCreated = false;
303
+ const nearestPkgDir = findNearestPackageJsonDir(cwd);
304
+ if (!nearestPkgDir) {
305
+ writeFileSync(join(cwd, "package.json"), `${JSON.stringify({ name: basename(cwd) || "askdb-project", private: true }, null, 2)}\n`, "utf8");
306
+ packageJsonCreated = true;
307
+ }
308
+ const pkgDir = nearestPkgDir ?? cwd;
309
+ const pm = detectPackageManager(pkgDir);
310
+ const approvedBuilds = supportedBuildApprovals(pm, pkgDir, allowBuilds);
311
+ // Only auto-install when the project manifest sits exactly at the wizard's
312
+ // directory. A package.json found further up might be a monorepo root or an
313
+ // unrelated project — never mutate those implicitly.
314
+ if (pkgDir !== resolve(cwd) || (isLikelyWorkspaceRoot(pkgDir) && !packageJsonCreated)) {
315
+ return {
316
+ installed: null,
317
+ manualInstallCommand: formatInstallCommand(pm, missing, approvedBuilds),
318
+ packageJsonCreated,
319
+ };
320
+ }
321
+ const installer = setupInstallerForTests ?? runInstall;
322
+ const ok = installer(pm, pkgDir, missing, approvedBuilds);
323
+ if (!ok) {
324
+ return {
325
+ installed: null,
326
+ manualInstallCommand: formatInstallCommand(pm, missing, approvedBuilds),
327
+ packageJsonCreated,
328
+ };
329
+ }
330
+ return { installed: missing, manualInstallCommand: null, packageJsonCreated };
331
+ }
332
+ /**
333
+ * Whether `packageName` is installed for `dir`: in a `node_modules` of `dir` or a parent,
334
+ * or in a `NODE_PATH` directory. Checked on disk, not with Node's resolver: Node 24 and
335
+ * later can keep a failed lookup until the process exits, so resolving a package this
336
+ * step then installs would hide it from the introspection step's load. Under Yarn
337
+ * Plug'n'Play there is no `node_modules`, and its resolver is the only record, so it asks that.
338
+ */
339
+ function isInstalledFor(dir, packageName) {
340
+ if (process.versions.pnp) {
341
+ try {
342
+ createRequire(join(dir, "package.json")).resolve(packageName);
343
+ return true;
344
+ }
345
+ catch {
346
+ return false;
347
+ }
348
+ }
349
+ const roots = (process.env.NODE_PATH ?? "").split(delimiter).filter(Boolean);
350
+ for (let current = resolve(dir);; current = dirname(current)) {
351
+ roots.push(join(current, "node_modules"));
352
+ if (dirname(current) === current)
353
+ break;
354
+ }
355
+ return roots.some((root) => existsSync(join(root, packageName, "package.json")));
356
+ }
357
+ /**
358
+ * Locate the `package.json` of the `@askdb/config` copy Studio itself runs
359
+ * with. `require.resolve("@askdb/config/package.json")` fails because the
360
+ * package's `exports` map doesn't expose it — resolve the entry point and
361
+ * walk up instead.
362
+ */
363
+ function readStudioConfigPackageJson() {
364
+ try {
365
+ const require = createRequire(import.meta.url);
366
+ const entry = require.resolve("@askdb/config");
367
+ const pkgDir = findNearestPackageJsonDir(dirname(entry));
368
+ if (!pkgDir)
369
+ return undefined;
370
+ return JSON.parse(readFileSync(join(pkgDir, "package.json"), "utf8"));
371
+ }
372
+ catch {
373
+ return undefined;
374
+ }
375
+ }
376
+ /** Pin `@askdb/config` to the version Studio itself was built against. */
377
+ function resolveConfigSpec() {
378
+ return readStudioConfigPackageJson()?.version ?? "latest";
379
+ }
380
+ /**
381
+ * The `@askdb/prisma` spec to install: Studio's published peer range (`^x`), or the
382
+ * workspace package's version in the monorepo. A range, not the floor: `askdb` hosts
383
+ * Studio and may be released later with a higher floor, which an exact pin to Studio's
384
+ * would break (npm exits with ERESOLVE). `askdb init` pins its own floor.
385
+ */
386
+ function resolvePrismaSpec() {
387
+ try {
388
+ const require = createRequire(import.meta.url);
389
+ const studioPkg = require("../package.json");
390
+ const declared = studioPkg.peerDependencies?.["@askdb/prisma"];
391
+ if (!declared)
392
+ return "latest";
393
+ if (!declared.startsWith("workspace:"))
394
+ return declared;
395
+ const pkgDir = findNearestPackageJsonDir(dirname(require.resolve("@askdb/prisma")));
396
+ if (!pkgDir)
397
+ return "latest";
398
+ return JSON.parse(readFileSync(join(pkgDir, "package.json"), "utf8")).version ?? "latest";
399
+ }
400
+ catch {
401
+ return "latest";
402
+ }
403
+ }
404
+ function findNearestPackageJsonDir(startDir) {
405
+ let dir = resolve(startDir);
406
+ for (let i = 0; i < 40; i += 1) {
407
+ if (existsSync(join(dir, "package.json")))
408
+ return dir;
409
+ const parent = dirname(dir);
410
+ if (parent === dir)
411
+ return undefined;
412
+ dir = parent;
413
+ }
414
+ return undefined;
415
+ }
416
+ function isLikelyWorkspaceRoot(packageDir) {
417
+ if (existsSync(join(packageDir, "pnpm-workspace.yaml")) ||
418
+ existsSync(join(packageDir, "pnpm-workspace.yml"))) {
419
+ return true;
420
+ }
421
+ try {
422
+ const pkg = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
423
+ return pkg.workspaces !== undefined && pkg.workspaces !== null;
424
+ }
425
+ catch {
426
+ return false;
427
+ }
428
+ }
429
+ let setupInstallerForTests;
430
+ /** @internal Tests only — replaces the real package-manager install. */
431
+ export function setSetupInstallerForTests(installer) {
432
+ setupInstallerForTests = installer;
433
+ }
434
+ function detectPackageManager(packageDir) {
435
+ let dir = packageDir;
436
+ for (let i = 0; i < 40; i += 1) {
437
+ const pm = lockfilePackageManager(dir);
438
+ if (pm)
439
+ return pm;
440
+ const parent = dirname(dir);
441
+ if (parent === dir)
442
+ break;
443
+ dir = parent;
444
+ }
445
+ return "npm";
446
+ }
447
+ function runInstall(pm, packageDir, packages, allowBuilds) {
448
+ const env = { ...process.env, CI: process.env.CI ?? "true" };
449
+ try {
450
+ const { command, args, shell } = packageManagerSpawnSpec(pm, packageManagerAddArgs(pm, packages, allowBuilds));
451
+ const result = spawnSync(command, args, { cwd: packageDir, stdio: "ignore", env, shell });
452
+ return result.status === 0;
453
+ }
454
+ catch {
455
+ return false;
456
+ }
457
+ }
458
+ /** Re-check the on-disk state (config file, schema artifact) for setup routing. */
459
+ export function probeSetupState(cwd) {
460
+ const configPath = discoverAskDbConfigPath(cwd) ?? null;
461
+ if (!configPath) {
462
+ return { hasConfig: false, configPath: null, hasArtifact: false, outputDir: null, loadError: null };
463
+ }
464
+ try {
465
+ // Re-bootstrap so config/.env edits made since server start are honored.
466
+ bootstrapAskDbEnv({ cwd });
467
+ const outputDir = resolve(cwd, getAskDbRuntimeConfig().introspection.outputDir);
468
+ return {
469
+ hasConfig: true,
470
+ configPath,
471
+ hasArtifact: existsSync(join(outputDir, "schema.json")),
472
+ outputDir,
473
+ loadError: null,
474
+ };
475
+ }
476
+ catch (error) {
477
+ return {
478
+ hasConfig: true,
479
+ configPath,
480
+ hasArtifact: false,
481
+ outputDir: null,
482
+ loadError: error instanceof Error ? error.message : String(error),
483
+ };
484
+ }
485
+ }
486
+ function validateEnvName(name, field) {
487
+ const trimmed = name.trim();
488
+ if (!ENV_NAME_PATTERN.test(trimmed)) {
489
+ throw new SetupError(400, `\`${field}\` must be an environment variable NAME like DATABASE_URL (got: ${JSON.stringify(name)}). Values belong in .env, not here.`);
490
+ }
491
+ return trimmed;
492
+ }
493
+ function validateRelativePath(path, field) {
494
+ const trimmed = path.trim();
495
+ if (trimmed === "" ||
496
+ isAbsolute(trimmed) ||
497
+ relative(".", trimmed).startsWith("..") ||
498
+ CONTROL_CHAR_PATTERN.test(trimmed)) {
499
+ throw new SetupError(400, `\`${field}\` must be a relative path inside the project (got: ${JSON.stringify(path)}).`);
500
+ }
501
+ return trimmed;
502
+ }
503
+ export class SetupError extends Error {
504
+ status;
505
+ constructor(status, message) {
506
+ super(message);
507
+ this.status = status;
508
+ this.name = "SetupError";
509
+ }
510
+ }
511
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}