json-schema#JSONSchema7 TypeScript Examples

The following examples show how to use json-schema#JSONSchema7. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: extend-config-schema.ts    From serverless-plugin with MIT License 6 votes vote down vote up
schemaCronCR: JSONSchema7 = {
    type: 'object',
    properties: {
        registry: { type: 'string' },
        registryId: { type: 'string' },
        imageName: { type: 'string' },
        tag: { type: 'string' },
        events: {
            type: 'array',
            items: {
                type: 'string',
            },
        },
        account: { type: 'string' },
        retry: {
            type: 'object',
            properties: {
                attempts: { type: 'number' },
                interval: { type: 'number' },
            },
        },
        dlq: { type: 'string' },
        dlqId: { type: 'string' },
        dlqAccountId: { type: 'string' },
        dlqAccount: { type: 'string' },
    },
    required: ['events', 'account', 'imageName', 'tag', 'registry'],
}
Example #2
Source File: extend-config-schema.ts    From serverless-plugin with MIT License 6 votes vote down vote up
schemaCronYMQ: JSONSchema7 = {
    type: 'object',
    properties: {
        queue: { type: 'string' },
        queueId: { type: 'string' },
        queueAccount: { type: 'string' },
        account: { type: 'string' },
        retry: {
            type: 'object',
            properties: {
                attempts: { type: 'number' },
                interval: { type: 'number' },
            },
        },
    },
    required: ['queue', 'account', 'queueAccount'],
}
Example #3
Source File: transform.ts    From farrow with MIT License 6 votes vote down vote up
transform = (input: FieldDescriptor): JSONSchema7 => {
  if (isSchemaCtor(input)) {
    const schemaCtor = toSchemaCtor(input)
    const formatResult = formatSchema(schemaCtor)
    return transformResult(formatResult)
    // eslint-disable-next-line no-else-return
  } else {
    const schemaCtor = toSchemaCtor(input.__type)
    const formatResult = formatSchema(schemaCtor)
    return {
      ...transformResult(formatResult),
      description: input.description,
    }
  }
}
Example #4
Source File: extend-config-schema.ts    From serverless-plugin with MIT License 6 votes vote down vote up
schemaCronS3: JSONSchema7 = {
    type: 'object',
    properties: {
        bucket: { type: 'string' },
        account: { type: 'string' },
        events: {
            type: 'array',
            items: {
                type: 'string',
            },
        },
        prefix: { type: 'string' },
        suffix: { type: 'string' },
        retry: {
            type: 'object',
            properties: {
                attempts: { type: 'number' },
                interval: { type: 'number' },
            },
        },
        dlq: { type: 'string' },
        dlqId: { type: 'string' },
        dlqAccountId: { type: 'string' },
        dlqAccount: { type: 'string' },
    },
    required: ['bucket', 'account', 'events'],
}
Example #5
Source File: useTemplateGeneration.ts    From template-based-generator-template with GNU General Public License v3.0 6 votes vote down vote up
export function useTemplateGeneration(configFormData: IConfiguration | undefined, fileName = 'input.md') {
  const [template, templateSetter] = useState('');
  const [result, resultSetter] = useState<Array<IOutputWIthMetadata<any[]>>>([]);
  const [templateData, templateDataSetter] = useState<ITemplateData | undefined>();
  const [errorMessage, errorMessageSetter] = useState('');
  const [configSchema, configSchemaSetter] = useState<JSONSchema7 | undefined>();
  const [rerender, rerenderHookTrigger] = useTrigger();
  const parseAndGenerateFromTemplate = useDebouncedFn(
    (templateStringToParse: string): void => {
      const vFile = new VFile({ path: fileName, value: templateStringToParse });
      let newErrorMessage = '';
      try {
        const templateData = templateFileToNLCSTNodes(vFile);
        configSchemaSetter(getConfigSchemaFromTemplate(templateData));
        if (configFormData === undefined) {
          throw new Error('模板参数不正确');
        }
        templateDataSetter(templateData);
        resultSetter(randomOutlineToArrayWithMetadataCompiler(templateData, configFormData));
      } catch (e) {
        newErrorMessage += (e as Error).message;
      }
      // newErrorMessage += reporter(vFile);
      errorMessageSetter(newErrorMessage);
    },
    500,
    undefined,
    [configFormData],
  );
  useEffect(() => {
    parseAndGenerateFromTemplate(template);
  }, [template, rerenderHookTrigger]);

  return [rerender, template, templateSetter, result, configSchema, errorMessage, templateData] as const;
}
Example #6
Source File: index.ts    From template-based-generator-template with GNU General Public License v3.0 6 votes vote down vote up
/**
 * 为 UI 制作待填参数表单
 */
export function getConfigSchemaFromTemplate(templateData: ITemplateData): JSONSchema7 {
  const slots = collectSlots(templateData);
  const configSchemaBase: JSONSchema7 = {
    title: '模板参数',
    description: '生成流程所需的参数',
    type: 'object',
    required: [],
    properties: {
      sub: {
        title: '模板槽位',
        description: '填入{{槽位}}中的内容',
        type: 'object',
        required: [],
        properties: {},
      },
    },
  };
  for (const slot of slots) {
    (configSchemaBase.properties!.sub as JSONSchema7).properties![slot] = {
      type: 'string',
      title: slot,
    };
  }
  return configSchemaBase;
}
Example #7
Source File: extend-config-schema.ts    From serverless-plugin with MIT License 6 votes vote down vote up
schemaCronTrigger: JSONSchema7 = {
    type: 'object',
    properties: {
        expression: { type: 'string' },
        account: { type: 'string' },
        retry: {
            type: 'object',
            properties: {
                attempts: { type: 'number' },
                interval: { type: 'number' },
            },
        },
        dlq: { type: 'string' },
        dlqId: { type: 'string' },
        dlqAccountId: { type: 'string' },
        dlqAccount: { type: 'string' },
    },
    required: ['expression', 'account'],
}
Example #8
Source File: transformDMMF.ts    From prisma-json-schema-generator with MIT License 6 votes vote down vote up
export function transformDMMF(
    dmmf: DMMF.Document,
    transformOptions: TransformOptions = {},
): JSONSchema7 {
    // TODO: Remove default values as soon as prisma version < 3.10.0 doesn't have to be supported anymore
    const { models = [], enums = [], types = [] } = dmmf.datamodel
    const initialJSON = getInitialJSON()
    const { schemaId } = transformOptions

    const modelDefinitionsMap = models.map(
        getJSONSchemaModel({ enums }, transformOptions),
    )

    const typeDefinitionsMap = types.map(
        getJSONSchemaModel({ enums }, transformOptions),
    )

    const modelPropertyDefinitionsMap = models.map(
        getPropertyDefinition(transformOptions),
    )
    const definitions = Object.fromEntries([
        ...modelDefinitionsMap,
        ...typeDefinitionsMap,
    ])

    const properties = Object.fromEntries(modelPropertyDefinitionsMap)

    return {
        ...(schemaId ? { $id: schemaId } : null),
        ...initialJSON,
        definitions,
        properties,
    }
}
Example #9
Source File: Widgets.tsx    From sapio-studio with Mozilla Public License 2.0 6 votes vote down vote up
export function PathOnly(
    props:
        | {
              schema: JSONSchema7;
              name: string;
              formData: string | null;
              value: string | null;
          }
        | any
) {
    const [val, set_val] = React.useState(props.value);
    React.useEffect(() => {
        props.onChange(val);
    }, [val]);
    return (
        <div>
            <Typography>{props.value ?? 'None Selected'}</Typography>
            <Button
                onClick={async () => {
                    const new_val = await window.electron.select_filename();
                    if (new_val) set_val(new_val);
                }}
            >
                {props.name ?? 'Select File'}
            </Button>
        </div>
    );
}
Example #10
Source File: meta.test.ts    From zod-to-json-schema with ISC License 6 votes vote down vote up
describe("Meta data", () => {
  it("should be possible to use description", () => {
    const $z = z.string().describe("My neat string");
    const $j = zodToJsonSchema($z);
    const $e: JSONSchema7 = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "string",
      description: "My neat string",
    };

    expect($j).toStrictEqual($e);
  });
});
Example #11
Source File: properties.ts    From prisma-json-schema-generator with MIT License 6 votes vote down vote up
function getItemsByDMMFType(
    field: DMMF.Field,
    transformOptions: TransformOptions,
): JSONSchema7['items'] {
    return (isScalarType(field) && !field.isList) || isEnumType(field)
        ? undefined
        : isScalarType(field) && field.isList
        ? { type: getJSONSchemaScalar(field.type) }
        : getJSONSchemaForPropertyReference(field, transformOptions)
}
Example #12
Source File: properties.ts    From prisma-json-schema-generator with MIT License 6 votes vote down vote up
function getJSONSchemaType(field: DMMF.Field): JSONSchema7['type'] {
    const { isList, isRequired } = field
    const scalarFieldType =
        isScalarType(field) && !isList
            ? getJSONSchemaScalar(field.type)
            : field.isList
            ? 'array'
            : isEnumType(field)
            ? 'string'
            : 'object'

    const isFieldUnion = Array.isArray(scalarFieldType)

    return isRequired || isList
        ? scalarFieldType
        : isFieldUnion
        ? Array.from(new Set([...scalarFieldType, 'null']))
        : [scalarFieldType, 'null']
}
Example #13
Source File: properties.ts    From prisma-json-schema-generator with MIT License 6 votes vote down vote up
function getDefaultValue(field: DMMF.Field): JSONSchema7['default'] {
    const fieldDefault = field.default

    if (!field.hasDefaultValue) {
        return null
    }

    if (field.kind === 'enum') {
        return typeof fieldDefault === 'string' ? fieldDefault : null
    }

    if (!isScalarType(field)) {
        return null
    }

    switch (field.type) {
        case 'String':
        case 'BigInt':
        case 'DateTime':
            return typeof fieldDefault === 'string' ? fieldDefault : null
        case 'Int':
        case 'Float':
        case 'Decimal':
            return typeof fieldDefault === 'number' ? fieldDefault : null
        case 'Boolean':
            return typeof fieldDefault === 'boolean' ? fieldDefault : null
        case 'Json':
        case 'Bytes':
            return null
        default:
            return assertNever(field.type)
    }
}
Example #14
Source File: properties.ts    From prisma-json-schema-generator with MIT License 6 votes vote down vote up
function getJSONSchemaForPropertyReference(
    field: DMMF.Field,
    { schemaId }: TransformOptions,
): JSONSchema7 {
    const notNullable = field.isRequired || field.isList

    assertFieldTypeIsString(field.type)

    const typeRef = `${DEFINITIONS_ROOT}${field.type}`
    const ref = { $ref: schemaId ? `${schemaId}${typeRef}` : typeRef }
    return notNullable ? ref : { anyOf: [ref, { type: 'null' }] }
}
Example #15
Source File: UTXODetail.tsx    From sapio-studio with Mozilla Public License 2.0 5 votes vote down vote up
name_schema: JSONSchema7 = {
    title: 'Name for this Update',
    type: 'string',
}
Example #16
Source File: extend-config-schema.ts    From serverless-plugin with MIT License 5 votes vote down vote up
schemaResources: JSONSchema7 = {
    type: 'object',
    patternProperties: {
        '^.*$': {
            oneOf: [
                {
                    type: 'object',
                    properties: {
                        type: {
                            enum: ['yc::ServiceAccount'],
                        },
                        roles: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                        },
                    },
                },
                {
                    type: 'object',
                    properties: {
                        type: {
                            enum: ['yc::MessageQueue'],
                        },
                        name: { type: 'string' },
                    },
                },
                {
                    type: 'object',
                    properties: {
                        type: {
                            enum: ['yc::ObjectStorageBucket'],
                        },
                        name: { type: 'string' },
                    },
                },
                {
                    type: 'object',
                    properties: {
                        type: {
                            enum: ['yc::ContainerRegistry'],
                        },
                        name: { type: 'string' },
                    },
                },
            ],
        },
    },
}
Example #17
Source File: jsonSchema.ts    From prisma-json-schema-generator with MIT License 5 votes vote down vote up
getInitialJSON = (): JSONSchema7 => ({
    $schema: 'http://json-schema.org/draft-07/schema#',
    definitions: {},
    type: 'object',
})
Example #18
Source File: index.ts    From json-schema-yup-transform with MIT License 5 votes vote down vote up
convertToYup = (
  schema: JSONSchema7,
  config?: yupTransformer.Config
): Yup.ObjectSchema<object> | undefined => {
  config && yupTransformer.setConfiguration(config);
  const normalizedSchema = normalize(schema);
  return yupTransformer.default(normalizedSchema);
}
Example #19
Source File: Settings.tsx    From baleen3 with Apache License 2.0 5 votes vote down vote up
Settings: React.FC<SettingsProps> = ({
  open,
  title,
  settings = {},
  schema,
  onClose,
  onSubmit,
  editable,
}: SettingsProps) => {
  const handleSubmit = (result: ISubmitEvent<object>): void => {
    if (onSubmit !== undefined) {
      onSubmit(result.formData)
    }
    onClose()
  }
  const [jsonSchema, setJsonSchema] = useState<JSONSchema7>({})
  const [uiSchema, setUiSchema] = useState<object>({})

  useEffect(() => {
    try {
      setJsonSchema(JSON.parse(schema.jsonSchema) as JSONSchema7)
      if ((schema as SettingsSchemaExtended).uiSchema !== undefined) {
        setUiSchema(
          JSON.parse((schema as SettingsSchemaExtended).uiSchema) as UiSchema
        )
      }
    } catch (e) {
      if (e instanceof Error) {
        throw new Error(`Error parsing json Schema\n${e.message}`)
      } else {
        throw e
      }
    }
  }, [schema])

  const readonly = !editable
  return (
    <Dialog open={open} onClose={onClose} disableBackdropClick>
      <DialogTitle>{title}</DialogTitle>
      <DialogContent>
        <Form
          disabled={readonly}
          liveValidate={readonly}
          schema={jsonSchema}
          formData={settings}
          onSubmit={handleSubmit}
          FieldTemplate={FieldTemplate}
          widgets={widgets}
          uiSchema={uiSchema}
        >
          <Divider mb={3} variant="fullWidth" />
          <DialogActions>
            {readonly ? (
              <Button type="submit" color="primary" onClick={onClose}>
                Done
              </Button>
            ) : (
              <>
                <Button variant="text" onClick={onClose}>
                  Cancel
                </Button>
                <Button type="submit" color="primary">
                  Save
                </Button>
              </>
            )}
          </DialogActions>
        </Form>
      </DialogContent>
    </Dialog>
  )
}
Example #20
Source File: sapio.ts    From sapio-studio with Mozilla Public License 2.0 4 votes vote down vote up
async list_contracts(workspace_name: string): Promise<Result<API>> {
        const workspace = await SapioWorkspace.new(workspace_name);
        const res = await SapioCompiler.command([
            'contract',
            'list',
            '--workspace',
            workspace.workspace_location(),
        ]);
        if ('err' in res) return res;
        const contracts = res.ok;
        const lines: Array<[string, string]> = contracts
            .trim()
            .split(/\r?\n/)
            .map((line: string) => {
                const v: string[] = line.split(' -- ')!;
                equal(v.length, 2);
                return v as [string, string];
            });

        const apis_p = Promise.all(
            lines.map(([name, key]: [string, string]): Promise<JSONSchema7> => {
                if (memo_apis.has(key)) {
                    return Promise.resolve(memo_apis.get(key));
                } else {
                    return SapioCompiler.command([
                        'contract',
                        'api',
                        '--key',
                        key,
                        '--workspace',
                        workspace.workspace_location(),
                    ]).then((v) => {
                        if ('err' in v) return v;
                        const api = JSON.parse(v.ok);
                        memo_apis.set(key, api);
                        return api;
                    });
                }
            })
        );
        const logos_p = Promise.all(
            lines.map(
                ([name, key]: [string, string]): Promise<Result<string>> => {
                    if (memo_logos.has(key)) {
                        return Promise.resolve(memo_logos.get(key));
                    } else {
                        return SapioCompiler.command([
                            'contract',
                            'logo',
                            '--key',
                            key,
                            '--workspace',
                            workspace.workspace_location(),
                        ])
                            .then((logo: Result<string>) => {
                                return 'ok' in logo
                                    ? { ok: logo.ok.trim() }
                                    : logo;
                            })
                            .then((logo: Result<string>) => {
                                if ('err' in logo) return logo;
                                memo_logos.set(key, logo);
                                return logo;
                            });
                    }
                }
            )
        );
        const [apis, logos] = await Promise.all([apis_p, logos_p]);

        const results: API = {};
        equal(lines.length, apis.length);
        equal(lines.length, logos.length);
        for (let i = 0; i < lines.length; ++i) {
            const [name, key] = lines[i]!;
            const api = apis[i]!;
            const logo = logos[i]!;
            if ('err' in logo) return logo;
            results[key] = {
                name,
                key,
                api,
                logo: logo.ok,
            };
        }
        return { ok: results };
    }
Example #21
Source File: transform.ts    From farrow with MIT License 4 votes vote down vote up
transformResult = (formatResult: FormatResult): JSONSchema7 => {
  const transformType = (input: FormatType): JSONSchema7 => {
    switch (input.type) {
      case 'Scalar': {
        return transformScalarType(input)
      }
      case 'Object': {
        return transformObjectType(input)
      }
      case 'Union': {
        return transformUnionType(input)
      }
      case 'Intersect': {
        return transformIntersectType(input)
      }
      case 'Struct': {
        return transformStructType(input)
      }
      case 'Record': {
        return transformRecordType(input)
      }
      case 'List': {
        return transformListType(input)
      }
      case 'Tuple': {
        return transformTupleType(input)
      }
      case 'Literal': {
        return transformLiteralType(input)
      }
      case 'Nullable': {
        return transformNullableType(input)
      }
      case 'Strict': {
        return transformStrictType(input)
      }
      case 'NonStrict': {
        return transformNonStrictType(input)
      }
      case 'ReadOnly': {
        return transformReadOnlyType(input)
      }
      case 'ReadOnlyDeep': {
        return transformReadOnlyDeepType(input)
      }
      // for eslint
      default: {
        throw new Error(`Unknown format type: ${input}`)
      }
    }
  }

  const transformScalarType = (input: FormatScalarType): JSONSchema7 => {
    switch (input.valueName) {
      case 'String':
        return {
          type: 'string',
        }
      case 'ID':
        return {
          type: 'integer',
        }
      case 'Number':
        return {
          type: 'number',
        }
      case 'Int':
        return {
          type: 'integer',
        }
      case 'Float':
        return {
          type: 'number',
        }
      case 'Boolean':
        return {
          type: 'boolean',
        }
      case 'Date':
        return {
          type: 'string',
        }
      case 'Unknown':
        return {}
      case 'Any':
        return {}
      case 'Json':
        return {}
      default:
        throw new Error(`Unknown Scalar Type name: ${input.valueName}`)
    }
  }

  const transformObjectType = (input: FormatObjectType): JSONSchema7 => {
    const fields = transformFieldsType(input.fields)
    return {
      ...fields,
      type: 'object',
    }
  }

  type Properties = {
    [key: string]: JSONSchema7Definition
  }
  const transformFieldsType = (input: FormatFields): JSONSchema7 => {
    const properties: Properties = {}

    for (const name in input) {
      properties[name] = transformFieldType(input[name])
    }

    return {
      properties,
    }
  }

  const transformFieldType = (input: FormatField): JSONSchema7 => {
    return {
      ...findSchema(input.typeId),
      description: input.description,
    }
  }

  const transformUnionType = (input: FormatUnionType): JSONSchema7 => {
    const items: JSONSchema7[] = input.itemTypes.map(({ typeId }) => findSchema(typeId))
    return {
      oneOf: items,
    }
  }

  const transformIntersectType = (input: FormatIntersectType): JSONSchema7 => {
    const items: JSONSchema7[] = input.itemTypes.map(({ typeId }) => findSchema(typeId))

    const properties: Properties = {}
    for (const item of items) {
      if (item.properties) {
        for (const key in item.properties) {
          properties[key] = item.properties[key]
        }
      }
    }

    return {
      type: 'object',
      properties,
    }
  }

  const transformStructType = (input: FormatStructType): JSONSchema7 => {
    const fields = transformFieldsType(input.fields)
    return {
      type: 'object',
      ...fields,
    }
  }

  const transformRecordType = (input: FormatRecordType): JSONSchema7 => {
    const item = findSchema(input.valueTypeId)
    return {
      type: 'object',
      additionalProperties: item,
    }
  }

  const transformListType = (input: FormatListType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return {
      type: 'array',
      additionalItems: item,
    }
  }

  const transformTupleType = (input: FormatTupleType): JSONSchema7 => {
    const items = input.itemTypes.map(({ typeId }) => findSchema(typeId))
    return {
      type: 'array',
      items,
    }
  }

  const transformLiteralType = (input: FormatLiteralType): JSONSchema7 => {
    return {
      const: [input.value!],
    }
  }

  const transformNullableType = (input: FormatNullableType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return {
      anyOf: [
        item,
        {
          const: [null],
        },
      ],
    }
  }

  const transformStrictType = (input: FormatStrictType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return item
  }

  const transformNonStrictType = (input: FormatNonStrictType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return item
  }

  const transformReadOnlyType = (input: FormatReadOnlyType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return item
  }

  const transformReadOnlyDeepType = (input: FormatReadonlyDeepType): JSONSchema7 => {
    const item = findSchema(input.itemTypeId)
    return item
  }

  const schemas = new Map<string, JSONSchema7>()

  const findSchema = (typeId: number): JSONSchema7 => {
    const schema = schemas.get(typeId.toString())

    if (!schema) {
      const item = findType(typeId)
      const schema = transformType(item)
      schemas.set(`${typeId}`, schema)
    }

    return {
      $ref: `#/definitions/${typeId}`,
    }
  }

  const findType = (typeId: number): FormatType => {
    for (const key in formatResult.types) {
      if (key === `${typeId}`) {
        return formatResult.types[key]
      }
    }

    throw new Error(`Unknown typeId: ${typeId}`)
  }

  for (const id in formatResult.types) {
    if (!schemas.has(id)) {
      schemas.set(id, {
        $id: id,
        ...transformType(formatResult.types[id]),
      })
    }
  }

  const definitions = Object.fromEntries(schemas)

  return {
    $id: '/farrow/schema',
    definitions,
    ...findSchema(formatResult.typeId),
  }
}
Example #22
Source File: ActionsPage.tsx    From backstage with Apache License 2.0 4 votes vote down vote up
ActionsPage = () => {
  const api = useApi(scaffolderApiRef);
  const classes = useStyles();
  const { loading, value, error } = useAsync(async () => {
    return api.listActions();
  });

  if (loading) {
    return <Progress />;
  }

  if (error) {
    return (
      <ErrorPage
        statusMessage="Failed to load installed actions"
        status="500"
      />
    );
  }

  const formatRows = (input: JSONSchema7) => {
    const properties = input.properties;
    if (!properties) {
      return undefined;
    }

    return Object.entries(properties).map(entry => {
      const [key] = entry;
      const props = entry[1] as unknown as JSONSchema7;
      const codeClassname = classNames(classes.code, {
        [classes.codeRequired]: input.required?.includes(key),
      });

      return (
        <TableRow key={key}>
          <TableCell>
            <div className={codeClassname}>{key}</div>
          </TableCell>
          <TableCell>{props.title}</TableCell>
          <TableCell>{props.description}</TableCell>
          <TableCell>
            <span className={classes.code}>{props.type}</span>
          </TableCell>
        </TableRow>
      );
    });
  };

  const renderTable = (input: JSONSchema7) => {
    if (!input.properties) {
      return undefined;
    }
    return (
      <TableContainer component={Paper}>
        <Table size="small">
          <TableHead>
            <TableRow>
              <TableCell>Name</TableCell>
              <TableCell>Title</TableCell>
              <TableCell>Description</TableCell>
              <TableCell>Type</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>{formatRows(input)}</TableBody>
        </Table>
      </TableContainer>
    );
  };

  const renderTables = (name: string, input?: JSONSchema7Definition[]) => {
    if (!input) {
      return undefined;
    }

    return (
      <>
        <Typography variant="h6">{name}</Typography>
        {input.map((i, index) => (
          <div key={index}>{renderTable(i as unknown as JSONSchema7)}</div>
        ))}
      </>
    );
  };

  const items = value?.map(action => {
    if (action.id.startsWith('legacy:')) {
      return undefined;
    }

    const oneOf = renderTables('oneOf', action.schema?.input?.oneOf);
    return (
      <Box pb={4} key={action.id}>
        <Typography variant="h4" className={classes.code}>
          {action.id}
        </Typography>
        <Typography>{action.description}</Typography>
        {action.schema?.input && (
          <Box pb={2}>
            <Typography variant="h5">Input</Typography>
            {renderTable(action.schema.input)}
            {oneOf}
          </Box>
        )}
        {action.schema?.output && (
          <Box pb={2}>
            <Typography variant="h5">Output</Typography>
            {renderTable(action.schema.output)}
          </Box>
        )}
      </Box>
    );
  });

  return (
    <Page themeId="home">
      <Header
        pageTitleOverride="Create a New Component"
        title="Installed actions"
        subtitle="This is the collection of all installed actions"
      />
      <Content>{items}</Content>
    </Page>
  );
}
Example #23
Source File: references.test.ts    From zod-to-json-schema with ISC License 4 votes vote down vote up
describe("Pathing", () => {
  it("should handle recurring properties with paths", () => {
    const addressSchema = z.object({
      street: z.string(),
      number: z.number(),
      city: z.string(),
    });
    const someAddresses = z.object({
      address1: addressSchema,
      address2: addressSchema,
      lotsOfAddresses: z.array(addressSchema),
    });
    const jsonSchema = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        address1: {
          type: "object",
          properties: {
            street: { type: "string" },
            number: { type: "number" },
            city: { type: "string" },
          },
          additionalProperties: false,
          required: ["street", "number", "city"],
        },
        address2: { $ref: "#/properties/address1" },
        lotsOfAddresses: {
          type: "array",
          items: { $ref: "#/properties/address1" },
        },
      },
      additionalProperties: false,
      required: ["address1", "address2", "lotsOfAddresses"],
    };

    const parsedSchema = zodToJsonSchema(someAddresses);
    expect(parsedSchema).toStrictEqual(jsonSchema);
    expect(ajv.validateSchema(parsedSchema!)).toEqual(true);
  });

  it("Should properly reference union participants", () => {
    const participant = z.object({ str: z.string() });

    const schema = z.object({
      union: z.union([participant, z.string()]),
      part: participant,
    });

    const expectedJsonSchema = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        union: {
          anyOf: [
            {
              type: "object",
              properties: {
                str: {
                  type: "string",
                },
              },
              additionalProperties: false,
              required: ["str"],
            },
            {
              type: "string",
            },
          ],
        },
        part: {
          $ref: "#/properties/union/anyOf/0",
        },
      },
      additionalProperties: false,
      required: ["union", "part"],
    };

    const parsedSchema = zodToJsonSchema(schema);
    expect(parsedSchema).toStrictEqual(expectedJsonSchema);
    expect(ajv.validateSchema(parsedSchema!)).toEqual(true);

    const resolvedSchema = deref(expectedJsonSchema);
    expect(resolvedSchema.properties.part).toBe(
      resolvedSchema.properties.union.anyOf[0]
    );
  });

  it("Should be able to handle recursive schemas", () => {
    type Category = {
      name: string;
      subcategories: Category[];
    };

    // cast to z.ZodSchema<Category>
    // @ts-ignore
    const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
      z.object({
        name: z.string(),
        subcategories: z.array(categorySchema),
      })
    );

    const parsedSchema = zodToJsonSchema(categorySchema);

    const expectedJsonSchema = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        name: {
          type: "string",
        },
        subcategories: {
          type: "array",
          items: {
            $ref: "#/",
          },
        },
      },
      required: ["name", "subcategories"],
      additionalProperties: false,
    };

    expect(parsedSchema).toStrictEqual(expectedJsonSchema);
    expect(ajv.validateSchema(parsedSchema!)).toEqual(true);

    const resolvedSchema = deref(parsedSchema);
    expect(resolvedSchema.properties.subcategories.items).toBe(resolvedSchema);
  });

  it("Should be able to handle complex & nested recursive schemas", () => {
    type Category = {
      name: string;
      inner: {
        subcategories?: Record<string, Category> | null;
      };
    };

    // cast to z.ZodSchema<Category>
    // @ts-ignore
    const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
      z.object({
        name: z.string(),
        inner: z.object({
          subcategories: z.record(categorySchema).nullable().optional(),
        }),
      })
    );

    const inObjectSchema = z.object({
      category: categorySchema,
    });

    const parsedSchema = zodToJsonSchema(inObjectSchema);

    const expectedJsonSchema = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      additionalProperties: false,
      required: ["category"],
      properties: {
        category: {
          type: "object",
          properties: {
            name: {
              type: "string",
            },
            inner: {
              type: "object",
              additionalProperties: false,
              properties: {
                subcategories: {
                  anyOf: [
                    {
                      type: "object",
                      additionalProperties: {
                        $ref: "#/properties/category",
                      },
                    },
                    {
                      type: "null",
                    },
                  ],
                },
              },
            },
          },
          required: ["name", "inner"],
          additionalProperties: false,
        },
      },
    };

    expect(parsedSchema).toStrictEqual(expectedJsonSchema);
    expect(ajv.validateSchema(parsedSchema!)).toEqual(true);
  });

  it("should work with relative references", () => {
    const recurringSchema = z.string();
    const objectSchema = z.object({
      foo: recurringSchema,
      bar: recurringSchema,
    });

    const jsonSchema = zodToJsonSchema(objectSchema, {
      $refStrategy: "relative",
    });

    const exptectedResult: JSONSchema7 = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        foo: {
          type: "string",
        },
        bar: {
          $ref: "1/foo",
        },
      },
      required: ["foo", "bar"],
      additionalProperties: false,
    };

    expect(jsonSchema).toStrictEqual(exptectedResult);
  });

  it("should be possible to override the base path", () => {
    const recurringSchema = z.string();
    const objectSchema = z.object({
      foo: recurringSchema,
      bar: recurringSchema,
    });

    const jsonSchema = zodToJsonSchema(objectSchema, {
      basePath: ["#", "lol", "xD"],
    });

    const exptectedResult: JSONSchema7 = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        foo: {
          type: "string",
        },
        bar: {
          $ref: "#/lol/xD/properties/foo",
        },
      },
      required: ["foo", "bar"],
      additionalProperties: false,
    };

    expect(jsonSchema).toStrictEqual(exptectedResult);
  });

  it("should be possible to opt out of $ref building", () => {
    const recurringSchema = z.string();
    const objectSchema = z.object({
      foo: recurringSchema,
      bar: recurringSchema,
    });

    const jsonSchema = zodToJsonSchema(objectSchema, {
      $refStrategy: "none",
    });

    const exptectedResult: JSONSchema7 = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        foo: {
          type: "string",
        },
        bar: {
          type: "string",
        },
      },
      required: ["foo", "bar"],
      additionalProperties: false,
    };

    expect(jsonSchema).toStrictEqual(exptectedResult);
  });

  it("When opting out of ref building and using recursive schemas, should warn and default to any", () => {
    global.console = { ...global.console, warn: jest.fn() };

    type Category = {
      name: string;
      subcategories: Category[];
    };

    // cast to z.ZodSchema<Category>
    // @ts-ignore
    const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
      z.object({
        name: z.string(),
        subcategories: z.array(categorySchema),
      })
    );

    const parsedSchema = zodToJsonSchema(categorySchema, {
      $refStrategy: "none",
    });

    const expectedJsonSchema = {
      $schema: "http://json-schema.org/draft-07/schema#",
      type: "object",
      properties: {
        name: {
          type: "string",
        },
        subcategories: {
          type: "array",
          items: {},
        },
      },
      required: ["name", "subcategories"],
      additionalProperties: false,
    };

    expect(parsedSchema).toStrictEqual(expectedJsonSchema);
    expect(console.warn).toBeCalledWith(
      "Recursive reference detected at #/properties/subcategories/items! Defaulting to any"
    );
  });

  it("should be possible to override get proper references even when picking optional definitions path $defs", () => {
    const recurringSchema = z.string();
    const objectSchema = z.object({
      foo: recurringSchema,
      bar: recurringSchema,
    });

    const jsonSchema = zodToJsonSchema(objectSchema, {
      name: "hello",
      definitionPath: "$defs",
    });

    const exptectedResult = {
      $schema: "http://json-schema.org/draft-07/schema#",
      $ref: "#/$defs/hello",
      $defs: {
        hello: {
          type: "object",
          properties: {
            foo: {
              type: "string",
            },
            bar: {
              $ref: "#/$defs/hello/properties/foo",
            },
          },
          required: ["foo", "bar"],
          additionalProperties: false,
        },
      },
    };

    expect(jsonSchema).toStrictEqual(exptectedResult);
  });

  it("should be possible to override get proper references even when picking optional definitions path definitions", () => {
    const recurringSchema = z.string();
    const objectSchema = z.object({
      foo: recurringSchema,
      bar: recurringSchema,
    });

    const jsonSchema = zodToJsonSchema(objectSchema, {
      name: "hello",
      definitionPath: "definitions",
    });

    const exptectedResult = {
      $schema: "http://json-schema.org/draft-07/schema#",
      $ref: "#/definitions/hello",
      definitions: {
        hello: {
          type: "object",
          properties: {
            foo: {
              type: "string",
            },
            bar: {
              $ref: "#/definitions/hello/properties/foo",
            },
          },
          required: ["foo", "bar"],
          additionalProperties: false,
        },
      },
    };

    expect(jsonSchema).toStrictEqual(exptectedResult);
  });
});