diff --git a/package.json b/package.json index 21e3275..1320824 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "airtable-typegen", - "version": "0.3.0-alpha.1", + "version": "0.3.1-alpha.1", "description": "Generate TypeScript & Zod types from your Airtable bases", "author": "Jake Correa @jkcorrea", "bin": { diff --git a/src/commands/index.ts b/src/commands/index.ts index 2e88055..cef7fbd 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -174,7 +174,7 @@ Reads environment from .env file if present in current working directory.` const enumName = getFieldEnumName(table, field) lines.push(`export const ${enumName} = z.enum([`) for (const choice of field.options.choices) { - lines.push(` '${choice.name}',`) + lines.push(` '${choice.name.replace(/'/g, "\\\'")}',`) } lines.push('])') lines.push('') diff --git a/src/utils/field-mappings.ts b/src/utils/field-mappings.ts index e2659cf..87a41f4 100644 --- a/src/utils/field-mappings.ts +++ b/src/utils/field-mappings.ts @@ -138,9 +138,9 @@ export function getTsType(field: FieldMetadata) { case 'multipleRecordLinks': return 'Array' case 'singleSelect': - return field.options.choices.map((choice) => `'${choice.name}'`).join(' | ') + return field.options.choices.map((choice) => `'${choice.name.replace(/'/g, "\\\'")}'`).join(' | ') case 'multipleSelects': - return `Array<${field.options.choices.map((choice) => `'${choice.name}'`).join(' | ')}>` + return `Array<${field.options.choices.map((choice) => `'${choice.name.replace(/'/g, "\\\'")}'`).join(' | ')}>` // TODO not sure what this one is case 'externalSyncSource': return 'unknown' diff --git a/test/fixtures/api/product-catalog-data.json b/test/fixtures/api/product-catalog-data.json index d0f0e12..2a4bba3 100644 --- a/test/fixtures/api/product-catalog-data.json +++ b/test/fixtures/api/product-catalog-data.json @@ -128,6 +128,67 @@ "Gross sales": 0 } }, + { + "id": "recF0JfpmnI1zwH2G", + "createdTime": "2015-01-27T19:42:25.000Z", + "fields": { + "Link": "www.examplelink.com", + "Name": "Sturdy Carpenter's Table", + "Type": "Baker's Racks and Carpenter's Tables", + "Images": [ + { + "id": "attPLeBxjQ5P7S6U5", + "width": 1000, + "height": 667, + "url": "https://v5.airtableusercontent.com/v1/14/14/1673726400000/PkfuuhsoIb10U9M--WHECQ/koVQG7QPEC_QUoDuAru1fGOYbyP0LO3N1AWez90ztWqVLIC9ZAQ3wpa8RSzBKgRrlMFVOuz-NHF2UZ5y5_u5BXY87333Tsvf-wdQiiGABBZ_EnSRULwHhrm7K2ghXEIoCIl_lNoEBMsrPFMQ3i6V4_pvnwZpaX7Nz1AjbDneYRJIcYFUEHMFsF27G0-c2SOpf2ZNargkrBG2_jLJ5snSOg/lLNTgu-wNK_grnbUGhSEavv7vTpcV58aE871tnhFhlY", + "filename": "photo-1530018607912-eff2daa1bac4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80", + "size": 56969, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://v5.airtableusercontent.com/v1/14/14/1673726400000/jA9JIWcV-cAFci4_wFSAag/IT4vnQT_ti67yZNx0B19zyBZuwQMEmuAanW4olk_kzR5yVXbFHRTSOhbtamPIOLoHmDpqmNBHNU-vOfrqvlPzA/4hAe6EVEaA-2B45EZMdb0gMX3bm46TT33OSUG5CpwEM", + "width": 54, + "height": 36 + }, + "large": { + "url": "https://v5.airtableusercontent.com/v1/14/14/1673726400000/6yp8DQhJ6MRFvfMAiwtQww/oRt_mTpZzXN2SF26OCgtkG_6BXfc1vh29U5-aeZKXtoLyfdYbicny0tnKVkq48d07xGJ0VbNreZSkDO13KH22g/k4bQ-KmXVTEfSLxijuFnQx9fki0b5ZlJyO8yMAtcV5c", + "width": 768, + "height": 512 + }, + "full": { + "url": "https://v5.airtableusercontent.com/v1/14/14/1673726400000/Hzkah7n_y0QhSEW7lzLARw/gUATJMI4LjmFdaX1R59cJ6oSvWZcMTKVBvBDzkdEG__aXccyJZ4STFzyhIcsWXxYcVV0gnbVda0bO4xgCb9AGQ/V8QjtoxxYurDemlX3D3edtvZ7vl67l_MJg38Fh82OvQ", + "width": 3000, + "height": 3000 + } + } + } + ], + "Description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + "Materials": [ + "Dark wood", + "Light wood" + ], + "Size (WxLxH)": "35.5x29.5", + "Unit cost": 4350, + "Settings": [ + "Living room", + "Office" + ], + "Vendor": [ + "reckJTZyYwrUTGFa0" + ], + "Color": [ + "Beige", + "Brown", + "White" + ], + "Designer": [ + "rechldhCrNa0yJv2S" + ], + "Total units sold": 0, + "Gross sales": 0 + } + }, { "id": "recGZdJCU9Ly6scrZ", "createdTime": "2015-01-27T19:12:50.000Z", @@ -937,7 +998,8 @@ "Settings": [ "Bedroom", "Office", - "Living room" + "Living room", + "Child's or infant's room" ], "Vendor": [ "recNuU4rHUhBBZojg" diff --git a/test/fixtures/api/tables-meta.json b/test/fixtures/api/tables-meta.json index 3828088..f5557f6 100644 --- a/test/fixtures/api/tables-meta.json +++ b/test/fixtures/api/tables-meta.json @@ -48,6 +48,11 @@ "id": "selhpnAwN7BRrhvae", "name": "Tables", "color": "redLight1" + }, + { + "id": "selDGccFqZVxogrLB", + "name": "Baker's Racks and Carpenter's Tables", + "color": "redLight1" } ] }, @@ -397,6 +402,11 @@ "id": "selGvIVMJ8OX7uSLl", "name": "Bedroom", "color": "purpleLight2" + }, + { + "id": "selqIAVygoSnxoWQ1", + "name": "Child's or infant's room", + "color": "blueLight1" } ] }, diff --git a/test/fixtures/output/product-catalog-ts.ts b/test/fixtures/output/product-catalog-ts.ts index 80348d5..90b0f1f 100644 --- a/test/fixtures/output/product-catalog-ts.ts +++ b/test/fixtures/output/product-catalog-ts.ts @@ -19,7 +19,7 @@ export interface IAirtableAttachment { export interface Furniture { 'Name'?: string - 'Type'?: 'Beds' | 'Bookshelves' | 'Chairs' | 'Lighting' | 'Rugs' | 'Sofas' | 'Tables' + 'Type'?: 'Beds' | 'Bookshelves' | 'Chairs' | 'Lighting' | 'Rugs' | 'Sofas' | 'Tables' | 'Baker\'s Racks and Carpenter\'s Tables' 'Images'?: Array 'Vendor'?: Array 'In stock'?: boolean @@ -27,7 +27,7 @@ export interface Furniture { 'Size (WxLxH)'?: string 'Materials'?: Array<'Brass' | 'Brushed nickel' | 'Corduroy' | 'Cotton' | 'Dark wood' | 'Foam beans' | 'Glass' | 'Glazed ceramic' | 'Indian wool' | 'Iron' | 'Lacquered ash' | 'Leather' | 'Leather cowhide' | 'Light wood' | 'Linen shade' | 'Marble' | 'Metal' | 'Mirror' | 'Poly-cotton shade' | 'Reclaimed wood' | 'Shiny black' | 'Solid maple' | 'Solid teak' | 'Stainless steel' | 'Steel' | 'Suede' | 'Tech suede' | 'Viscose' | 'Walnut' | 'Wool'> 'Color'?: Array<'Beige' | 'Black' | 'Blue' | 'Blue purple' | 'Brown' | 'Cherry' | 'Cream' | 'Fern' | 'Framboise' | 'Gold' | 'Green' | 'Grey' | 'Matte black' | 'Orange' | 'Red' | 'Shiny black' | 'Silver' | 'Taupe' | 'Velvet' | 'White' | 'Yellow'> - 'Settings'?: Array<'Living room' | 'Office' | 'Outdoor' | 'Dining' | 'Bedroom'> + 'Settings'?: Array<'Living room' | 'Office' | 'Outdoor' | 'Dining' | 'Bedroom' | 'Child\'s or infant\'s room'> 'Schematic'?: Array 'Designer'?: Array 'Description'?: string diff --git a/test/fixtures/output/product-catalog-zod.ts b/test/fixtures/output/product-catalog-zod.ts index b658dc3..c45aea8 100644 --- a/test/fixtures/output/product-catalog-zod.ts +++ b/test/fixtures/output/product-catalog-zod.ts @@ -27,6 +27,7 @@ export const FurnitureType = z.enum([ 'Rugs', 'Sofas', 'Tables', + 'Baker\'s Racks and Carpenter\'s Tables', ]) export const FurnitureMaterials = z.enum([ @@ -92,6 +93,7 @@ export const FurnitureSettings = z.enum([ 'Outdoor', 'Dining', 'Bedroom', + 'Child\'s or infant\'s room', ]) export const FurnitureSchema = z.object({