zitejs 0.9.105 → 0.9.107
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/cjs/api/index.js +5 -0
- package/dist/cjs/db/index.js +5 -0
- package/dist/cjs/runtime/index.d.ts +25 -3
- package/dist/cjs/runtime/writeResultTypes.test-d.d.ts +1 -0
- package/dist/cjs/runtime/writeResultTypes.test-d.js +29 -0
- package/dist/cjs/sync/lib.d.ts +2 -13
- package/dist/cjs/sync/lib.js +62 -65
- package/dist/cjs/sync/sdkNames.d.ts +111 -0
- package/dist/cjs/sync/sdkNames.js +279 -0
- package/dist/cjs/sync/sdkNames.test.d.ts +1 -0
- package/dist/cjs/sync/sdkNames.test.js +205 -0
- package/dist/esm/api/index.d.ts +2 -0
- package/dist/esm/api/index.js +1 -0
- package/dist/esm/cli.js +0 -0
- package/dist/esm/db/index.d.ts +2 -0
- package/dist/esm/db/index.js +1 -0
- package/dist/esm/runtime/index.d.ts +25 -3
- package/dist/esm/runtime/writeResultTypes.test-d.d.ts +1 -0
- package/dist/esm/runtime/writeResultTypes.test-d.js +27 -0
- package/dist/esm/sync/lib.d.ts +2 -13
- package/dist/esm/sync/lib.js +52 -56
- package/dist/esm/sync/sdkNames.d.ts +111 -0
- package/dist/esm/sync/sdkNames.js +269 -0
- package/dist/esm/sync/sdkNames.test.d.ts +1 -0
- package/dist/esm/sync/sdkNames.test.js +203 -0
- package/package.json +1 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCaller = void 0;
|
|
4
|
+
var index_js_1 = require("../caller/index.js");
|
|
5
|
+
Object.defineProperty(exports, "createCaller", { enumerable: true, get: function () { return index_js_1.createCaller; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTableClient = void 0;
|
|
4
|
+
var index_js_1 = require("../runtime/index.js");
|
|
5
|
+
Object.defineProperty(exports, "createTableClient", { enumerable: true, get: function () { return index_js_1.createTableClient; } });
|
|
@@ -99,15 +99,37 @@ export interface TableFindAllOptions<T = Record<string, unknown>> {
|
|
|
99
99
|
filter?: unknown;
|
|
100
100
|
fields?: Array<FieldSelector<T>>;
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Both write results carry the record twice — flat, and again under `fields`.
|
|
104
|
+
*
|
|
105
|
+
* That is not a quirk of the type. Both dispatchers build it deliberately, with
|
|
106
|
+
* the same code and the same comment ("Return both flat fields and nested
|
|
107
|
+
* fields for backwards compatibility"):
|
|
108
|
+
* `cloudflare-lambda/src/integrations/databases.ts` and
|
|
109
|
+
* `workflow-runner/src/sdk/databases.ts`.
|
|
110
|
+
*
|
|
111
|
+
* The types said otherwise, each in a different direction — `BulkCreateResult`
|
|
112
|
+
* declared only the flat form, `UpdateResult` only the nested one. So a 1.0 app
|
|
113
|
+
* reading `created.fields.token`, which is what 1.0's SDK typed, stopped
|
|
114
|
+
* compiling after migrating even though the value was sitting right there at
|
|
115
|
+
* runtime. DSA Employee Portal migrated "successfully" and then would not build.
|
|
116
|
+
*
|
|
117
|
+
* Declaring both is the whole fix: nothing about the running code changes, and
|
|
118
|
+
* no app source has to be rewritten to match a type narrower than what the
|
|
119
|
+
* runtime actually returns.
|
|
120
|
+
*/
|
|
102
121
|
export interface BulkCreateResult<T> {
|
|
103
122
|
/** Absent when `records: []` was passed — the dispatch short-circuits before setting it. */
|
|
104
123
|
success?: boolean;
|
|
105
|
-
records: T
|
|
124
|
+
records: Array<T & {
|
|
125
|
+
fields: T;
|
|
126
|
+
}>;
|
|
106
127
|
}
|
|
107
|
-
|
|
128
|
+
/** A type alias, not an interface: an interface cannot extend a generic `Partial<T>`. */
|
|
129
|
+
export type UpdateResult<T> = Partial<T> & {
|
|
108
130
|
id: string;
|
|
109
131
|
fields: Partial<T>;
|
|
110
|
-
}
|
|
132
|
+
};
|
|
111
133
|
export interface DeleteResult {
|
|
112
134
|
success: true;
|
|
113
135
|
id: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
(0, vitest_1.describe)("BulkCreateResult", () => {
|
|
5
|
+
// The 1.0 spelling. This is the one that regressed.
|
|
6
|
+
(0, vitest_1.it)("reads through .fields", () => {
|
|
7
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
8
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
9
|
+
});
|
|
10
|
+
// The 2.0 spelling, which must keep working — apps written since migration
|
|
11
|
+
// use it, so this is not a case of swapping one shape for the other.
|
|
12
|
+
(0, vitest_1.it)("reads flat", () => {
|
|
13
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
14
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
15
|
+
});
|
|
16
|
+
(0, vitest_1.it)("keeps success optional", () => {
|
|
17
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
(0, vitest_1.describe)("UpdateResult", () => {
|
|
21
|
+
// The mirror image: `update` returned `{ ...transformed, fields: transformed }`
|
|
22
|
+
// but the type declared only `id` and `fields`, so reading a column straight
|
|
23
|
+
// off an update result failed to compile.
|
|
24
|
+
(0, vitest_1.it)("reads flat and through .fields", () => {
|
|
25
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
26
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
27
|
+
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
|
|
28
|
+
});
|
|
29
|
+
});
|
package/dist/cjs/sync/lib.d.ts
CHANGED
|
@@ -14,18 +14,7 @@ export type ZiteSchemaTable = {
|
|
|
14
14
|
export type ZiteSchema = {
|
|
15
15
|
tables: ZiteSchemaTable[];
|
|
16
16
|
};
|
|
17
|
-
export
|
|
18
|
-
export declare function toCamelCase(name: string): string;
|
|
19
|
-
/**
|
|
20
|
-
* camelCase for a FRESH sdkName, reading acronym runs as words: "VIP" ->
|
|
21
|
-
* "vip", "APIKey" -> "apiKey" (plain toCamelCase yields "vIP" / "aPIKey").
|
|
22
|
-
*
|
|
23
|
-
* Deliberately not folded into toCamelCase: that also derives endpoint
|
|
24
|
-
* identifiers from existing filenames on every generate, where normalizing
|
|
25
|
-
* would rename a working app's `api.sendSMS`. This is only for names being
|
|
26
|
-
* chosen for the first time — generateSchema preserves existing sdkNames.
|
|
27
|
-
*/
|
|
28
|
-
export declare function toSdkName(name: string): string;
|
|
17
|
+
export { toPascalCase, toCamelCase, toSdkName } from "./sdkNames.js";
|
|
29
18
|
/**
|
|
30
19
|
* Build a ZiteSchema from a Database API response.
|
|
31
20
|
*
|
|
@@ -39,7 +28,7 @@ export declare function generateSchema(database: Database, existingSchema?: Zite
|
|
|
39
28
|
* Generate .zite/db.ts purely from ZiteSchema.
|
|
40
29
|
* Pure function — no external data needed beyond what's in the schema file.
|
|
41
30
|
*/
|
|
42
|
-
export declare function generateDbTs(
|
|
31
|
+
export declare function generateDbTs(inputSchema: ZiteSchema): string;
|
|
43
32
|
export type EndpointFileInfo = {
|
|
44
33
|
fileName: string;
|
|
45
34
|
content?: string;
|
package/dist/cjs/sync/lib.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toPascalCase =
|
|
4
|
-
exports.toCamelCase = toCamelCase;
|
|
5
|
-
exports.toSdkName = toSdkName;
|
|
3
|
+
exports.toSdkName = exports.toCamelCase = exports.toPascalCase = void 0;
|
|
6
4
|
exports.generateSchema = generateSchema;
|
|
7
5
|
exports.generateDbTs = generateDbTs;
|
|
8
6
|
exports.generateApiTs = generateApiTs;
|
|
@@ -10,6 +8,7 @@ exports.generateAirtableTs = generateAirtableTs;
|
|
|
10
8
|
exports.generateBackendWrapperTs = generateBackendWrapperTs;
|
|
11
9
|
exports.generateEmailSdk = generateEmailSdk;
|
|
12
10
|
const parser_1 = require("@babel/parser");
|
|
11
|
+
const sdkNames_js_1 = require("./sdkNames.js");
|
|
13
12
|
const AUTH_USERS_TABLE_ID = "zite_user";
|
|
14
13
|
/**
|
|
15
14
|
* What a field's value looks like when a record is READ back.
|
|
@@ -181,47 +180,12 @@ const withDateFormatExample = (format) => {
|
|
|
181
180
|
? `"${format}" format (e.g. ${example})`
|
|
182
181
|
: `"${format}" format`;
|
|
183
182
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.replace(/[^a-zA-Z0-9]+/g, "");
|
|
191
|
-
if (!pascal)
|
|
192
|
-
return "_";
|
|
193
|
-
return /^[0-9]/.test(pascal) ? `_${pascal}` : pascal; // can't start with a digit
|
|
194
|
-
}
|
|
195
|
-
function toCamelCase(name) {
|
|
196
|
-
const pascal = toPascalCase(name);
|
|
197
|
-
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* camelCase for a FRESH sdkName, reading acronym runs as words: "VIP" ->
|
|
201
|
-
* "vip", "APIKey" -> "apiKey" (plain toCamelCase yields "vIP" / "aPIKey").
|
|
202
|
-
*
|
|
203
|
-
* Deliberately not folded into toCamelCase: that also derives endpoint
|
|
204
|
-
* identifiers from existing filenames on every generate, where normalizing
|
|
205
|
-
* would rename a working app's `api.sendSMS`. This is only for names being
|
|
206
|
-
* chosen for the first time — generateSchema preserves existing sdkNames.
|
|
207
|
-
*/
|
|
208
|
-
function toSdkName(name) {
|
|
209
|
-
const deAcronymed = name
|
|
210
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, (_, run, next) => run.charAt(0) + run.slice(1).toLowerCase() + next)
|
|
211
|
-
.replace(/([A-Z])([A-Z]+)/g, (_, first, rest) => first + rest.toLowerCase());
|
|
212
|
-
return toCamelCase(deAcronymed);
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Existing sdkNames are preserved across syncs so user code keeps compiling,
|
|
216
|
-
* but schemas written before the sanitizer stripped trailing symbols can carry
|
|
217
|
-
* invalid identifiers (e.g. "timeSeconds)"). Keep an existing name only when
|
|
218
|
-
* it's a valid identifier; otherwise fall through to recomputing it.
|
|
219
|
-
*/
|
|
220
|
-
function keepValidSdkName(sdkName) {
|
|
221
|
-
if (!sdkName)
|
|
222
|
-
return undefined;
|
|
223
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(sdkName) ? sdkName : undefined;
|
|
224
|
-
}
|
|
183
|
+
// Owned by ./sdkNames.ts (which must not import back into this module);
|
|
184
|
+
// re-exported so the published surface is unchanged.
|
|
185
|
+
var sdkNames_js_2 = require("./sdkNames.js");
|
|
186
|
+
Object.defineProperty(exports, "toPascalCase", { enumerable: true, get: function () { return sdkNames_js_2.toPascalCase; } });
|
|
187
|
+
Object.defineProperty(exports, "toCamelCase", { enumerable: true, get: function () { return sdkNames_js_2.toCamelCase; } });
|
|
188
|
+
Object.defineProperty(exports, "toSdkName", { enumerable: true, get: function () { return sdkNames_js_2.toSdkName; } });
|
|
225
189
|
/**
|
|
226
190
|
* `null` is how you CLEAR a cell — every scalar write schema in
|
|
227
191
|
* `flexible-inputs.ts` ends in `.nullable()` and update runs with
|
|
@@ -364,7 +328,7 @@ function generateSchema(database, existingSchema) {
|
|
|
364
328
|
for (const t of existingSchema?.tables ?? []) {
|
|
365
329
|
existingTableById.set(t.id, t);
|
|
366
330
|
}
|
|
367
|
-
const
|
|
331
|
+
const drafts = [];
|
|
368
332
|
for (const table of database.tables) {
|
|
369
333
|
if (table.id === AUTH_USERS_TABLE_ID)
|
|
370
334
|
continue;
|
|
@@ -373,23 +337,44 @@ function generateSchema(database, existingSchema) {
|
|
|
373
337
|
for (const f of existingTable?.fields ?? []) {
|
|
374
338
|
existingFieldById.set(f.id, f);
|
|
375
339
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
340
|
+
// `sdkName` is filled in by `allocateSchemaNames` below; the draft carries
|
|
341
|
+
// what each name would like to be and whether user code already depends on
|
|
342
|
+
// it. A name from the existing schema is locked — it is what the app is
|
|
343
|
+
// compiling against — and only moves if it is reserved or collides.
|
|
344
|
+
const fields = table.fields.map((field) => {
|
|
345
|
+
const existing = (0, sdkNames_js_1.keepValidSdkName)(existingFieldById.get(field.id)?.sdkName);
|
|
379
346
|
const { id: _id, order: _order, ...definition } = field;
|
|
380
|
-
|
|
381
|
-
id: field.id,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
347
|
+
return {
|
|
348
|
+
field: { id: field.id, sdkName: "", definition },
|
|
349
|
+
draft: {
|
|
350
|
+
preferred: existing ?? (0, sdkNames_js_1.toSdkName)(field.name),
|
|
351
|
+
locked: existing !== undefined,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
});
|
|
355
|
+
const existingName = (0, sdkNames_js_1.keepValidSdkName)(existingTable?.sdkName);
|
|
356
|
+
drafts.push({
|
|
357
|
+
table: {
|
|
358
|
+
id: table.id,
|
|
359
|
+
sdkName: "",
|
|
360
|
+
primaryFieldId: table.primaryFieldId,
|
|
361
|
+
fields: [],
|
|
362
|
+
},
|
|
363
|
+
draft: {
|
|
364
|
+
preferred: existingName ?? (0, sdkNames_js_1.toSdkName)(table.name),
|
|
365
|
+
locked: existingName !== undefined,
|
|
366
|
+
},
|
|
390
367
|
fields,
|
|
391
368
|
});
|
|
392
369
|
}
|
|
370
|
+
const { tables, renames } = (0, sdkNames_js_1.allocateSchemaNames)(drafts);
|
|
371
|
+
if (renames.length > 0) {
|
|
372
|
+
// Never silent: a rename means the accessor a developer would reach for is
|
|
373
|
+
// not the one that got emitted.
|
|
374
|
+
for (const line of (0, sdkNames_js_1.describeRenames)(renames)) {
|
|
375
|
+
console.warn(`[zitejs] SDK name collision resolved: ${line}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
393
378
|
return { tables };
|
|
394
379
|
}
|
|
395
380
|
function generateSentinelSdkTypes() {
|
|
@@ -445,8 +430,8 @@ function buildLinkTableComments(schema) {
|
|
|
445
430
|
const target = tablesById.get(targetId);
|
|
446
431
|
if (!target)
|
|
447
432
|
continue;
|
|
448
|
-
const sourceSdk = toPascalCase(table.sdkName);
|
|
449
|
-
const targetSdk = toPascalCase(target.sdkName);
|
|
433
|
+
const sourceSdk = (0, sdkNames_js_1.toPascalCase)(table.sdkName);
|
|
434
|
+
const targetSdk = (0, sdkNames_js_1.toPascalCase)(target.sdkName);
|
|
450
435
|
const [first, second] = [sourceSdk, targetSdk].sort();
|
|
451
436
|
const linkName = `${first}${second}`;
|
|
452
437
|
if (seen.has(linkName))
|
|
@@ -477,8 +462,20 @@ function buildLinkTableComments(schema) {
|
|
|
477
462
|
* Generate .zite/db.ts purely from ZiteSchema.
|
|
478
463
|
* Pure function — no external data needed beyond what's in the schema file.
|
|
479
464
|
*/
|
|
480
|
-
function generateDbTs(
|
|
465
|
+
function generateDbTs(inputSchema) {
|
|
481
466
|
const lines = [];
|
|
467
|
+
// Defensive, and idempotent: a schema whose names are already unique and
|
|
468
|
+
// unreserved normalizes to itself. It matters for a `zite.schema.json`
|
|
469
|
+
// committed before allocation existed — the sandbox's boot-time
|
|
470
|
+
// `zitejs generate` reads that file directly, with no `generateSchema` pass
|
|
471
|
+
// in front of it, and would otherwise emit an object literal with a
|
|
472
|
+
// duplicate key (TS1117) that no build can recover from.
|
|
473
|
+
const { schema, renames } = (0, sdkNames_js_1.normalizeSchemaNames)(inputSchema);
|
|
474
|
+
if (renames.length > 0) {
|
|
475
|
+
for (const line of (0, sdkNames_js_1.describeRenames)(renames)) {
|
|
476
|
+
console.warn(`[zitejs] Repaired SDK name in zite.schema.json: ${line}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
482
479
|
const tables = schema.tables.filter((table) => table.id !== AUTH_USERS_TABLE_ID);
|
|
483
480
|
lines.push("// Auto-generated by zitejs generate. Do not edit manually.");
|
|
484
481
|
lines.push("//");
|
|
@@ -542,7 +539,7 @@ function generateDbTs(schema) {
|
|
|
542
539
|
lines.push("");
|
|
543
540
|
lines.push(...ATTACHMENT_TYPES);
|
|
544
541
|
for (const table of tables) {
|
|
545
|
-
const className = toPascalCase(table.sdkName);
|
|
542
|
+
const className = (0, sdkNames_js_1.toPascalCase)(table.sdkName);
|
|
546
543
|
const recordType = `${className}RecordType`;
|
|
547
544
|
lines.push(`/** A ${table.sdkName} record as it is read back. */`);
|
|
548
545
|
lines.push(`export type ${recordType} = {`);
|
|
@@ -579,7 +576,7 @@ function generateDbTs(schema) {
|
|
|
579
576
|
lines.push(...generateSentinelSdkTypes());
|
|
580
577
|
lines.push("export const zite = {");
|
|
581
578
|
for (const table of tables) {
|
|
582
|
-
const className = toPascalCase(table.sdkName);
|
|
579
|
+
const className = (0, sdkNames_js_1.toPascalCase)(table.sdkName);
|
|
583
580
|
lines.push(` ${table.sdkName}: createTableClient<${className}RecordType, ${className}RecordInput>('${className}'),`);
|
|
584
581
|
}
|
|
585
582
|
lines.push(` sql: createSqlClient(),`);
|
|
@@ -734,7 +731,7 @@ function generateApiTs(endpointFiles) {
|
|
|
734
731
|
continue;
|
|
735
732
|
}
|
|
736
733
|
const baseName = fileName.replace(/\.(ts|js)$/, "");
|
|
737
|
-
const key = toCamelCase(baseName);
|
|
734
|
+
const key = (0, sdkNames_js_1.toCamelCase)(baseName);
|
|
738
735
|
const ident = toSafeIdentifier(key);
|
|
739
736
|
// Distinct files can collide on one identifier (`send-email.ts` and
|
|
740
737
|
// `send_email.ts` both camelCase to `sendEmail`), which used to emit the
|
|
@@ -750,7 +747,7 @@ function generateApiTs(endpointFiles) {
|
|
|
750
747
|
baseName,
|
|
751
748
|
key,
|
|
752
749
|
ident,
|
|
753
|
-
pascal: toPascalCase(key),
|
|
750
|
+
pascal: (0, sdkNames_js_1.toPascalCase)(key),
|
|
754
751
|
stream: shape?.stream ?? false,
|
|
755
752
|
// No content to inspect means a bare-filename caller, which historically
|
|
756
753
|
// assumed a default export — keep that assumption.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allocation of the identifiers `generateDbTs` emits.
|
|
3
|
+
*
|
|
4
|
+
* Every accessor on the generated `zite` object, and every field key on a
|
|
5
|
+
* record type, has to be unique — and `generateSchema` used to choose them with
|
|
6
|
+
* `toSdkName` and no memory at all. Two consequences, both seen in the wild:
|
|
7
|
+
*
|
|
8
|
+
* - A table named "Notifications" allocated `notifications`, which
|
|
9
|
+
* `generateDbTs` also emits for the platform's notifications client. The
|
|
10
|
+
* sentinel is written last, so it won: the table lost its client entirely
|
|
11
|
+
* and typed as `{ create(params: NotificationsCreateParams) }`.
|
|
12
|
+
* - Two fields whose display names normalize alike both claimed one accessor,
|
|
13
|
+
* and the second silently overwrote the first in the emitted type. No
|
|
14
|
+
* error, no diagnostic — just a column you could no longer read. Zite 1.0's
|
|
15
|
+
* generator de-duplicated with numeric suffixes; 2.0 dropped that.
|
|
16
|
+
*
|
|
17
|
+
* `allocateSchemaNames` is idempotent: a schema whose names are already unique
|
|
18
|
+
* and unreserved allocates to itself. That is what lets `generateDbTs` run it
|
|
19
|
+
* defensively over its input — a schema file written before this existed
|
|
20
|
+
* repairs itself on the next generate instead of emitting TypeScript that
|
|
21
|
+
* cannot compile.
|
|
22
|
+
*/
|
|
23
|
+
import type { ZiteSchema, ZiteSchemaField, ZiteSchemaTable } from "./lib.js";
|
|
24
|
+
export declare function toPascalCase(name: string): string;
|
|
25
|
+
export declare function toCamelCase(name: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* camelCase for a FRESH sdkName, reading acronym runs as words: "VIP" ->
|
|
28
|
+
* "vip", "APIKey" -> "apiKey" (plain toCamelCase yields "vIP" / "aPIKey").
|
|
29
|
+
*
|
|
30
|
+
* Deliberately not folded into toCamelCase: that also derives endpoint
|
|
31
|
+
* identifiers from existing filenames on every generate, where normalizing
|
|
32
|
+
* would rename a working app's `api.sendSMS`. This is only for names being
|
|
33
|
+
* chosen for the first time — generateSchema preserves existing sdkNames.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toSdkName(name: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Accessors `generateDbTs` puts on the `zite` object itself, after the tables.
|
|
38
|
+
* A table that allocates one of these produces a duplicate key.
|
|
39
|
+
*/
|
|
40
|
+
export declare const RESERVED_TABLE_ACCESSORS: readonly ["sql", "notifications", "auth"];
|
|
41
|
+
/**
|
|
42
|
+
* Never safe as a generated key, in any namespace. Assigning `__proto__` in an
|
|
43
|
+
* object literal sets the prototype rather than defining a property, and
|
|
44
|
+
* `constructor` / `prototype` shadow members every object already carries.
|
|
45
|
+
*/
|
|
46
|
+
export declare const RESERVED_IDENTIFIERS: readonly ["__proto__", "constructor", "prototype"];
|
|
47
|
+
/**
|
|
48
|
+
* `id` is emitted by hand on every record type and filtered out of every input
|
|
49
|
+
* type, so a field that allocated it vanished from both. Reserving it means a
|
|
50
|
+
* field genuinely named "ID" gets a usable accessor instead.
|
|
51
|
+
*/
|
|
52
|
+
export declare const RESERVED_FIELD_ACCESSORS: readonly ["id"];
|
|
53
|
+
/** A name that could not be kept, reported so a rename is never silent. */
|
|
54
|
+
export interface SdkNameRename {
|
|
55
|
+
kind: "table" | "field";
|
|
56
|
+
/** The table this happened in; the table itself for `kind: 'table'`. */
|
|
57
|
+
tableId: string;
|
|
58
|
+
fieldId?: string;
|
|
59
|
+
from: string;
|
|
60
|
+
to: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Existing sdkNames are preserved across syncs so user code keeps compiling,
|
|
64
|
+
* but a schema written before the sanitizer stripped trailing symbols can carry
|
|
65
|
+
* an invalid identifier (e.g. `timeSeconds)`). Keep one only when it is a valid
|
|
66
|
+
* identifier; otherwise the caller recomputes it from the display name.
|
|
67
|
+
*/
|
|
68
|
+
export declare function keepValidSdkName(sdkName: string | undefined): string | undefined;
|
|
69
|
+
/** What a table/field would like to be called, and how hard it is holding on. */
|
|
70
|
+
interface NameDraft {
|
|
71
|
+
preferred: string;
|
|
72
|
+
/**
|
|
73
|
+
* True when the name is already baked into a committed schema and user code
|
|
74
|
+
* is compiling against it. Locked names are claimed first, so a fresh name
|
|
75
|
+
* can never displace one; a locked name still moves when it is reserved or
|
|
76
|
+
* when two locked names collide, because the alternative is a file that does
|
|
77
|
+
* not compile.
|
|
78
|
+
*/
|
|
79
|
+
locked: boolean;
|
|
80
|
+
}
|
|
81
|
+
export interface SchemaNameDraft {
|
|
82
|
+
table: ZiteSchemaTable;
|
|
83
|
+
draft: NameDraft;
|
|
84
|
+
fields: Array<{
|
|
85
|
+
field: ZiteSchemaField;
|
|
86
|
+
draft: NameDraft;
|
|
87
|
+
}>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolve every drafted name to a unique, unreserved one.
|
|
91
|
+
*
|
|
92
|
+
* Two passes per namespace: locked names claim first in declaration order, then
|
|
93
|
+
* fresh ones fill in around them. Without that ordering a new table could take
|
|
94
|
+
* an accessor an existing app already imports.
|
|
95
|
+
*/
|
|
96
|
+
export declare function allocateSchemaNames(drafts: SchemaNameDraft[]): {
|
|
97
|
+
tables: ZiteSchemaTable[];
|
|
98
|
+
renames: SdkNameRename[];
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Repair a schema whose names may already be unique — the idempotent case — or
|
|
102
|
+
* may predate allocation entirely. Everything is treated as locked: these names
|
|
103
|
+
* are what user code compiles against, so only a genuine conflict moves one.
|
|
104
|
+
*/
|
|
105
|
+
export declare function normalizeSchemaNames(schema: ZiteSchema): {
|
|
106
|
+
schema: ZiteSchema;
|
|
107
|
+
renames: SdkNameRename[];
|
|
108
|
+
};
|
|
109
|
+
/** One line per rename, for a generator that has no logger of its own. */
|
|
110
|
+
export declare function describeRenames(renames: SdkNameRename[]): string[];
|
|
111
|
+
export {};
|