zitejs 0.9.99 → 0.9.100
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/sync/lib.js +72 -27
- package/dist/esm/sync/lib.js +72 -27
- package/package.json +1 -1
package/dist/cjs/sync/lib.js
CHANGED
|
@@ -10,33 +10,47 @@ exports.generateBackendWrapperTs = generateBackendWrapperTs;
|
|
|
10
10
|
exports.generateEmailSdk = generateEmailSdk;
|
|
11
11
|
const parser_1 = require("@babel/parser");
|
|
12
12
|
const AUTH_USERS_TABLE_ID = "zite_user";
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* What a field's value looks like when a record is READ back.
|
|
15
|
+
*
|
|
16
|
+
* `| null` on the nullable ones is load-bearing, not pedantry: every field
|
|
17
|
+
* column is created nullable with no default (`recordsTableManager`), and only
|
|
18
|
+
* the six text types get their NULL rewritten to `''` on the way out
|
|
19
|
+
* (`normalizeEmptyStringFields` keys on `emptyValue === ''`). The product's own
|
|
20
|
+
* test asserts `fld_number` and `fld_checkbox` read back as `null`. Typing them
|
|
21
|
+
* non-null let `task.estimate.toFixed(2)` compile and throw.
|
|
22
|
+
*/
|
|
14
23
|
const FIELD_TYPE_MAP = {
|
|
24
|
+
// Text: NULL is rewritten to '' on read, so these genuinely can't be null.
|
|
15
25
|
single_line_text: "string",
|
|
16
26
|
long_text: "string",
|
|
17
27
|
rich_text: "string",
|
|
18
28
|
email: "string",
|
|
19
29
|
url: "string",
|
|
20
30
|
phone_number: "string",
|
|
21
|
-
number: "number",
|
|
22
|
-
currency: "number",
|
|
23
|
-
percent: "number",
|
|
24
|
-
rating: "number",
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
number: "number | null",
|
|
32
|
+
currency: "number | null",
|
|
33
|
+
percent: "number | null",
|
|
34
|
+
rating: "number | null",
|
|
35
|
+
// DECIMAL seconds, unlike Airtable's, which is formatted to "HH:mm:ss".
|
|
36
|
+
duration: "number | null",
|
|
37
|
+
checkbox: "boolean | null",
|
|
38
|
+
single_select: "string | null",
|
|
39
|
+
multiple_select: "string[] | null",
|
|
29
40
|
date: "string | null",
|
|
30
41
|
datetime: "string | null",
|
|
31
|
-
attachments: "ZiteAttachment[]",
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
attachments: "ZiteAttachment[] | null",
|
|
43
|
+
// `string | string[]`, matching the pre-monorepo type. base-runner does force
|
|
44
|
+
// an array on read today, but 1.0 code is written with `typeof x === 'string'`
|
|
45
|
+
// guards — narrowing to `string[]` turns those branches into `never` and
|
|
46
|
+
// fails the app's typecheck for no gain.
|
|
47
|
+
linked_record: "string | string[]",
|
|
48
|
+
user: "string | string[]",
|
|
36
49
|
lookup: "unknown",
|
|
37
50
|
rollup: "unknown",
|
|
38
51
|
autonumber: "number",
|
|
39
|
-
|
|
52
|
+
// JSONB change metadata (`{ type: "PublicAPI", apiKeyId: 3 }`), not a string.
|
|
53
|
+
source: "unknown",
|
|
40
54
|
formula: "unknown",
|
|
41
55
|
created_at: "string",
|
|
42
56
|
updated_at: "string",
|
|
@@ -47,9 +61,18 @@ const FIELD_TYPE_MAP = {
|
|
|
47
61
|
* looser input than it stores.
|
|
48
62
|
*/
|
|
49
63
|
const FIELD_INPUT_TYPE_MAP = {
|
|
50
|
-
attachments: "ZiteAttachmentInput[]",
|
|
51
|
-
linked_record: "string | string[]
|
|
52
|
-
user: "string | string[]
|
|
64
|
+
attachments: "ZiteAttachmentInput[] | ZiteAttachmentInput",
|
|
65
|
+
linked_record: "string | string[]",
|
|
66
|
+
user: "string | string[]",
|
|
67
|
+
multiple_select: "string | string[]",
|
|
68
|
+
date: "string | Date",
|
|
69
|
+
datetime: "string | Date",
|
|
70
|
+
number: "string | number",
|
|
71
|
+
currency: "string | number",
|
|
72
|
+
percent: "string | number",
|
|
73
|
+
rating: "string | number",
|
|
74
|
+
duration: "string | number",
|
|
75
|
+
checkbox: "string | boolean",
|
|
53
76
|
};
|
|
54
77
|
/**
|
|
55
78
|
* Computed and system-managed fields, omitted from the generated input type
|
|
@@ -156,6 +179,13 @@ function keepValidSdkName(sdkName) {
|
|
|
156
179
|
return undefined;
|
|
157
180
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(sdkName) ? sdkName : undefined;
|
|
158
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* `null` is how you CLEAR a cell — every scalar write schema in
|
|
184
|
+
* `flexible-inputs.ts` ends in `.nullable()` and update runs with
|
|
185
|
+
* `allowExplicitNull`. A write type without it makes the documented way to
|
|
186
|
+
* empty a field a compile error.
|
|
187
|
+
*/
|
|
188
|
+
const withNull = (type) => type.includes("null") ? type : `${type} | null`;
|
|
159
189
|
function tsTypeForSchemaField(def, variant = "read") {
|
|
160
190
|
if (def.type === "single_select" || def.type === "multiple_select") {
|
|
161
191
|
const options = def.template
|
|
@@ -166,13 +196,19 @@ function tsTypeForSchemaField(def, variant = "read") {
|
|
|
166
196
|
.map((o) => `"${o.label.replace(/"/g, '\\"')}"`)
|
|
167
197
|
.join(" | ");
|
|
168
198
|
const union = `${literals} | string`;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
199
|
+
const read = def.type === "multiple_select" ? `(${union})[] | null` : `${union} | null`;
|
|
200
|
+
if (variant === "write") {
|
|
201
|
+
return def.type === "multiple_select"
|
|
202
|
+
? `${union} | (${union})[] | null`
|
|
203
|
+
: `${union} | null`;
|
|
204
|
+
}
|
|
205
|
+
return read;
|
|
172
206
|
}
|
|
173
207
|
}
|
|
174
|
-
if (variant === "write"
|
|
175
|
-
|
|
208
|
+
if (variant === "write") {
|
|
209
|
+
const write = FIELD_INPUT_TYPE_MAP[def.type] ?? FIELD_TYPE_MAP[def.type];
|
|
210
|
+
if (write)
|
|
211
|
+
return withNull(write);
|
|
176
212
|
}
|
|
177
213
|
if (FIELD_TYPE_MAP[def.type])
|
|
178
214
|
return FIELD_TYPE_MAP[def.type];
|
|
@@ -474,7 +510,11 @@ function generateDbTs(schema) {
|
|
|
474
510
|
if (jsdoc) {
|
|
475
511
|
lines.push(` /** ${jsdoc} */`);
|
|
476
512
|
}
|
|
477
|
-
|
|
513
|
+
// Optional, matching the pre-monorepo type (`required: ['id']` — "none of
|
|
514
|
+
// these are required to be defined aside from 'id'"). A `fields:`
|
|
515
|
+
// projection omits every key it wasn't asked for, so any field really can
|
|
516
|
+
// be absent on a read.
|
|
517
|
+
lines.push(` ${field.sdkName}?: ${tsType};`);
|
|
478
518
|
}
|
|
479
519
|
lines.push("};");
|
|
480
520
|
lines.push("");
|
|
@@ -712,14 +752,18 @@ const AIRTABLE_FIELD_TYPE_MAP = {
|
|
|
712
752
|
currency: "number",
|
|
713
753
|
percent: "number",
|
|
714
754
|
rating: "number",
|
|
715
|
-
|
|
755
|
+
// Formatted to "HH:mm:ss" before it reaches the app — `formatAirtableDuration`
|
|
756
|
+
// in BOTH dispatches. Unlike the Zite DB's, which is DECIMAL seconds.
|
|
757
|
+
duration: "string",
|
|
716
758
|
checkbox: "boolean",
|
|
717
759
|
date: "string",
|
|
718
760
|
dateTime: "string",
|
|
719
761
|
singleSelect: "string",
|
|
720
762
|
multipleSelects: "string[]",
|
|
721
763
|
multipleAttachments: "AirtableAttachment[]",
|
|
722
|
-
|
|
764
|
+
// `string | string[]`, matching the pre-monorepo type — see the note on the
|
|
765
|
+
// Zite DB's `linked_record`.
|
|
766
|
+
multipleRecordLinks: "string | string[]",
|
|
723
767
|
singleCollaborator: "{ id: string; email: string; name?: string }",
|
|
724
768
|
multipleCollaborators: "Array<{ id: string; email: string; name?: string }>",
|
|
725
769
|
// Read-only fields
|
|
@@ -732,7 +776,8 @@ const AIRTABLE_FIELD_TYPE_MAP = {
|
|
|
732
776
|
lastModifiedTime: "string",
|
|
733
777
|
createdBy: "{ id: string; email: string; name?: string }",
|
|
734
778
|
lastModifiedBy: "{ id: string; email: string; name?: string }",
|
|
735
|
-
button
|
|
779
|
+
// Both dispatches extract the URL string off the button object.
|
|
780
|
+
button: "string",
|
|
736
781
|
externalSyncSource: "unknown",
|
|
737
782
|
aiText: "string",
|
|
738
783
|
};
|
package/dist/esm/sync/lib.js
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
1
|
import { parse } from "@babel/parser";
|
|
2
2
|
const AUTH_USERS_TABLE_ID = "zite_user";
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* What a field's value looks like when a record is READ back.
|
|
5
|
+
*
|
|
6
|
+
* `| null` on the nullable ones is load-bearing, not pedantry: every field
|
|
7
|
+
* column is created nullable with no default (`recordsTableManager`), and only
|
|
8
|
+
* the six text types get their NULL rewritten to `''` on the way out
|
|
9
|
+
* (`normalizeEmptyStringFields` keys on `emptyValue === ''`). The product's own
|
|
10
|
+
* test asserts `fld_number` and `fld_checkbox` read back as `null`. Typing them
|
|
11
|
+
* non-null let `task.estimate.toFixed(2)` compile and throw.
|
|
12
|
+
*/
|
|
4
13
|
const FIELD_TYPE_MAP = {
|
|
14
|
+
// Text: NULL is rewritten to '' on read, so these genuinely can't be null.
|
|
5
15
|
single_line_text: "string",
|
|
6
16
|
long_text: "string",
|
|
7
17
|
rich_text: "string",
|
|
8
18
|
email: "string",
|
|
9
19
|
url: "string",
|
|
10
20
|
phone_number: "string",
|
|
11
|
-
number: "number",
|
|
12
|
-
currency: "number",
|
|
13
|
-
percent: "number",
|
|
14
|
-
rating: "number",
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
number: "number | null",
|
|
22
|
+
currency: "number | null",
|
|
23
|
+
percent: "number | null",
|
|
24
|
+
rating: "number | null",
|
|
25
|
+
// DECIMAL seconds, unlike Airtable's, which is formatted to "HH:mm:ss".
|
|
26
|
+
duration: "number | null",
|
|
27
|
+
checkbox: "boolean | null",
|
|
28
|
+
single_select: "string | null",
|
|
29
|
+
multiple_select: "string[] | null",
|
|
19
30
|
date: "string | null",
|
|
20
31
|
datetime: "string | null",
|
|
21
|
-
attachments: "ZiteAttachment[]",
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
attachments: "ZiteAttachment[] | null",
|
|
33
|
+
// `string | string[]`, matching the pre-monorepo type. base-runner does force
|
|
34
|
+
// an array on read today, but 1.0 code is written with `typeof x === 'string'`
|
|
35
|
+
// guards — narrowing to `string[]` turns those branches into `never` and
|
|
36
|
+
// fails the app's typecheck for no gain.
|
|
37
|
+
linked_record: "string | string[]",
|
|
38
|
+
user: "string | string[]",
|
|
26
39
|
lookup: "unknown",
|
|
27
40
|
rollup: "unknown",
|
|
28
41
|
autonumber: "number",
|
|
29
|
-
|
|
42
|
+
// JSONB change metadata (`{ type: "PublicAPI", apiKeyId: 3 }`), not a string.
|
|
43
|
+
source: "unknown",
|
|
30
44
|
formula: "unknown",
|
|
31
45
|
created_at: "string",
|
|
32
46
|
updated_at: "string",
|
|
@@ -37,9 +51,18 @@ const FIELD_TYPE_MAP = {
|
|
|
37
51
|
* looser input than it stores.
|
|
38
52
|
*/
|
|
39
53
|
const FIELD_INPUT_TYPE_MAP = {
|
|
40
|
-
attachments: "ZiteAttachmentInput[]",
|
|
41
|
-
linked_record: "string | string[]
|
|
42
|
-
user: "string | string[]
|
|
54
|
+
attachments: "ZiteAttachmentInput[] | ZiteAttachmentInput",
|
|
55
|
+
linked_record: "string | string[]",
|
|
56
|
+
user: "string | string[]",
|
|
57
|
+
multiple_select: "string | string[]",
|
|
58
|
+
date: "string | Date",
|
|
59
|
+
datetime: "string | Date",
|
|
60
|
+
number: "string | number",
|
|
61
|
+
currency: "string | number",
|
|
62
|
+
percent: "string | number",
|
|
63
|
+
rating: "string | number",
|
|
64
|
+
duration: "string | number",
|
|
65
|
+
checkbox: "string | boolean",
|
|
43
66
|
};
|
|
44
67
|
/**
|
|
45
68
|
* Computed and system-managed fields, omitted from the generated input type
|
|
@@ -146,6 +169,13 @@ function keepValidSdkName(sdkName) {
|
|
|
146
169
|
return undefined;
|
|
147
170
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(sdkName) ? sdkName : undefined;
|
|
148
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* `null` is how you CLEAR a cell — every scalar write schema in
|
|
174
|
+
* `flexible-inputs.ts` ends in `.nullable()` and update runs with
|
|
175
|
+
* `allowExplicitNull`. A write type without it makes the documented way to
|
|
176
|
+
* empty a field a compile error.
|
|
177
|
+
*/
|
|
178
|
+
const withNull = (type) => type.includes("null") ? type : `${type} | null`;
|
|
149
179
|
function tsTypeForSchemaField(def, variant = "read") {
|
|
150
180
|
if (def.type === "single_select" || def.type === "multiple_select") {
|
|
151
181
|
const options = def.template
|
|
@@ -156,13 +186,19 @@ function tsTypeForSchemaField(def, variant = "read") {
|
|
|
156
186
|
.map((o) => `"${o.label.replace(/"/g, '\\"')}"`)
|
|
157
187
|
.join(" | ");
|
|
158
188
|
const union = `${literals} | string`;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
189
|
+
const read = def.type === "multiple_select" ? `(${union})[] | null` : `${union} | null`;
|
|
190
|
+
if (variant === "write") {
|
|
191
|
+
return def.type === "multiple_select"
|
|
192
|
+
? `${union} | (${union})[] | null`
|
|
193
|
+
: `${union} | null`;
|
|
194
|
+
}
|
|
195
|
+
return read;
|
|
162
196
|
}
|
|
163
197
|
}
|
|
164
|
-
if (variant === "write"
|
|
165
|
-
|
|
198
|
+
if (variant === "write") {
|
|
199
|
+
const write = FIELD_INPUT_TYPE_MAP[def.type] ?? FIELD_TYPE_MAP[def.type];
|
|
200
|
+
if (write)
|
|
201
|
+
return withNull(write);
|
|
166
202
|
}
|
|
167
203
|
if (FIELD_TYPE_MAP[def.type])
|
|
168
204
|
return FIELD_TYPE_MAP[def.type];
|
|
@@ -464,7 +500,11 @@ export function generateDbTs(schema) {
|
|
|
464
500
|
if (jsdoc) {
|
|
465
501
|
lines.push(` /** ${jsdoc} */`);
|
|
466
502
|
}
|
|
467
|
-
|
|
503
|
+
// Optional, matching the pre-monorepo type (`required: ['id']` — "none of
|
|
504
|
+
// these are required to be defined aside from 'id'"). A `fields:`
|
|
505
|
+
// projection omits every key it wasn't asked for, so any field really can
|
|
506
|
+
// be absent on a read.
|
|
507
|
+
lines.push(` ${field.sdkName}?: ${tsType};`);
|
|
468
508
|
}
|
|
469
509
|
lines.push("};");
|
|
470
510
|
lines.push("");
|
|
@@ -702,14 +742,18 @@ const AIRTABLE_FIELD_TYPE_MAP = {
|
|
|
702
742
|
currency: "number",
|
|
703
743
|
percent: "number",
|
|
704
744
|
rating: "number",
|
|
705
|
-
|
|
745
|
+
// Formatted to "HH:mm:ss" before it reaches the app — `formatAirtableDuration`
|
|
746
|
+
// in BOTH dispatches. Unlike the Zite DB's, which is DECIMAL seconds.
|
|
747
|
+
duration: "string",
|
|
706
748
|
checkbox: "boolean",
|
|
707
749
|
date: "string",
|
|
708
750
|
dateTime: "string",
|
|
709
751
|
singleSelect: "string",
|
|
710
752
|
multipleSelects: "string[]",
|
|
711
753
|
multipleAttachments: "AirtableAttachment[]",
|
|
712
|
-
|
|
754
|
+
// `string | string[]`, matching the pre-monorepo type — see the note on the
|
|
755
|
+
// Zite DB's `linked_record`.
|
|
756
|
+
multipleRecordLinks: "string | string[]",
|
|
713
757
|
singleCollaborator: "{ id: string; email: string; name?: string }",
|
|
714
758
|
multipleCollaborators: "Array<{ id: string; email: string; name?: string }>",
|
|
715
759
|
// Read-only fields
|
|
@@ -722,7 +766,8 @@ const AIRTABLE_FIELD_TYPE_MAP = {
|
|
|
722
766
|
lastModifiedTime: "string",
|
|
723
767
|
createdBy: "{ id: string; email: string; name?: string }",
|
|
724
768
|
lastModifiedBy: "{ id: string; email: string; name?: string }",
|
|
725
|
-
button
|
|
769
|
+
// Both dispatches extract the URL string off the button object.
|
|
770
|
+
button: "string",
|
|
726
771
|
externalSyncSource: "unknown",
|
|
727
772
|
aiText: "string",
|
|
728
773
|
};
|