UNPKG

@flatfile/plugin-convert-json-schema

Version:

A plugin for converting JSON Schema to Flatfile Blueprint and configuring a Flatfile Space.

1 lines 11.6 kB
{"version":3,"sources":["../src/setup.factory.ts","../src/index.ts"],"names":["generateSetup","setupFactory","workbook","sheets","partialSheetConfig","model","getModel","fields","generateFields","source","isValidUrl","fetchExternalReference","url","data","origin","key","getPropertyType","schema","property","parentKey","isRequired","resolvedProperty","resolveReference","fieldTypes","value","ref","hashIndex","resolveLocalReference","urlPart","fragmentPart","externalSchema","resolved","acc","part","response","fetch","error","configureSpaceWithJsonSchema","callback","configureSpace"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import type { Flatfile } from '@flatfile/api'\nimport type { Setup } from '@flatfile/plugin-space-configure'\nimport fetch from 'cross-fetch'\n\nexport type JsonSetupFactory = {\n workbooks: PartialWorkbookConfig[]\n space?: Partial<Flatfile.spaces.SpaceConfig>\n}\n\nexport interface PartialWorkbookConfig\n extends Omit<Flatfile.CreateWorkbookConfig, 'sheets'> {\n sheets: PartialSheetConfig[]\n}\n\nexport interface PartialSheetConfig\n extends Omit<Flatfile.SheetConfig, 'fields' | 'name'> {\n name?: string\n source: object | string | (() => object | Promise<object>)\n}\n\nexport async function generateSetup(\n setupFactory: JsonSetupFactory\n): Promise<Setup> {\n const workbooks = await Promise.all(\n setupFactory.workbooks.map(async (workbook) => {\n const sheets = await Promise.all(\n workbook.sheets.map(async (partialSheetConfig: PartialSheetConfig) => {\n const model = await getModel(partialSheetConfig.source)\n const fields = await generateFields(model)\n\n return {\n name: partialSheetConfig?.name || model.title,\n ...(model?.description && { description: model.description }),\n fields,\n ...partialSheetConfig,\n }\n })\n )\n\n return {\n ...workbook,\n sheets,\n }\n })\n )\n\n return { workbooks, space: setupFactory.space }\n}\n\nasync function getModel(\n source: object | string | (() => object | Promise<object>)\n) {\n if (typeof source === 'function') {\n return await source()\n }\n\n if (typeof source === 'string' && isValidUrl(source)) {\n return await fetchExternalReference(source)\n }\n\n return source\n}\n\nfunction isValidUrl(url: string) {\n try {\n new URL(url)\n return true\n } catch (error) {\n return false\n }\n}\n\nexport async function generateFields(data: any): Promise<Flatfile.Property[]> {\n if (!data || !data.properties) return []\n\n const getOrigin = (url: string) => {\n try {\n return new URL(url).origin\n } catch (error) {\n return ''\n }\n }\n const origin = getOrigin(data.$id)\n\n const fields = await Promise.all(\n Object.keys(data.properties).map(async (key) => {\n return await getPropertyType(\n data,\n data.properties[key],\n key,\n (data.required && data.required.includes(key)) || false,\n origin\n )\n })\n )\n return fields.flat().filter(Boolean)\n}\n\nexport async function getPropertyType(\n schema: any,\n property: any,\n parentKey = '',\n isRequired = false,\n origin: string\n): Promise<Flatfile.Property[]> {\n if (property.$ref) {\n const resolvedProperty = await resolveReference(\n schema,\n property.$ref,\n origin\n )\n return await getPropertyType(\n schema,\n resolvedProperty,\n parentKey,\n false,\n origin\n )\n }\n\n if (property.type === 'object' && property.properties) {\n const propertyFields = await Promise.all(\n Object.keys(property.properties).map(async (key) => {\n return await getPropertyType(\n property,\n property.properties[key],\n parentKey ? `${parentKey}_${key}` : key,\n (property.required && property.required.includes(key)) || false,\n origin\n )\n })\n )\n return propertyFields.flat()\n }\n\n const fieldTypes: Record<string, Flatfile.Property> = {\n string: { key: parentKey, type: 'string' },\n number: { key: parentKey, type: 'number' },\n integer: { key: parentKey, type: 'number' },\n boolean: { key: parentKey, type: 'boolean' },\n array: {\n key: parentKey,\n type: 'string-list',\n },\n enum: {\n key: parentKey,\n type: 'enum-list',\n config: property?.enum\n ? {\n options: property.enum.map((value: any) => ({\n value,\n label: String(value),\n })),\n }\n : {\n options: [],\n },\n },\n }\n\n if (!fieldTypes[property.type]) return []\n\n const fieldConfig: Flatfile.Property = {\n label: parentKey,\n ...(property?.description && { description: property.description }),\n ...(isRequired && { constraints: [{ type: 'required' }] }),\n ...fieldTypes[property.type],\n }\n\n return [fieldConfig]\n}\n\nexport async function resolveReference(\n schema: any,\n ref: string,\n origin: string\n): Promise<any> {\n const hashIndex = ref.indexOf('#')\n\n if (ref.startsWith('#/')) return resolveLocalReference(schema, ref)\n\n const urlPart = hashIndex >= 0 ? ref.substring(0, hashIndex) : ref\n const fragmentPart = hashIndex >= 0 ? ref.substring(hashIndex) : ''\n\n const externalSchema = await fetchExternalReference(`${origin}${urlPart}`)\n\n return fragmentPart\n ? resolveLocalReference(externalSchema, fragmentPart)\n : externalSchema\n}\n\nexport function resolveLocalReference(schema: any, ref: string): any {\n const resolved = ref\n .split('/')\n .slice(1)\n .reduce(\n (acc, part) =>\n acc && (acc[part] || acc.$defs?.[part] || acc.definitions?.[part]),\n schema\n )\n\n if (!resolved) throw new Error(`Cannot resolve reference: ${ref}`)\n return resolved\n}\n\nexport async function fetchExternalReference(url: string): Promise<any> {\n try {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(\n `API returned status ${response.status}: ${response.statusText}`\n )\n }\n\n const data = await response.json()\n return data\n } catch (error) {\n throw new Error(\n `Error fetching external reference: ${(error as any).message}`\n )\n }\n}\n","import type { FlatfileEvent } from '@flatfile/listener'\nimport type { TickFunction } from '@flatfile/plugin-job-handler'\nimport { configureSpace } from '@flatfile/plugin-space-configure'\nimport { generateSetup, type JsonSetupFactory } from './setup.factory'\n\nexport function configureSpaceWithJsonSchema(\n setupFactory: JsonSetupFactory,\n callback?: (\n event: FlatfileEvent,\n workbookIds: string[],\n tick: TickFunction\n ) => any | Promise<any>\n) {\n return configureSpace(() => generateSetup(setupFactory), callback)\n}\n\nexport * from './setup.factory'\n"]}