turbine-orm 0.14.0 → 0.15.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/dist/adapters/cockroachdb.js +1 -1
- package/dist/adapters/index.d.ts +7 -4
- package/dist/adapters/index.js +1 -1
- package/dist/adapters/yugabytedb.js +1 -1
- package/dist/cjs/adapters/cockroachdb.js +1 -1
- package/dist/cjs/adapters/index.js +1 -1
- package/dist/cjs/adapters/yugabytedb.js +1 -1
- package/dist/cjs/cli/studio.js +45 -7
- package/dist/cjs/client.js +48 -1
- package/dist/cjs/errors.js +44 -1
- package/dist/cjs/generate.js +86 -0
- package/dist/cjs/index.js +10 -1
- package/dist/cjs/nested-write.js +467 -0
- package/dist/cjs/query/builder.js +205 -10
- package/dist/cli/studio.d.ts +10 -2
- package/dist/cli/studio.js +45 -7
- package/dist/client.d.ts +23 -0
- package/dist/client.js +47 -1
- package/dist/errors.d.ts +23 -0
- package/dist/errors.js +41 -0
- package/dist/generate.js +86 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -2
- package/dist/nested-write.d.ts +95 -0
- package/dist/nested-write.js +461 -0
- package/dist/query/builder.d.ts +28 -12
- package/dist/query/builder.js +173 -11
- package/dist/query/index.d.ts +1 -1
- package/dist/query/types.d.ts +76 -8
- package/package.json +2 -2
package/dist/errors.js
CHANGED
|
@@ -20,6 +20,8 @@ export const TurbineErrorCode = {
|
|
|
20
20
|
DEADLOCK_DETECTED: 'TURBINE_E012',
|
|
21
21
|
SERIALIZATION_FAILURE: 'TURBINE_E013',
|
|
22
22
|
PIPELINE: 'TURBINE_E014',
|
|
23
|
+
OPTIMISTIC_LOCK: 'TURBINE_E015',
|
|
24
|
+
EXCLUSION_VIOLATION: 'TURBINE_E016',
|
|
23
25
|
};
|
|
24
26
|
/** Base error class for all Turbine errors */
|
|
25
27
|
export class TurbineError extends Error {
|
|
@@ -331,6 +333,25 @@ export class CheckConstraintError extends TurbineError {
|
|
|
331
333
|
this.table = table;
|
|
332
334
|
}
|
|
333
335
|
}
|
|
336
|
+
export class ExclusionConstraintError extends TurbineError {
|
|
337
|
+
constraint;
|
|
338
|
+
table;
|
|
339
|
+
constructor(opts = {}) {
|
|
340
|
+
const { constraint, table, cause } = opts;
|
|
341
|
+
let message = opts.message;
|
|
342
|
+
if (!message) {
|
|
343
|
+
const constraintPart = constraint ? ` on ${constraint}` : '';
|
|
344
|
+
message = `[turbine] Exclusion constraint violation${constraintPart}`;
|
|
345
|
+
const detail = detailFromCause(cause);
|
|
346
|
+
if (detail)
|
|
347
|
+
message += `: ${detail}`;
|
|
348
|
+
}
|
|
349
|
+
super(TurbineErrorCode.EXCLUSION_VIOLATION, message, { cause });
|
|
350
|
+
this.name = 'ExclusionConstraintError';
|
|
351
|
+
this.constraint = constraint;
|
|
352
|
+
this.table = table;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
334
355
|
/**
|
|
335
356
|
* Thrown when a non-transactional pipeline has partial failures.
|
|
336
357
|
*
|
|
@@ -371,6 +392,19 @@ export class PipelineError extends TurbineError {
|
|
|
371
392
|
this.failedTag = failedTag;
|
|
372
393
|
}
|
|
373
394
|
}
|
|
395
|
+
export class OptimisticLockError extends TurbineError {
|
|
396
|
+
table;
|
|
397
|
+
versionField;
|
|
398
|
+
expectedVersion;
|
|
399
|
+
constructor(opts) {
|
|
400
|
+
super(TurbineErrorCode.OPTIMISTIC_LOCK, `[turbine] Optimistic lock failed on "${opts.table}" — ` +
|
|
401
|
+
`expected ${opts.versionField} = ${opts.expectedVersion} but row was modified by another transaction`);
|
|
402
|
+
this.name = 'OptimisticLockError';
|
|
403
|
+
this.table = opts.table;
|
|
404
|
+
this.versionField = opts.versionField;
|
|
405
|
+
this.expectedVersion = opts.expectedVersion;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
374
408
|
/**
|
|
375
409
|
* Parse column names out of a pg `detail` string like:
|
|
376
410
|
* "Key (email)=(foo@bar) already exists."
|
|
@@ -391,6 +425,7 @@ function parseColumnsFromDetail(detail) {
|
|
|
391
425
|
* 23503 (foreign_key_violation) -> ForeignKeyError
|
|
392
426
|
* 23502 (not_null_violation) -> NotNullViolationError
|
|
393
427
|
* 23514 (check_violation) -> CheckConstraintError
|
|
428
|
+
* 23P01 (exclusion_violation) -> ExclusionConstraintError
|
|
394
429
|
* 40P01 (deadlock_detected) -> DeadlockError (retryable)
|
|
395
430
|
* 40001 (serialization_failure) -> SerializationFailureError (retryable)
|
|
396
431
|
*
|
|
@@ -430,6 +465,12 @@ export function wrapPgError(err) {
|
|
|
430
465
|
table: e.table,
|
|
431
466
|
cause: err,
|
|
432
467
|
});
|
|
468
|
+
case '23P01':
|
|
469
|
+
return new ExclusionConstraintError({
|
|
470
|
+
constraint: e.constraint,
|
|
471
|
+
table: e.table,
|
|
472
|
+
cause: err,
|
|
473
|
+
});
|
|
433
474
|
case '40P01':
|
|
434
475
|
return new DeadlockError({
|
|
435
476
|
constraint: e.constraint,
|
package/dist/generate.js
CHANGED
|
@@ -177,6 +177,92 @@ export function generateTypes(schema) {
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// Nested write types (WhereUnique, NestedCreateInput, NestedUpdateInput,
|
|
182
|
+
// ConnectOrCreate, CreateInput, UpdateInput)
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
for (const table of Object.values(schema.tables)) {
|
|
185
|
+
const typeName = entityName(table.name);
|
|
186
|
+
const hasRels = Object.keys(table.relations).length > 0;
|
|
187
|
+
// WhereUnique — union of unique constraint shapes, deduplicating PK
|
|
188
|
+
const seen = new Set();
|
|
189
|
+
const uniqueSets = [];
|
|
190
|
+
// Always include the primary key first
|
|
191
|
+
const pkKey = table.primaryKey.join(',');
|
|
192
|
+
seen.add(pkKey);
|
|
193
|
+
uniqueSets.push(table.primaryKey);
|
|
194
|
+
// Add unique indexes that aren't duplicates of the PK
|
|
195
|
+
for (const uc of table.uniqueColumns) {
|
|
196
|
+
const ucKey = uc.join(',');
|
|
197
|
+
if (!seen.has(ucKey)) {
|
|
198
|
+
seen.add(ucKey);
|
|
199
|
+
uniqueSets.push(uc);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (uniqueSets.length > 0) {
|
|
203
|
+
const branches = uniqueSets.map((cols) => {
|
|
204
|
+
const fields = cols.map((colName) => {
|
|
205
|
+
const col = table.columns.find((c) => c.name === colName);
|
|
206
|
+
const field = col?.field ?? colName;
|
|
207
|
+
const tsType = col?.tsType ?? 'unknown';
|
|
208
|
+
return `${field}: ${tsType}`;
|
|
209
|
+
});
|
|
210
|
+
return `{ ${fields.join('; ')} }`;
|
|
211
|
+
});
|
|
212
|
+
lines.push(`export type ${typeName}WhereUnique = ${branches.join(' | ')};`);
|
|
213
|
+
lines.push('');
|
|
214
|
+
}
|
|
215
|
+
// CreateInput / UpdateInput — extends base type with optional relation fields
|
|
216
|
+
if (hasRels) {
|
|
217
|
+
lines.push(`export type ${typeName}CreateInput = ${typeName}Create & {`);
|
|
218
|
+
for (const [relName, rel] of Object.entries(table.relations)) {
|
|
219
|
+
const targetType = entityName(rel.to);
|
|
220
|
+
lines.push(` ${relName}?: ${targetType}NestedCreateInput;`);
|
|
221
|
+
}
|
|
222
|
+
lines.push('};');
|
|
223
|
+
lines.push('');
|
|
224
|
+
lines.push(`export type ${typeName}UpdateInput = ${typeName}Update & {`);
|
|
225
|
+
for (const [relName, rel] of Object.entries(table.relations)) {
|
|
226
|
+
const targetType = entityName(rel.to);
|
|
227
|
+
if (rel.type === 'hasMany') {
|
|
228
|
+
lines.push(` ${relName}?: ${targetType}NestedUpdateInput;`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
lines.push(` ${relName}?: ${targetType}NestedCreateInput;`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
lines.push('};');
|
|
235
|
+
lines.push('');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Emit NestedCreateInput, NestedUpdateInput, ConnectOrCreate for every table
|
|
239
|
+
for (const table of Object.values(schema.tables)) {
|
|
240
|
+
const typeName = entityName(table.name);
|
|
241
|
+
const hasRels = Object.keys(table.relations).length > 0;
|
|
242
|
+
// NestedCreateInput uses *CreateInput (which includes relation fields) when
|
|
243
|
+
// the table has relations, otherwise falls back to the plain *Create type.
|
|
244
|
+
const createRefType = hasRels ? `${typeName}CreateInput` : `${typeName}Create`;
|
|
245
|
+
lines.push(`export interface ${typeName}NestedCreateInput {`);
|
|
246
|
+
lines.push(` create?: ${createRefType} | ${createRefType}[];`);
|
|
247
|
+
lines.push(` connect?: ${typeName}WhereUnique | ${typeName}WhereUnique[];`);
|
|
248
|
+
lines.push(` connectOrCreate?: ${typeName}ConnectOrCreate | ${typeName}ConnectOrCreate[];`);
|
|
249
|
+
lines.push('}');
|
|
250
|
+
lines.push('');
|
|
251
|
+
lines.push(`export interface ${typeName}NestedUpdateInput {`);
|
|
252
|
+
lines.push(` create?: ${createRefType} | ${createRefType}[];`);
|
|
253
|
+
lines.push(` connect?: ${typeName}WhereUnique | ${typeName}WhereUnique[];`);
|
|
254
|
+
lines.push(` connectOrCreate?: ${typeName}ConnectOrCreate | ${typeName}ConnectOrCreate[];`);
|
|
255
|
+
lines.push(` disconnect?: ${typeName}WhereUnique | ${typeName}WhereUnique[];`);
|
|
256
|
+
lines.push(` set?: ${typeName}WhereUnique[];`);
|
|
257
|
+
lines.push(` delete?: ${typeName}WhereUnique | ${typeName}WhereUnique[];`);
|
|
258
|
+
lines.push('}');
|
|
259
|
+
lines.push('');
|
|
260
|
+
lines.push(`export interface ${typeName}ConnectOrCreate {`);
|
|
261
|
+
lines.push(` where: ${typeName}WhereUnique;`);
|
|
262
|
+
lines.push(` create: ${createRefType};`);
|
|
263
|
+
lines.push('}');
|
|
264
|
+
lines.push('');
|
|
265
|
+
}
|
|
180
266
|
return lines.join('\n');
|
|
181
267
|
}
|
|
182
268
|
// ---------------------------------------------------------------------------
|
package/dist/index.d.ts
CHANGED
|
@@ -34,14 +34,15 @@
|
|
|
34
34
|
*/
|
|
35
35
|
export type { DatabaseAdapter, IntrospectionOverrides } from './adapters/index.js';
|
|
36
36
|
export { alloydb, cockroachdb, postgresql, timescale, yugabytedb } from './adapters/index.js';
|
|
37
|
-
export { type Middleware, type MiddlewareNext, type MiddlewareParams, type PgCompatPool, type PgCompatPoolClient, type PgCompatQueryResult, TransactionClient, type TransactionOptions, TurbineClient, type TurbineConfig, } from './client.js';
|
|
37
|
+
export { type Middleware, type MiddlewareNext, type MiddlewareParams, type PgCompatPool, type PgCompatPoolClient, type PgCompatQueryResult, type RetryOptions, TransactionClient, type TransactionOptions, TurbineClient, type TurbineConfig, withRetry, } from './client.js';
|
|
38
38
|
export type { BuiltStatement, BulkInsertStatementInput, ColumnDefinitionInput, ColumnTypeInput, CreateIndexStatementInput, CreateTableStatementInput, Dialect, DialectIntrospector, DialectMigrator, DialectName, InsertStatementInput, IntrospectOptions as DialectIntrospectOptions, UpsertStatementInput, } from './dialect.js';
|
|
39
39
|
export { postgresDialect } from './dialect.js';
|
|
40
|
-
export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, type ErrorMessageMode, ForeignKeyError, getErrorMessageMode, MigrationError, NotFoundError, NotNullViolationError, PipelineError, type PipelineResultSlot, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, TurbineError, TurbineErrorCode, UniqueConstraintError, ValidationError, wrapPgError, } from './errors.js';
|
|
40
|
+
export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, type ErrorMessageMode, ExclusionConstraintError, ForeignKeyError, getErrorMessageMode, MigrationError, NotFoundError, NotNullViolationError, OptimisticLockError, PipelineError, type PipelineResultSlot, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, TurbineError, TurbineErrorCode, UniqueConstraintError, ValidationError, wrapPgError, } from './errors.js';
|
|
41
41
|
export { type GenerateOptions, generate } from './generate.js';
|
|
42
42
|
export { type IntrospectOptions, introspect } from './introspect.js';
|
|
43
|
+
export { executeNestedCreate, executeNestedUpdate, hasRelationFields, type NestedWriteContext, } from './nested-write.js';
|
|
43
44
|
export { executePipeline, type PipelineOptions, type PipelineResults, pipelineSupported } from './pipeline.js';
|
|
44
|
-
export { type AggregateArgs, type AggregateResult, type ArrayFilter, type CountArgs, type CreateArgs, type CreateManyArgs, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GroupByArgs, type JsonFilter, type OrderDirection, QueryInterface, type RelationDescriptor, type RelationFilter, type TypedWithClause, type UpdateArgs, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type WithClause, type WithOptions, type WithResult, } from './query/index.js';
|
|
45
|
+
export { type AggregateArgs, type AggregateResult, type ArrayFilter, type ConnectOrCreateOp, type CountArgs, type CreateArgs, type CreateManyArgs, type DeferredQuery, type DeleteArgs, type DeleteManyArgs, type FieldResult, type FindManyArgs, type FindManyStreamArgs, type FindUniqueArgs, type GroupByArgs, type JsonFilter, type NestedCreateOp, type NestedUpdateOp, type OmitResult, type OrderDirection, QueryInterface, type QueryResult, type RelationDescriptor, type RelationFilter, type SelectResult, type TextSearchFilter, type TypedWithClause, type UpdateArgs, type UpdateInput, type UpdateManyArgs, type UpdateOperatorInput, type UpsertArgs, type WithClause, type WithOptions, type WithResult, } from './query/index.js';
|
|
45
46
|
export type { ColumnMetadata, IndexMetadata, RelationDef, SchemaMetadata, TableMetadata, } from './schema.js';
|
|
46
47
|
export { camelToSnake, isDateType, normalizeKeyColumns, pgArrayType, pgTypeToTs, singularize, snakeToCamel, snakeToPascal, } from './schema.js';
|
|
47
48
|
export { ColumnBuilder, type ColumnConfig, type ColumnDef, type ColumnType, type ColumnTypeName, column, defineSchema, type SchemaDef, type TableDef, table, } from './schema-builder.js';
|
package/dist/index.js
CHANGED
|
@@ -34,14 +34,16 @@
|
|
|
34
34
|
*/
|
|
35
35
|
export { alloydb, cockroachdb, postgresql, timescale, yugabytedb } from './adapters/index.js';
|
|
36
36
|
// Client
|
|
37
|
-
export { TransactionClient, TurbineClient, } from './client.js';
|
|
37
|
+
export { TransactionClient, TurbineClient, withRetry, } from './client.js';
|
|
38
38
|
export { postgresDialect } from './dialect.js';
|
|
39
39
|
// Error types
|
|
40
|
-
export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, ForeignKeyError, getErrorMessageMode, MigrationError, NotFoundError, NotNullViolationError, PipelineError, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, TurbineError, TurbineErrorCode, UniqueConstraintError, ValidationError, wrapPgError, } from './errors.js';
|
|
40
|
+
export { CheckConstraintError, CircularRelationError, ConnectionError, DeadlockError, ExclusionConstraintError, ForeignKeyError, getErrorMessageMode, MigrationError, NotFoundError, NotNullViolationError, OptimisticLockError, PipelineError, RelationError, SerializationFailureError, setErrorMessageMode, TimeoutError, TurbineError, TurbineErrorCode, UniqueConstraintError, ValidationError, wrapPgError, } from './errors.js';
|
|
41
41
|
// Code generation
|
|
42
42
|
export { generate } from './generate.js';
|
|
43
43
|
// Introspection
|
|
44
44
|
export { introspect } from './introspect.js';
|
|
45
|
+
// Nested writes
|
|
46
|
+
export { executeNestedCreate, executeNestedUpdate, hasRelationFields, } from './nested-write.js';
|
|
45
47
|
// Pipeline
|
|
46
48
|
export { executePipeline, pipelineSupported } from './pipeline.js';
|
|
47
49
|
// Query builder
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm — Nested write engine
|
|
3
|
+
*
|
|
4
|
+
* Tree-walking create/update that resolves relation fields in `data` into
|
|
5
|
+
* batched SQL operations within a transaction. Supports create, connect,
|
|
6
|
+
* connectOrCreate, disconnect, set, and delete on related records at
|
|
7
|
+
* arbitrary depth (capped at 10).
|
|
8
|
+
*
|
|
9
|
+
* This module is imported by `query/builder.ts` when the `data` argument
|
|
10
|
+
* of `create()` or `update()` contains relation fields. It never imports
|
|
11
|
+
* `client.ts` directly — the transaction handle is passed in via
|
|
12
|
+
* `NestedWriteContext`.
|
|
13
|
+
*/
|
|
14
|
+
import type { RelationDef, SchemaMetadata, TableMetadata } from './schema.js';
|
|
15
|
+
export interface ExtractedFields {
|
|
16
|
+
scalars: Record<string, unknown>;
|
|
17
|
+
relations: Record<string, Record<string, unknown>>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Transaction context for nested write operations.
|
|
21
|
+
* Matches the subset of TransactionClient that we actually use.
|
|
22
|
+
*/
|
|
23
|
+
export interface NestedWriteContext {
|
|
24
|
+
schema: SchemaMetadata;
|
|
25
|
+
tx: {
|
|
26
|
+
table<T extends object>(name: string): {
|
|
27
|
+
create(args: {
|
|
28
|
+
data: Partial<T>;
|
|
29
|
+
}): Promise<T>;
|
|
30
|
+
createMany(args: {
|
|
31
|
+
data: Partial<T>[];
|
|
32
|
+
}): Promise<T[]>;
|
|
33
|
+
update(args: {
|
|
34
|
+
where: Record<string, unknown>;
|
|
35
|
+
data: Record<string, unknown>;
|
|
36
|
+
}): Promise<T>;
|
|
37
|
+
updateMany(args: {
|
|
38
|
+
where: Record<string, unknown>;
|
|
39
|
+
data: Record<string, unknown>;
|
|
40
|
+
allowFullTableScan?: boolean;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
count: number;
|
|
43
|
+
}>;
|
|
44
|
+
delete(args: {
|
|
45
|
+
where: Record<string, unknown>;
|
|
46
|
+
}): Promise<T>;
|
|
47
|
+
deleteMany(args: {
|
|
48
|
+
where: Record<string, unknown>;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
count: number;
|
|
51
|
+
}>;
|
|
52
|
+
findMany(args: {
|
|
53
|
+
where: Record<string, unknown>;
|
|
54
|
+
}): Promise<T[]>;
|
|
55
|
+
findUnique(args: {
|
|
56
|
+
where: Record<string, unknown>;
|
|
57
|
+
with?: Record<string, unknown>;
|
|
58
|
+
}): Promise<T | null>;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Separates scalar data fields from relation operation fields.
|
|
64
|
+
*
|
|
65
|
+
* A key is treated as a relation field only when:
|
|
66
|
+
* 1. It matches a relation name in `tableMeta.relations`
|
|
67
|
+
* 2. Its value is a non-null, non-array, non-Date plain object
|
|
68
|
+
*
|
|
69
|
+
* Everything else goes into `scalars`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function extractRelationFields(data: Record<string, unknown>, tableMeta: TableMetadata): ExtractedFields;
|
|
72
|
+
/**
|
|
73
|
+
* Quick check: does `data` contain any relation fields that would trigger
|
|
74
|
+
* the nested write path? Used by QueryInterface to decide whether to
|
|
75
|
+
* delegate to the nested write engine or take the fast scalar-only path.
|
|
76
|
+
*/
|
|
77
|
+
export declare function hasRelationFields(data: Record<string, unknown>, tableMeta: TableMetadata): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Inject the parent row's PK value(s) as FK field(s) into child data.
|
|
80
|
+
* Handles composite keys. Returns a new object (does not mutate input).
|
|
81
|
+
*/
|
|
82
|
+
export declare function injectForeignKey(childData: Record<string, unknown>, relation: RelationDef, parentRow: Record<string, unknown>, schema: SchemaMetadata): Record<string, unknown>;
|
|
83
|
+
/**
|
|
84
|
+
* Tree-walking create: inserts the parent row, then processes each relation
|
|
85
|
+
* operation (create, connect, connectOrCreate), and finally reads back the
|
|
86
|
+
* full tree using `findUnique` with an auto-built `with` clause.
|
|
87
|
+
*/
|
|
88
|
+
export declare function executeNestedCreate(ctx: NestedWriteContext, tableName: string, data: Record<string, unknown>, depth?: number, path?: string[]): Promise<Record<string, unknown>>;
|
|
89
|
+
/**
|
|
90
|
+
* Tree-walking update: updates the parent row with scalar data, then
|
|
91
|
+
* processes each relation operation (create, connect, connectOrCreate,
|
|
92
|
+
* disconnect, set, delete), and reads back the full tree.
|
|
93
|
+
*/
|
|
94
|
+
export declare function executeNestedUpdate(ctx: NestedWriteContext, tableName: string, where: Record<string, unknown>, data: Record<string, unknown>, depth?: number, path?: string[]): Promise<Record<string, unknown>>;
|
|
95
|
+
//# sourceMappingURL=nested-write.d.ts.map
|