@happyvertical/smrt-config 0.53.3 → 0.53.5
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/AGENTS.md +4 -0
- package/README.md +64 -0
- package/dist/ai.d.ts +130 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/database-environment.d.ts +57 -0
- package/dist/database-environment.d.ts.map +1 -0
- package/dist/export.d.ts +0 -8
- package/dist/export.d.ts.map +1 -1
- package/dist/index.d.ts +74 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +339 -4
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts.map +1 -1
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -22,7 +22,10 @@ Configuration management with cosmiconfig, secret sanitization, and SSG export.
|
|
|
22
22
|
| `sanitizeConfig(config)` | Strips keys matching: apiKey, password, secret, token, credential, private, auth, key |
|
|
23
23
|
| `resolveApplicationRuntime(config)` | Resolve and validate a local, self-hosted, or cloud infrastructure profile |
|
|
24
24
|
| `resolveConfiguredApplicationRuntime()` | Resolve loaded file config plus highest-priority `setConfig()` runtime overrides |
|
|
25
|
+
| `resolveEffectiveApplicationRuntime(config)` | The `smrt app` / SvelteKit runtime rule: no `runtime` block in either layer → `local`; a present non-block value (`null`/`false`/`0`/`''`) fails closed |
|
|
26
|
+
| `resolveConfiguredAIProvider()` / `tryResolveAIProviderConfig()` | One AI provider resolver (`src/ai.ts`): explicit > `ai` block > `SMRT_AI_*`/`HAVE_AI_*` env > selected provider's key var > auto-detect; see README |
|
|
25
27
|
| `getApplicationRuntimePreset(profile)` | Inspect a profile's safe provider defaults |
|
|
28
|
+
| `resolveCliDatabaseConfig(env?)` | CLI database precedence shared by `smrt` and `smrt-dev-mcp`: declared `packages.cli.database.url` > `DATABASE_URL` (engine: config type > `DATABASE_TYPE` > scheme); read-only (`src/database-environment.ts`) |
|
|
26
29
|
|
|
27
30
|
## Key Files
|
|
28
31
|
|
|
@@ -34,6 +37,7 @@ Configuration management with cosmiconfig, secret sanitization, and SSG export.
|
|
|
34
37
|
|
|
35
38
|
## Gotchas
|
|
36
39
|
|
|
40
|
+
- **AI credentials are bound to their source's provider**: a lower-priority key/baseUrl is dropped when another provider wins; redacted base URLs show only the origin. **AI keys come from the environment**: the `ai` block names a variable (`apiKeyEnv`); resolver errors/`toJSON()` never contain keys or URL credentials. Core and the chat dev routes use this resolver; agents share its provider key-name map (`getDefaultAIKeyEnvName`) and keep per-tenant secret lookup; do not add new provider-env parsing elsewhere.
|
|
37
41
|
- **clearCache() is global**: affects all modules sharing the config instance
|
|
38
42
|
- **SSG export defaults to no secrets**: must explicitly set `includeSecrets: true` to include them
|
|
39
43
|
- **Deep merge**: later values override earlier ones at each key level
|
package/README.md
CHANGED
|
@@ -106,6 +106,14 @@ calls deep-merge providers while the profile is unchanged; an explicit profile
|
|
|
106
106
|
switch resets earlier runtime provider selections before applying the new
|
|
107
107
|
profile.
|
|
108
108
|
|
|
109
|
+
An application that may omit the block uses
|
|
110
|
+
`resolveEffectiveApplicationRuntime(await loadConfig())`, the rule `smrt app`
|
|
111
|
+
and the SvelteKit runtime share: when neither the file nor a `setConfig()`
|
|
112
|
+
override declares `runtime`, the profile is `local`; a present value that is
|
|
113
|
+
not a runtime block (`null`, `false`, `0`, `''`) throws the same
|
|
114
|
+
`RuntimeProfileValidationError` instead of selecting `local`; `setConfig()`
|
|
115
|
+
rejects such a `runtime` override with that error before storing anything.
|
|
116
|
+
|
|
109
117
|
### Use config in code
|
|
110
118
|
|
|
111
119
|
```typescript
|
|
@@ -169,6 +177,56 @@ const safeJson = exportConfig(config, { includeSecrets: false });
|
|
|
169
177
|
const sanitized = sanitizeConfig(config);
|
|
170
178
|
```
|
|
171
179
|
|
|
180
|
+
## AI provider
|
|
181
|
+
|
|
182
|
+
Declare the assistant model once in `smrt.config.ts`; keep the secret in the environment.
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export default defineConfig({
|
|
186
|
+
ai: { provider: 'openai', model: 'gpt-4o', apiKeyEnv: 'OPENAI_API_KEY' },
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import { resolveConfiguredAIProvider, toAIClientOptions } from '@happyvertical/smrt-config';
|
|
192
|
+
import { getAI } from '@happyvertical/ai';
|
|
193
|
+
|
|
194
|
+
const ai = await getAI(toAIClientOptions(resolveConfiguredAIProvider()));
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Default precedence, applied per field (`provider`, `apiKey`, `baseUrl`, `model`), highest first:
|
|
198
|
+
|
|
199
|
+
1. `explicit` values passed by the caller (for example a class's `options.ai`)
|
|
200
|
+
2. the `ai` block (`provider`, `model`, `baseUrl`, `apiKeyEnv`; legacy `packages.ai` is read below `ai`)
|
|
201
|
+
3. environment, one prefix at a time: `<PREFIX>_PROVIDER`, `_API_KEY`, `_BASE_URL`, `_MODEL` for `SMRT_AI`, then `HAVE_AI`
|
|
202
|
+
4. the selected provider's own key variable (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`); a key for any other provider is never used
|
|
203
|
+
5. with no provider selected, auto-detect the first provider whose key variable is set (openai, anthropic, gemini)
|
|
204
|
+
|
|
205
|
+
Credential binding: a key or base URL belongs to the provider named by its own source (explicit, the
|
|
206
|
+
`ai` block, or one env prefix). If a higher-priority source selects a different provider, the lower
|
|
207
|
+
source's key and base URL are discarded and the key comes only from sources valid for the selected
|
|
208
|
+
provider (then that provider's own key variable). A source that supplies a key but names no provider is
|
|
209
|
+
generic and binds to whichever provider is selected. Displayed base URLs (`toJSON()`,
|
|
210
|
+
`describeAIProviderConfig()`, `redactBaseUrl()`) expose only the origin; the real URL still goes to the client.
|
|
211
|
+
The rule holds at every layer: the `ai` block layers (runtime `ai`, runtime `packages.ai`, file `ai`, file `packages.ai`)
|
|
212
|
+
are merged with provider ownership (`mergeAIConfigLayers`): when a higher layer names a different provider, the lower
|
|
213
|
+
layers' `apiKey`, `apiKeyEnv`, `baseUrl` and `model` are dropped (a model id is provider-specific). A layer with no provider
|
|
214
|
+
binds to the provider selected so far. Core applies the same rule between its global `ai` config and `options.ai`, and always
|
|
215
|
+
builds its client from the resolver's bound result. Aliases are normalised before coalescing (`provider`/`type`,
|
|
216
|
+
`model`/`defaultModel`), so a blank primary never hides the alias.
|
|
217
|
+
All object merges go through one canonicalising helper, `mergeAIConfigObjects(lower, higher)`
|
|
218
|
+
(folds `provider`/`type` and `model`/`defaultModel`, drops blanks, and drops the lower side's provider, key, key variable, base URL and model
|
|
219
|
+
when the higher side names a different provider): accumulating `setConfig({ ai })` / `setConfig({ packages: { ai } })`, `mergeExportedConfig`
|
|
220
|
+
`ai` blocks, and core's global `ai` + `options.ai`. `withAIAliases()` sets both client-facing aliases on the final result.
|
|
221
|
+
Core consults the block only when it names a `provider`; a partial block behaves like no block.
|
|
222
|
+
|
|
223
|
+
Call sites keep their historical order through options: the chat dev routes pass
|
|
224
|
+
`prefixes: ['SMRT_CHAT_DEV', 'SMRT_AI', 'HAVE_AI']` and `envOverridesConfig: true`; core passes
|
|
225
|
+
`prefixes: ['SMRT_AI']`, `autoDetect: false`. `resolveAIProviderConfig` throws
|
|
226
|
+
`AIProviderNotConfiguredError` (naming variables only) when nothing is configured;
|
|
227
|
+
`tryResolveAIProviderConfig` returns `undefined`. Results redact the key in `toJSON()` /
|
|
228
|
+
`describeAIProviderConfig()`; errors never include key or URL credentials.
|
|
229
|
+
|
|
172
230
|
## API
|
|
173
231
|
|
|
174
232
|
### Functions
|
|
@@ -187,9 +245,15 @@ const sanitized = sanitizeConfig(config);
|
|
|
187
245
|
| `sanitizeConfig(config)` | Strip secret-matching keys |
|
|
188
246
|
| `resolveApplicationRuntime(config)` | Resolve and fail-closed validate a runtime profile |
|
|
189
247
|
| `resolveConfiguredApplicationRuntime()` | Resolve effective file plus runtime-overridden profile config |
|
|
248
|
+
| `resolveEffectiveApplicationRuntime(config)` | Same, but no `runtime` block (file or override) selects `local`; a present non-block value fails closed |
|
|
190
249
|
| `getApplicationRuntimePreset(profile)` | Inspect an immutable copy of a profile preset |
|
|
250
|
+
| `resolveCliDatabaseConfig(env?)` | The `smrt` / `smrt-dev-mcp` database: configured `packages.cli.database.url`, else `DATABASE_URL` / `DATABASE_TYPE` (read-only) |
|
|
191
251
|
| `mergeExportedConfig(baseConfig, exportedConfig)` | Merge an exported config over a base |
|
|
192
252
|
| `parseExportedConfig(raw)` | Parse an exported config string |
|
|
253
|
+
| `resolveAIProviderConfig(options?)` / `tryResolveAIProviderConfig(options?)` | Pure resolver (throws / returns `undefined` when unconfigured) |
|
|
254
|
+
| `resolveConfiguredAIProvider(options?)` / `tryResolveConfiguredAIProvider(options?)` | Same, against the loaded `ai` block |
|
|
255
|
+
| `getAIConfigBlock()` | Effective `ai` block (runtime > file; `ai` > `packages.ai`) |
|
|
256
|
+
| `toAIClientOptions(resolved)` | `getAI()` options (`type`, `provider`, `apiKey`, `baseUrl`, `defaultModel`) |
|
|
193
257
|
|
|
194
258
|
### Priority Order
|
|
195
259
|
|
package/dist/ai.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared AI provider resolution (#3372).
|
|
3
|
+
*
|
|
4
|
+
* One resolver for every AI consumer. Default precedence, highest first, applied
|
|
5
|
+
* per field (`provider`, `apiKey`, `baseUrl`, `model`):
|
|
6
|
+
*
|
|
7
|
+
* 1. `explicit` — values the caller passes in (for example `options.ai`).
|
|
8
|
+
* 2. The `ai` block of `smrt.config.ts` (`apiKeyEnv` names the key variable).
|
|
9
|
+
* 3. Environment variables, one prefix at a time, in `prefixes` order:
|
|
10
|
+
* `<PREFIX>_PROVIDER`, `<PREFIX>_API_KEY`, `<PREFIX>_BASE_URL`,
|
|
11
|
+
* `<PREFIX>_MODEL`. Default prefixes: `SMRT_AI`, then `HAVE_AI`.
|
|
12
|
+
* 4. Provider-specific key variable for the *selected* provider only
|
|
13
|
+
* (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`).
|
|
14
|
+
* 5. Auto-detect: with no provider selected, the first provider whose key
|
|
15
|
+
* variable is set (openai, anthropic, gemini).
|
|
16
|
+
*
|
|
17
|
+
* `envOverridesConfig` swaps (2) and (3) for call sites that historically let
|
|
18
|
+
* env win.
|
|
19
|
+
*
|
|
20
|
+
* Credential binding: a key or base URL is bound to the provider named by its
|
|
21
|
+
* own source (explicit, the config block, or one env prefix). When a
|
|
22
|
+
* higher-priority source selects a different provider, the lower source's key
|
|
23
|
+
* and base URL are discarded, then the selected provider's own key variable is
|
|
24
|
+
* used. A source that supplies a key but names no provider is generic and
|
|
25
|
+
* binds to whichever provider is selected.
|
|
26
|
+
*
|
|
27
|
+
* Redaction: displayed base URLs expose only the origin. Secrets are never included in errors, `toJSON()` or `describe`.
|
|
28
|
+
*/
|
|
29
|
+
import type { AIConfigBlock } from './types.js';
|
|
30
|
+
/** Provider -> conventional API key variable. */
|
|
31
|
+
export declare const AI_PROVIDER_KEY_ENV: Readonly<Record<string, string>>;
|
|
32
|
+
/** Default env prefixes, highest priority first. */
|
|
33
|
+
export declare const DEFAULT_AI_ENV_PREFIXES: readonly string[];
|
|
34
|
+
/** Conventional key variable for a provider name, if it has one. */
|
|
35
|
+
export declare function getDefaultAIKeyEnvName(provider: string | undefined | null): string | undefined;
|
|
36
|
+
export type AIConfigField = 'provider' | 'apiKey' | 'baseUrl' | 'model';
|
|
37
|
+
/** Where a field came from. Names only; never values. */
|
|
38
|
+
export type AIConfigSource = 'explicit' | 'config' | `env:${string}` | 'provider-key-env' | 'auto-detect';
|
|
39
|
+
export interface AIExplicitConfig {
|
|
40
|
+
provider?: string;
|
|
41
|
+
/** Alias of `provider` accepted for `AIClientOptions` compatibility. */
|
|
42
|
+
type?: string;
|
|
43
|
+
apiKey?: string;
|
|
44
|
+
baseUrl?: string;
|
|
45
|
+
model?: string;
|
|
46
|
+
/** Alias of `model` accepted for `AIClientOptions` compatibility. */
|
|
47
|
+
defaultModel?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ResolveAIProviderOptions {
|
|
50
|
+
/** Caller-supplied values; highest priority. */
|
|
51
|
+
explicit?: AIExplicitConfig | null;
|
|
52
|
+
/**
|
|
53
|
+
* The `smrt.config.ts` `ai` block. Omit to use the loaded config (via
|
|
54
|
+
* `resolveConfiguredAIProvider`); pass `null` to ignore config entirely.
|
|
55
|
+
*/
|
|
56
|
+
config?: AIConfigBlock | null;
|
|
57
|
+
/** Environment to read. Defaults to `process.env`. */
|
|
58
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
59
|
+
/** Env prefixes, highest priority first. Default `['SMRT_AI', 'HAVE_AI']`. */
|
|
60
|
+
prefixes?: readonly string[];
|
|
61
|
+
/**
|
|
62
|
+
* Fall back to the selected provider's own key variable (`OPENAI_API_KEY`...).
|
|
63
|
+
* Default `true`.
|
|
64
|
+
*/
|
|
65
|
+
providerKeyEnvFallback?: boolean;
|
|
66
|
+
/** Auto-detect provider from well-known key variables. Default `true`. */
|
|
67
|
+
autoDetect?: boolean;
|
|
68
|
+
/** Let env prefixes beat the config block. Default `false`. */
|
|
69
|
+
envOverridesConfig?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Treat "no provider" as unconfigured even when an API key is present.
|
|
72
|
+
* Default `true`; when `false`, a key alone is enough (`provider` stays
|
|
73
|
+
* undefined and the provider layer applies its own default).
|
|
74
|
+
*/
|
|
75
|
+
requireProvider?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface ResolvedAIProviderConfig {
|
|
78
|
+
provider?: string;
|
|
79
|
+
apiKey?: string;
|
|
80
|
+
baseUrl?: string;
|
|
81
|
+
model?: string;
|
|
82
|
+
/** Which source supplied each field (names only). */
|
|
83
|
+
sources: Partial<Record<AIConfigField, AIConfigSource>>;
|
|
84
|
+
/** Redacted view: safe to log or serialize. */
|
|
85
|
+
toJSON(): Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
/** Options for `getAI` (from `@happyvertical/ai`). */
|
|
88
|
+
export interface AIProviderClientOptions {
|
|
89
|
+
type?: string;
|
|
90
|
+
provider?: string;
|
|
91
|
+
apiKey?: string;
|
|
92
|
+
baseUrl?: string;
|
|
93
|
+
defaultModel?: string;
|
|
94
|
+
}
|
|
95
|
+
/** Thrown when no provider is configured. The message names variables only. */
|
|
96
|
+
export declare class AIProviderNotConfiguredError extends Error {
|
|
97
|
+
readonly code = "SMRT_AI_NOT_CONFIGURED";
|
|
98
|
+
constructor(message: string);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Reduce a base URL to its origin (scheme, host, port) for display. Userinfo,
|
|
102
|
+
* path, query and fragment can all carry credentials, so none are shown. The
|
|
103
|
+
* real URL is still what is passed to the client.
|
|
104
|
+
*/
|
|
105
|
+
export declare function redactBaseUrl(value: string | undefined): string | undefined;
|
|
106
|
+
export declare function tryResolveAIProviderConfig(options?: ResolveAIProviderOptions): ResolvedAIProviderConfig | undefined;
|
|
107
|
+
/** Resolve or throw {@link AIProviderNotConfiguredError}. */
|
|
108
|
+
export declare function resolveAIProviderConfig(options?: ResolveAIProviderOptions): ResolvedAIProviderConfig;
|
|
109
|
+
/** Redacted description: presence flags and source names, never secrets. */
|
|
110
|
+
export declare function describeAIProviderConfig(resolved: Pick<ResolvedAIProviderConfig, 'provider' | 'apiKey' | 'baseUrl' | 'model' | 'sources'>): Record<string, unknown>;
|
|
111
|
+
/** Convert a resolved config into `getAI()` options, omitting unset fields. */
|
|
112
|
+
export declare function toAIClientOptions(resolved: Pick<ResolvedAIProviderConfig, 'provider' | 'apiKey' | 'baseUrl' | 'model'>): AIProviderClientOptions;
|
|
113
|
+
/**
|
|
114
|
+
* Canonicalise one AI config object: blank strings are removed, `type` folds
|
|
115
|
+
* into `provider` and `defaultModel` into `model` (`provider`/`model` win when
|
|
116
|
+
* both are non-blank). Other keys pass through untouched.
|
|
117
|
+
*/
|
|
118
|
+
export declare function canonicalizeAIConfig(input: unknown): Record<string, unknown>;
|
|
119
|
+
/**
|
|
120
|
+
* The one merge for two AI config objects (`lower` < `higher`). Both sides are
|
|
121
|
+
* canonicalised first. When `higher` names a provider and `lower` names a
|
|
122
|
+
* different one, `lower`'s provider, key, key variable, base URL and model are
|
|
123
|
+
* dropped so no credential is paired with another provider. Everything else is
|
|
124
|
+
* a shallow overlay with `higher` winning. The result carries canonical
|
|
125
|
+
* `provider` / `model` only; use {@link withAIAliases} for client-facing aliases.
|
|
126
|
+
*/
|
|
127
|
+
export declare function mergeAIConfigObjects(lower: unknown, higher: unknown): Record<string, unknown>;
|
|
128
|
+
/** Set both client-facing aliases (`provider`+`type`, `model`+`defaultModel`). */
|
|
129
|
+
export declare function withAIAliases<T extends Record<string, unknown>>(config: T): T;
|
|
130
|
+
//# sourceMappingURL=ai.d.ts.map
|
package/dist/ai.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DATABASE_URL` / `DATABASE_TYPE` as the fallback for the CLI database
|
|
3
|
+
* (`packages.cli.database`), shared by `smrt` and `smrt-dev-mcp` (#3410,
|
|
4
|
+
* #3446). The precedence is explicit:
|
|
5
|
+
*
|
|
6
|
+
* 1. `packages.cli.database.url` from any config layer (runtime `setConfig`,
|
|
7
|
+
* `smrt.config` `packages.cli`, or the global `smrt` section) — an explicit
|
|
8
|
+
* project setting always wins, so a stray shell `DATABASE_URL` can never
|
|
9
|
+
* retarget a project that names its database.
|
|
10
|
+
* 2. `DATABASE_URL`, with the engine from the config's `database.type`, else
|
|
11
|
+
* `DATABASE_TYPE` (`sqlite`, `postgres`, `postgresql`), else inferred from
|
|
12
|
+
* the URL scheme (`postgres://`/`postgresql://` → postgres, anything else
|
|
13
|
+
* sqlite — the same default the commands apply to a typeless config).
|
|
14
|
+
* 3. Nothing: callers apply their own default (`:memory:` for the CLI).
|
|
15
|
+
*
|
|
16
|
+
* URL and engine travel as a pair: a configured URL never combines with an
|
|
17
|
+
* environment engine. An unrecognised `DATABASE_TYPE` disables the fallback
|
|
18
|
+
* rather than guess; its error names the variable, never the URL.
|
|
19
|
+
*/
|
|
20
|
+
/** Database engines `packages.cli.database.type` accepts from the environment. */
|
|
21
|
+
export type CliDatabaseType = 'sqlite' | 'postgres';
|
|
22
|
+
/** Where {@link resolveCliDatabase} found the effective CLI database. */
|
|
23
|
+
export type CliDatabaseSource =
|
|
24
|
+
/** A config layer declares `database.url`; the environment was not read. */
|
|
25
|
+
'config'
|
|
26
|
+
/** `DATABASE_URL` supplies the database. */
|
|
27
|
+
| 'environment'
|
|
28
|
+
/** `DATABASE_URL` is set but `DATABASE_TYPE` is not a supported engine. */
|
|
29
|
+
| 'invalid-environment'
|
|
30
|
+
/** Neither the config nor the environment names a database. */
|
|
31
|
+
| 'none';
|
|
32
|
+
/** Result of {@link resolveCliDatabase}. */
|
|
33
|
+
export interface ResolvedCliDatabase {
|
|
34
|
+
readonly source: CliDatabaseSource;
|
|
35
|
+
/**
|
|
36
|
+
* The effective database: the declared block (`type` only when the config
|
|
37
|
+
* declares a string) for `config`, the resolved pair for `environment`,
|
|
38
|
+
* otherwise `null`.
|
|
39
|
+
*/
|
|
40
|
+
readonly database: {
|
|
41
|
+
readonly type?: string;
|
|
42
|
+
readonly url: string;
|
|
43
|
+
} | null;
|
|
44
|
+
/** For `invalid-environment`: why the fallback was refused (no URL). */
|
|
45
|
+
readonly error?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply the precedence above to a declared `packages.cli.database` block.
|
|
49
|
+
*
|
|
50
|
+
* @internal Exported through `resolveCliDatabaseConfig()` in the package
|
|
51
|
+
* entry, which supplies the declared block from the loaded config layers.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveCliDatabase(declared: {
|
|
54
|
+
url?: unknown;
|
|
55
|
+
type?: unknown;
|
|
56
|
+
} | undefined, env: Readonly<Record<string, string | undefined>>): ResolvedCliDatabase;
|
|
57
|
+
//# sourceMappingURL=database-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-environment.d.ts","sourceRoot":"","sources":["../src/database-environment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,kFAAkF;AAClF,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEpD,yEAAyE;AACzE,MAAM,MAAM,iBAAiB;AAC3B,4EAA4E;AAC1E,QAAQ;AACV,4CAA4C;GAC1C,aAAa;AACf,2EAA2E;GACzE,qBAAqB;AACvB,+DAA+D;GAC7D,MAAM,CAAC;AAEX,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EACvD,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAChD,mBAAmB,CA6BrB"}
|
package/dist/export.d.ts
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config export utilities for static site generation
|
|
3
|
-
*
|
|
4
|
-
* These utilities enable exporting database-backed agent configurations
|
|
5
|
-
* to static files for SSG sites.
|
|
6
|
-
*
|
|
7
|
-
* @module
|
|
8
|
-
*/
|
|
9
1
|
/**
|
|
10
2
|
* Deep-clone a config object, removing every key that looks like a secret.
|
|
11
3
|
*
|
package/dist/export.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AA8KA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAyCvD;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAaR;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAY5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnE,UAAU,EAAE,CAAC,EACb,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,GACzB,CAAC,CA2CH"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { type ResolveAIProviderOptions, type ResolvedAIProviderConfig } from './ai.js';
|
|
2
|
+
import { type ResolvedCliDatabase } from './database-environment.js';
|
|
1
3
|
import { type ResolvedApplicationRuntime } from './runtime-profile.js';
|
|
2
|
-
import type { LoadConfigOptions, SmrtConfig } from './types.js';
|
|
4
|
+
import type { AIConfigBlock, LoadConfigOptions, SmrtConfig } from './types.js';
|
|
5
|
+
export { AI_PROVIDER_KEY_ENV, type AIConfigField, type AIConfigSource, type AIExplicitConfig, type AIProviderClientOptions, AIProviderNotConfiguredError, canonicalizeAIConfig, DEFAULT_AI_ENV_PREFIXES, describeAIProviderConfig, getDefaultAIKeyEnvName, mergeAIConfigObjects, type ResolveAIProviderOptions, type ResolvedAIProviderConfig, redactBaseUrl, resolveAIProviderConfig, toAIClientOptions, tryResolveAIProviderConfig, withAIAliases, } from './ai.js';
|
|
6
|
+
export type { CliDatabaseSource, CliDatabaseType, ResolvedCliDatabase, } from './database-environment.js';
|
|
3
7
|
export { type ExportConfigOptions, exportConfig, mergeExportedConfig, parseExportedConfig, sanitizeConfig, } from './export.js';
|
|
4
8
|
export { clearRuntimeConfig, getRuntimeConfig, mergeConfigs } from './merge.js';
|
|
5
9
|
export type { ApplicationRuntimeConfig, ApplicationRuntimeProfile, AssetOwnership, AssetStorageProvider, AuthenticationProvider, BackupProvider, ConnectionOwnership, DatabaseEngine, JobTopology, NetworkExposure, OwnerBootstrapMode, ResolvedApplicationRuntime, RuntimeAssetProvider, RuntimeAuthenticationProvider, RuntimeCapabilities, RuntimeDatabaseProvider, RuntimeInvariants, RuntimeJobProvider, RuntimeNetworkProvider, RuntimeOverrideReport, RuntimePortabilityProvider, RuntimeProfileValidationIssue, RuntimeProviderOverrides, RuntimeProviders, RuntimeSecretProvider, RuntimeTenancyProvider, SecretOwnership, SecretProvider, TenancyMode, TenantContextMode, TenantIsolation, } from './runtime-profile.js';
|
|
6
10
|
export { getApplicationRuntimePreset, RuntimeProfileValidationError, resolveApplicationRuntime, } from './runtime-profile.js';
|
|
7
|
-
export type { CliConfig, DatabaseConfig, ExportConfig, ExportFileConfig, ExportFilterValue, LoadConfigOptions, MigrationsConfig, MigrationsPostgresConfig, PostgresPermissionsConfig, SchemaContractConfig, SiteConfig, SiteLocation, SiteNavigation, SiteNavigationLink, SitePublisher, SiteTheme, SmrtConfig, SmrtGlobalConfig, } from './types.js';
|
|
11
|
+
export type { AIConfigBlock, CliConfig, DatabaseConfig, ExportConfig, ExportFileConfig, ExportFilterValue, LoadConfigOptions, MigrationsConfig, MigrationsPostgresConfig, PostgresPermissionsConfig, SchemaContractConfig, SiteConfig, SiteLocation, SiteNavigation, SiteNavigationLink, SitePublisher, SiteTheme, SmrtConfig, SmrtGlobalConfig, } from './types.js';
|
|
8
12
|
/**
|
|
9
13
|
* Extend globalThis to include our config cache properties.
|
|
10
14
|
* Using globalThis ensures all module instances share the same config,
|
|
@@ -94,6 +98,30 @@ export declare function getConfig(): SmrtConfig | null;
|
|
|
94
98
|
* effective provider composition violates a profile invariant.
|
|
95
99
|
*/
|
|
96
100
|
export declare function resolveConfiguredApplicationRuntime(): Readonly<ResolvedApplicationRuntime>;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve the runtime an application actually runs with, from its loaded
|
|
103
|
+
* file config plus {@link setConfig} runtime overrides.
|
|
104
|
+
*
|
|
105
|
+
* The one rule `smrt app` and the SvelteKit runtime share (#3446): when
|
|
106
|
+
* neither layer declares a `runtime` block — the property is absent, or
|
|
107
|
+
* explicitly `undefined` — the application runs the `local` profile.
|
|
108
|
+
* Otherwise this is {@link resolveConfiguredApplicationRuntime}, so a present
|
|
109
|
+
* value that is not a runtime block (`null`, `false`, `0`, `''`, a string, an
|
|
110
|
+
* array) fails closed with the same {@link RuntimeProfileValidationError}
|
|
111
|
+
* instead of silently selecting `local`.
|
|
112
|
+
*
|
|
113
|
+
* @param config - The file configuration returned by {@link loadConfig};
|
|
114
|
+
* `null`/`undefined` means no file configuration.
|
|
115
|
+
* @returns A validated, deterministic, secret-free runtime snapshot.
|
|
116
|
+
* @throws {RuntimeProfileValidationError} When a declared runtime block is not
|
|
117
|
+
* an object or violates a profile invariant.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const runtime = resolveEffectiveApplicationRuntime(await loadConfig());
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export declare function resolveEffectiveApplicationRuntime(config: SmrtConfig | null | undefined): Readonly<ResolvedApplicationRuntime>;
|
|
97
125
|
/**
|
|
98
126
|
* Return the `site` section of the loaded configuration.
|
|
99
127
|
*
|
|
@@ -143,6 +171,27 @@ export declare function getSiteConfig(): import('./types.js').SiteConfig | null;
|
|
|
143
171
|
* @see {@link SmrtConfig.modules}
|
|
144
172
|
*/
|
|
145
173
|
export declare function getModuleConfig<T extends Record<string, unknown>>(moduleName: string, defaults?: T): T;
|
|
174
|
+
/**
|
|
175
|
+
* Resolve the database `smrt` commands and `smrt-dev-mcp` use: the declared
|
|
176
|
+
* `packages.cli.database` from any config layer, else `DATABASE_URL` /
|
|
177
|
+
* `DATABASE_TYPE` (#3410, #3446).
|
|
178
|
+
*
|
|
179
|
+
* A configured `database.url` always wins and the environment is not read.
|
|
180
|
+
* Otherwise `DATABASE_URL` supplies the URL and its engine comes from the
|
|
181
|
+
* config's `database.type`, else `DATABASE_TYPE`, else the URL scheme. An
|
|
182
|
+
* unsupported `DATABASE_TYPE` yields `invalid-environment` instead of a guess.
|
|
183
|
+
* Read-only: nothing is written to the config. Call after {@link loadConfig}.
|
|
184
|
+
*
|
|
185
|
+
* @param env - Environment to read (defaults to `process.env`).
|
|
186
|
+
* @returns The source and, for `config`/`environment`, the database block.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* await loadConfig();
|
|
191
|
+
* const { source, database } = resolveCliDatabaseConfig();
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export declare function resolveCliDatabaseConfig(env?: Readonly<Record<string, string | undefined>>): ResolvedCliDatabase;
|
|
146
195
|
/**
|
|
147
196
|
* Return the resolved configuration for a named package.
|
|
148
197
|
*
|
|
@@ -251,4 +300,27 @@ export declare function clearCache(): void;
|
|
|
251
300
|
* @see {@link loadConfig}
|
|
252
301
|
*/
|
|
253
302
|
export declare function defineConfig(config: SmrtConfig): SmrtConfig;
|
|
303
|
+
/**
|
|
304
|
+
* The effective `ai` block: runtime `ai` > runtime `packages.ai` > file `ai` >
|
|
305
|
+
* file `packages.ai` (`smrt init` historically wrote `packages.ai`), merged
|
|
306
|
+
* field by field. Returns `null` when none is declared.
|
|
307
|
+
*/
|
|
308
|
+
export declare function getAIConfigBlock(): AIConfigBlock | null;
|
|
309
|
+
/**
|
|
310
|
+
* Merge `ai` block layers, lowest priority first, preserving provider
|
|
311
|
+
* ownership: `apiKey`, `apiKeyEnv`, `baseUrl` and `model` belong to the
|
|
312
|
+
* provider their layer names. When a higher layer names a different provider,
|
|
313
|
+
* the credentials and model already collected from lower layers for another
|
|
314
|
+
* provider are dropped (a model id is provider-specific, so it is dropped
|
|
315
|
+
* too). A layer that names no provider contributes generic values that bind to
|
|
316
|
+
* the provider selected so far.
|
|
317
|
+
*/
|
|
318
|
+
export declare function mergeAIConfigLayers(layers: ReadonlyArray<unknown>): AIConfigBlock | null;
|
|
319
|
+
/**
|
|
320
|
+
* {@link resolveAIProviderConfig} against the loaded `smrt.config.ts` `ai`
|
|
321
|
+
* block. Throws `AIProviderNotConfiguredError` when nothing is configured.
|
|
322
|
+
*/
|
|
323
|
+
export declare function resolveConfiguredAIProvider(options?: ResolveAIProviderOptions): ResolvedAIProviderConfig;
|
|
324
|
+
/** Non-throwing variant of {@link resolveConfiguredAIProvider}. */
|
|
325
|
+
export declare function tryResolveConfiguredAIProvider(options?: ResolveAIProviderOptions): ResolvedAIProviderConfig | undefined;
|
|
254
326
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|