UNPKG

@seamapi/blueprint

Version:

Build tools for the Seam API using this blueprint.

94 lines (79 loc) 2.8 kB
import { z, type ZodSchema } from 'zod' import type { Resource as BlueprintResource } from 'lib/blueprint.js' import { JsonSchema } from 'lib/json.js' import { formatResourceRecords } from './format.js' import { createSeamCliResourceData } from './seam-cli.js' import { SdkNameSchema, type SyntaxName, SyntaxNameSchema } from './syntax.js' export const ResourceSampleDefinitionSchema = z.object({ title: z.string().trim().min(1), description: z.string().trim().min(1), resource_type: z.string().trim().min(1), properties: z.record(z.string().min(1), JsonSchema), }) export type ResourceSampleDefinitionInput = z.input< typeof ResourceSampleDefinitionSchema > export type ResourceSampleDefinition = z.output< typeof ResourceSampleDefinitionSchema > export interface ResourceSampleContext { resource: Omit<BlueprintResource, 'resourceSamples'> schemas: Record<string, unknown> formatCode: (content: string, syntax: SyntaxName) => Promise<string> } const ResourceSchema = z.record( SdkNameSchema, z.object({ title: z.string().min(1), resource_data: z.string(), resource_data_syntax: SyntaxNameSchema, }), ) export type Resource = z.infer<typeof ResourceSchema> const _ResourceSampleSchema = ResourceSampleDefinitionSchema.extend({ resource: ResourceSchema, }) export type ResourceSample = z.output<typeof _ResourceSampleSchema> export const createResourceSample = async ( resourceSampleDefinition: ResourceSampleDefinition, context: ResourceSampleContext, ): Promise<ResourceSample> => { const resourceType = resourceSampleDefinition.resource_type const schema = toPartialZodSchema(context.schemas[resourceType]) if (schema != null) { const { success, error } = schema.safeParse( resourceSampleDefinition.properties, ) if (!success) { throw new Error( `Invalid properties for resource sample definition of type '${resourceType}': ${error.message}`, ) } } else { // TODO: Skip event and action_attempt warning until support is added. if (!['event', 'action_attempt'].includes(resourceType)) { // eslint-disable-next-line no-console console.warn(`Missing Zod schema for resource ${resourceType}.`) } } const resource: Resource = { seam_cli: { title: 'Seam CLI', resource_data: createSeamCliResourceData( resourceSampleDefinition, context, ), resource_data_syntax: 'json', }, } return { ...resourceSampleDefinition, resource: await formatResourceRecords(resource, context), } } const toPartialZodSchema = (input: unknown): ZodSchema | null => { if (typeof input !== 'object') return null if (input == null) return null if ('deepPartial' in input) return input as unknown as ZodSchema return null }