zitejs 0.9.41 → 0.9.43
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/bundle/index.js +9 -0
- package/dist/cjs/dev/index.js +37 -0
- package/dist/cjs/runtime/index.js +30 -0
- package/dist/cjs/sync/index.js +18 -6
- package/dist/cjs/sync/lib.js +263 -33
- package/dist/esm/bundle/index.js +9 -0
- package/dist/esm/client/index.d.ts +18 -18
- package/dist/esm/dev/index.js +38 -1
- package/dist/esm/runtime/index.d.ts +26 -0
- package/dist/esm/runtime/index.js +29 -0
- package/dist/esm/sync/index.js +19 -7
- package/dist/esm/sync/lib.d.ts +43 -18
- package/dist/esm/sync/lib.js +262 -33
- package/dist/esm/types/fields.d.ts +17 -17
- package/dist/esm/types/tables.d.ts +12 -12
- package/package.json +1 -1
package/dist/cjs/bundle/index.js
CHANGED
|
@@ -250,6 +250,15 @@ function createAliasPlugin(opts) {
|
|
|
250
250
|
}
|
|
251
251
|
return { path: 'zitejs/db', external: true };
|
|
252
252
|
});
|
|
253
|
+
// Resolve zitejs/integrations to .zite/integrations/airtable.ts
|
|
254
|
+
build.onResolve({ filter: /^zitejs\/integrations$/ }, () => {
|
|
255
|
+
if (opts.baseDir) {
|
|
256
|
+
const intPath = path.resolve(opts.baseDir, '.zite/integrations/airtable.ts');
|
|
257
|
+
if (fs.existsSync(intPath))
|
|
258
|
+
return { path: intPath };
|
|
259
|
+
}
|
|
260
|
+
return { path: 'zitejs/integrations', external: true };
|
|
261
|
+
});
|
|
253
262
|
// zitejs/runtime is NOT in PREBUNDLED_LIBS — it's a thin fetch()
|
|
254
263
|
// wrapper that gets bundled inline by esbuild (no special handling).
|
|
255
264
|
for (const [pkgName, modulePath] of Object.entries(PREBUNDLED_LIBS)) {
|
package/dist/cjs/dev/index.js
CHANGED
|
@@ -53,6 +53,42 @@ function regenerateAppApiTs(appDir) {
|
|
|
53
53
|
console.log(`Updated apps/${appDir}/.zite/api.ts`);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
function regenerateAppAirtableSdk(appDir) {
|
|
57
|
+
const lockPath = (0, path_1.join)('apps', appDir, 'zite.lock');
|
|
58
|
+
if (!(0, fs_2.existsSync)(lockPath))
|
|
59
|
+
return;
|
|
60
|
+
try {
|
|
61
|
+
const lockContent = JSON.parse((0, fs_2.readFileSync)(lockPath, 'utf-8'));
|
|
62
|
+
const integrations = lockContent.integrations ?? {};
|
|
63
|
+
for (const [integrationId, integration] of Object.entries(integrations)) {
|
|
64
|
+
const int = integration;
|
|
65
|
+
if (!int.idMappings?.tables)
|
|
66
|
+
continue;
|
|
67
|
+
const airtableLock = {
|
|
68
|
+
integrationId,
|
|
69
|
+
tables: Object.entries(int.idMappings.tables).map(([sdkName, tableId]) => ({
|
|
70
|
+
id: tableId,
|
|
71
|
+
sdkName,
|
|
72
|
+
fields: Object.entries(int.idMappings?.fields?.[sdkName] ?? {}).map(([fieldSdkName, fieldId]) => ({
|
|
73
|
+
id: fieldId,
|
|
74
|
+
sdkName: fieldSdkName,
|
|
75
|
+
type: 'singleLineText',
|
|
76
|
+
})),
|
|
77
|
+
})),
|
|
78
|
+
};
|
|
79
|
+
const content = (0, lib_js_1.generateAirtableTs)(airtableLock);
|
|
80
|
+
if (content) {
|
|
81
|
+
const outDir = (0, path_1.join)('apps', appDir, '.zite', 'integrations');
|
|
82
|
+
(0, fs_2.mkdirSync)(outDir, { recursive: true });
|
|
83
|
+
(0, fs_2.writeFileSync)((0, path_1.join)(outDir, 'airtable.ts'), content);
|
|
84
|
+
console.log(`Updated apps/${appDir}/.zite/integrations/airtable.ts`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Lock file invalid or missing — skip
|
|
90
|
+
}
|
|
91
|
+
}
|
|
56
92
|
async function runGenerate() {
|
|
57
93
|
// 1. Run sync (generates root .zite/db.ts)
|
|
58
94
|
try {
|
|
@@ -66,6 +102,7 @@ async function runGenerate() {
|
|
|
66
102
|
for (const app of appDirs) {
|
|
67
103
|
regenerateAppApiTs(app);
|
|
68
104
|
regenerateAppTypedWrappers(app);
|
|
105
|
+
regenerateAppAirtableSdk(app);
|
|
69
106
|
}
|
|
70
107
|
console.log('Done!');
|
|
71
108
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createCaller = void 0;
|
|
4
4
|
exports.createTableClient = createTableClient;
|
|
5
5
|
exports.createSqlClient = createSqlClient;
|
|
6
|
+
exports.createAirtableClient = createAirtableClient;
|
|
6
7
|
function getSdkCall() {
|
|
7
8
|
const fn = globalThis.__wrapSdkCall;
|
|
8
9
|
if (!fn) {
|
|
@@ -76,5 +77,34 @@ function createSqlClient() {
|
|
|
76
77
|
...params,
|
|
77
78
|
});
|
|
78
79
|
}
|
|
80
|
+
function createAirtableClient(integrationId, className, implicitParams) {
|
|
81
|
+
return {
|
|
82
|
+
findAll: (options) => getSdkCall()(integrationId, className, "findAll", {
|
|
83
|
+
...implicitParams,
|
|
84
|
+
...options,
|
|
85
|
+
}),
|
|
86
|
+
findOne: (params) => getSdkCall()(integrationId, className, "findOne", {
|
|
87
|
+
...implicitParams,
|
|
88
|
+
...params,
|
|
89
|
+
}),
|
|
90
|
+
create: (data) => getSdkCall()(integrationId, className, "create", {
|
|
91
|
+
...implicitParams,
|
|
92
|
+
...data,
|
|
93
|
+
}),
|
|
94
|
+
bulkCreate: (records) => getSdkCall()(integrationId, className, "bulkCreate", {
|
|
95
|
+
...implicitParams,
|
|
96
|
+
records,
|
|
97
|
+
}),
|
|
98
|
+
update: (id, data) => getSdkCall()(integrationId, className, "update", {
|
|
99
|
+
...implicitParams,
|
|
100
|
+
id,
|
|
101
|
+
...data,
|
|
102
|
+
}),
|
|
103
|
+
delete: (id) => getSdkCall()(integrationId, className, "delete", {
|
|
104
|
+
...implicitParams,
|
|
105
|
+
id,
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
79
109
|
var index_js_1 = require("../caller/index.js");
|
|
80
110
|
Object.defineProperty(exports, "createCaller", { enumerable: true, get: function () { return index_js_1.createCaller; } });
|
package/dist/cjs/sync/index.js
CHANGED
|
@@ -12,9 +12,11 @@ const DB_ENVIRONMENTS = {
|
|
|
12
12
|
local: "http://localhost:2507/api/v1",
|
|
13
13
|
};
|
|
14
14
|
const env = process.env.ZITE_ENV ?? "production";
|
|
15
|
-
const BASE_URL = process.env.ZITE_DB_URL ??
|
|
15
|
+
const BASE_URL = process.env.ZITE_DB_URL ??
|
|
16
|
+
DB_ENVIRONMENTS[env] ??
|
|
17
|
+
DB_ENVIRONMENTS.production;
|
|
16
18
|
const TOKEN = process.env.ZITE_DB_TOKEN ?? "";
|
|
17
|
-
async function
|
|
19
|
+
async function fetchDatabase(baseId) {
|
|
18
20
|
const url = `${BASE_URL}/bases/${encodeURIComponent(baseId)}`;
|
|
19
21
|
const res = await fetch(url, {
|
|
20
22
|
headers: { Authorization: `Bearer ${TOKEN}` },
|
|
@@ -35,6 +37,15 @@ function resolveBaseId() {
|
|
|
35
37
|
return undefined;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
40
|
+
function readExistingSchema() {
|
|
41
|
+
try {
|
|
42
|
+
if ((0, fs_1.existsSync)("zite.schema.json")) {
|
|
43
|
+
return JSON.parse((0, fs_1.readFileSync)("zite.schema.json", "utf-8"));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch { }
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
38
49
|
async function runSync() {
|
|
39
50
|
if (!TOKEN) {
|
|
40
51
|
throw new Error("ZITE_DB_TOKEN is required.");
|
|
@@ -44,12 +55,13 @@ async function runSync() {
|
|
|
44
55
|
throw new Error("Could not determine base ID.");
|
|
45
56
|
}
|
|
46
57
|
console.log(`Syncing database ${baseId}...`);
|
|
47
|
-
const
|
|
48
|
-
console.log(`Found ${
|
|
49
|
-
const
|
|
58
|
+
const database = await fetchDatabase(baseId);
|
|
59
|
+
console.log(`Found ${database.tables?.length ?? 0} tables`);
|
|
60
|
+
const existingSchema = readExistingSchema();
|
|
61
|
+
const schema = (0, lib_js_1.generateSchema)(database, existingSchema);
|
|
50
62
|
(0, fs_1.writeFileSync)("zite.schema.json", JSON.stringify(schema, null, 2));
|
|
51
63
|
console.log("Wrote zite.schema.json");
|
|
52
|
-
const dbTs = (0, lib_js_1.generateDbTs)(
|
|
64
|
+
const dbTs = (0, lib_js_1.generateDbTs)(schema);
|
|
53
65
|
const dotZite = ".zite";
|
|
54
66
|
(0, fs_1.mkdirSync)(dotZite, { recursive: true });
|
|
55
67
|
(0, fs_1.writeFileSync)((0, path_1.join)(dotZite, "db.ts"), dbTs);
|
package/dist/cjs/sync/lib.js
CHANGED
|
@@ -7,10 +7,12 @@ exports.generateDbTs = generateDbTs;
|
|
|
7
7
|
exports.generateApiTs = generateApiTs;
|
|
8
8
|
exports.generateUserTs = generateUserTs;
|
|
9
9
|
exports.generateAuthWrapperTs = generateAuthWrapperTs;
|
|
10
|
+
exports.generateAirtableTs = generateAirtableTs;
|
|
10
11
|
exports.generateBackendWrapperTs = generateBackendWrapperTs;
|
|
11
12
|
const FIELD_TYPE_MAP = {
|
|
12
13
|
single_line_text: "string",
|
|
13
14
|
long_text: "string",
|
|
15
|
+
rich_text: "string",
|
|
14
16
|
email: "string",
|
|
15
17
|
url: "string",
|
|
16
18
|
phone_number: "string",
|
|
@@ -29,6 +31,25 @@ const FIELD_TYPE_MAP = {
|
|
|
29
31
|
lookup: "unknown",
|
|
30
32
|
autonumber: "number",
|
|
31
33
|
source: "string",
|
|
34
|
+
formula: "unknown",
|
|
35
|
+
created_at: "string",
|
|
36
|
+
updated_at: "string",
|
|
37
|
+
};
|
|
38
|
+
const MAX_SELECT_OPTIONS = 100;
|
|
39
|
+
const NUMBER_FORMAT_EXAMPLES = {
|
|
40
|
+
local: "1,000,000.50",
|
|
41
|
+
comma_period: "1,000,000.50",
|
|
42
|
+
period_comma: "1.000.000,50",
|
|
43
|
+
space_comma: "1 000 000,50",
|
|
44
|
+
space_period: "1 000 000.50",
|
|
45
|
+
no_separator: "1000000.50",
|
|
46
|
+
};
|
|
47
|
+
const DURATION_FORMAT_EXAMPLES = {
|
|
48
|
+
"h:mm": "1:23",
|
|
49
|
+
"h:mm:ss": "1:23:03",
|
|
50
|
+
"h:mm:ss.s": "1:23:03.0",
|
|
51
|
+
"h:mm:ss.ss": "1:23:03.00",
|
|
52
|
+
"h:mm:ss.sss": "1:23:03.000",
|
|
32
53
|
};
|
|
33
54
|
function toPascalCase(name) {
|
|
34
55
|
return name
|
|
@@ -39,33 +60,157 @@ function toCamelCase(name) {
|
|
|
39
60
|
const pascal = toPascalCase(name);
|
|
40
61
|
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
41
62
|
}
|
|
42
|
-
function
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
63
|
+
function tsTypeForSchemaField(def) {
|
|
64
|
+
if (def.type === "single_select" || def.type === "multiple_select") {
|
|
65
|
+
const options = def.template
|
|
66
|
+
?.options;
|
|
67
|
+
if (options && options.length > 0) {
|
|
68
|
+
const literals = options
|
|
69
|
+
.slice(0, MAX_SELECT_OPTIONS)
|
|
70
|
+
.map((o) => `"${o.label.replace(/"/g, '\\"')}"`)
|
|
71
|
+
.join(" | ");
|
|
72
|
+
const union = `${literals} | string`;
|
|
73
|
+
if (def.type === "multiple_select")
|
|
74
|
+
return `(${union})[]`;
|
|
75
|
+
return union;
|
|
76
|
+
}
|
|
51
77
|
}
|
|
78
|
+
if (FIELD_TYPE_MAP[def.type])
|
|
79
|
+
return FIELD_TYPE_MAP[def.type];
|
|
52
80
|
return "string";
|
|
53
81
|
}
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
function fieldJsdoc(schemaField, table) {
|
|
83
|
+
const def = schemaField.definition;
|
|
84
|
+
const parts = [];
|
|
85
|
+
if (table.primaryFieldId === schemaField.id)
|
|
86
|
+
parts.push("Primary field");
|
|
87
|
+
if (def.type === "created_at" ||
|
|
88
|
+
def.type === "updated_at" ||
|
|
89
|
+
def.type === "lookup" ||
|
|
90
|
+
def.type === "formula" ||
|
|
91
|
+
def.type === "autonumber") {
|
|
92
|
+
parts.push("Read-only");
|
|
93
|
+
}
|
|
94
|
+
if (def.type === "linked_record") {
|
|
95
|
+
const tpl = def.template;
|
|
96
|
+
if (tpl.tableId)
|
|
97
|
+
parts.push(`Links to table ${tpl.tableId}`);
|
|
98
|
+
if (tpl.allowMultiple === false)
|
|
99
|
+
parts.push("Single record only");
|
|
100
|
+
}
|
|
101
|
+
parts.push(`"${def.name}"`);
|
|
102
|
+
if (def.type === "date") {
|
|
103
|
+
const tpl = def.template;
|
|
104
|
+
if (tpl.dateFormat)
|
|
105
|
+
parts.push(`Date-only field (YYYY-MM-DD string), display as "${tpl.dateFormat}" format`);
|
|
106
|
+
}
|
|
107
|
+
if (def.type === "datetime") {
|
|
108
|
+
const tpl = def.template;
|
|
109
|
+
const timeParts = [
|
|
110
|
+
"Date+time field (ISO 8601 timestamp)",
|
|
111
|
+
];
|
|
112
|
+
if (tpl.dateFormat)
|
|
113
|
+
timeParts.push(`date: ${tpl.dateFormat}`);
|
|
114
|
+
if (tpl.timeFormat)
|
|
115
|
+
timeParts.push(`time: ${tpl.timeFormat}`);
|
|
116
|
+
if (tpl.timezone)
|
|
117
|
+
timeParts.push(`tz: ${tpl.timezone}`);
|
|
118
|
+
if (tpl.displayTimeZone)
|
|
119
|
+
timeParts.push("timezone displayed to user");
|
|
120
|
+
parts.push(timeParts.join(", "));
|
|
121
|
+
}
|
|
122
|
+
if (def.type === "currency") {
|
|
123
|
+
const tpl = def.template;
|
|
124
|
+
if (tpl.currencySymbol) {
|
|
125
|
+
const formatHint = NUMBER_FORMAT_EXAMPLES[tpl.numberFormat ?? "local"] ?? "";
|
|
126
|
+
parts.push(`Value is a raw number; display as currency with symbol "${tpl.currencySymbol}", ${tpl.decimalPlaces ?? 2} decimal places, format: ${tpl.numberFormat ?? "local"} (e.g. ${formatHint})`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (def.type === "number") {
|
|
130
|
+
const tpl = def.template;
|
|
131
|
+
const formatHint = NUMBER_FORMAT_EXAMPLES[tpl.numberFormat ?? "local"] ?? "";
|
|
132
|
+
parts.push(`${tpl.decimalPlaces ?? 0} decimal places, format: ${tpl.numberFormat ?? "local"} (e.g. ${formatHint})`);
|
|
133
|
+
}
|
|
134
|
+
if (def.type === "percent") {
|
|
135
|
+
const tpl = def.template;
|
|
136
|
+
if (tpl.decimalPlaces !== undefined)
|
|
137
|
+
parts.push(`${tpl.decimalPlaces} decimal places`);
|
|
138
|
+
}
|
|
139
|
+
if (def.type === "duration") {
|
|
140
|
+
const tpl = def.template;
|
|
141
|
+
if (tpl.format) {
|
|
142
|
+
const example = DURATION_FORMAT_EXAMPLES[tpl.format] ?? "";
|
|
143
|
+
parts.push(`Value is in seconds; display in "${tpl.format}" format (${example})`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (def.type === "rating") {
|
|
147
|
+
const tpl = def.template;
|
|
148
|
+
if (tpl.maxRating)
|
|
149
|
+
parts.push(`Max rating: ${tpl.maxRating}`);
|
|
150
|
+
}
|
|
151
|
+
if (def.type === "created_at") {
|
|
152
|
+
parts.push("Auto-set when record was created (ISO 8601)");
|
|
153
|
+
}
|
|
154
|
+
if (def.type === "updated_at") {
|
|
155
|
+
parts.push("Auto-set when record was last modified (ISO 8601)");
|
|
156
|
+
}
|
|
157
|
+
if ((def.type === "single_select" || def.type === "multiple_select") &&
|
|
158
|
+
def.template?.options) {
|
|
159
|
+
const count = (def.template.options ?? []).length;
|
|
160
|
+
if (count > MAX_SELECT_OPTIONS) {
|
|
161
|
+
parts.push(`${count - MAX_SELECT_OPTIONS} more options omitted`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (parts.length <= 1)
|
|
165
|
+
return undefined;
|
|
166
|
+
return parts.join(". ");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Build a ZiteSchema from a Database API response.
|
|
170
|
+
*
|
|
171
|
+
* If `existingSchema` is provided, locked SDK names are preserved for
|
|
172
|
+
* tables/fields that already exist (matched by ID). New tables/fields
|
|
173
|
+
* get fresh camelCase SDK names. This is how `zitejs sync` preserves
|
|
174
|
+
* name stability across schema changes.
|
|
175
|
+
*/
|
|
176
|
+
function generateSchema(database, existingSchema) {
|
|
177
|
+
const existingTableById = new Map();
|
|
178
|
+
for (const t of existingSchema?.tables ?? []) {
|
|
179
|
+
existingTableById.set(t.id, t);
|
|
180
|
+
}
|
|
181
|
+
const tables = [];
|
|
182
|
+
for (const table of database.tables) {
|
|
183
|
+
const existingTable = existingTableById.get(table.id);
|
|
184
|
+
const existingFieldById = new Map();
|
|
185
|
+
for (const f of existingTable?.fields ?? []) {
|
|
186
|
+
existingFieldById.set(f.id, f);
|
|
61
187
|
}
|
|
62
|
-
|
|
188
|
+
const fields = [];
|
|
189
|
+
for (const field of table.fields) {
|
|
190
|
+
const existing = existingFieldById.get(field.id);
|
|
191
|
+
const { id: _id, order: _order, ...definition } = field;
|
|
192
|
+
fields.push({
|
|
193
|
+
id: field.id,
|
|
194
|
+
sdkName: existing?.sdkName ?? toCamelCase(field.name),
|
|
195
|
+
definition,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
tables.push({
|
|
199
|
+
id: table.id,
|
|
200
|
+
sdkName: existingTable?.sdkName ?? toCamelCase(table.name),
|
|
201
|
+
primaryFieldId: table.primaryFieldId,
|
|
202
|
+
fields,
|
|
203
|
+
});
|
|
63
204
|
}
|
|
64
|
-
return
|
|
205
|
+
return { tables };
|
|
65
206
|
}
|
|
66
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Generate .zite/db.ts purely from ZiteSchema.
|
|
209
|
+
* Pure function — no external data needed beyond what's in the schema file.
|
|
210
|
+
*/
|
|
211
|
+
function generateDbTs(schema) {
|
|
67
212
|
const lines = [];
|
|
68
|
-
lines.push("// Auto-generated by zitejs
|
|
213
|
+
lines.push("// Auto-generated by zitejs generate. Do not edit manually.");
|
|
69
214
|
lines.push("//");
|
|
70
215
|
lines.push("// Usage in endpoint files (src/api/*.ts):");
|
|
71
216
|
lines.push('// import { zite } from "zitejs/db";');
|
|
@@ -97,26 +242,28 @@ function generateDbTs(base, schema) {
|
|
|
97
242
|
lines.push('// - Load the "zite:sql" skill for full SQL reference (formulas, lookups, etc.)');
|
|
98
243
|
lines.push("import { createTableClient, createSqlClient } from 'zitejs/runtime';");
|
|
99
244
|
lines.push("");
|
|
100
|
-
for (const table of
|
|
101
|
-
const className = toPascalCase(table.
|
|
245
|
+
for (const table of schema.tables) {
|
|
246
|
+
const className = toPascalCase(table.sdkName);
|
|
102
247
|
const recordType = `${className}RecordType`;
|
|
103
248
|
lines.push(`export type ${recordType} = {`);
|
|
104
249
|
lines.push(" id: string;");
|
|
105
|
-
for (const field of table.fields
|
|
106
|
-
|
|
107
|
-
if (fieldName === "id")
|
|
250
|
+
for (const field of table.fields) {
|
|
251
|
+
if (field.sdkName === "id")
|
|
108
252
|
continue;
|
|
109
|
-
const tsType =
|
|
110
|
-
|
|
253
|
+
const tsType = tsTypeForSchemaField(field.definition);
|
|
254
|
+
const jsdoc = fieldJsdoc(field, table);
|
|
255
|
+
if (jsdoc) {
|
|
256
|
+
lines.push(` /** ${jsdoc} */`);
|
|
257
|
+
}
|
|
258
|
+
lines.push(` ${field.sdkName}: ${tsType};`);
|
|
111
259
|
}
|
|
112
260
|
lines.push("};");
|
|
113
261
|
lines.push("");
|
|
114
262
|
}
|
|
115
263
|
lines.push("export const zite = {");
|
|
116
|
-
for (const table of
|
|
117
|
-
const className = toPascalCase(table.
|
|
118
|
-
|
|
119
|
-
lines.push(` ${propName}: createTableClient<${className}RecordType>('${className}'),`);
|
|
264
|
+
for (const table of schema.tables) {
|
|
265
|
+
const className = toPascalCase(table.sdkName);
|
|
266
|
+
lines.push(` ${table.sdkName}: createTableClient<${className}RecordType>('${className}'),`);
|
|
120
267
|
}
|
|
121
268
|
lines.push(` sql: createSqlClient(),`);
|
|
122
269
|
lines.push("};");
|
|
@@ -144,14 +291,12 @@ function generateApiTs(endpointFiles) {
|
|
|
144
291
|
lines.push(`export const ${name} = createCaller(${name}Endpoint, '${name}');`);
|
|
145
292
|
}
|
|
146
293
|
lines.push("");
|
|
147
|
-
// Inferred input/output types per endpoint (e.g. GetDashboardInputType, GetDashboardOutputType)
|
|
148
294
|
for (const name of endpointNames) {
|
|
149
295
|
const pascal = toPascalCase(name);
|
|
150
296
|
lines.push(`export type ${pascal}InputType = Parameters<typeof ${name}Endpoint.execute>[0]['input'];`);
|
|
151
297
|
lines.push(`export type ${pascal}OutputType = Awaited<ReturnType<typeof ${name}Endpoint.execute>>;`);
|
|
152
298
|
}
|
|
153
299
|
lines.push("");
|
|
154
|
-
// Also export as a single api object
|
|
155
300
|
lines.push("export const api = {");
|
|
156
301
|
for (const name of endpointNames) {
|
|
157
302
|
lines.push(` ${name},`);
|
|
@@ -160,6 +305,11 @@ function generateApiTs(endpointFiles) {
|
|
|
160
305
|
lines.push("");
|
|
161
306
|
return lines.join("\n");
|
|
162
307
|
}
|
|
308
|
+
function tsTypeForField(field) {
|
|
309
|
+
if (FIELD_TYPE_MAP[field.type])
|
|
310
|
+
return FIELD_TYPE_MAP[field.type];
|
|
311
|
+
return "string";
|
|
312
|
+
}
|
|
163
313
|
function generateUserTs(usersTableFields) {
|
|
164
314
|
const lines = [
|
|
165
315
|
"// Auto-generated by zitejs sync. Do not edit manually.",
|
|
@@ -208,6 +358,86 @@ function generateAuthWrapperTs() {
|
|
|
208
358
|
"",
|
|
209
359
|
].join("\n");
|
|
210
360
|
}
|
|
361
|
+
const AIRTABLE_FIELD_TYPE_MAP = {
|
|
362
|
+
singleLineText: "string",
|
|
363
|
+
multilineText: "string",
|
|
364
|
+
richText: "string",
|
|
365
|
+
email: "string",
|
|
366
|
+
url: "string",
|
|
367
|
+
phoneNumber: "string",
|
|
368
|
+
number: "number",
|
|
369
|
+
currency: "number",
|
|
370
|
+
percent: "number",
|
|
371
|
+
rating: "number",
|
|
372
|
+
duration: "number",
|
|
373
|
+
singleSelect: "string",
|
|
374
|
+
multipleSelects: "string[]",
|
|
375
|
+
checkbox: "boolean",
|
|
376
|
+
date: "string",
|
|
377
|
+
dateTime: "string",
|
|
378
|
+
attachment: "Array<{ url: string; filename?: string }>",
|
|
379
|
+
multipleRecordLinks: "string | string[]",
|
|
380
|
+
formula: "unknown",
|
|
381
|
+
rollup: "unknown",
|
|
382
|
+
lookup: "unknown",
|
|
383
|
+
count: "number",
|
|
384
|
+
autoNumber: "number",
|
|
385
|
+
barcode: "string",
|
|
386
|
+
button: "unknown",
|
|
387
|
+
createdTime: "string",
|
|
388
|
+
lastModifiedTime: "string",
|
|
389
|
+
createdBy: "unknown",
|
|
390
|
+
lastModifiedBy: "unknown",
|
|
391
|
+
externalSyncSource: "unknown",
|
|
392
|
+
aiText: "string",
|
|
393
|
+
};
|
|
394
|
+
function airtableTsType(field) {
|
|
395
|
+
if ((field.type === "singleSelect" || field.type === "multipleSelects") &&
|
|
396
|
+
field.options &&
|
|
397
|
+
field.options.length > 0) {
|
|
398
|
+
const literals = field.options
|
|
399
|
+
.slice(0, MAX_SELECT_OPTIONS)
|
|
400
|
+
.map((o) => `"${o.replace(/"/g, '\\"')}"`)
|
|
401
|
+
.join(" | ");
|
|
402
|
+
const union = `${literals} | string`;
|
|
403
|
+
if (field.type === "multipleSelects")
|
|
404
|
+
return `(${union})[]`;
|
|
405
|
+
return union;
|
|
406
|
+
}
|
|
407
|
+
return AIRTABLE_FIELD_TYPE_MAP[field.type] ?? "unknown";
|
|
408
|
+
}
|
|
409
|
+
function generateAirtableTs(lock) {
|
|
410
|
+
if (lock.tables.length === 0)
|
|
411
|
+
return null;
|
|
412
|
+
const lines = [
|
|
413
|
+
"// Auto-generated by zitejs generate from zite.lock. Do not edit manually.",
|
|
414
|
+
"// Airtable SDK — uses createAirtableClient from zitejs/runtime.",
|
|
415
|
+
"// The airtable package is externalized (not bundled per-endpoint).",
|
|
416
|
+
"",
|
|
417
|
+
"import { createAirtableClient } from 'zitejs/runtime';",
|
|
418
|
+
"",
|
|
419
|
+
];
|
|
420
|
+
for (const table of lock.tables) {
|
|
421
|
+
const recordType = `${table.sdkName}RecordType`;
|
|
422
|
+
lines.push(`export type ${recordType} = {`);
|
|
423
|
+
lines.push(" id: string;");
|
|
424
|
+
for (const field of table.fields) {
|
|
425
|
+
if (field.sdkName === "id")
|
|
426
|
+
continue;
|
|
427
|
+
const tsType = airtableTsType(field);
|
|
428
|
+
lines.push(` ${field.sdkName}: ${tsType};`);
|
|
429
|
+
}
|
|
430
|
+
lines.push("};");
|
|
431
|
+
lines.push("");
|
|
432
|
+
lines.push(`export const ${table.sdkName} = createAirtableClient<${recordType}>(`);
|
|
433
|
+
lines.push(` '${lock.integrationId}',`);
|
|
434
|
+
lines.push(` '${table.sdkName}',`);
|
|
435
|
+
lines.push(` { tableId: '${table.id}' },`);
|
|
436
|
+
lines.push(`);`);
|
|
437
|
+
lines.push("");
|
|
438
|
+
}
|
|
439
|
+
return lines.join("\n");
|
|
440
|
+
}
|
|
211
441
|
function generateBackendWrapperTs() {
|
|
212
442
|
return [
|
|
213
443
|
"// Auto-generated type-narrowing wrapper. Do not edit manually.",
|
package/dist/esm/bundle/index.js
CHANGED
|
@@ -214,6 +214,15 @@ function createAliasPlugin(opts) {
|
|
|
214
214
|
}
|
|
215
215
|
return { path: 'zitejs/db', external: true };
|
|
216
216
|
});
|
|
217
|
+
// Resolve zitejs/integrations to .zite/integrations/airtable.ts
|
|
218
|
+
build.onResolve({ filter: /^zitejs\/integrations$/ }, () => {
|
|
219
|
+
if (opts.baseDir) {
|
|
220
|
+
const intPath = path.resolve(opts.baseDir, '.zite/integrations/airtable.ts');
|
|
221
|
+
if (fs.existsSync(intPath))
|
|
222
|
+
return { path: intPath };
|
|
223
|
+
}
|
|
224
|
+
return { path: 'zitejs/integrations', external: true };
|
|
225
|
+
});
|
|
217
226
|
// zitejs/runtime is NOT in PREBUNDLED_LIBS — it's a thin fetch()
|
|
218
227
|
// wrapper that gets bundled inline by esbuild (no special handling).
|
|
219
228
|
for (const [pkgName, modulePath] of Object.entries(PREBUNDLED_LIBS)) {
|
|
@@ -249,7 +249,7 @@ export declare class Zite {
|
|
|
249
249
|
linkedRecordFieldId: string;
|
|
250
250
|
lookupFieldId: string;
|
|
251
251
|
formulaExpression?: string | undefined;
|
|
252
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
252
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
253
253
|
};
|
|
254
254
|
} | {
|
|
255
255
|
name: string;
|
|
@@ -260,9 +260,9 @@ export declare class Zite {
|
|
|
260
260
|
type: "formula";
|
|
261
261
|
template: {
|
|
262
262
|
expression: string;
|
|
263
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
263
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
264
264
|
formatting?: {
|
|
265
|
-
numberDisplayType?: "number" | "currency" | "
|
|
265
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
266
266
|
currencyCode?: string | undefined;
|
|
267
267
|
decimalPlaces?: number | undefined;
|
|
268
268
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|
|
@@ -428,7 +428,7 @@ export declare class Zite {
|
|
|
428
428
|
linkedRecordFieldId: string;
|
|
429
429
|
lookupFieldId: string;
|
|
430
430
|
formulaExpression?: string | undefined;
|
|
431
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
431
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
432
432
|
};
|
|
433
433
|
} | {
|
|
434
434
|
name: string;
|
|
@@ -439,9 +439,9 @@ export declare class Zite {
|
|
|
439
439
|
type: "formula";
|
|
440
440
|
template: {
|
|
441
441
|
expression: string;
|
|
442
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
442
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
443
443
|
formatting?: {
|
|
444
|
-
numberDisplayType?: "number" | "currency" | "
|
|
444
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
445
445
|
currencyCode?: string | undefined;
|
|
446
446
|
decimalPlaces?: number | undefined;
|
|
447
447
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|
|
@@ -617,7 +617,7 @@ export declare class Zite {
|
|
|
617
617
|
linkedRecordFieldId: string;
|
|
618
618
|
lookupFieldId: string;
|
|
619
619
|
formulaExpression?: string | undefined;
|
|
620
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
620
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
621
621
|
};
|
|
622
622
|
} | {
|
|
623
623
|
name: string;
|
|
@@ -628,9 +628,9 @@ export declare class Zite {
|
|
|
628
628
|
type: "formula";
|
|
629
629
|
template: {
|
|
630
630
|
expression: string;
|
|
631
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
631
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
632
632
|
formatting?: {
|
|
633
|
-
numberDisplayType?: "number" | "currency" | "
|
|
633
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
634
634
|
currencyCode?: string | undefined;
|
|
635
635
|
decimalPlaces?: number | undefined;
|
|
636
636
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|
|
@@ -809,7 +809,7 @@ export declare class Zite {
|
|
|
809
809
|
linkedRecordFieldId: string;
|
|
810
810
|
lookupFieldId: string;
|
|
811
811
|
formulaExpression?: string | undefined;
|
|
812
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
812
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
813
813
|
};
|
|
814
814
|
} | {
|
|
815
815
|
name: string;
|
|
@@ -820,9 +820,9 @@ export declare class Zite {
|
|
|
820
820
|
type: "formula";
|
|
821
821
|
template: {
|
|
822
822
|
expression: string;
|
|
823
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
823
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
824
824
|
formatting?: {
|
|
825
|
-
numberDisplayType?: "number" | "currency" | "
|
|
825
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
826
826
|
currencyCode?: string | undefined;
|
|
827
827
|
decimalPlaces?: number | undefined;
|
|
828
828
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|
|
@@ -1009,7 +1009,7 @@ export declare class Zite {
|
|
|
1009
1009
|
linkedRecordFieldId: string;
|
|
1010
1010
|
lookupFieldId: string;
|
|
1011
1011
|
formulaExpression?: string | undefined;
|
|
1012
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
1012
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
1013
1013
|
};
|
|
1014
1014
|
} | {
|
|
1015
1015
|
name: string;
|
|
@@ -1020,9 +1020,9 @@ export declare class Zite {
|
|
|
1020
1020
|
type: "formula";
|
|
1021
1021
|
template: {
|
|
1022
1022
|
expression: string;
|
|
1023
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
1023
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
1024
1024
|
formatting?: {
|
|
1025
|
-
numberDisplayType?: "number" | "currency" | "
|
|
1025
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
1026
1026
|
currencyCode?: string | undefined;
|
|
1027
1027
|
decimalPlaces?: number | undefined;
|
|
1028
1028
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|
|
@@ -1210,7 +1210,7 @@ export declare class Zite {
|
|
|
1210
1210
|
linkedRecordFieldId: string;
|
|
1211
1211
|
lookupFieldId: string;
|
|
1212
1212
|
formulaExpression?: string | undefined;
|
|
1213
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
1213
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
1214
1214
|
};
|
|
1215
1215
|
} | {
|
|
1216
1216
|
name: string;
|
|
@@ -1221,9 +1221,9 @@ export declare class Zite {
|
|
|
1221
1221
|
type: "formula";
|
|
1222
1222
|
template: {
|
|
1223
1223
|
expression: string;
|
|
1224
|
-
resultType?: "number" | "boolean" | "date" | "
|
|
1224
|
+
resultType?: "number" | "boolean" | "date" | "array" | "text" | undefined;
|
|
1225
1225
|
formatting?: {
|
|
1226
|
-
numberDisplayType?: "number" | "currency" | "
|
|
1226
|
+
numberDisplayType?: "number" | "currency" | "duration" | "percent" | undefined;
|
|
1227
1227
|
currencyCode?: string | undefined;
|
|
1228
1228
|
decimalPlaces?: number | undefined;
|
|
1229
1229
|
numberFormat?: "local" | "comma_period" | "period_comma" | "space_comma" | "space_period" | undefined;
|