@askdb/config 1.0.0-beta.16 → 1.0.0-beta.18
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 +15 -4
- package/dist/ai-env.d.ts +31 -0
- package/dist/ai-env.d.ts.map +1 -0
- package/dist/ai-env.js +88 -0
- package/dist/ai-env.js.map +1 -0
- package/dist/bootstrap.d.ts +6 -4
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +6 -17
- package/dist/bootstrap.js.map +1 -1
- package/dist/defaults.d.ts +7 -20
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +7 -58
- package/dist/defaults.js.map +1 -1
- package/dist/env.d.ts +2 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +2 -1
- package/dist/env.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/load-merge.js +1 -1
- package/dist/load-merge.js.map +1 -1
- package/dist/projection.d.ts +12 -2
- package/dist/projection.d.ts.map +1 -1
- package/dist/projection.js +18 -6
- package/dist/projection.js.map +1 -1
- package/dist/resolve.d.ts +36 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/{normalize.js → resolve.js} +375 -8
- package/dist/resolve.js.map +1 -0
- package/dist/runtime-config.d.ts +5 -173
- package/dist/runtime-config.d.ts.map +1 -1
- package/dist/runtime-config.js +18 -222
- package/dist/runtime-config.js.map +1 -1
- package/dist/runtime-store.d.ts +9 -6
- package/dist/runtime-store.d.ts.map +1 -1
- package/dist/runtime-store.js +9 -11
- package/dist/runtime-store.js.map +1 -1
- package/dist/runtime-types.d.ts +176 -0
- package/dist/runtime-types.d.ts.map +1 -0
- package/dist/runtime-types.js +2 -0
- package/dist/runtime-types.js.map +1 -0
- package/dist/scaffold/ai.d.ts +3 -0
- package/dist/scaffold/ai.d.ts.map +1 -1
- package/dist/scaffold/ai.js +3 -0
- package/dist/scaffold/ai.js.map +1 -1
- package/dist/scaffold/index.d.ts +12 -3
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +10 -3
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/package-manager.d.ts +93 -0
- package/dist/scaffold/package-manager.d.ts.map +1 -0
- package/dist/scaffold/package-manager.js +200 -0
- package/dist/scaffold/package-manager.js.map +1 -0
- package/dist/scaffold/plan.d.ts +110 -0
- package/dist/scaffold/plan.d.ts.map +1 -0
- package/dist/scaffold/plan.js +301 -0
- package/dist/scaffold/plan.js.map +1 -0
- package/dist/types.d.ts +6 -13
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/flatten.d.ts +0 -14
- package/dist/flatten.d.ts.map +0 -1
- package/dist/flatten.js +0 -255
- package/dist/flatten.js.map +0 -1
- package/dist/normalize.d.ts +0 -58
- package/dist/normalize.d.ts.map +0 -1
- package/dist/normalize.js.map +0 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { AskDbDialectId, AskDbIntrospectionProvider, AskDbLogLevel, AskDbModeV1, AskDbRagStore, AskDbStudioExecuteProvider } from "./constants.js";
|
|
2
|
+
import type { AskDbConfig } from "./types.js";
|
|
3
|
+
/** One resolved `ai` section: its provider, the connection it uses, its model, and an env view built from that connection only. */
|
|
4
|
+
export type AskDbRuntimeAiSection = {
|
|
5
|
+
provider: string;
|
|
6
|
+
/** Connection name within `ai.providerConfig.<provider>`. */
|
|
7
|
+
connection: string;
|
|
8
|
+
model: string | undefined;
|
|
9
|
+
/** `AiEnv` for `@askdb/ai` registry calls, built from this section's connection only. */
|
|
10
|
+
env: Record<string, string | undefined>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Typed AI runtime settings for `@askdb/core` (not `process.env`).
|
|
14
|
+
*/
|
|
15
|
+
export type AskDbRuntimeAiConfig = {
|
|
16
|
+
/**
|
|
17
|
+
* Flat env-shaped map built from the runtime snapshot: the language view plus every other
|
|
18
|
+
* canonical key. Pass to `@askdb/ai` registry methods such as `resolveAiConfig` and
|
|
19
|
+
* `createLanguageModelFromEnv`.
|
|
20
|
+
*/
|
|
21
|
+
aiEnv: Record<string, string | undefined>;
|
|
22
|
+
/** `ai.language`: the language model. `model` is undefined only for a custom provider with no model set. */
|
|
23
|
+
language: AskDbRuntimeAiSection & {
|
|
24
|
+
modelFamily: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* `ai.embedding`: the embedding model. Undefined unless `rag.embedder` is `"ai"`. Pass `env`
|
|
28
|
+
* to `resolveEmbeddingConfig` / `createEmbeddingModelFromEnv`, and `{ dimensions }` as the
|
|
29
|
+
* latter's options: `env` holds the connection and model, not the width.
|
|
30
|
+
*/
|
|
31
|
+
embedding: (AskDbRuntimeAiSection & {
|
|
32
|
+
model: string;
|
|
33
|
+
/**
|
|
34
|
+
* `ai.embedding.dimensions`: the vector size to request from the provider. Undefined
|
|
35
|
+
* leaves the width to the model; `detectEmbeddingDimensions` in `@askdb/rag` learns it.
|
|
36
|
+
*/
|
|
37
|
+
dimensions: number | undefined;
|
|
38
|
+
}) | undefined;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* OpenAI embedder settings for the `askdb-rag` CLI. Filled from `ai.embedding` when its provider
|
|
42
|
+
* is `openai`; otherwise only from the OpenAI language connection.
|
|
43
|
+
*/
|
|
44
|
+
export type AskDbRuntimeRagEmbedderConfig = {
|
|
45
|
+
apiKey: string | undefined;
|
|
46
|
+
baseURL: string | undefined;
|
|
47
|
+
model: string | undefined;
|
|
48
|
+
};
|
|
49
|
+
export type AskDbRuntimeRagConfig = {
|
|
50
|
+
embedder: AskDbRuntimeRagEmbedderConfig;
|
|
51
|
+
/** `rag.store`, or `"memory"` when the config has no `rag` block. Read this rather than `structured.rag`, which is `undefined` when the block is omitted. */
|
|
52
|
+
store: AskDbRagStore;
|
|
53
|
+
/** `rag.storeConfig` as written, with no defaults filled in; `{}` when the config has no `rag` block or the block has no `storeConfig`. */
|
|
54
|
+
storeConfig: NonNullable<AskDbConfig["rag"]>["storeConfig"];
|
|
55
|
+
};
|
|
56
|
+
export type AskDbRuntimeLoggingConfig = {
|
|
57
|
+
/** `logging.level`; `undefined` leaves the level to each tool (the CLI and the HTTP API server differ). */
|
|
58
|
+
level: AskDbLogLevel | undefined;
|
|
59
|
+
correlationId: string | undefined;
|
|
60
|
+
logFile: string | undefined;
|
|
61
|
+
logStdout: boolean;
|
|
62
|
+
};
|
|
63
|
+
export type AskDbRuntimeHttpApiConfig = {
|
|
64
|
+
listen: {
|
|
65
|
+
port: number;
|
|
66
|
+
host: string;
|
|
67
|
+
};
|
|
68
|
+
/** Whether `POST /ask` accepts a per-request `schemaJson` override. Default `false`. */
|
|
69
|
+
allowSchemaOverride: boolean;
|
|
70
|
+
/** Model-call timeout per `POST /ask` request, in milliseconds (1 to 2147483647). Default `60000`. */
|
|
71
|
+
requestTimeoutMs: number;
|
|
72
|
+
};
|
|
73
|
+
export type AskDbRuntimeIntrospectionConfig = {
|
|
74
|
+
provider: AskDbIntrospectionProvider;
|
|
75
|
+
/**
|
|
76
|
+
* Resolved Postgres connection URL when `provider === "postgres"`:
|
|
77
|
+
* `providerConfig.postgres.databaseUrl`. Never read from `process.env`.
|
|
78
|
+
* `undefined` for non-Postgres providers.
|
|
79
|
+
*/
|
|
80
|
+
postgresDatabaseUrl: string | undefined;
|
|
81
|
+
/** Resolved from `introspection.providerConfig.prisma.schemaPath`; `undefined` triggers auto-discovery in `@askdb/prisma`. */
|
|
82
|
+
prismaSchemaPath: string | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Resolved MySQL connection URL when `provider === "mysql"`:
|
|
85
|
+
* `providerConfig.mysql.databaseUrl`. Never read from `process.env`.
|
|
86
|
+
* `undefined` for non-MySQL providers.
|
|
87
|
+
*/
|
|
88
|
+
mysqlDatabaseUrl: string | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Schemas (MySQL/MariaDB: databases) to introspect, for every provider: `introspection.schemas`.
|
|
91
|
+
* `undefined` means the engine's default. `askdb introspect --schemas` overrides it.
|
|
92
|
+
*/
|
|
93
|
+
schemas: string[] | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Resolved SQLite file path when `provider === "sqlite"`:
|
|
96
|
+
* `providerConfig.sqlite.file`. Never read from `process.env`.
|
|
97
|
+
* `undefined` for non-SQLite providers.
|
|
98
|
+
*/
|
|
99
|
+
sqliteFile: string | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Resolved SQL Server connection URL when `provider === "sqlserver"`:
|
|
102
|
+
* `providerConfig.sqlserver.databaseUrl`. Never read from `process.env`.
|
|
103
|
+
* `undefined` for non-SQL Server providers.
|
|
104
|
+
*/
|
|
105
|
+
sqlserverDatabaseUrl: string | undefined;
|
|
106
|
+
/** Resolved from `introspection.outputDir`; falls back to the package default (`./askdb/`). */
|
|
107
|
+
outputDir: string;
|
|
108
|
+
};
|
|
109
|
+
export type AskDbRuntimeDevConfig = {
|
|
110
|
+
mockSql: string | undefined;
|
|
111
|
+
};
|
|
112
|
+
export type AskDbRuntimeModesConfig = {
|
|
113
|
+
/** `modes.askdbMode`; `undefined` means `"schema_only"`. */
|
|
114
|
+
askdbMode: AskDbModeV1 | undefined;
|
|
115
|
+
omitSensitiveFromPrompt: boolean;
|
|
116
|
+
};
|
|
117
|
+
export type AskDbRuntimeNlToSqlConfig = {
|
|
118
|
+
/**
|
|
119
|
+
* Optional NL→SQL dialect override from `askdb.config.ts`. When set, hosts
|
|
120
|
+
* (CLI / HTTP API / Studio) pass this to `ask({ dialect })` instead of
|
|
121
|
+
* inferring from the introspection provider.
|
|
122
|
+
*/
|
|
123
|
+
dialect: AskDbDialectId | undefined;
|
|
124
|
+
};
|
|
125
|
+
export type AskDbRuntimeStudioConfig = {
|
|
126
|
+
execute: {
|
|
127
|
+
/**
|
|
128
|
+
* Resolved execute provider. Falls back to the active introspection provider when it
|
|
129
|
+
* is a live engine (`postgres`, `mysql`, `sqlite`, `sqlserver`), then defaults to
|
|
130
|
+
* `"postgres"`.
|
|
131
|
+
*/
|
|
132
|
+
provider: AskDbStudioExecuteProvider;
|
|
133
|
+
/** Connection URL used by the Studio playground query runner for network databases. */
|
|
134
|
+
databaseUrl: string | undefined;
|
|
135
|
+
/** SQLite file path used when `provider === "sqlite"`. */
|
|
136
|
+
file: string | undefined;
|
|
137
|
+
/** Whether `POST /api/execute` is allowed. Default `false` (opt-in). */
|
|
138
|
+
enabled: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Whether `databaseUrl` / `file` may fall back to the active introspection
|
|
141
|
+
* connection. Default `false`.
|
|
142
|
+
*/
|
|
143
|
+
useIntrospectionConnection: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* True when the introspection config has a connection for this provider that
|
|
146
|
+
* Studio did not use because `useIntrospectionConnection` is off. Lets hosts
|
|
147
|
+
* explain why execute reports "not configured".
|
|
148
|
+
*/
|
|
149
|
+
introspectionConnectionAvailable: boolean;
|
|
150
|
+
/** Per-query timeout in milliseconds. Default `30000`. */
|
|
151
|
+
timeoutMs: number;
|
|
152
|
+
/** Maximum rows returned per query. Default `500`. */
|
|
153
|
+
maxRows: number;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Typed runtime view over the bootstrapped AskDB config snapshot. Every field is resolved from
|
|
158
|
+
* `structured`; `flat` and `ai.aiEnv` are projections of the same resolution, never read back.
|
|
159
|
+
*/
|
|
160
|
+
export type AskDbRuntimeConfig = {
|
|
161
|
+
readonly structured: Readonly<AskDbConfig>;
|
|
162
|
+
/** Canonical flattened map (subprocess env via {@link mergeAskDbFlatIntoEnvMap}), built from `structured`. */
|
|
163
|
+
readonly flat: Readonly<Record<string, string>>;
|
|
164
|
+
ai: AskDbRuntimeAiConfig;
|
|
165
|
+
introspection: AskDbRuntimeIntrospectionConfig;
|
|
166
|
+
rag: AskDbRuntimeRagConfig;
|
|
167
|
+
logging: AskDbRuntimeLoggingConfig;
|
|
168
|
+
httpApi: AskDbRuntimeHttpApiConfig;
|
|
169
|
+
dev: AskDbRuntimeDevConfig;
|
|
170
|
+
modes: AskDbRuntimeModesConfig;
|
|
171
|
+
nlToSql: AskDbRuntimeNlToSqlConfig;
|
|
172
|
+
studio: AskDbRuntimeStudioConfig;
|
|
173
|
+
/** One message per deprecated config key in use (it names the old and new key, never a value). */
|
|
174
|
+
deprecations: readonly string[];
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=runtime-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-types.d.ts","sourceRoot":"","sources":["../src/runtime-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-types.js","sourceRoot":"","sources":["../src/runtime-types.ts"],"names":[],"mappings":""}
|
package/dist/scaffold/ai.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ export type AskDbAiConfigScaffold = {
|
|
|
25
25
|
*
|
|
26
26
|
* Every value is emitted as a JSON string literal: the generated file is
|
|
27
27
|
* executed when the config loads, so a raw quote in a name must not inject code.
|
|
28
|
+
*
|
|
29
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
30
|
+
* `@askdb/config` may change it (ADR 0030).
|
|
28
31
|
*/
|
|
29
32
|
export declare function renderAskDbAiConfigScaffold(input: AskDbAiConfigScaffoldInput): AskDbAiConfigScaffold;
|
|
30
33
|
//# sourceMappingURL=ai.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/scaffold/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,oHAAoH;IACpH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAYF
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/scaffold/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,oHAAoH;IACpH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAYF;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,0BAA0B,GAAG,qBAAqB,CAmCpG"}
|
package/dist/scaffold/ai.js
CHANGED
|
@@ -14,6 +14,9 @@ const AZURE_RESOURCE_NAME_ENV = "AZURE_RESOURCE_NAME";
|
|
|
14
14
|
*
|
|
15
15
|
* Every value is emitted as a JSON string literal: the generated file is
|
|
16
16
|
* executed when the config loads, so a raw quote in a name must not inject code.
|
|
17
|
+
*
|
|
18
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
19
|
+
* `@askdb/config` may change it (ADR 0030).
|
|
17
20
|
*/
|
|
18
21
|
export function renderAskDbAiConfigScaffold(input) {
|
|
19
22
|
const { provider, keyEnv, modelEnv } = input;
|
package/dist/scaffold/ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/scaffold/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,iBAAiB,CAAC;AAwB7E,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AAEtD
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/scaffold/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,iBAAiB,CAAC;AAwB7E,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAiC;IAC3E,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC7C,8EAA8E;IAC9E,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,OAAO,GAA0B,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,UAAU,EAAE,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,oGAAoG;IACpG,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,iBAAiB,EAAE,CAAC,CAAC;QACxE,QAAQ,GAAG;;mBAEI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;OACpC,CAAC;IACN,CAAC;IACD,gFAAgF;IAChF,yEAAyE;IACzE,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,kFAAkF;SAC5F,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,MAAM,GAAG;gBACD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;;QAEhC,QAAQ;EACd,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;QAE9C,QAAQ;KACX,CAAC;IACJ,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
|
package/dist/scaffold/index.d.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@askdb/config/scaffold`: helpers for tools that write a new
|
|
3
|
-
* (`askdb init`, Studio's setup wizard)
|
|
4
|
-
*
|
|
2
|
+
* `@askdb/config/scaffold`: helpers for tools that set up a project and write a new
|
|
3
|
+
* `askdb.config.ts` (`askdb init`, Studio's setup wizard): the planner, which turns a
|
|
4
|
+
* project's answers into its config, `.env.example` and installs, and the package-manager
|
|
5
|
+
* helpers that run the installs. Kept off the main entry, which user configs import, so
|
|
6
|
+
* tooling can change without touching the config API.
|
|
7
|
+
*
|
|
8
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
9
|
+
* `@askdb/config` may change these exports (ADR 0030).
|
|
5
10
|
*/
|
|
6
11
|
export { renderAskDbAiConfigScaffold } from "./ai.js";
|
|
7
12
|
export type { AskDbAiConfigScaffold, AskDbAiConfigScaffoldInput, AskDbScaffoldEnvVar } from "./ai.js";
|
|
13
|
+
export { AskDbScaffoldInputError, isAskDbScaffoldEnvName, planAskDbScaffold } from "./plan.js";
|
|
14
|
+
export type { AskDbScaffoldAnswers, AskDbScaffoldPlan, ScaffoldValue } from "./plan.js";
|
|
15
|
+
export { detectPackageManager, findNearestPackageJsonDir, formatInstallCommand, isLikelyWorkspaceRoot, lockfilePackageManager, packageManagerAddArgs, packageManagerSpawnSpec, supportedBuildApprovals, } from "./package-manager.js";
|
|
16
|
+
export type { PackageManager, PackageManagerSpawnSpec } from "./package-manager.js";
|
|
8
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC/F,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACxF,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/scaffold/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@askdb/config/scaffold`: helpers for tools that write a new
|
|
3
|
-
* (`askdb init`, Studio's setup wizard)
|
|
4
|
-
*
|
|
2
|
+
* `@askdb/config/scaffold`: helpers for tools that set up a project and write a new
|
|
3
|
+
* `askdb.config.ts` (`askdb init`, Studio's setup wizard): the planner, which turns a
|
|
4
|
+
* project's answers into its config, `.env.example` and installs, and the package-manager
|
|
5
|
+
* helpers that run the installs. Kept off the main entry, which user configs import, so
|
|
6
|
+
* tooling can change without touching the config API.
|
|
7
|
+
*
|
|
8
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
9
|
+
* `@askdb/config` may change these exports (ADR 0030).
|
|
5
10
|
*/
|
|
6
11
|
export { renderAskDbAiConfigScaffold } from "./ai.js";
|
|
12
|
+
export { AskDbScaffoldInputError, isAskDbScaffoldEnvName, planAskDbScaffold } from "./plan.js";
|
|
13
|
+
export { detectPackageManager, findNearestPackageJsonDir, formatInstallCommand, isLikelyWorkspaceRoot, lockfilePackageManager, packageManagerAddArgs, packageManagerSpawnSpec, supportedBuildApprovals, } from "./package-manager.js";
|
|
7
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAEtD,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE/F,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-manager helpers for the tools that set up a project: `askdb init` and
|
|
3
|
+
* Studio's setup wizard and execute-driver install. One copy, so the two front
|
|
4
|
+
* ends detect, format and spawn the same way.
|
|
5
|
+
*
|
|
6
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
7
|
+
* `@askdb/config` may change these exports (ADR 0030).
|
|
8
|
+
*
|
|
9
|
+
* Only allowlisted package names ever reach these helpers, never user- or
|
|
10
|
+
* browser-supplied strings, but {@link packageManagerSpawnSpec} re-checks every
|
|
11
|
+
* argument anyway because Windows needs `shell: true` (see below).
|
|
12
|
+
*/
|
|
13
|
+
/** @experimental See the module note. */
|
|
14
|
+
export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
|
|
15
|
+
/**
|
|
16
|
+
* The nearest directory at or above `startDir` that holds a `package.json`.
|
|
17
|
+
*
|
|
18
|
+
* @experimental See the module note.
|
|
19
|
+
*/
|
|
20
|
+
export declare function findNearestPackageJsonDir(startDir: string): string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Whether `packageDir` looks like a monorepo or workspace root (a `pnpm-workspace.yaml`,
|
|
23
|
+
* or a `workspaces` field), whose `package.json` setup tools leave alone.
|
|
24
|
+
*
|
|
25
|
+
* @experimental See the module note.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isLikelyWorkspaceRoot(packageDir: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The package manager implied by a lockfile directly inside `dir`, if any.
|
|
30
|
+
*
|
|
31
|
+
* @experimental See the module note.
|
|
32
|
+
*/
|
|
33
|
+
export declare function lockfilePackageManager(dir: string): PackageManager | null;
|
|
34
|
+
/**
|
|
35
|
+
* The package manager to install with in `packageDir`, from the first of these that
|
|
36
|
+
* names one:
|
|
37
|
+
*
|
|
38
|
+
* 1. a lockfile in `packageDir` or a parent (pnpm, then Bun, Yarn, npm in one directory);
|
|
39
|
+
* 2. the nearest `package.json`, walking up, that declares a manager: its `packageManager`
|
|
40
|
+
* field (Corepack's `pnpm@11.28.10`), then `devEngines.packageManager` (`{ name }` or a
|
|
41
|
+
* list of them; `pnpm init` writes it);
|
|
42
|
+
* 3. `npm_config_user_agent` in `env`, which `pnpm dlx`, `yarn dlx`, `npx` and `bunx` set;
|
|
43
|
+
* 4. npm.
|
|
44
|
+
*
|
|
45
|
+
* An existing lockfile wins, so a project's install never switches managers.
|
|
46
|
+
*
|
|
47
|
+
* @experimental See the module note.
|
|
48
|
+
*/
|
|
49
|
+
export declare function detectPackageManager(packageDir: string, env?: Readonly<Record<string, string | undefined>>): PackageManager;
|
|
50
|
+
/**
|
|
51
|
+
* Arguments that add `packages` as dependencies with the given package manager.
|
|
52
|
+
* `allowBuilds` are dependencies whose install scripts pnpm must be told to run
|
|
53
|
+
* (`--allow-build=<name>`; pnpm 11 exits 1 on an unapproved one). npm and Yarn
|
|
54
|
+
* run install scripts, and Bun skips untrusted ones without failing, so only
|
|
55
|
+
* pnpm gets them.
|
|
56
|
+
*
|
|
57
|
+
* @experimental See the module note.
|
|
58
|
+
*/
|
|
59
|
+
export declare function packageManagerAddArgs(pm: PackageManager, packages: readonly string[], allowBuilds?: readonly string[]): string[];
|
|
60
|
+
/**
|
|
61
|
+
* The build approvals to pass `pm` in `dir`: `allowBuilds`, or none for a pnpm older
|
|
62
|
+
* than 10.4.0, whose `add` rejects `--allow-build` (pnpm 9 runs install scripts, and
|
|
63
|
+
* 10.0 to 10.3 skip unapproved ones without failing). A pnpm whose version can't be
|
|
64
|
+
* read keeps them.
|
|
65
|
+
*
|
|
66
|
+
* @experimental See the module note.
|
|
67
|
+
*/
|
|
68
|
+
export declare function supportedBuildApprovals(pm: PackageManager, dir: string, allowBuilds: readonly string[]): string[];
|
|
69
|
+
/**
|
|
70
|
+
* Human-readable install command, e.g. `pnpm add pg`.
|
|
71
|
+
*
|
|
72
|
+
* @experimental See the module note.
|
|
73
|
+
*/
|
|
74
|
+
export declare function formatInstallCommand(pm: PackageManager, packages: readonly string[], allowBuilds?: readonly string[]): string;
|
|
75
|
+
/** @experimental See the module note. */
|
|
76
|
+
export type PackageManagerSpawnSpec = {
|
|
77
|
+
command: string;
|
|
78
|
+
args: string[];
|
|
79
|
+
shell: boolean;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* How to spawn a package manager on this platform.
|
|
83
|
+
*
|
|
84
|
+
* On Windows, package managers are `.cmd` shims, and Node refuses to spawn
|
|
85
|
+
* `.cmd`/`.bat` files without a shell (EINVAL since Node 18.20.2 / 20.12.2,
|
|
86
|
+
* CVE-2024-27980). So Windows gets `shell: true` with the bare command name.
|
|
87
|
+
* Arguments are validated against a strict allowlist pattern first, so the
|
|
88
|
+
* shell never sees anything it could interpret.
|
|
89
|
+
*
|
|
90
|
+
* @experimental See the module note.
|
|
91
|
+
*/
|
|
92
|
+
export declare function packageManagerSpawnSpec(pm: PackageManager, args: readonly string[], platform?: NodeJS.Platform): PackageManagerSpawnSpec;
|
|
93
|
+
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/scaffold/package-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,yCAAyC;AACzC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAK7D;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAUjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,cAAc,CAWhB;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,cAAc,EAClB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,GAAE,SAAS,MAAM,EAAO,GAClC,MAAM,EAAE,CAIV;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAMjH;AAQD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,cAAc,EAClB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,GAAE,SAAS,MAAM,EAAO,GAClC,MAAM,CAER;AAED,yCAAyC;AACzC,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAQF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,uBAAuB,CAUzB"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-manager helpers for the tools that set up a project: `askdb init` and
|
|
3
|
+
* Studio's setup wizard and execute-driver install. One copy, so the two front
|
|
4
|
+
* ends detect, format and spawn the same way.
|
|
5
|
+
*
|
|
6
|
+
* @experimental Tooling for `askdb init` and AskDB Studio: a minor release of
|
|
7
|
+
* `@askdb/config` may change these exports (ADR 0030).
|
|
8
|
+
*
|
|
9
|
+
* Only allowlisted package names ever reach these helpers, never user- or
|
|
10
|
+
* browser-supplied strings, but {@link packageManagerSpawnSpec} re-checks every
|
|
11
|
+
* argument anyway because Windows needs `shell: true` (see below).
|
|
12
|
+
*/
|
|
13
|
+
import { spawnSync } from "node:child_process";
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import { dirname, join, resolve } from "node:path";
|
|
16
|
+
/** How far up the helpers walk looking for a `package.json` or lockfile. */
|
|
17
|
+
const MAX_WALK_UP = 40;
|
|
18
|
+
/**
|
|
19
|
+
* The nearest directory at or above `startDir` that holds a `package.json`.
|
|
20
|
+
*
|
|
21
|
+
* @experimental See the module note.
|
|
22
|
+
*/
|
|
23
|
+
export function findNearestPackageJsonDir(startDir) {
|
|
24
|
+
return ancestors(startDir).find((dir) => existsSync(join(dir, "package.json")));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether `packageDir` looks like a monorepo or workspace root (a `pnpm-workspace.yaml`,
|
|
28
|
+
* or a `workspaces` field), whose `package.json` setup tools leave alone.
|
|
29
|
+
*
|
|
30
|
+
* @experimental See the module note.
|
|
31
|
+
*/
|
|
32
|
+
export function isLikelyWorkspaceRoot(packageDir) {
|
|
33
|
+
if (existsSync(join(packageDir, "pnpm-workspace.yaml")) || existsSync(join(packageDir, "pnpm-workspace.yml"))) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const pkg = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
38
|
+
return pkg.workspaces !== undefined && pkg.workspaces !== null;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The package manager implied by a lockfile directly inside `dir`, if any.
|
|
46
|
+
*
|
|
47
|
+
* @experimental See the module note.
|
|
48
|
+
*/
|
|
49
|
+
export function lockfilePackageManager(dir) {
|
|
50
|
+
if (existsSync(join(dir, "pnpm-lock.yaml")))
|
|
51
|
+
return "pnpm";
|
|
52
|
+
if (existsSync(join(dir, "bun.lockb")) || existsSync(join(dir, "bun.lock")))
|
|
53
|
+
return "bun";
|
|
54
|
+
if (existsSync(join(dir, "yarn.lock")))
|
|
55
|
+
return "yarn";
|
|
56
|
+
if (existsSync(join(dir, "package-lock.json")))
|
|
57
|
+
return "npm";
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The package manager to install with in `packageDir`, from the first of these that
|
|
62
|
+
* names one:
|
|
63
|
+
*
|
|
64
|
+
* 1. a lockfile in `packageDir` or a parent (pnpm, then Bun, Yarn, npm in one directory);
|
|
65
|
+
* 2. the nearest `package.json`, walking up, that declares a manager: its `packageManager`
|
|
66
|
+
* field (Corepack's `pnpm@11.28.10`), then `devEngines.packageManager` (`{ name }` or a
|
|
67
|
+
* list of them; `pnpm init` writes it);
|
|
68
|
+
* 3. `npm_config_user_agent` in `env`, which `pnpm dlx`, `yarn dlx`, `npx` and `bunx` set;
|
|
69
|
+
* 4. npm.
|
|
70
|
+
*
|
|
71
|
+
* An existing lockfile wins, so a project's install never switches managers.
|
|
72
|
+
*
|
|
73
|
+
* @experimental See the module note.
|
|
74
|
+
*/
|
|
75
|
+
export function detectPackageManager(packageDir, env = process.env) {
|
|
76
|
+
const dirs = ancestors(packageDir);
|
|
77
|
+
for (const dir of dirs) {
|
|
78
|
+
const pm = lockfilePackageManager(dir);
|
|
79
|
+
if (pm)
|
|
80
|
+
return pm;
|
|
81
|
+
}
|
|
82
|
+
for (const dir of dirs) {
|
|
83
|
+
const pm = declaredPackageManager(dir);
|
|
84
|
+
if (pm)
|
|
85
|
+
return pm;
|
|
86
|
+
}
|
|
87
|
+
return knownPackageManager(env.npm_config_user_agent?.split("/")[0]) ?? "npm";
|
|
88
|
+
}
|
|
89
|
+
/** `dir` and its parents, nearest first, at most {@link MAX_WALK_UP} of them. */
|
|
90
|
+
function ancestors(dir) {
|
|
91
|
+
const dirs = [resolve(dir)];
|
|
92
|
+
while (dirs.length < MAX_WALK_UP) {
|
|
93
|
+
const parent = dirname(dirs[dirs.length - 1]);
|
|
94
|
+
if (parent === dirs[dirs.length - 1])
|
|
95
|
+
break;
|
|
96
|
+
dirs.push(parent);
|
|
97
|
+
}
|
|
98
|
+
return dirs;
|
|
99
|
+
}
|
|
100
|
+
/** The manager `dir/package.json` declares in `packageManager` or `devEngines.packageManager`. */
|
|
101
|
+
function declaredPackageManager(dir) {
|
|
102
|
+
let pkg;
|
|
103
|
+
try {
|
|
104
|
+
pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (pkg === null || typeof pkg !== "object")
|
|
110
|
+
return null;
|
|
111
|
+
if (typeof pkg.packageManager === "string") {
|
|
112
|
+
const pm = knownPackageManager(pkg.packageManager.split("@")[0]);
|
|
113
|
+
if (pm)
|
|
114
|
+
return pm;
|
|
115
|
+
}
|
|
116
|
+
const devEngine = pkg.devEngines?.packageManager;
|
|
117
|
+
for (const entry of Array.isArray(devEngine) ? devEngine : [devEngine]) {
|
|
118
|
+
const name = entry !== null && typeof entry === "object" ? entry.name : undefined;
|
|
119
|
+
const pm = knownPackageManager(name);
|
|
120
|
+
if (pm)
|
|
121
|
+
return pm;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
function knownPackageManager(name) {
|
|
126
|
+
return name === "pnpm" || name === "npm" || name === "yarn" || name === "bun" ? name : null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Arguments that add `packages` as dependencies with the given package manager.
|
|
130
|
+
* `allowBuilds` are dependencies whose install scripts pnpm must be told to run
|
|
131
|
+
* (`--allow-build=<name>`; pnpm 11 exits 1 on an unapproved one). npm and Yarn
|
|
132
|
+
* run install scripts, and Bun skips untrusted ones without failing, so only
|
|
133
|
+
* pnpm gets them.
|
|
134
|
+
*
|
|
135
|
+
* @experimental See the module note.
|
|
136
|
+
*/
|
|
137
|
+
export function packageManagerAddArgs(pm, packages, allowBuilds = []) {
|
|
138
|
+
if (pm === "npm")
|
|
139
|
+
return ["install", "--save", ...packages];
|
|
140
|
+
if (pm === "pnpm")
|
|
141
|
+
return ["add", ...allowBuilds.map((name) => `--allow-build=${name}`), ...packages];
|
|
142
|
+
return ["add", ...packages];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The build approvals to pass `pm` in `dir`: `allowBuilds`, or none for a pnpm older
|
|
146
|
+
* than 10.4.0, whose `add` rejects `--allow-build` (pnpm 9 runs install scripts, and
|
|
147
|
+
* 10.0 to 10.3 skip unapproved ones without failing). A pnpm whose version can't be
|
|
148
|
+
* read keeps them.
|
|
149
|
+
*
|
|
150
|
+
* @experimental See the module note.
|
|
151
|
+
*/
|
|
152
|
+
export function supportedBuildApprovals(pm, dir, allowBuilds) {
|
|
153
|
+
if (pm !== "pnpm" || allowBuilds.length === 0)
|
|
154
|
+
return [...allowBuilds];
|
|
155
|
+
const match = /^(\d+)\.(\d+)\./.exec(pnpmVersion(dir) ?? "");
|
|
156
|
+
if (!match)
|
|
157
|
+
return [...allowBuilds];
|
|
158
|
+
const [major, minor] = [Number(match[1]), Number(match[2])];
|
|
159
|
+
return major > 10 || (major === 10 && minor >= 4) ? [...allowBuilds] : [];
|
|
160
|
+
}
|
|
161
|
+
function pnpmVersion(dir) {
|
|
162
|
+
const { command, args, shell } = packageManagerSpawnSpec("pnpm", ["--version"]);
|
|
163
|
+
const result = spawnSync(command, args, { cwd: dir, encoding: "utf8", shell, stdio: ["ignore", "pipe", "ignore"], timeout: 15_000 });
|
|
164
|
+
return result.status === 0 ? result.stdout.trim() : null;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Human-readable install command, e.g. `pnpm add pg`.
|
|
168
|
+
*
|
|
169
|
+
* @experimental See the module note.
|
|
170
|
+
*/
|
|
171
|
+
export function formatInstallCommand(pm, packages, allowBuilds = []) {
|
|
172
|
+
return [pm, ...packageManagerAddArgs(pm, packages, allowBuilds)].join(" ");
|
|
173
|
+
}
|
|
174
|
+
// npm package names (optionally scoped, optionally with a version/range suffix),
|
|
175
|
+
// simple `--flag` arguments, and pnpm's `--allow-build=<package name>`. Nothing a
|
|
176
|
+
// shell would interpret.
|
|
177
|
+
const SAFE_ARG = /^(?:--[a-z][a-z-]*|--allow-build=(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*|(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*(?:@[a-z0-9.^~<>=*_-]+)?|add|install)$/i;
|
|
178
|
+
/**
|
|
179
|
+
* How to spawn a package manager on this platform.
|
|
180
|
+
*
|
|
181
|
+
* On Windows, package managers are `.cmd` shims, and Node refuses to spawn
|
|
182
|
+
* `.cmd`/`.bat` files without a shell (EINVAL since Node 18.20.2 / 20.12.2,
|
|
183
|
+
* CVE-2024-27980). So Windows gets `shell: true` with the bare command name.
|
|
184
|
+
* Arguments are validated against a strict allowlist pattern first, so the
|
|
185
|
+
* shell never sees anything it could interpret.
|
|
186
|
+
*
|
|
187
|
+
* @experimental See the module note.
|
|
188
|
+
*/
|
|
189
|
+
export function packageManagerSpawnSpec(pm, args, platform = process.platform) {
|
|
190
|
+
for (const arg of args) {
|
|
191
|
+
if (!SAFE_ARG.test(arg)) {
|
|
192
|
+
throw new Error(`Refusing to pass unsafe argument to ${pm}: ${JSON.stringify(arg)}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (platform === "win32") {
|
|
196
|
+
return { command: pm, args: [...args], shell: true };
|
|
197
|
+
}
|
|
198
|
+
return { command: pm, args: [...args], shell: false };
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=package-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/scaffold/package-manager.ts"],"names":[],"mappings":"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"}
|