zitejs 0.9.42 → 0.9.44

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.
@@ -0,0 +1,6 @@
1
+ export declare function useUpload(): {
2
+ upload: (file: File) => Promise<{
3
+ url: string;
4
+ }>;
5
+ isUploading: boolean;
6
+ };
@@ -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)) {
@@ -2,7 +2,7 @@ import { watch } from 'fs';
2
2
  import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, } from 'fs';
3
3
  import { join } from 'path';
4
4
  import { runSync } from '../sync/index.js';
5
- import { generateApiTs, generateUserTs, generateAuthWrapperTs, generateBackendWrapperTs, } from '../sync/lib.js';
5
+ import { generateApiTs, generateUserTs, generateAuthWrapperTs, generateBackendWrapperTs, generateAirtableTs, } from '../sync/lib.js';
6
6
  const debounceTimers = new Map();
7
7
  function debounce(key, fn, ms) {
8
8
  const existing = debounceTimers.get(key);
@@ -49,6 +49,42 @@ function regenerateAppApiTs(appDir) {
49
49
  console.log(`Updated apps/${appDir}/.zite/api.ts`);
50
50
  }
51
51
  }
52
+ function regenerateAppAirtableSdk(appDir) {
53
+ const lockPath = join('apps', appDir, 'zite.lock');
54
+ if (!existsSync(lockPath))
55
+ return;
56
+ try {
57
+ const lockContent = JSON.parse(readFileSync(lockPath, 'utf-8'));
58
+ const integrations = lockContent.integrations ?? {};
59
+ for (const [integrationId, integration] of Object.entries(integrations)) {
60
+ const int = integration;
61
+ if (!int.idMappings?.tables)
62
+ continue;
63
+ const airtableLock = {
64
+ integrationId,
65
+ tables: Object.entries(int.idMappings.tables).map(([sdkName, tableId]) => ({
66
+ id: tableId,
67
+ sdkName,
68
+ fields: Object.entries(int.idMappings?.fields?.[sdkName] ?? {}).map(([fieldSdkName, fieldId]) => ({
69
+ id: fieldId,
70
+ sdkName: fieldSdkName,
71
+ type: 'singleLineText',
72
+ })),
73
+ })),
74
+ };
75
+ const content = generateAirtableTs(airtableLock);
76
+ if (content) {
77
+ const outDir = join('apps', appDir, '.zite', 'integrations');
78
+ mkdirSync(outDir, { recursive: true });
79
+ writeFileSync(join(outDir, 'airtable.ts'), content);
80
+ console.log(`Updated apps/${appDir}/.zite/integrations/airtable.ts`);
81
+ }
82
+ }
83
+ }
84
+ catch {
85
+ // Lock file invalid or missing — skip
86
+ }
87
+ }
52
88
  export async function runGenerate() {
53
89
  // 1. Run sync (generates root .zite/db.ts)
54
90
  try {
@@ -62,6 +98,7 @@ export async function runGenerate() {
62
98
  for (const app of appDirs) {
63
99
  regenerateAppApiTs(app);
64
100
  regenerateAppTypedWrappers(app);
101
+ regenerateAppAirtableSdk(app);
65
102
  }
66
103
  console.log('Done!');
67
104
  }
@@ -39,5 +39,31 @@ export declare function createSqlClient(): (params: {
39
39
  query: string;
40
40
  params?: unknown[];
41
41
  }) => Promise<SqlResult>;
42
+ export interface AirtableTableClient<T> {
43
+ findAll(options?: {
44
+ offset?: string;
45
+ limit?: number;
46
+ filters?: unknown;
47
+ }): Promise<{
48
+ records: T[];
49
+ offset: string | undefined;
50
+ hasMore: boolean;
51
+ }>;
52
+ findOne(params: {
53
+ id?: string;
54
+ filters?: unknown;
55
+ }): Promise<T | undefined>;
56
+ create(data: {
57
+ record: Partial<T>;
58
+ }): Promise<T>;
59
+ bulkCreate(records: Partial<T>[]): Promise<T[]>;
60
+ update(id: string, data: {
61
+ record: Partial<T>;
62
+ }): Promise<T>;
63
+ delete(id: string): Promise<{
64
+ deleted: true;
65
+ }>;
66
+ }
67
+ export declare function createAirtableClient<T>(integrationId: string, className: string, implicitParams: Record<string, unknown>): AirtableTableClient<T>;
42
68
  export { createCaller } from "../caller/index.js";
43
69
  export type { EndpointConfig } from "../caller/index.js";
@@ -71,4 +71,33 @@ export function createSqlClient() {
71
71
  ...params,
72
72
  });
73
73
  }
74
+ export function createAirtableClient(integrationId, className, implicitParams) {
75
+ return {
76
+ findAll: (options) => getSdkCall()(integrationId, className, "findAll", {
77
+ ...implicitParams,
78
+ ...options,
79
+ }),
80
+ findOne: (params) => getSdkCall()(integrationId, className, "findOne", {
81
+ ...implicitParams,
82
+ ...params,
83
+ }),
84
+ create: (data) => getSdkCall()(integrationId, className, "create", {
85
+ ...implicitParams,
86
+ ...data,
87
+ }),
88
+ bulkCreate: (records) => getSdkCall()(integrationId, className, "bulkCreate", {
89
+ ...implicitParams,
90
+ records,
91
+ }),
92
+ update: (id, data) => getSdkCall()(integrationId, className, "update", {
93
+ ...implicitParams,
94
+ id,
95
+ ...data,
96
+ }),
97
+ delete: (id) => getSdkCall()(integrationId, className, "delete", {
98
+ ...implicitParams,
99
+ id,
100
+ }),
101
+ };
102
+ }
74
103
  export { createCaller } from "../caller/index.js";
@@ -36,4 +36,20 @@ export declare function generateUserTs(usersTableFields?: Array<{
36
36
  type: string;
37
37
  }>): string;
38
38
  export declare function generateAuthWrapperTs(): string;
39
+ export type AirtableLockField = {
40
+ id: string;
41
+ sdkName: string;
42
+ type: string;
43
+ options?: string[];
44
+ };
45
+ export type AirtableLockTable = {
46
+ id: string;
47
+ sdkName: string;
48
+ fields: AirtableLockField[];
49
+ };
50
+ export type AirtableLock = {
51
+ integrationId: string;
52
+ tables: AirtableLockTable[];
53
+ };
54
+ export declare function generateAirtableTs(lock: AirtableLock): string | null;
39
55
  export declare function generateBackendWrapperTs(): string;
@@ -347,6 +347,86 @@ export function generateAuthWrapperTs() {
347
347
  "",
348
348
  ].join("\n");
349
349
  }
350
+ const AIRTABLE_FIELD_TYPE_MAP = {
351
+ singleLineText: "string",
352
+ multilineText: "string",
353
+ richText: "string",
354
+ email: "string",
355
+ url: "string",
356
+ phoneNumber: "string",
357
+ number: "number",
358
+ currency: "number",
359
+ percent: "number",
360
+ rating: "number",
361
+ duration: "number",
362
+ singleSelect: "string",
363
+ multipleSelects: "string[]",
364
+ checkbox: "boolean",
365
+ date: "string",
366
+ dateTime: "string",
367
+ attachment: "Array<{ url: string; filename?: string }>",
368
+ multipleRecordLinks: "string | string[]",
369
+ formula: "unknown",
370
+ rollup: "unknown",
371
+ lookup: "unknown",
372
+ count: "number",
373
+ autoNumber: "number",
374
+ barcode: "string",
375
+ button: "unknown",
376
+ createdTime: "string",
377
+ lastModifiedTime: "string",
378
+ createdBy: "unknown",
379
+ lastModifiedBy: "unknown",
380
+ externalSyncSource: "unknown",
381
+ aiText: "string",
382
+ };
383
+ function airtableTsType(field) {
384
+ if ((field.type === "singleSelect" || field.type === "multipleSelects") &&
385
+ field.options &&
386
+ field.options.length > 0) {
387
+ const literals = field.options
388
+ .slice(0, MAX_SELECT_OPTIONS)
389
+ .map((o) => `"${o.replace(/"/g, '\\"')}"`)
390
+ .join(" | ");
391
+ const union = `${literals} | string`;
392
+ if (field.type === "multipleSelects")
393
+ return `(${union})[]`;
394
+ return union;
395
+ }
396
+ return AIRTABLE_FIELD_TYPE_MAP[field.type] ?? "unknown";
397
+ }
398
+ export function generateAirtableTs(lock) {
399
+ if (lock.tables.length === 0)
400
+ return null;
401
+ const lines = [
402
+ "// Auto-generated by zitejs generate from zite.lock. Do not edit manually.",
403
+ "// Airtable SDK — uses createAirtableClient from zitejs/runtime.",
404
+ "// The airtable package is externalized (not bundled per-endpoint).",
405
+ "",
406
+ "import { createAirtableClient } from 'zitejs/runtime';",
407
+ "",
408
+ ];
409
+ for (const table of lock.tables) {
410
+ const recordType = `${table.sdkName}RecordType`;
411
+ lines.push(`export type ${recordType} = {`);
412
+ lines.push(" id: string;");
413
+ for (const field of table.fields) {
414
+ if (field.sdkName === "id")
415
+ continue;
416
+ const tsType = airtableTsType(field);
417
+ lines.push(` ${field.sdkName}: ${tsType};`);
418
+ }
419
+ lines.push("};");
420
+ lines.push("");
421
+ lines.push(`export const ${table.sdkName} = createAirtableClient<${recordType}>(`);
422
+ lines.push(` '${lock.integrationId}',`);
423
+ lines.push(` '${table.sdkName}',`);
424
+ lines.push(` { tableId: '${table.id}' },`);
425
+ lines.push(`);`);
426
+ lines.push("");
427
+ }
428
+ return lines.join("\n");
429
+ }
350
430
  export function generateBackendWrapperTs() {
351
431
  return [
352
432
  "// Auto-generated type-narrowing wrapper. Do not edit manually.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zitejs",
3
- "version": "0.9.42",
3
+ "version": "0.9.44",
4
4
  "description": "The Zite framework — build apps on Zite Database",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",