zitejs 0.9.69 → 0.9.70
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 +25 -8
- package/dist/esm/sync/lib.js +25 -8
- package/package.json +1 -1
package/dist/cjs/sync/lib.js
CHANGED
|
@@ -26,8 +26,8 @@ const FIELD_TYPE_MAP = {
|
|
|
26
26
|
single_select: "string",
|
|
27
27
|
multiple_select: "string[]",
|
|
28
28
|
checkbox: "boolean",
|
|
29
|
-
date: "string",
|
|
30
|
-
datetime: "string",
|
|
29
|
+
date: "string | null",
|
|
30
|
+
datetime: "string | null",
|
|
31
31
|
attachments: "Array<{ url: string; name?: string }>",
|
|
32
32
|
linked_record: "string | string[]",
|
|
33
33
|
lookup: "unknown",
|
|
@@ -54,14 +54,31 @@ const DURATION_FORMAT_EXAMPLES = {
|
|
|
54
54
|
"h:mm:ss.sss": "1:23:03.000",
|
|
55
55
|
};
|
|
56
56
|
function toPascalCase(name) {
|
|
57
|
-
|
|
57
|
+
const pascal = name
|
|
58
58
|
.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase())
|
|
59
|
-
.replace(/^(.)/, (_, c) => c.toUpperCase())
|
|
59
|
+
.replace(/^(.)/, (_, c) => c.toUpperCase())
|
|
60
|
+
// Drop leftover non-alphanumerics (e.g. a trailing ">" from "</p>") so the
|
|
61
|
+
// sdkName is always a valid identifier in .zite/db.ts.
|
|
62
|
+
.replace(/[^a-zA-Z0-9]+/g, "");
|
|
63
|
+
if (!pascal)
|
|
64
|
+
return "_";
|
|
65
|
+
return /^[0-9]/.test(pascal) ? `_${pascal}` : pascal; // can't start with a digit
|
|
60
66
|
}
|
|
61
67
|
function toCamelCase(name) {
|
|
62
68
|
const pascal = toPascalCase(name);
|
|
63
69
|
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
64
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Existing sdkNames are preserved across syncs so user code keeps compiling,
|
|
73
|
+
* but schemas written before the sanitizer stripped trailing symbols can carry
|
|
74
|
+
* invalid identifiers (e.g. "timeSeconds)"). Keep an existing name only when
|
|
75
|
+
* it's a valid identifier; otherwise fall through to recomputing it.
|
|
76
|
+
*/
|
|
77
|
+
function keepValidSdkName(sdkName) {
|
|
78
|
+
if (!sdkName)
|
|
79
|
+
return undefined;
|
|
80
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(sdkName) ? sdkName : undefined;
|
|
81
|
+
}
|
|
65
82
|
function tsTypeForSchemaField(def) {
|
|
66
83
|
if (def.type === "single_select" || def.type === "multiple_select") {
|
|
67
84
|
const options = def.template
|
|
@@ -104,11 +121,11 @@ function fieldJsdoc(schemaField, table) {
|
|
|
104
121
|
if (def.type === "date") {
|
|
105
122
|
const tpl = def.template;
|
|
106
123
|
if (tpl.dateFormat)
|
|
107
|
-
parts.push(`Date-only field (YYYY-MM-DD string), display as "${tpl.dateFormat}" format`);
|
|
124
|
+
parts.push(`Date-only field (YYYY-MM-DD string), null when unset, display as "${tpl.dateFormat}" format`);
|
|
108
125
|
}
|
|
109
126
|
if (def.type === "datetime") {
|
|
110
127
|
const tpl = def.template;
|
|
111
|
-
const timeParts = ["Date+time field (ISO 8601 timestamp)"];
|
|
128
|
+
const timeParts = ["Date+time field (ISO 8601 timestamp), null when unset"];
|
|
112
129
|
if (tpl.dateFormat)
|
|
113
130
|
timeParts.push(`date: ${tpl.dateFormat}`);
|
|
114
131
|
if (tpl.timeFormat)
|
|
@@ -192,13 +209,13 @@ function generateSchema(database, existingSchema) {
|
|
|
192
209
|
const { id: _id, order: _order, ...definition } = field;
|
|
193
210
|
fields.push({
|
|
194
211
|
id: field.id,
|
|
195
|
-
sdkName: existing?.sdkName ?? toCamelCase(field.name),
|
|
212
|
+
sdkName: keepValidSdkName(existing?.sdkName) ?? toCamelCase(field.name),
|
|
196
213
|
definition,
|
|
197
214
|
});
|
|
198
215
|
}
|
|
199
216
|
tables.push({
|
|
200
217
|
id: table.id,
|
|
201
|
-
sdkName: existingTable?.sdkName ?? toCamelCase(table.name),
|
|
218
|
+
sdkName: keepValidSdkName(existingTable?.sdkName) ?? toCamelCase(table.name),
|
|
202
219
|
primaryFieldId: table.primaryFieldId,
|
|
203
220
|
fields,
|
|
204
221
|
});
|
package/dist/esm/sync/lib.js
CHANGED
|
@@ -14,8 +14,8 @@ const FIELD_TYPE_MAP = {
|
|
|
14
14
|
single_select: "string",
|
|
15
15
|
multiple_select: "string[]",
|
|
16
16
|
checkbox: "boolean",
|
|
17
|
-
date: "string",
|
|
18
|
-
datetime: "string",
|
|
17
|
+
date: "string | null",
|
|
18
|
+
datetime: "string | null",
|
|
19
19
|
attachments: "Array<{ url: string; name?: string }>",
|
|
20
20
|
linked_record: "string | string[]",
|
|
21
21
|
lookup: "unknown",
|
|
@@ -42,14 +42,31 @@ const DURATION_FORMAT_EXAMPLES = {
|
|
|
42
42
|
"h:mm:ss.sss": "1:23:03.000",
|
|
43
43
|
};
|
|
44
44
|
export function toPascalCase(name) {
|
|
45
|
-
|
|
45
|
+
const pascal = name
|
|
46
46
|
.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase())
|
|
47
|
-
.replace(/^(.)/, (_, c) => c.toUpperCase())
|
|
47
|
+
.replace(/^(.)/, (_, c) => c.toUpperCase())
|
|
48
|
+
// Drop leftover non-alphanumerics (e.g. a trailing ">" from "</p>") so the
|
|
49
|
+
// sdkName is always a valid identifier in .zite/db.ts.
|
|
50
|
+
.replace(/[^a-zA-Z0-9]+/g, "");
|
|
51
|
+
if (!pascal)
|
|
52
|
+
return "_";
|
|
53
|
+
return /^[0-9]/.test(pascal) ? `_${pascal}` : pascal; // can't start with a digit
|
|
48
54
|
}
|
|
49
55
|
export function toCamelCase(name) {
|
|
50
56
|
const pascal = toPascalCase(name);
|
|
51
57
|
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
52
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Existing sdkNames are preserved across syncs so user code keeps compiling,
|
|
61
|
+
* but schemas written before the sanitizer stripped trailing symbols can carry
|
|
62
|
+
* invalid identifiers (e.g. "timeSeconds)"). Keep an existing name only when
|
|
63
|
+
* it's a valid identifier; otherwise fall through to recomputing it.
|
|
64
|
+
*/
|
|
65
|
+
function keepValidSdkName(sdkName) {
|
|
66
|
+
if (!sdkName)
|
|
67
|
+
return undefined;
|
|
68
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(sdkName) ? sdkName : undefined;
|
|
69
|
+
}
|
|
53
70
|
function tsTypeForSchemaField(def) {
|
|
54
71
|
if (def.type === "single_select" || def.type === "multiple_select") {
|
|
55
72
|
const options = def.template
|
|
@@ -92,11 +109,11 @@ function fieldJsdoc(schemaField, table) {
|
|
|
92
109
|
if (def.type === "date") {
|
|
93
110
|
const tpl = def.template;
|
|
94
111
|
if (tpl.dateFormat)
|
|
95
|
-
parts.push(`Date-only field (YYYY-MM-DD string), display as "${tpl.dateFormat}" format`);
|
|
112
|
+
parts.push(`Date-only field (YYYY-MM-DD string), null when unset, display as "${tpl.dateFormat}" format`);
|
|
96
113
|
}
|
|
97
114
|
if (def.type === "datetime") {
|
|
98
115
|
const tpl = def.template;
|
|
99
|
-
const timeParts = ["Date+time field (ISO 8601 timestamp)"];
|
|
116
|
+
const timeParts = ["Date+time field (ISO 8601 timestamp), null when unset"];
|
|
100
117
|
if (tpl.dateFormat)
|
|
101
118
|
timeParts.push(`date: ${tpl.dateFormat}`);
|
|
102
119
|
if (tpl.timeFormat)
|
|
@@ -180,13 +197,13 @@ export function generateSchema(database, existingSchema) {
|
|
|
180
197
|
const { id: _id, order: _order, ...definition } = field;
|
|
181
198
|
fields.push({
|
|
182
199
|
id: field.id,
|
|
183
|
-
sdkName: existing?.sdkName ?? toCamelCase(field.name),
|
|
200
|
+
sdkName: keepValidSdkName(existing?.sdkName) ?? toCamelCase(field.name),
|
|
184
201
|
definition,
|
|
185
202
|
});
|
|
186
203
|
}
|
|
187
204
|
tables.push({
|
|
188
205
|
id: table.id,
|
|
189
|
-
sdkName: existingTable?.sdkName ?? toCamelCase(table.name),
|
|
206
|
+
sdkName: keepValidSdkName(existingTable?.sdkName) ?? toCamelCase(table.name),
|
|
190
207
|
primaryFieldId: table.primaryFieldId,
|
|
191
208
|
fields,
|
|
192
209
|
});
|