@modootoday/envs 0.1.0
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/.agent/skills/env-value-store/SKILL.md +350 -0
- package/LICENSE +93 -0
- package/NOTICE +24 -0
- package/README.md +97 -0
- package/dist/chunk-47XO3SDE.js +4591 -0
- package/dist/chunk-STHFIZRP.js +1310 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +10 -0
- package/dist/config-DKLCgBZX.d.cts +116 -0
- package/dist/config-DKLCgBZX.d.ts +116 -0
- package/dist/config.cjs +940 -0
- package/dist/config.d.cts +5 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +10 -0
- package/dist/index.cjs +5915 -0
- package/dist/index.d.cts +418 -0
- package/dist/index.d.ts +418 -0
- package/dist/index.js +112 -0
- package/package.json +98 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { U as Unlock, D as DekWrap } from './config-DKLCgBZX.js';
|
|
2
|
+
export { a as ConfigOptions, C as ConfigResult, b as ConflictError, c as CreateKeyringOptions, d as DEK_BYTES, E as Encoding, K as KekMissingError, e as Keyring, f as KeyringLockedError, L as Layer, O as OnConflict, P as Provenance, R as RecoveryCodeError, W as WrapMethod, g as addWrap, h as config, i as createKeyring, j as formatRecoveryCode, k as generateRecoveryCode, n as normaliseRecoveryCode, s as sameKey, u as unlockDek } from './config-DKLCgBZX.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* env format parser. An env document is a sequence of logical entries, each a
|
|
6
|
+
* comment, a blank line, or KEY=VALUE; a fourth kind means the file is not env
|
|
7
|
+
* format and none of it loads. Values never appear in findings.
|
|
8
|
+
*/
|
|
9
|
+
type EntryKind = "comment" | "blank" | "assignment";
|
|
10
|
+
type Quote = '"' | "'" | "`";
|
|
11
|
+
interface ParsedEntry {
|
|
12
|
+
readonly kind: EntryKind;
|
|
13
|
+
/** 1-based line where the entry starts. */
|
|
14
|
+
readonly line: number;
|
|
15
|
+
/** 1-based line where the entry ends; differs from line for multiline values. */
|
|
16
|
+
readonly endLine: number;
|
|
17
|
+
readonly key?: string;
|
|
18
|
+
readonly value?: string;
|
|
19
|
+
readonly quote?: Quote | null;
|
|
20
|
+
/** `export KEY=v` form. */
|
|
21
|
+
readonly exported?: boolean;
|
|
22
|
+
}
|
|
23
|
+
type FindingCode = "NOT_ENV_LINE" | "EMPTY_KEY" | "INVALID_KEY" | "UNTERMINATED_QUOTE" | "TRAILING_CONTENT";
|
|
24
|
+
interface ParseFinding {
|
|
25
|
+
readonly code: FindingCode;
|
|
26
|
+
readonly line: number;
|
|
27
|
+
}
|
|
28
|
+
interface ParseResult {
|
|
29
|
+
readonly ok: boolean;
|
|
30
|
+
readonly entries: readonly ParsedEntry[];
|
|
31
|
+
readonly findings: readonly ParseFinding[];
|
|
32
|
+
}
|
|
33
|
+
declare function parseEnv(input: string): ParseResult;
|
|
34
|
+
/**
|
|
35
|
+
* All-or-nothing: a file with any finding contributes no values at all, so a
|
|
36
|
+
* partially parseable file cannot lose entries silently.
|
|
37
|
+
*/
|
|
38
|
+
declare function toRecord(result: ParseResult): Record<string, string> | null;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* One provider per sqlite backend. Everything the backends disagree about lives
|
|
42
|
+
* here as data, so the open path stays the same for all three.
|
|
43
|
+
*/
|
|
44
|
+
type SqliteBackend = "bun" | "node" | "better-sqlite3";
|
|
45
|
+
interface SqliteProvider {
|
|
46
|
+
readonly backend: SqliteBackend;
|
|
47
|
+
/** Held as a string: a literal specifier would make bundlers hard-fail. */
|
|
48
|
+
readonly specifier: string;
|
|
49
|
+
/** Export holding the constructor; "default" for the CJS module. */
|
|
50
|
+
readonly exportName: string;
|
|
51
|
+
/** Built into its runtime, so it costs a consumer nothing. */
|
|
52
|
+
readonly builtIn: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether this provider may even be attempted here. Not every bad import
|
|
55
|
+
* throws: loading better-sqlite3 under bun 1.3.14 panics the process with
|
|
56
|
+
* NAPI FATAL ERROR, which no try/catch can contain. Ineligible providers are
|
|
57
|
+
* skipped rather than tried.
|
|
58
|
+
*/
|
|
59
|
+
eligible(): boolean;
|
|
60
|
+
/** Constructor options. No two backends spell these the same way. */
|
|
61
|
+
openOptions(readOnly: boolean): unknown;
|
|
62
|
+
/**
|
|
63
|
+
* Key form for a named parameter. Measured: bun needs the sigil token,
|
|
64
|
+
* better-sqlite3 needs the bare name, node takes either. Getting it wrong is
|
|
65
|
+
* not always an error — bun binds NULL and says nothing.
|
|
66
|
+
*/
|
|
67
|
+
bindKey(bare: string, token: string): string;
|
|
68
|
+
}
|
|
69
|
+
declare const PROVIDERS: readonly SqliteProvider[];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* One sqlite surface over three providers. Each built-in resolves only in its
|
|
73
|
+
* own runtime, so an import failure is the ordinary path, and better-sqlite3 is
|
|
74
|
+
* the fallback for runtimes that have neither.
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
type SqliteValue = null | number | bigint | string | Uint8Array;
|
|
78
|
+
type BindValue = SqliteValue | boolean;
|
|
79
|
+
type BindParams = readonly BindValue[] | Readonly<Record<string, BindValue>>;
|
|
80
|
+
interface RunResult {
|
|
81
|
+
readonly changes: number | bigint;
|
|
82
|
+
readonly lastInsertRowid: number | bigint;
|
|
83
|
+
}
|
|
84
|
+
interface Statement<Row = Record<string, SqliteValue>> {
|
|
85
|
+
get(params?: BindParams): Row | undefined;
|
|
86
|
+
all(params?: BindParams): Row[];
|
|
87
|
+
run(params?: BindParams): RunResult;
|
|
88
|
+
}
|
|
89
|
+
interface Database {
|
|
90
|
+
readonly backend: SqliteBackend;
|
|
91
|
+
exec(sql: string): void;
|
|
92
|
+
prepare<Row = Record<string, SqliteValue>>(sql: string): Statement<Row>;
|
|
93
|
+
/** BEGIN/COMMIT around fn, ROLLBACK if it throws. Not nestable. */
|
|
94
|
+
transaction<T>(fn: () => T): T;
|
|
95
|
+
close(): void;
|
|
96
|
+
}
|
|
97
|
+
interface OpenOptions {
|
|
98
|
+
/** WAL unless the database is in memory, where it is not available. */
|
|
99
|
+
readonly journalMode?: "WAL" | "DELETE" | "MEMORY";
|
|
100
|
+
readonly readOnly?: boolean;
|
|
101
|
+
/** Pin a backend instead of taking the first that loads. */
|
|
102
|
+
readonly backend?: SqliteBackend;
|
|
103
|
+
}
|
|
104
|
+
declare class SqliteUnavailableError extends Error {
|
|
105
|
+
readonly attempts: ReadonlyArray<readonly [string, string]>;
|
|
106
|
+
constructor(attempts: ReadonlyArray<readonly [string, string]>);
|
|
107
|
+
}
|
|
108
|
+
declare class SqliteBindError extends Error {
|
|
109
|
+
constructor(message: string);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Named placeholders in a statement, bare name to the exact token. bun binds
|
|
113
|
+
* NULL without complaint when a key's sigil does not match its placeholder, so
|
|
114
|
+
* keys are matched against the SQL rather than trusted or stripped.
|
|
115
|
+
*/
|
|
116
|
+
declare function scanPlaceholders(sql: string): ReadonlyMap<string, string>;
|
|
117
|
+
declare function openDatabase(path: string, options?: OpenOptions): Promise<Database>;
|
|
118
|
+
declare function openDatabaseSync(path: string, options?: OpenOptions): Database;
|
|
119
|
+
/** Which backends load here. Empty when none do. */
|
|
120
|
+
declare function availableBackends(): Promise<readonly SqliteBackend[]>;
|
|
121
|
+
/** Test seam: forget loaded constructors so resolution can run again. */
|
|
122
|
+
declare function resetBindingCache(): void;
|
|
123
|
+
|
|
124
|
+
/** Algorithm agility. One value today; without the field there is no second. */
|
|
125
|
+
declare const FORMAT_AES_256_GCM = 1;
|
|
126
|
+
declare class EnvelopeFormatError extends Error {
|
|
127
|
+
constructor(message: string);
|
|
128
|
+
}
|
|
129
|
+
declare class EnvelopeAuthError extends Error {
|
|
130
|
+
constructor(message: string);
|
|
131
|
+
}
|
|
132
|
+
interface EnvelopeHeader {
|
|
133
|
+
readonly format: number;
|
|
134
|
+
readonly kekVersion: number;
|
|
135
|
+
readonly iv: Uint8Array;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Context is what the blob is bound to — the row it belongs to, or the freshness
|
|
139
|
+
* of the catalog it was derived from. Moving an authentic blob elsewhere then
|
|
140
|
+
* fails to decrypt instead of resurrecting a value.
|
|
141
|
+
*/
|
|
142
|
+
interface SealInput {
|
|
143
|
+
readonly kek: Uint8Array;
|
|
144
|
+
readonly kekVersion: number;
|
|
145
|
+
readonly plaintext: Uint8Array;
|
|
146
|
+
readonly context: Uint8Array;
|
|
147
|
+
/** Injectable for tests; production leaves it to the runtime CSPRNG. */
|
|
148
|
+
readonly iv?: Uint8Array;
|
|
149
|
+
}
|
|
150
|
+
declare function seal(input: SealInput): Uint8Array;
|
|
151
|
+
interface OpenInput {
|
|
152
|
+
readonly kek: Uint8Array;
|
|
153
|
+
readonly blob: Uint8Array;
|
|
154
|
+
readonly context: Uint8Array;
|
|
155
|
+
}
|
|
156
|
+
declare function open(input: OpenInput): Uint8Array;
|
|
157
|
+
/** Read the header without the key, so a reader can tell which KEK is needed. */
|
|
158
|
+
declare function readHeader(blob: Uint8Array): EnvelopeHeader;
|
|
159
|
+
/**
|
|
160
|
+
* Key names are stored as deterministic HMACs, so opening the database without
|
|
161
|
+
* the key shows neither values nor which keys exist. Derived under its own
|
|
162
|
+
* label rather than using the KEK directly for a second algorithm.
|
|
163
|
+
*/
|
|
164
|
+
declare function hashKeyName(kek: Uint8Array, name: string): Uint8Array;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Catalog schema and its version gate. Statements are literals; nothing a
|
|
168
|
+
* caller supplies reaches statement text.
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
declare const SCHEMA_VERSION = 4;
|
|
172
|
+
interface Migration {
|
|
173
|
+
readonly version: number;
|
|
174
|
+
readonly statements: readonly string[];
|
|
175
|
+
}
|
|
176
|
+
declare const MIGRATIONS: readonly Migration[];
|
|
177
|
+
declare class CatalogVersionError extends Error {
|
|
178
|
+
readonly found: number;
|
|
179
|
+
readonly supported: number;
|
|
180
|
+
constructor(found: number, supported: number, message: string);
|
|
181
|
+
}
|
|
182
|
+
interface CatalogMeta {
|
|
183
|
+
readonly version: number;
|
|
184
|
+
readonly catalogId: string;
|
|
185
|
+
readonly createdAt: string;
|
|
186
|
+
}
|
|
187
|
+
declare function readMeta(db: Database): CatalogMeta | undefined;
|
|
188
|
+
interface CreateOptions {
|
|
189
|
+
readonly catalogId?: string;
|
|
190
|
+
readonly now?: () => string;
|
|
191
|
+
}
|
|
192
|
+
/** Build an empty catalog at the current version. */
|
|
193
|
+
declare function createSchema(db: Database, options?: CreateOptions): CatalogMeta;
|
|
194
|
+
/**
|
|
195
|
+
* A catalog newer than this build is refused rather than read: reading it with
|
|
196
|
+
* an older understanding is how a value comes back wrong. An older one is
|
|
197
|
+
* reported, never migrated as a side effect of being opened -- one run of a
|
|
198
|
+
* floating CLI must not upgrade a catalog another project has pinned.
|
|
199
|
+
*/
|
|
200
|
+
declare function checkVersion(meta: CatalogMeta): void;
|
|
201
|
+
interface OpenCatalogOptions extends OpenOptions {
|
|
202
|
+
/** Create the schema when the file holds none. Off for read paths. */
|
|
203
|
+
readonly create?: boolean;
|
|
204
|
+
readonly catalogId?: string;
|
|
205
|
+
readonly now?: () => string;
|
|
206
|
+
}
|
|
207
|
+
interface OpenedCatalog {
|
|
208
|
+
readonly db: Database;
|
|
209
|
+
readonly meta: CatalogMeta;
|
|
210
|
+
}
|
|
211
|
+
declare function openCatalog(path: string, options?: OpenCatalogOptions): Promise<OpenedCatalog>;
|
|
212
|
+
/** Bring an older catalog up to this build's version, on purpose. */
|
|
213
|
+
declare function migrate(db: Database): CatalogMeta;
|
|
214
|
+
|
|
215
|
+
declare function findProjectRoot(from: string): string | undefined;
|
|
216
|
+
declare function globalDir(home?: string): string;
|
|
217
|
+
interface LocateOptions {
|
|
218
|
+
readonly cwd?: string;
|
|
219
|
+
readonly home?: string;
|
|
220
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
221
|
+
}
|
|
222
|
+
interface Located {
|
|
223
|
+
/** The catalog this project reads and writes. Always present. */
|
|
224
|
+
readonly project: string;
|
|
225
|
+
/**
|
|
226
|
+
* The machine-wide layer, when a project catalog is distinct from it. Absent
|
|
227
|
+
* when there is no project root, because then the home catalog is the project
|
|
228
|
+
* one and there is no second layer.
|
|
229
|
+
*/
|
|
230
|
+
readonly global?: string;
|
|
231
|
+
readonly projectRoot?: string;
|
|
232
|
+
readonly source: "explicit" | "project" | "global";
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* ENVS_CATALOG_PATH names one catalog and suppresses the layering: a caller
|
|
236
|
+
* that says exactly which file to read should not silently get a second.
|
|
237
|
+
*/
|
|
238
|
+
declare function locateCatalogs(options?: LocateOptions): Located;
|
|
239
|
+
/**
|
|
240
|
+
* The cache follows the binary rather than the catalog: node_modules when
|
|
241
|
+
* installed, the home directory under npx or a global install. It is derived,
|
|
242
|
+
* so the two never disagree in a way that matters.
|
|
243
|
+
*/
|
|
244
|
+
declare function cacheDir(options?: LocateOptions): string;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* export — the one command that prints values. Everything else in this package
|
|
248
|
+
* reports keys and provenance and never a value, so this path is explicit,
|
|
249
|
+
* asks for the secret rather than taking it from argv, and says what it did.
|
|
250
|
+
*/
|
|
251
|
+
|
|
252
|
+
type ExportFormat = "csv" | "env" | "json" | "shell";
|
|
253
|
+
interface ExportOptions extends LocateOptions {
|
|
254
|
+
readonly unlock: Unlock;
|
|
255
|
+
readonly format?: ExportFormat;
|
|
256
|
+
readonly aliases?: readonly string[];
|
|
257
|
+
readonly revisionId?: string;
|
|
258
|
+
/** Include the machine-wide layer. Off by default: export one store at a time. */
|
|
259
|
+
readonly includeGlobal?: boolean;
|
|
260
|
+
}
|
|
261
|
+
interface ExportResult {
|
|
262
|
+
readonly text: string;
|
|
263
|
+
readonly count: number;
|
|
264
|
+
/** Keys whose value a spreadsheet would evaluate rather than display. */
|
|
265
|
+
readonly formulaKeys: readonly string[];
|
|
266
|
+
readonly catalogs: readonly string[];
|
|
267
|
+
}
|
|
268
|
+
/** RFC 4180. Every field is quoted: env values carry commas and newlines. */
|
|
269
|
+
declare function csvField(value: string): string;
|
|
270
|
+
declare function exportValues(options: ExportOptions): ExportResult;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Reading values out of a catalog. Every item is sealed under the DEK and bound
|
|
274
|
+
* to its row, and the key name travels inside the envelope rather than beside
|
|
275
|
+
* it, so a database opened without the key shows neither.
|
|
276
|
+
*/
|
|
277
|
+
|
|
278
|
+
interface CatalogEntry {
|
|
279
|
+
readonly key: string;
|
|
280
|
+
readonly value: string;
|
|
281
|
+
readonly sourceId: string;
|
|
282
|
+
readonly alias: string;
|
|
283
|
+
readonly path: string;
|
|
284
|
+
}
|
|
285
|
+
declare class NoReleaseError extends Error {
|
|
286
|
+
constructor(message: string);
|
|
287
|
+
}
|
|
288
|
+
/** Binds an item to its row, so a blob cannot be moved between them. */
|
|
289
|
+
declare function itemContext(sourceId: string, keyHash: Uint8Array, revisionId: string): Uint8Array;
|
|
290
|
+
declare function readWraps(db: Database): DekWrap[];
|
|
291
|
+
declare function currentRevision(db: Database): string | undefined;
|
|
292
|
+
interface ReadOptions {
|
|
293
|
+
readonly unlock: Unlock;
|
|
294
|
+
/** Read a specific release instead of whatever the pointer names. */
|
|
295
|
+
readonly revisionId?: string;
|
|
296
|
+
/** Restrict to these source aliases, in this order. */
|
|
297
|
+
readonly aliases?: readonly string[];
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Entries for one release, in source order. Order is what the caller uses to
|
|
301
|
+
* decide a winner, so it is preserved rather than collapsed here: which file
|
|
302
|
+
* declared a key is the question this store exists to answer.
|
|
303
|
+
*/
|
|
304
|
+
declare function readEntries(db: Database, options: ReadOptions): readonly CatalogEntry[];
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Terminal output in the shape prompts uses — a symbol, a colour, aligned
|
|
308
|
+
* secondary text — written here rather than depended on, because this package
|
|
309
|
+
* ships with no runtime dependencies.
|
|
310
|
+
*/
|
|
311
|
+
interface Stream {
|
|
312
|
+
write(text: string): unknown;
|
|
313
|
+
isTTY?: boolean;
|
|
314
|
+
}
|
|
315
|
+
interface UiOptions {
|
|
316
|
+
readonly stdout?: Stream;
|
|
317
|
+
readonly stderr?: Stream;
|
|
318
|
+
/** Force colour on or off. Otherwise a TTY and NO_COLOR decide. */
|
|
319
|
+
readonly color?: boolean;
|
|
320
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
321
|
+
}
|
|
322
|
+
declare const CODES: {
|
|
323
|
+
readonly reset: `${string}[0m`;
|
|
324
|
+
readonly bold: `${string}[1m`;
|
|
325
|
+
readonly dim: `${string}[2m`;
|
|
326
|
+
readonly red: `${string}[31m`;
|
|
327
|
+
readonly green: `${string}[32m`;
|
|
328
|
+
readonly yellow: `${string}[33m`;
|
|
329
|
+
readonly cyan: `${string}[36m`;
|
|
330
|
+
};
|
|
331
|
+
type Colour = keyof typeof CODES;
|
|
332
|
+
/**
|
|
333
|
+
* Symbols are ASCII on purpose. The colour carries the state, and a glyph that
|
|
334
|
+
* a terminal renders as a box carries nothing.
|
|
335
|
+
*/
|
|
336
|
+
declare const SYMBOL: {
|
|
337
|
+
readonly success: "+";
|
|
338
|
+
readonly error: "x";
|
|
339
|
+
readonly warn: "!";
|
|
340
|
+
readonly info: "-";
|
|
341
|
+
readonly prompt: ">";
|
|
342
|
+
};
|
|
343
|
+
type Kind = keyof typeof SYMBOL;
|
|
344
|
+
declare class Ui {
|
|
345
|
+
private readonly out;
|
|
346
|
+
private readonly err;
|
|
347
|
+
readonly colour: boolean;
|
|
348
|
+
constructor(options?: UiOptions);
|
|
349
|
+
paint(text: string, ...colours: readonly Colour[]): string;
|
|
350
|
+
/** Data goes to stdout so it can be piped; everything else to stderr. */
|
|
351
|
+
data(text: string): void;
|
|
352
|
+
line(text?: string): void;
|
|
353
|
+
message(kind: Kind, text: string, detail?: string): void;
|
|
354
|
+
success(text: string, detail?: string): void;
|
|
355
|
+
error(text: string, detail?: string): void;
|
|
356
|
+
warn(text: string, detail?: string): void;
|
|
357
|
+
info(text: string, detail?: string): void;
|
|
358
|
+
/** Two aligned columns, as a help screen or a summary. */
|
|
359
|
+
table(rows: ReadonlyArray<readonly [string, string]>, indent?: string): void;
|
|
360
|
+
heading(text: string): void;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* A command is a value: its name, what it takes, and what it does. Help is
|
|
365
|
+
* generated from that rather than written twice, so a flag cannot exist in one
|
|
366
|
+
* and not the other.
|
|
367
|
+
*/
|
|
368
|
+
|
|
369
|
+
interface OptionSpec {
|
|
370
|
+
readonly name: string;
|
|
371
|
+
readonly describe: string;
|
|
372
|
+
/** A flag with no value. */
|
|
373
|
+
readonly boolean?: boolean;
|
|
374
|
+
/** May appear more than once; the parsed value is always an array. */
|
|
375
|
+
readonly repeat?: boolean;
|
|
376
|
+
readonly placeholder?: string;
|
|
377
|
+
}
|
|
378
|
+
interface ParsedArgs {
|
|
379
|
+
readonly positional: readonly string[];
|
|
380
|
+
readonly options: ReadonlyMap<string, readonly string[]>;
|
|
381
|
+
readonly flags: ReadonlySet<string>;
|
|
382
|
+
}
|
|
383
|
+
interface CommandContext {
|
|
384
|
+
readonly ui: Ui;
|
|
385
|
+
readonly args: ParsedArgs;
|
|
386
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
387
|
+
readonly cwd: string;
|
|
388
|
+
}
|
|
389
|
+
/** Help headings, in the order someone meets them. */
|
|
390
|
+
declare const GROUPS: readonly ["start here", "values", "check", "history", "backup", "hosted account", "publish"];
|
|
391
|
+
type Group = (typeof GROUPS)[number];
|
|
392
|
+
interface Command {
|
|
393
|
+
readonly name: string;
|
|
394
|
+
readonly describe: string;
|
|
395
|
+
readonly usage: string;
|
|
396
|
+
/** Which help heading it sits under. Absent means the trailing one. */
|
|
397
|
+
readonly group?: Group;
|
|
398
|
+
readonly options?: readonly OptionSpec[];
|
|
399
|
+
/**
|
|
400
|
+
* Exit code. 0 success, 1 the work failed, 2 the invocation was wrong.
|
|
401
|
+
* May be async: a destination can be a network. config() stays synchronous,
|
|
402
|
+
* which is a rule about the loader rather than about commands.
|
|
403
|
+
*/
|
|
404
|
+
run(context: CommandContext): number | Promise<number>;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
declare const COMMANDS: readonly Command[];
|
|
408
|
+
/** Named so an unknown verb can say "designed, not built" rather than "unknown". */
|
|
409
|
+
/** Empty: every verb the design named is built. */
|
|
410
|
+
declare const PLANNED: readonly string[];
|
|
411
|
+
interface DispatchOptions {
|
|
412
|
+
readonly ui?: Ui;
|
|
413
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
414
|
+
readonly cwd?: string;
|
|
415
|
+
}
|
|
416
|
+
declare function dispatch(argv: readonly string[], options?: DispatchOptions): number | Promise<number>;
|
|
417
|
+
|
|
418
|
+
export { type BindParams, type BindValue, COMMANDS, type CatalogEntry, type CatalogMeta, CatalogVersionError, type Database, DekWrap, type DispatchOptions, type EntryKind, EnvelopeAuthError, EnvelopeFormatError, type EnvelopeHeader, type ExportFormat, type ExportOptions, type ExportResult, FORMAT_AES_256_GCM, type FindingCode, type LocateOptions, type Located, MIGRATIONS, type Migration, NoReleaseError, type OpenCatalogOptions, type OpenInput, type OpenOptions, type OpenedCatalog, PLANNED, PROVIDERS, type ParseFinding, type ParseResult, type ParsedEntry, type Quote, type ReadOptions, type RunResult, SCHEMA_VERSION, type SealInput, type SqliteBackend, SqliteBindError, type SqliteProvider, SqliteUnavailableError, type SqliteValue, type Statement, type Stream, Ui, type UiOptions, Unlock, availableBackends, cacheDir, checkVersion, createSchema, csvField, currentRevision, dispatch, exportValues, findProjectRoot, globalDir, hashKeyName, itemContext, locateCatalogs, migrate, openCatalog, openDatabase, openDatabaseSync, open as openEnvelope, parseEnv, readEntries, readHeader, readMeta, readWraps, resetBindingCache, scanPlaceholders, seal, toRecord };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
COMMANDS,
|
|
3
|
+
PLANNED,
|
|
4
|
+
Ui,
|
|
5
|
+
csvField,
|
|
6
|
+
dispatch,
|
|
7
|
+
exportValues
|
|
8
|
+
} from "./chunk-47XO3SDE.js";
|
|
9
|
+
import {
|
|
10
|
+
CatalogVersionError,
|
|
11
|
+
ConflictError,
|
|
12
|
+
DEK_BYTES,
|
|
13
|
+
EnvelopeAuthError,
|
|
14
|
+
EnvelopeFormatError,
|
|
15
|
+
FORMAT_AES_256_GCM,
|
|
16
|
+
KekMissingError,
|
|
17
|
+
KeyringLockedError,
|
|
18
|
+
MIGRATIONS,
|
|
19
|
+
NoReleaseError,
|
|
20
|
+
PROVIDERS,
|
|
21
|
+
RecoveryCodeError,
|
|
22
|
+
SCHEMA_VERSION,
|
|
23
|
+
SqliteBindError,
|
|
24
|
+
SqliteUnavailableError,
|
|
25
|
+
addWrap,
|
|
26
|
+
availableBackends,
|
|
27
|
+
cacheDir,
|
|
28
|
+
checkVersion,
|
|
29
|
+
config,
|
|
30
|
+
createKeyring,
|
|
31
|
+
createSchema,
|
|
32
|
+
currentRevision,
|
|
33
|
+
findProjectRoot,
|
|
34
|
+
formatRecoveryCode,
|
|
35
|
+
generateRecoveryCode,
|
|
36
|
+
globalDir,
|
|
37
|
+
hashKeyName,
|
|
38
|
+
itemContext,
|
|
39
|
+
locateCatalogs,
|
|
40
|
+
migrate,
|
|
41
|
+
normaliseRecoveryCode,
|
|
42
|
+
open,
|
|
43
|
+
openCatalog,
|
|
44
|
+
openDatabase,
|
|
45
|
+
openDatabaseSync,
|
|
46
|
+
parseEnv,
|
|
47
|
+
readEntries,
|
|
48
|
+
readHeader,
|
|
49
|
+
readMeta,
|
|
50
|
+
readWraps,
|
|
51
|
+
resetBindingCache,
|
|
52
|
+
sameKey,
|
|
53
|
+
scanPlaceholders,
|
|
54
|
+
seal,
|
|
55
|
+
toRecord,
|
|
56
|
+
unlockDek
|
|
57
|
+
} from "./chunk-STHFIZRP.js";
|
|
58
|
+
export {
|
|
59
|
+
COMMANDS,
|
|
60
|
+
CatalogVersionError,
|
|
61
|
+
ConflictError,
|
|
62
|
+
DEK_BYTES,
|
|
63
|
+
EnvelopeAuthError,
|
|
64
|
+
EnvelopeFormatError,
|
|
65
|
+
FORMAT_AES_256_GCM,
|
|
66
|
+
KekMissingError,
|
|
67
|
+
KeyringLockedError,
|
|
68
|
+
MIGRATIONS,
|
|
69
|
+
NoReleaseError,
|
|
70
|
+
PLANNED,
|
|
71
|
+
PROVIDERS,
|
|
72
|
+
RecoveryCodeError,
|
|
73
|
+
SCHEMA_VERSION,
|
|
74
|
+
SqliteBindError,
|
|
75
|
+
SqliteUnavailableError,
|
|
76
|
+
Ui,
|
|
77
|
+
addWrap,
|
|
78
|
+
availableBackends,
|
|
79
|
+
cacheDir,
|
|
80
|
+
checkVersion,
|
|
81
|
+
config,
|
|
82
|
+
createKeyring,
|
|
83
|
+
createSchema,
|
|
84
|
+
csvField,
|
|
85
|
+
currentRevision,
|
|
86
|
+
dispatch,
|
|
87
|
+
exportValues,
|
|
88
|
+
findProjectRoot,
|
|
89
|
+
formatRecoveryCode,
|
|
90
|
+
generateRecoveryCode,
|
|
91
|
+
globalDir,
|
|
92
|
+
hashKeyName,
|
|
93
|
+
itemContext,
|
|
94
|
+
locateCatalogs,
|
|
95
|
+
migrate,
|
|
96
|
+
normaliseRecoveryCode,
|
|
97
|
+
openCatalog,
|
|
98
|
+
openDatabase,
|
|
99
|
+
openDatabaseSync,
|
|
100
|
+
open as openEnvelope,
|
|
101
|
+
parseEnv,
|
|
102
|
+
readEntries,
|
|
103
|
+
readHeader,
|
|
104
|
+
readMeta,
|
|
105
|
+
readWraps,
|
|
106
|
+
resetBindingCache,
|
|
107
|
+
sameKey,
|
|
108
|
+
scanPlaceholders,
|
|
109
|
+
seal,
|
|
110
|
+
toRecord,
|
|
111
|
+
unlockDek
|
|
112
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modootoday/envs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Elastic-2.0",
|
|
5
|
+
"author": "modootoday",
|
|
6
|
+
"description": "Environment values in an encrypted catalog rather than scattered files — provenance, releases, rollback and a strict .env format gate. dotenv-compatible surface.",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./config": {
|
|
18
|
+
"types": "./dist/config.d.ts",
|
|
19
|
+
"import": "./dist/config.js",
|
|
20
|
+
"require": "./dist/config.cjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"!dist/**/*.map",
|
|
26
|
+
"!dist/.tsbuildinfo",
|
|
27
|
+
"!dist/cli.cjs",
|
|
28
|
+
"!dist/cli.d.cts",
|
|
29
|
+
"README.md",
|
|
30
|
+
".agent/skills",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"NOTICE"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"test": "vitest run --passWithNoTests",
|
|
37
|
+
"site:build": "node scripts/build-registry-pages.mjs",
|
|
38
|
+
"site:deployed": "node scripts/check-deployed.mjs",
|
|
39
|
+
"typecheck": "tsc --noEmit --incremental --tsBuildInfoFile ./dist/.tsbuildinfo",
|
|
40
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
41
|
+
"prepack": "npm run build && npm run typecheck && npm test"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^22.15.21",
|
|
46
|
+
"better-sqlite3": "^13.0.3",
|
|
47
|
+
"tsup": "^8.5.1",
|
|
48
|
+
"typescript": "^5.9.3",
|
|
49
|
+
"vitest": "^4.0.18"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"better-sqlite3": ">=9"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"better-sqlite3": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=22.0.0",
|
|
61
|
+
"bun": ">=1.3.0"
|
|
62
|
+
},
|
|
63
|
+
"bin": {
|
|
64
|
+
"envs": "dist/cli.js"
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public",
|
|
68
|
+
"provenance": false
|
|
69
|
+
},
|
|
70
|
+
"homepage": "https://envs.build",
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "git+https://github.com/modootoday/envs.git"
|
|
74
|
+
},
|
|
75
|
+
"bugs": {
|
|
76
|
+
"url": "https://github.com/modootoday/envs/issues"
|
|
77
|
+
},
|
|
78
|
+
"keywords": [
|
|
79
|
+
"dotenv",
|
|
80
|
+
"env",
|
|
81
|
+
".env",
|
|
82
|
+
"environment",
|
|
83
|
+
"variables",
|
|
84
|
+
"config",
|
|
85
|
+
"settings",
|
|
86
|
+
"env vars",
|
|
87
|
+
"environment variables",
|
|
88
|
+
"secrets",
|
|
89
|
+
"secret-management",
|
|
90
|
+
"encryption",
|
|
91
|
+
"encrypted",
|
|
92
|
+
"credentials",
|
|
93
|
+
"key-rotation",
|
|
94
|
+
"recovery-codes",
|
|
95
|
+
"rollback",
|
|
96
|
+
"cli"
|
|
97
|
+
]
|
|
98
|
+
}
|