json-schema#JSONSchema6 TypeScript Examples

The following examples show how to use json-schema#JSONSchema6. 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: Codec.ts    From purifree with ISC License 6 votes vote down vote up
removeOneOfWithSingleElement = (schema: JSONSchema6): JSONSchema6 => {
  const schemaKeys = Object.keys(schema)

  if (
    schemaKeys.length === 1 &&
    schema.oneOf?.length === 1 &&
    typeof schema.oneOf[0] === 'object'
  ) {
    Object.assign(schema, schema.oneOf[0])
    delete schema.oneOf
  }

  return schema
}
Example #2
Source File: Codec.ts    From purifree with ISC License 6 votes vote down vote up
flattenNestedOneOf = (schema: JSONSchema6): JSONSchema6 => {
  if (Array.isArray(schema.oneOf)) {
    for (let i = 0; i < schema.oneOf.length; i++) {
      const e = schema.oneOf[i]
      if (typeof e === 'object' && e.oneOf) {
        schema.oneOf.splice(i, 1)
        schema.oneOf.push(...e.oneOf)
        return optimizeSchema(schema)
      }
    }
  }

  return schema
}
Example #3
Source File: Codec.ts    From purifree with ISC License 5 votes vote down vote up
isEmptySchema = (schema: JSONSchema6): boolean =>
  Object.keys(schema).length === 0
Example #4
Source File: Codec.ts    From purifree with ISC License 5 votes vote down vote up
optimizeSchema = (schema: JSONSchema6): JSONSchema6 => {
  flattenNestedOneOf(schema)
  removeOneOfWithSingleElement(schema)

  return schema
}
Example #5
Source File: Codec.ts    From purifree with ISC License 4 votes vote down vote up
Codec = {
  /** Creates a codec for any JSON object */
  interface<T extends Record<string, Codec<any>>>(
    properties: T
  ): Codec<
    {
      [k in keyof T]: GetInterface<T[k]>
    }
  > {
    const keys = Object.keys(properties)

    const decode = (input: any) => {
      if (!isObject(input)) {
        return Left(reportError('an object', input))
      }

      const result = {} as { [k in keyof T]: GetInterface<T[k]> }

      for (const key of keys) {
        if (
          !input.hasOwnProperty(key) &&
          !(properties[key] as any)._isOptional
        ) {
          return Left(
            `Problem with property "${key}": it does not exist in received object ${JSON.stringify(
              input
            )}`
          )
        }

        const decodedProperty = properties[key].decode(input[key])

        if (decodedProperty.isLeft()) {
          return Left(
            `Problem with the value of property "${key}": ${decodedProperty.extract()}`
          )
        }

        const value = decodedProperty.extract()

        if (value !== undefined) {
          result[key as keyof T] = value
        }
      }

      return Right(result)
    }

    const encode = (input: any) => {
      const result = {} as { [k in keyof T]: GetInterface<T[k]> }

      for (const key of keys) {
        result[key as keyof T] = properties[key].encode(input[key]) as any
      }

      return result
    }

    return {
      decode,
      encode,
      unsafeDecode: (input) => decode(input).unsafeCoerce(),
      schema: () =>
        keys.reduce(
          (acc, key) => {
            const isOptional = (properties[key] as any)._isOptional

            if (!isOptional) {
              acc.required.push(key)
            }

            acc.properties[key] = optimizeSchema(properties[key].schema())

            return acc
          },
          {
            type: 'object',
            properties: {} as Record<string, JSONSchema6>,
            required: [] as string[]
          }
        )
    }
  },

  /** Creates a codec for any type, you can add your own deserialization/validation logic in the decode argument */
  custom<T>({
    decode,
    encode,
    schema
  }: {
    decode: (value: unknown) => Either<string, T>
    encode: (value: T) => any
    schema?: () => object
  }): Codec<T> {
    return {
      decode,
      encode,
      unsafeDecode: (input) => decode(input).unsafeCoerce(),
      schema: schema ?? (() => ({}))
    }
  }
}