airtable-ts
Advanced tools
Comparing version 1.2.0 to 1.3.0
@@ -15,3 +15,3 @@ "use strict"; | ||
*/ | ||
function assertMatchesSchema(table, data, mode = 'full') { | ||
function assertMatchesSchema(table, data, mode = 'partial') { | ||
if (typeof data !== 'object' || data === null) { | ||
@@ -18,0 +18,0 @@ throw new Error(`[airtable-ts] Item for ${table.name} is not an object`); |
@@ -11,3 +11,3 @@ import Airtable from 'airtable'; | ||
scan<T extends Item>(table: Table<T>, params?: ScanParams): Promise<T[]>; | ||
insert<T extends Item>(table: Table<T>, data: Omit<T, 'id'>): Promise<T>; | ||
insert<T extends Item>(table: Table<T>, data: Partial<Omit<T, 'id'>>): Promise<T>; | ||
update<T extends Item>(table: Table<T>, data: Partial<T> & { | ||
@@ -14,0 +14,0 @@ id: string; |
@@ -49,3 +49,3 @@ "use strict"; | ||
async update(table, data) { | ||
(0, assertMatchesSchema_1.assertMatchesSchema)(table, { ...data }, 'partial'); | ||
(0, assertMatchesSchema_1.assertMatchesSchema)(table, { ...data }); | ||
const { id, ...withoutId } = data; | ||
@@ -52,0 +52,0 @@ const airtableTable = await (0, getAirtableTable_1.getAirtableTable)(this.airtable, table, this.options); |
@@ -91,2 +91,34 @@ "use strict"; | ||
}, | ||
createdTime: { | ||
toAirtable: (value) => { | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime string'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
const date = new Date(value ?? ''); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime string'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
}, | ||
lastModifiedTime: { | ||
toAirtable: (value) => { | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime string'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
const date = new Date(value ?? ''); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime string'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
}, | ||
multipleLookupValues: { | ||
@@ -208,2 +240,42 @@ toAirtable: () => { throw new Error('[airtable-ts] lookup type field is readonly'); }, | ||
}, | ||
createdTime: { | ||
toAirtable: (value) => { | ||
if (value === null) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
if (value === null || value === undefined) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
}, | ||
lastModifiedTime: { | ||
toAirtable: (value) => { | ||
if (value === null) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
if (value === null || value === undefined) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
}, | ||
multipleLookupValues: { | ||
@@ -329,2 +401,34 @@ toAirtable: () => { throw new Error('[airtable-ts] lookup type field is readonly'); }, | ||
}, | ||
createdTime: { | ||
toAirtable: (value) => { | ||
const date = new Date(value * 1000); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
const date = new Date(value ?? ''); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return Math.floor(date.getTime() / 1000); | ||
}, | ||
}, | ||
lastModifiedTime: { | ||
toAirtable: (value) => { | ||
const date = new Date(value * 1000); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
const date = new Date(value ?? ''); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return Math.floor(date.getTime() / 1000); | ||
}, | ||
}, | ||
multipleLookupValues: { | ||
@@ -418,2 +522,42 @@ toAirtable: () => { throw new Error('[airtable-ts] lookup type field is readonly'); }, | ||
}, | ||
createdTime: { | ||
toAirtable: (value) => { | ||
if (value === null) | ||
return null; | ||
const date = new Date(value * 1000); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
if (value === null || value === undefined) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return Math.floor(date.getTime() / 1000); | ||
}, | ||
}, | ||
lastModifiedTime: { | ||
toAirtable: (value) => { | ||
if (value === null) | ||
return null; | ||
const date = new Date(value * 1000); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return date.toJSON(); | ||
}, | ||
fromAirtable: (value) => { | ||
if (value === null || value === undefined) | ||
return null; | ||
const date = new Date(value); | ||
if (Number.isNaN(date.getTime())) { | ||
throw new Error('[airtable-ts] Invalid dateTime'); | ||
} | ||
return Math.floor(date.getTime() / 1000); | ||
}, | ||
}, | ||
multipleLookupValues: { | ||
@@ -420,0 +564,0 @@ toAirtable: () => { throw new Error('[airtable-ts] lookup type field is readonly'); }, |
{ | ||
"name": "airtable-ts", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "A type-safe Airtable SDK", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -30,17 +30,18 @@ # airtable-ts | ||
export const studentTable: Table<{ id: string, name: string, classes: string[] }> = { | ||
// Tip: use airtable-ts-codegen to autogenerate these from your Airtable base | ||
export const studentTable: Table<{ id: string, firstName: string, classes: string[] }> = { | ||
name: 'student', | ||
baseId: 'app1234', | ||
tableId: 'tbl1234', | ||
schema: { name: 'string', classes: 'string[]' }, | ||
schema: { firstName: 'string', classes: 'string[]' }, | ||
// optional: use mappings with field ids to prevent renamings breaking your app, | ||
// or with field names to make handling renamings easy | ||
mappings: { name: 'fld1234', classes: 'Classes student is enrolled in' }, | ||
mappings: { firstName: 'fld1234', classes: 'Classes student is enrolled in' }, | ||
}; | ||
export const classTable: Table<{ id: string, name: string }> = { | ||
export const classTable: Table<{ id: string, title: string }> = { | ||
name: 'class', | ||
baseId: 'app1234', | ||
tableId: 'tbl4567', | ||
schema: { name: 'string' }, | ||
schema: { title: 'string' }, | ||
}; | ||
@@ -53,7 +54,7 @@ | ||
const student = await db.get(studentTable, 'rec1234'); | ||
await db.update(studentTable, { id: 'rec1234', name: 'Adam' }); | ||
await db.update(studentTable, { id: 'rec1234', firstName: 'Adam' }); | ||
await db.remove(studentTable, 'rec5678'); | ||
// Or for a more involved example: | ||
async function prefixNameOfFirstClassOfFirstStudent(namePrefix: string) { | ||
async function prefixTitleOfFirstClassOfFirstStudent(prefix: string) { | ||
const students = await db.scan(studentTable); | ||
@@ -64,4 +65,4 @@ if (!students[0]) throw new Error('There are no students'); | ||
const currentClass = await db.get(classTable, students[0].classes[0]); | ||
const newName = namePrefix + currentClass.name; | ||
await db.update(classTable, { id: currentClass.id, name: newName }); | ||
const newTitle = prefix + currentClass.title; | ||
await db.update(classTable, { id: currentClass.id, title: newTitle }); | ||
} | ||
@@ -68,0 +69,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67063
1371
90