From 54ccba8612278c227b9ddfccc5049540dc990580 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Fri, 19 Jul 2024 08:59:32 -0500 Subject: [PATCH 01/18] setup project scaffold --- .../ts/ts-codegen-reference/.eslintrc.json | 18 +++++++++ languages/ts/ts-codegen-reference/README.md | 11 ++++++ .../ts/ts-codegen-reference/package.json | 30 +++++++++++++++ .../ts/ts-codegen-reference/project.json | 29 +++++++++++++++ .../ts/ts-codegen-reference/src/index.ts | 2 + .../ts/ts-codegen-reference/tsconfig.json | 14 +++++++ .../ts/ts-codegen-reference/tsconfig.lib.json | 10 +++++ .../ts-codegen-reference/tsconfig.spec.json | 21 +++++++++++ .../ts/ts-codegen-reference/vite.config.ts | 37 +++++++++++++++++++ 9 files changed, 172 insertions(+) create mode 100644 languages/ts/ts-codegen-reference/.eslintrc.json create mode 100644 languages/ts/ts-codegen-reference/README.md create mode 100644 languages/ts/ts-codegen-reference/package.json create mode 100644 languages/ts/ts-codegen-reference/project.json create mode 100644 languages/ts/ts-codegen-reference/src/index.ts create mode 100644 languages/ts/ts-codegen-reference/tsconfig.json create mode 100644 languages/ts/ts-codegen-reference/tsconfig.lib.json create mode 100644 languages/ts/ts-codegen-reference/tsconfig.spec.json create mode 100644 languages/ts/ts-codegen-reference/vite.config.ts diff --git a/languages/ts/ts-codegen-reference/.eslintrc.json b/languages/ts/ts-codegen-reference/.eslintrc.json new file mode 100644 index 00000000..81a7d281 --- /dev/null +++ b/languages/ts/ts-codegen-reference/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.js"], + "ignorePatterns": [], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/languages/ts/ts-codegen-reference/README.md b/languages/ts/ts-codegen-reference/README.md new file mode 100644 index 00000000..3cf2f626 --- /dev/null +++ b/languages/ts/ts-codegen-reference/README.md @@ -0,0 +1,11 @@ +# ts-codegen-reference + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build ts-codegen-reference` to build the library. + +## Running unit tests + +Run `nx test ts-codegen-reference` to execute the unit tests via [Vitest](https://vitest.dev). diff --git a/languages/ts/ts-codegen-reference/package.json b/languages/ts/ts-codegen-reference/package.json new file mode 100644 index 00000000..0db7c07e --- /dev/null +++ b/languages/ts/ts-codegen-reference/package.json @@ -0,0 +1,30 @@ +{ + "name": "ts-codegen-reference", + "version": "0.56.0", + "type": "module", + "license": "MIT", + "author": { + "name": "joshmossas", + "url": "https://github.com/joshmossas" + }, + "bugs": { + "url": "https://github.com/modiimedia/arri/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/modiimedia/arri.git", + "directory": "tooling/ts-codegen-reference" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "dependencies": { + + }, + "devDependencies": { + + } +} \ No newline at end of file diff --git a/languages/ts/ts-codegen-reference/project.json b/languages/ts/ts-codegen-reference/project.json new file mode 100644 index 00000000..ebb0c87c --- /dev/null +++ b/languages/ts/ts-codegen-reference/project.json @@ -0,0 +1,29 @@ +{ + "name": "ts-codegen-reference", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "languages/ts/ts-codegen-reference/src", + "projectType": "application", + "targets": { + "lint": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm eslint languages/ts/ts-codegen-reference" + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{workspaceRoot}/coverage/languages/ts/ts-codegen-reference"], + "options": { + "passWithNoTests": true, + "reportsDirectory": "../../coverage/languages/ts/ts-codegen-reference", + "watch": false + }, + "configurations": { + "watch": { + "command": "vitest watch --passWithNoTests --globals" + } + } + } + }, + "tags": [] +} diff --git a/languages/ts/ts-codegen-reference/src/index.ts b/languages/ts/ts-codegen-reference/src/index.ts new file mode 100644 index 00000000..7e0e36e1 --- /dev/null +++ b/languages/ts/ts-codegen-reference/src/index.ts @@ -0,0 +1,2 @@ +// ts-codegen-reference entry +// todo \ No newline at end of file diff --git a/languages/ts/ts-codegen-reference/tsconfig.json b/languages/ts/ts-codegen-reference/tsconfig.json new file mode 100644 index 00000000..c1d8de72 --- /dev/null +++ b/languages/ts/ts-codegen-reference/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "types": ["vitest"] + }, + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/languages/ts/ts-codegen-reference/tsconfig.lib.json b/languages/ts/ts-codegen-reference/tsconfig.lib.json new file mode 100644 index 00000000..53d09276 --- /dev/null +++ b/languages/ts/ts-codegen-reference/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/languages/ts/ts-codegen-reference/tsconfig.spec.json b/languages/ts/ts-codegen-reference/tsconfig.spec.json new file mode 100644 index 00000000..8432da41 --- /dev/null +++ b/languages/ts/ts-codegen-reference/tsconfig.spec.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] + }, + "include": [ + "vite.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts", + "src/**/*.ts", + ], + "exclude": [] +} diff --git a/languages/ts/ts-codegen-reference/vite.config.ts b/languages/ts/ts-codegen-reference/vite.config.ts new file mode 100644 index 00000000..812cabad --- /dev/null +++ b/languages/ts/ts-codegen-reference/vite.config.ts @@ -0,0 +1,37 @@ +import viteTsConfigPaths from "vite-tsconfig-paths"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + cacheDir: "../../node_modules/.vite/tooling/ts-codegen-reference", + + plugins: [ + viteTsConfigPaths({ + root: "../../", + }) as any, + ], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ + // viteTsConfigPaths({ + // root: '../../', + // }), + // ], + // }, + + test: { + globals: true, + reporters: ["default"], + pool: "threads", + pollOptions: { + threads: { + singleThread: true, + }, + }, + cache: { + dir: "../../node_modules/.vitest", + }, + environment: "node", + include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], + }, +}); From 7794f48b890259a32e955a7a6ee04a42413aeb00 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sat, 20 Jul 2024 03:38:38 -0500 Subject: [PATCH 02/18] start creating the codegen reference --- languages/ts/ts-client/src/request.ts | 43 ++ languages/ts/ts-client/src/utils.ts | 8 +- .../ts/ts-codegen-reference/package.json | 56 +- .../ts/ts-codegen-reference/src/index.ts | 2 - .../src/referenceClient.test.ts | 31 + .../src/referenceClient.ts | 685 ++++++++++++++++++ pnpm-lock.yaml | 6 + 7 files changed, 796 insertions(+), 35 deletions(-) delete mode 100644 languages/ts/ts-codegen-reference/src/index.ts create mode 100644 languages/ts/ts-codegen-reference/src/referenceClient.test.ts create mode 100644 languages/ts/ts-codegen-reference/src/referenceClient.ts diff --git a/languages/ts/ts-client/src/request.ts b/languages/ts/ts-client/src/request.ts index baba07bc..218494b3 100644 --- a/languages/ts/ts-client/src/request.ts +++ b/languages/ts/ts-client/src/request.ts @@ -1,3 +1,4 @@ +import { serializeSmallString } from "@arrirpc/schema"; import { EventSourcePlusOptions, type HttpMethod } from "event-source-plus"; import { FetchError, ofetch } from "ofetch"; @@ -118,3 +119,45 @@ export type SafeResponse = value: T; } | { success: false; error: ArriErrorInstance }; + +export interface ArriModelValidator { + new: () => T; + validate: (input: unknown) => input is T; + fromJson: (input: Record) => T; + fromJsonString: (input: string) => T; + toJsonString: (input: T) => string; + toUrlQueryString: (input: T) => string; +} +export interface ArriEnumValidator { + new: () => T; + values: readonly T[]; + validate: (input: unknown) => input is T; + fromSerialValue: (input: string) => T; +} +const STR_ESCAPE = + // eslint-disable-next-line no-control-regex + /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + +export function serializeString(input: string): string { + if (input.length < 42) { + return serializeSmallString(input); + } + if (input.length < 5000 && !STR_ESCAPE.test(input)) { + return `"${input}"`; + } + return JSON.stringify(input); +} + +export const INT8_MIN = 128; +export const INT8_MAX = 127; +export const UINT8_MAX = 255; +export const INT16_MIN = -32768; +export const INT16_MAX = 32767; +export const UINT16_MAX = 65535; +export const INT32_MIN = -2147483648; +export const INT32_MAX = 2147483647; +export const UINT32_MAX = 4294967295; + +export function isObject(input: unknown): input is Record { + return typeof input === "object" && input !== null; +} diff --git a/languages/ts/ts-client/src/utils.ts b/languages/ts/ts-client/src/utils.ts index 91c2e65f..b63f91e0 100644 --- a/languages/ts/ts-client/src/utils.ts +++ b/languages/ts/ts-client/src/utils.ts @@ -2,13 +2,13 @@ import { EventSourcePlusOptions } from "event-source-plus"; export async function getHeaders( input: EventSourcePlusOptions["headers"], -): Promise | undefined> { +): Promise> { if (typeof input === "function") { const result = input(); if ("then" in result && typeof result.then === "function") { - return result.then((data) => data); + return result.then((data) => data as Record); } - return result; + return result as Record; } - return input; + return (input ?? {}) as Record; } diff --git a/languages/ts/ts-codegen-reference/package.json b/languages/ts/ts-codegen-reference/package.json index 0db7c07e..de7cfec7 100644 --- a/languages/ts/ts-codegen-reference/package.json +++ b/languages/ts/ts-codegen-reference/package.json @@ -1,30 +1,28 @@ { - "name": "ts-codegen-reference", - "version": "0.56.0", - "type": "module", - "license": "MIT", - "author": { - "name": "joshmossas", - "url": "https://github.com/joshmossas" - }, - "bugs": { - "url": "https://github.com/modiimedia/arri/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/modiimedia/arri.git", - "directory": "tooling/ts-codegen-reference" - }, - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "files": [ - "dist" - ], - "dependencies": { - - }, - "devDependencies": { - - } -} \ No newline at end of file + "name": "ts-codegen-reference", + "version": "0.56.0", + "type": "module", + "license": "MIT", + "author": { + "name": "joshmossas", + "url": "https://github.com/joshmossas" + }, + "bugs": { + "url": "https://github.com/modiimedia/arri/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/modiimedia/arri.git", + "directory": "tooling/ts-codegen-reference" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "dependencies": { + "@arrirpc/client": "workspace:*" + }, + "devDependencies": {} +} diff --git a/languages/ts/ts-codegen-reference/src/index.ts b/languages/ts/ts-codegen-reference/src/index.ts deleted file mode 100644 index 7e0e36e1..00000000 --- a/languages/ts/ts-codegen-reference/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// ts-codegen-reference entry -// todo \ No newline at end of file diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts new file mode 100644 index 00000000..8f260464 --- /dev/null +++ b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts @@ -0,0 +1,31 @@ +import fs from "node:fs"; +import path from "node:path"; + +import { $$Book, Book } from "./referenceClient"; + +const testDate = new Date("2001-01-01T16:00:00.000Z"); +const referenceDir = path.resolve(__dirname, "../../../../tests/test-files"); +const testFile = (filename: string) => + fs.readFileSync(path.resolve(referenceDir, filename), "utf8"); + +describe("Book", () => { + const targetValue: Book = { + id: "1", + name: "The Adventures of Tom Sawyer", + createdAt: testDate, + updatedAt: testDate, + }; + const jsonReference = testFile("Book.json"); + test("JSON Parsing", () => { + const result = $$Book.fromJsonString(jsonReference); + expect(result).toStrictEqual(targetValue); + }); + test("JSON Output", () => { + expect($$Book.toJsonString(targetValue)).toEqual(jsonReference); + }); + test("URL Query String Output", () => { + expect($$Book.toUrlQueryString(targetValue)).toEqual( + `id=1&name=The Adventures of Tom Sawyer&createdAt=2001-01-01T16:00:00.000Z&updatedAt=2001-01-01T16:00:00.000Z`, + ); + }); +}); diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts new file mode 100644 index 00000000..c1b3dd9d --- /dev/null +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -0,0 +1,685 @@ +import { + ArriEnumValidator, + ArriModelValidator, + INT8_MAX, + INT8_MIN, + INT16_MAX, + INT16_MIN, + INT32_MIN, + isObject, + serializeString, + UINT8_MAX, + UINT16_MAX, + UINT32_MAX, +} from "@arrirpc/client"; + +type HeaderMap = Record; + +export class ExampleClient { + private readonly _baseUrl: string; + private readonly _headers: HeaderMap | (() => HeaderMap); + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; + } +} + +export interface Book { + id: string; + name: string; + createdAt: Date; + updatedAt: Date; +} +export const $$Book: ArriModelValidator = { + new(): Book { + return { + id: "", + name: "", + createdAt: new Date(), + updatedAt: new Date(), + }; + }, + validate(input: unknown): input is Book { + return ( + isObject(input) && + input.id === "string" && + input.name === "string" && + input.createdAt instanceof Date && + input.updatedAt instanceof Date + ); + }, + fromJson(input: Record): Book { + let id: string; + if (typeof input.id === "string") { + id = input.id; + } else { + id = ""; + } + let name: string; + if (typeof input.name === "string") { + name = input.name; + } else { + name = ""; + } + let createdAt: Date; + if (typeof input.createdAt === "string") { + createdAt = new Date(input.createdAt); + } else if (input.createdAt instanceof Date) { + createdAt = input.createdAt; + } else { + createdAt = new Date(); + } + let updatedAt: Date; + if (typeof input.updatedAt === "string") { + updatedAt = new Date(input.updatedAt); + } else if (input.updatedAt instanceof Date) { + updatedAt = input.updatedAt; + } else { + updatedAt = new Date(); + } + return { + id, + name, + createdAt, + updatedAt, + }; + }, + fromJsonString(input: string): Book { + return $$Book.fromJson(JSON.parse(input)); + }, + toJsonString(input: Book): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"name":'; + json += serializeString(input.name); + json += ',"createdAt":'; + json += `"${input.createdAt.toISOString()}"`; + json += `,"updatedAt":`; + json += `"${input.updatedAt.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`name=${input.name}`); + queryParts.push(`createdAt=${input.createdAt.toISOString()}`); + queryParts.push(`updatedAt=${input.updatedAt.toISOString()}`); + return queryParts.join("&"); + }, +}; + +export interface BookParams { + bookId: string; +} +export const $$BookParams: ArriModelValidator = { + new(): BookParams { + return { + bookId: "", + }; + }, + validate(input: unknown): input is BookParams { + return isObject(input) && typeof input.bookId === "string"; + }, + fromJson(input: Record): BookParams { + let bookId: string; + if (typeof input.bookId === "string") { + bookId = input.bookId; + } else { + bookId = ""; + } + return { + bookId, + }; + }, + fromJsonString(input: string): BookParams { + return $$BookParams.fromJson(JSON.parse(input)); + }, + toJsonString(input: BookParams): string { + let json = "{"; + json += `"bookId":`; + json += serializeString(input.bookId); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`bookId=${input.bookId}`); + return queryParts.join("&"); + }, +}; + +export interface NestedObject { + id: string; + content: string; +} +export const $$NestedObject: ArriModelValidator = { + new(): NestedObject { + return { + id: "", + content: "", + }; + }, + validate(input: unknown): input is NestedObject { + return ( + isObject(input) && + typeof input.id === "string" && + typeof input.content === "string" + ); + }, + fromJson(input: Record): NestedObject { + let id: string; + if (typeof input.id === "string") { + id = input.id; + } else { + id = ""; + } + let content: string; + if (typeof input.content === "string") { + content = input.content; + } else { + content = ""; + } + return { + id, + content, + }; + }, + fromJsonString(input: string): NestedObject { + return $$NestedObject.fromJson(JSON.parse(input)); + }, + toJsonString(input: NestedObject): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"content":'; + json += serializeString(input.content); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`content=${input.content}`); + return queryParts.join("&"); + }, +}; + +export interface ObjectWithEveryType { + string: string; + boolean: boolean; + timestamp: Date; + float32: number; + float64: number; + int8: number; + uint8: number; + int16: number; + uint16: number; + int32: number; + uint32: number; + int64: bigint; + uint64: bigint; + enum: Enumerator; + object: NestedObject; + array: boolean[]; + record: Record; + discriminator: Discriminator; + any: any; +} +export const $$ObjectWithEveryType: ArriModelValidator = { + new(): ObjectWithEveryType { + return { + string: "", + boolean: false, + timestamp: new Date(), + float32: 0, + float64: 0, + int8: 0, + uint8: 0, + int16: 0, + uint16: 0, + int32: 0, + uint32: 0, + int64: BigInt(0), + uint64: BigInt(0), + enum: "FOO", + object: $$NestedObject.new(), + array: [], + record: {}, + discriminator: $$Discriminator.new(), + any: null, + }; + }, + validate(input): input is ObjectWithEveryType { + return ( + isObject(input) && + typeof input.string === "string" && + typeof input.boolean === "boolean" && + input.timestamp instanceof Date && + typeof input.float32 === "number" && + typeof input.float64 === "number" && + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + (input.int8 as number) >= INT8_MIN && + (input.int8 as number) <= INT8_MAX && + typeof input.uint8 === "number" && + (input.uint8 as number) >= 0 && + (input.uint8 as number) <= UINT8_MAX && + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + (input.int16 as number) >= INT16_MIN && + (input.int16 as number) <= INT16_MAX && + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + (input.uint16 as number) >= 0 && + (input.uint16 as number) <= UINT16_MAX && + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + (input.int32 as number) >= INT32_MIN && + (input.int32 as number) <= UINT32_MAX && + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + (input.uint32 as number) >= 0 && + (input.uint32 as number) <= UINT32_MAX && + typeof input.int64 === "bigint" && + typeof input.uint64 === "bigint" && + (input.uint64 as bigint) >= BigInt(0) && + $$Enumerator.validate(input.enum) && + $$NestedObject.validate(input.object) && + Array.isArray(input.array) && + input.array.every((value) => typeof value === "boolean") && + isObject(input.record) && + Object.entries(input.record).every( + ([_, value]) => typeof value === "boolean", + ) && + $$Discriminator.validate(input.discriminator) + ); + }, + fromJson(input): ObjectWithEveryType { + let _string: string; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = ""; + } + let _boolean: boolean; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = false; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input instanceof Date) { + _timestamp = input; + } else { + _timestamp = new Date(); + } + let _float32: number; + if (typeof input.float32 === "number") { + _float32 = input.float32; + } else { + _float32 = 0; + } + let _float64: number; + if (typeof input.float64 === "number") { + _float64 = input.float64; + } else { + _float64 = 0; + } + let _int8: number; + if ( + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX + ) { + _int8 = input.int8; + } else { + _int8 = 0; + } + let _uint8: number; + if ( + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX + ) { + _uint8 = input.uint8; + } else { + _uint8 = 0; + } + let _int16: number; + let _uint16: number; + let _int32: number; + let _uint32: number; + let _int64: bigint; + let _uint64: bigint; + let _enum: Enumerator; + let _object: NestedObject; + let _array: boolean[]; + let _record: Record; + let _discriminator: Discriminator; + let _any: any; + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enum: _enum, + object: _object, + array: _array, + record: _record, + discriminator: _discriminator, + any: _any, + }; + }, + fromJsonString(input): ObjectWithEveryType { + return $$ObjectWithEveryType.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + return queryParts.join("&"); + }, +}; + +export type Enumerator = (typeof $$EnumeratorValues)[number]; +const $$EnumeratorValues = ["FOO", "BAR", "BAZ"] as const; +export const $$Enumerator: ArriEnumValidator = { + new(): Enumerator { + return $$EnumeratorValues[0]; + }, + validate(input): input is Enumerator { + return ( + typeof input === "string" && + $$EnumeratorValues.includes(input as any) + ); + }, + values: $$EnumeratorValues, + fromSerialValue(input): Enumerator { + if ($$EnumeratorValues.includes(input as any)) { + return input as Enumerator; + } + if ($$EnumeratorValues.includes(input.toLowerCase() as any)) { + return input.toLowerCase() as Enumerator; + } + if ($$EnumeratorValues.includes(input.toUpperCase() as any)) { + return input.toUpperCase() as Enumerator; + } + return "FOO"; + }, +}; + +export type Discriminator = DiscriminatorA | DiscriminatorB | DiscriminatorC; +export const $$Discriminator: ArriModelValidator = { + new(): Discriminator { + return $$DiscriminatorA.new(); + }, + validate(input): input is Discriminator { + if (!isObject(input)) { + return false; + } + if (typeof input.typeName !== "string") { + return false; + } + switch (input.typeName) { + case "A": + return $$DiscriminatorA.validate(input); + case "B": + return $$DiscriminatorB.validate(input); + case "C": + return $$DiscriminatorC.validate(input); + default: + return false; + } + }, + fromJson(input): Discriminator { + switch (input.typeName) { + case "A": + return $$DiscriminatorA.fromJson(input); + case "B": + return $$DiscriminatorB.fromJson(input); + case "C": + return $$DiscriminatorC.fromJson(input); + default: + return $$DiscriminatorA.new(); + } + }, + fromJsonString(input): Discriminator { + return $$Discriminator.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + switch (input.typeName) { + case "A": + return $$DiscriminatorA.toJsonString(input); + case "B": + return $$DiscriminatorB.toJsonString(input); + case "C": + return $$DiscriminatorC.toJsonString(input); + default: + input satisfies never; + throw new Error(`Unhandled case "${(input as any).typeName}"`); + } + }, + toUrlQueryString(input): string { + switch (input.typeName) { + case "A": + return $$DiscriminatorA.toUrlQueryString(input); + case "B": + return $$DiscriminatorB.toUrlQueryString(input); + case "C": + return $$DiscriminatorC.toUrlQueryString(input); + default: + throw new Error(`Unhandled case`); + } + }, +}; +export interface DiscriminatorA { + typeName: "A"; + id: string; +} +const $$DiscriminatorA: ArriModelValidator = { + new(): DiscriminatorA { + return { + typeName: "A", + id: "", + }; + }, + validate(input): input is DiscriminatorA { + return ( + isObject(input) && + input.typeName === "A" && + typeof input.id === "string" + ); + }, + fromJson(input): DiscriminatorA { + const typeName = "A"; + let id: string; + if (typeof input.id === "string") { + id = input.id; + } else { + id = ""; + } + return { + typeName, + id, + }; + }, + fromJsonString(input): DiscriminatorA { + return $$DiscriminatorA.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"typeName":"A"'; + json += ',"id":'; + json += serializeString(input.id); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`typeName=A`); + queryParts.push(`id=${input.id}`); + return queryParts.join("&"); + }, +}; +export interface DiscriminatorB { + typeName: "B"; + id: string; + name: string; +} +const $$DiscriminatorB: ArriModelValidator = { + new(): DiscriminatorB { + return { + typeName: "B", + id: "", + name: "", + }; + }, + validate(input): input is DiscriminatorB { + return ( + isObject(input) && + input.typeName === "B" && + typeof input.id === "string" && + typeof input.name === "string" + ); + }, + fromJson(input): DiscriminatorB { + const typeName = "B"; + let id: string; + if (typeof input.id === "string") { + id = input.id; + } else { + id = ""; + } + let name: string; + if (typeof input.name === "string") { + name = input.name; + } else { + name = ""; + } + return { + typeName, + id, + name, + }; + }, + fromJsonString(input): DiscriminatorB { + return $$DiscriminatorB.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"typeName":"B"'; + json += ',"id":'; + json += serializeString(input.id); + json += ',"name":'; + json += serializeString(input.name); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("typeName=B"); + queryParts.push(`id=${input.id}`); + queryParts.push(`name=${input.name}`); + return queryParts.join("&"); + }, +}; +export interface DiscriminatorC { + typeName: "C"; + id: string; + name: string; + date: Date; +} +const $$DiscriminatorC: ArriModelValidator = { + new(): DiscriminatorC { + return { + typeName: "C", + id: "", + name: "", + date: new Date(), + }; + }, + validate(input): input is DiscriminatorC { + return ( + isObject(input) && + input.typeName === "C" && + typeof input.id === "string" && + typeof input.name === "string" && + input.date instanceof Date + ); + }, + fromJson(input): DiscriminatorC { + const typeName = "C"; + let id: string; + if (typeof input.id === "string") { + id = input.id; + } else { + id = ""; + } + let name: string; + if (typeof input.name === "string") { + name = input.name; + } else { + name = ""; + } + let date: Date; + if (typeof input.date === "string") { + date = new Date(input.date); + } else if (input.date instanceof Date) { + date = input.date; + } else { + date = new Date(); + } + return { + typeName, + id, + name, + date, + }; + }, + fromJsonString(input): DiscriminatorC { + return $$DiscriminatorC.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"typeName":"C"'; + json += ',"id":'; + json += serializeString(input.id); + json += ',"name":'; + json += serializeString(input.name); + json += ',"date":'; + json += `"${input.date.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("typeName=C"); + queryParts.push(`id=${input.id}`); + queryParts.push(`name=${input.name}`); + queryParts.push(`date=${input.date.toISOString()}`); + return queryParts.join("&"); + }, +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 928478a4..79fc5908 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -180,6 +180,12 @@ importers: specifier: workspace:* version: link:../ts-client + languages/ts/ts-codegen-reference: + dependencies: + '@arrirpc/client': + specifier: workspace:* + version: link:../ts-client + languages/ts/ts-server: dependencies: '@arrirpc/codegen-dart': From 615a0f21641ce189908661804ef6f7ea1f6a8d7c Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sat, 20 Jul 2024 03:57:53 -0500 Subject: [PATCH 03/18] get recursive types working --- .../src/referenceClient.test.ts | 27 +++- .../src/referenceClient.ts | 137 ++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts index 8f260464..00fb3039 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts @@ -1,7 +1,12 @@ import fs from "node:fs"; import path from "node:path"; -import { $$Book, Book } from "./referenceClient"; +import { + $$Book, + $$RecursiveObject, + Book, + RecursiveObject, +} from "./referenceClient"; const testDate = new Date("2001-01-01T16:00:00.000Z"); const referenceDir = path.resolve(__dirname, "../../../../tests/test-files"); @@ -29,3 +34,23 @@ describe("Book", () => { ); }); }); + +describe("RecursiveObject", () => { + const targetValue: RecursiveObject = { + left: { + left: { left: null, right: { left: null, right: null } }, + right: null, + }, + right: { left: null, right: null }, + }; + const jsonReference = testFile("RecursiveObject.json"); + test("JSON parsing", () => { + const result = $$RecursiveObject.fromJsonString(jsonReference); + expect(result).toStrictEqual(targetValue); + }); + test("JSON output", () => { + expect($$RecursiveObject.toJsonString(targetValue)).toEqual( + jsonReference, + ); + }); +}); diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index c1b3dd9d..e250c675 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -683,3 +683,140 @@ const $$DiscriminatorC: ArriModelValidator = { return queryParts.join("&"); }, }; + +export interface ObjectWithOptionalFields { + string?: string; + boolean?: boolean; + timestamp?: Date; + float32?: number; + float64?: number; + int8?: number; + uint8?: number; + int16?: number; + uint16?: number; + int32?: number; + uint32?: number; + enum?: Enumerator; + object?: NestedObject; + array?: boolean[]; + record?: Record; + discriminator?: Discriminator; + any?: any; +} +export const $$ObjectWithOptionalFields: ArriModelValidator = + { + new(): ObjectWithOptionalFields { + return {}; + }, + }; + +export interface ObjectWithNullableFields { + string: string | null; + boolean: boolean | null; + timestamp: Date | null; + float32: number | null; + float64: number | null; + int8: number | null; + uint8: number | null; + int16: number | null; + uint16: number | null; + int32: number | null; + uint32: number | null; + int64: bigint | null; + uint64: bigint | null; + enum: Enumerator | null; + object: NestedObject | null; + array: boolean[] | null; + record: Record | null; + discriminator: Discriminator | null; + any: any; +} +export const $$ObjectWithNullableFields: ArriModelValidator = + { + new(): ObjectWithNullableFields { + return { + string: null, + boolean: null, + timestamp: null, + float32: null, + float64: null, + int8: null, + uint8: null, + int16: null, + uint16: null, + int32: null, + uint32: null, + int64: null, + uint64: null, + enum: null, + object: null, + array: null, + record: null, + discriminator: null, + any: null, + }; + }, + }; + +export interface RecursiveObject { + left: RecursiveObject | null; + right: RecursiveObject | null; +} +export const $$RecursiveObject: ArriModelValidator = { + new(): RecursiveObject { + return { + left: null, + right: null, + }; + }, + validate(input): input is RecursiveObject { + return ( + isObject(input) && + (input.left === null || $$RecursiveObject.validate(input.left)) && + (input.right === null || $$RecursiveObject.validate(input.right)) + ); + }, + fromJson(input): RecursiveObject { + let left: RecursiveObject | null; + if (isObject(input.left)) { + left = $$RecursiveObject.fromJson(input.left); + } else { + left = null; + } + let right: RecursiveObject | null; + if (isObject(input.right)) { + right = $$RecursiveObject.fromJson(input.right); + } else { + right = null; + } + return { + left, + right, + }; + }, + fromJsonString(input): RecursiveObject { + return $$RecursiveObject.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"left":'; + if (input.left) { + json += $$RecursiveObject.toJsonString(input.left); + } else { + json += "null"; + } + json += ',"right":'; + if (input.right) { + json += $$RecursiveObject.toJsonString(input.right); + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + // TODO: + return queryParts.join("&"); + }, +}; From 2a814f9ef0aa9c85527b060130528ea8b081356d Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sat, 20 Jul 2024 09:05:32 -0500 Subject: [PATCH 04/18] more parts --- .../src/referenceClient.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index e250c675..bbe831fe 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -5,6 +5,7 @@ import { INT8_MIN, INT16_MAX, INT16_MIN, + INT32_MAX, INT32_MIN, isObject, serializeString, @@ -357,13 +358,73 @@ export const $$ObjectWithEveryType: ArriModelValidator = { _uint8 = 0; } let _int16: number; + if ( + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX + ) { + _int16 = input.int16; + } else { + _int16 = 0; + } let _uint16: number; + if ( + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX + ) { + _uint16 = input.uint16; + } else { + _uint16 = 0; + } let _int32: number; + if ( + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX + ) { + _int32 = input.int32; + } else { + _int32 = 0; + } let _uint32: number; + if ( + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX + ) { + _uint32 = input.uint32; + } else { + _uint32 = 0; + } let _int64: bigint; + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); + } else { + _int64 = BigInt(0); + } let _uint64: bigint; + if (typeof input.uint64 === "string") { + _uint64 = BigInt(input.uint64); + } else { + _uint64 = BigInt(0); + } let _enum: Enumerator; + if ($$Enumerator.validate(input.enum)) { + _enum = input.enum; + } else { + _enum = "FOO"; + } let _object: NestedObject; + if (isObject(input.object)) { + _object = $$NestedObject.fromJson(input.object); + } else { + _object = $$NestedObject.new(); + } let _array: boolean[]; let _record: Record; let _discriminator: Discriminator; From 3ed3ea766d8d0df5977461a2efd24048c2a27e43 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sat, 20 Jul 2024 19:23:57 -0500 Subject: [PATCH 05/18] finished ObjectWithEveryType --- languages/ts/ts-client/src/request.ts | 2 +- .../src/referenceClient.test.ts | 54 ++++++++ .../src/referenceClient.ts | 120 +++++++++++++++++- 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/languages/ts/ts-client/src/request.ts b/languages/ts/ts-client/src/request.ts index 218494b3..10c07aa7 100644 --- a/languages/ts/ts-client/src/request.ts +++ b/languages/ts/ts-client/src/request.ts @@ -148,7 +148,7 @@ export function serializeString(input: string): string { return JSON.stringify(input); } -export const INT8_MIN = 128; +export const INT8_MIN = -128; export const INT8_MAX = 127; export const UINT8_MAX = 255; export const INT16_MIN = -32768; diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts index 00fb3039..1b3342c9 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts @@ -3,8 +3,10 @@ import path from "node:path"; import { $$Book, + $$ObjectWithEveryType, $$RecursiveObject, Book, + ObjectWithEveryType, RecursiveObject, } from "./referenceClient"; @@ -35,6 +37,58 @@ describe("Book", () => { }); }); +describe("ObjectWithEveryType", () => { + const targetValue: ObjectWithEveryType = { + string: "", + boolean: false, + timestamp: testDate, + float32: 1.5, + float64: 1.5, + int8: 1, + uint8: 1, + int16: 10, + uint16: 10, + int32: 100, + uint32: 100, + int64: 1000n, + uint64: 1000n, + enum: "BAZ", + object: { + id: "1", + content: "hello world", + }, + array: [true, false, false], + record: { + A: true, + B: false, + }, + discriminator: { + typeName: "C", + id: "", + name: "", + date: testDate, + }, + any: "hello world", + }; + const jsonReference = testFile("ObjectWithEveryType.json"); + const emptyJsonReference = testFile( + "ObjectWithOptionalFields_AllUndefined.json", + ); + test("JSON parsing", () => { + const result = $$ObjectWithEveryType.fromJsonString(jsonReference); + expect(result).toStrictEqual(targetValue); + + const emptyJsonResult = + $$ObjectWithEveryType.fromJsonString(emptyJsonReference); + expect(emptyJsonResult).toStrictEqual($$ObjectWithEveryType.new()); + }); + test("JSON output", () => { + expect($$ObjectWithEveryType.toJsonString(targetValue)).toEqual( + jsonReference, + ); + }); +}); + describe("RecursiveObject", () => { const targetValue: RecursiveObject = { left: { diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index bbe831fe..b663087e 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -254,7 +254,7 @@ export const $$ObjectWithEveryType: ArriModelValidator = { array: [], record: {}, discriminator: $$Discriminator.new(), - any: null, + any: undefined, }; }, validate(input): input is ObjectWithEveryType { @@ -336,6 +336,14 @@ export const $$ObjectWithEveryType: ArriModelValidator = { _float64 = 0; } let _int8: number; + console.log( + "INT, ", + input.int8, + typeof input.int8 === "number", + Number.isInteger(input.int8), + input.int8 >= INT8_MIN, + input.int8 <= INT8_MAX, + ); if ( typeof input.int8 === "number" && Number.isInteger(input.int8) && @@ -426,9 +434,39 @@ export const $$ObjectWithEveryType: ArriModelValidator = { _object = $$NestedObject.new(); } let _array: boolean[]; + if (Array.isArray(input.array)) { + _array = []; + for (const _element of input.array) { + if (typeof _element === "boolean") { + _array.push(_element); + } else { + _array.push(false); + } + } + } else { + _array = []; + } let _record: Record; + if (isObject(input.record)) { + _record = {}; + for (const key of Object.keys(input.record)) { + if (typeof input.record[key] === "boolean") { + _record[key] = input.record[key]; + } else { + _record[key] = false; + } + } + } else { + _record = {}; + } let _discriminator: Discriminator; + if (isObject(input.discriminator)) { + _discriminator = $$Discriminator.fromJson(input.discriminator); + } else { + _discriminator = $$Discriminator.new(); + } let _any: any; + _any = input.any; return { string: _string, boolean: _boolean, @@ -456,11 +494,91 @@ export const $$ObjectWithEveryType: ArriModelValidator = { }, toJsonString(input): string { let json = "{"; + json += '"string":'; + json += serializeString(input.string); + json += ',"boolean":'; + json += input.boolean.toString(); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"float32":'; + json += input.float32.toString(); + json += ',"float64":'; + json += input.float64.toString(); + json += ',"int8":'; + json += input.int8.toString(); + json += ',"uint8":'; + json += input.uint8.toString(); + json += ',"int16":'; + json += input.int16.toString(); + json += ',"uint16":'; + json += input.uint16.toString(); + json += ',"int32":'; + json += input.int32.toString(); + json += ',"uint32":'; + json += input.uint32.toString(); + json += ',"int64":'; + json += `"${input.int64.toString()}"`; + json += ',"uint64":'; + json += `"${input.uint64.toString()}"`; + json += ',"enum":'; + json += `"${input.enum}"`; + json += ',"object":'; + json += $$NestedObject.toJsonString(input.object); + json += ',"array":'; + json += "["; + for (let i = 0; i < input.array.length; i++) { + const _element = input.array[i]!; + if (i !== 0) json += ","; + json += _element.toString(); + } + json += "]"; + json += ',"record":'; + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.record)) { + if (_recordPropertyCount !== 0) { + json += ","; + } + json += `"${_key}":`; + json += _value.toString(); + _recordPropertyCount++; + } + json += "}"; + json += ',"discriminator":'; + json += $$Discriminator.toJsonString(input.discriminator); + json += ',"any":'; + json += JSON.stringify(input.any); json += "}"; return json; }, toUrlQueryString(input): string { const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + queryParts.push(`float32=${input.float32}`); + queryParts.push(`float64=${input.float64}`); + queryParts.push(`int8=${input.int8}`); + queryParts.push(`uint8=${input.uint8}`); + queryParts.push(`int16=${input.int16}`); + queryParts.push(`uint16=${input.uint16}`); + queryParts.push(`int32=${input.int32}`); + queryParts.push(`uint32=${input.uint32}`); + queryParts.push(`int64=${input.int64}`); + queryParts.push(`uint64=${input.uint64}`); + queryParts.push(`enum=${input.enum}`); + console.warn( + `[WARNING] Cannot serialize nested objects to query params. Ignoring property at /ObjectWithEveryType/object.`, + ); + console.warn( + `[WARNING] Cannot serialize arrays to query params. Ignoring property at /ObjectWithEveryType/array.`, + ); + console.warn( + `[WARNING] Cannot serialize nested objects to query params. Ignoring property at /ObjectWithEveryType/record.`, + ); + console.warn( + `[WARNING] Cannot serialize any's to query params. Ignoring property at /ObjectWithEveryType/any.`, + ); return queryParts.join("&"); }, }; From 9ee787028f7b37f8c480c46e2c387ceb27947046 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sun, 21 Jul 2024 01:43:55 -0500 Subject: [PATCH 06/18] ts enums --- languages/ts/ts-client/src/request.ts | 13 +- languages/ts/ts-client/src/sse.ts | 6 +- languages/ts/ts-client/src/ws.ts | 6 +- .../src/referenceClient.ts | 89 +- languages/ts/ts-codegen/src/any.ts | 25 + languages/ts/ts-codegen/src/common.ts | 80 ++ languages/ts/ts-codegen/src/enum.ts | 80 ++ languages/ts/ts-codegen/src/index.test.ts | 256 +---- languages/ts/ts-codegen/src/index.ts | 1001 +---------------- languages/ts/ts-codegen/src/primitives.ts | 251 +++++ 10 files changed, 574 insertions(+), 1233 deletions(-) create mode 100644 languages/ts/ts-codegen/src/any.ts create mode 100644 languages/ts/ts-codegen/src/common.ts create mode 100644 languages/ts/ts-codegen/src/enum.ts create mode 100644 languages/ts/ts-codegen/src/primitives.ts diff --git a/languages/ts/ts-client/src/request.ts b/languages/ts/ts-client/src/request.ts index 10c07aa7..a9c8b7d1 100644 --- a/languages/ts/ts-client/src/request.ts +++ b/languages/ts/ts-client/src/request.ts @@ -11,13 +11,13 @@ export interface ArriRequestOpts< > { url: string; method: HttpMethod; - headers?: EventSourcePlusOptions["headers"]; + headers: EventSourcePlusOptions["headers"]; params?: TParams; - parser: (input: unknown) => TType; + parser: (input: string) => TType; serializer: ( input: TParams, ) => TParams extends undefined ? undefined : string; - clientVersion?: string; + clientVersion: string; } export async function arriRequest< @@ -31,12 +31,7 @@ export async function arriRequest< case "get": case "head": if (opts.params && typeof opts.params === "object") { - const urlParts: string[] = []; - Object.keys(opts.params).forEach((key) => { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - urlParts.push(`${key}=${(opts.params as any)[key]}`); - }); - url = `${opts.url}?${urlParts.join("&")}`; + url = `${opts.url}?${opts.serializer(opts.params)}`; } break; default: diff --git a/languages/ts/ts-client/src/sse.ts b/languages/ts/ts-client/src/sse.ts index e700b975..d1fd7985 100644 --- a/languages/ts/ts-client/src/sse.ts +++ b/languages/ts/ts-client/src/sse.ts @@ -53,11 +53,7 @@ export function arriSseRequest< typeof opts.params === "object" && opts.params !== null ) { - const urlParts: string[] = []; - Object.keys(opts.params).forEach((key) => { - urlParts.push(`${key}=${(opts.params as any)[key]}`); - }); - url = `${opts.url}?${urlParts.join("&")}`; + url = `${opts.url}?${opts.serializer(opts.params)}`; } break; default: diff --git a/languages/ts/ts-client/src/ws.ts b/languages/ts/ts-client/src/ws.ts index 5849a730..be1b67c3 100644 --- a/languages/ts/ts-client/src/ws.ts +++ b/languages/ts/ts-client/src/ws.ts @@ -11,7 +11,7 @@ function isBrowser() { interface WsControllerOptions { url: string; serializer: (input: TParams) => string; - parser: (input: unknown) => TResponse; + parser: (input: string) => TResponse; onMessage?: WsMessageHook; onErrorMessage?: WsErrorHook; onConnectionError?: WsErrorHook; @@ -31,7 +31,7 @@ interface ArriWsRequestOptions { url: string; headers?: EventSourcePlusOptions["headers"]; params?: TParams; - parser: (input: unknown) => TResponse; + parser: (input: string) => TResponse; serializer: (input: TParams) => string; onMessage?: WsMessageHook; onError?: WsErrorHook; @@ -98,7 +98,7 @@ class WsController { url: string; private _ws?: NodeWebsocket | WebSocket; private readonly _serializer: (input: TParams) => string; - private readonly _parser: (input: unknown) => TResponse; + private readonly _parser: (input: string) => TResponse; onMessage?: WsMessageHook; onErrorMessage?: WsErrorHook; onConnectionError?: WsErrorHook; diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index b663087e..37cf68e0 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -1,6 +1,9 @@ import { ArriEnumValidator, ArriModelValidator, + arriRequest, + arriSseRequest, + arriWsRequest, INT8_MAX, INT8_MIN, INT16_MAX, @@ -9,9 +12,11 @@ import { INT32_MIN, isObject, serializeString, + SseOptions, UINT8_MAX, UINT16_MAX, UINT32_MAX, + WsOptions, } from "@arrirpc/client"; type HeaderMap = Record; @@ -28,6 +33,82 @@ export class ExampleClient { this._baseUrl = options.baseUrl ?? ""; this._headers = options.headers ?? {}; } + + async sendObject(params: NestedObject) { + return arriRequest({ + url: `${this._baseUrl}/send-object`, + method: "post", + headers: this._headers, + params: params, + parser: $$NestedObject.fromJsonString, + serializer: $$NestedObject.toJsonString, + clientVersion: "20", + }); + } +} + +export class ExampleClientBooksService { + private readonly _baseUrl: string; + private readonly _headers: HeaderMap | (() => HeaderMap); + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; + } + async getBook(params: BookParams) { + return arriRequest({ + url: `${this._baseUrl}/books/get-book`, + method: "get", + headers: this._headers, + params: params, + parser: $$Book.fromJsonString, + serializer: $$BookParams.toUrlQueryString, + clientVersion: "20", + }); + } + async createBook(params: Book) { + return arriRequest({ + url: `${this._baseUrl}/books/create-book`, + method: "post", + headers: this._headers, + params: params, + parser: $$Book.fromJsonString, + serializer: $$Book.toJsonString, + clientVersion: "20", + }); + } + async watchBook(params: BookParams, options: SseOptions = {}) { + return arriSseRequest( + { + url: `${this._baseUrl}/books/watch-book`, + method: "get", + headers: this._headers, + params: params, + parser: $$Book.fromJsonString, + serializer: $$BookParams.toUrlQueryString, + clientVersion: "20", + }, + options, + ); + } + async createConnection(options: WsOptions = {}) { + return arriWsRequest({ + url: `${this._baseUrl}/books/create-connection`, + headers: this._headers, + parser: $$Book.fromJsonString, + serializer: $$BookParams.toJsonString, + onOpen: options.onOpen, + onClose: options.onClose, + onError: options.onError, + onConnectionError: options.onConnectionError, + onMessage: options.onMessage, + clientVersion: "20", + }); + } } export interface Book { @@ -336,14 +417,6 @@ export const $$ObjectWithEveryType: ArriModelValidator = { _float64 = 0; } let _int8: number; - console.log( - "INT, ", - input.int8, - typeof input.int8 === "number", - Number.isInteger(input.int8), - input.int8 >= INT8_MIN, - input.int8 <= INT8_MAX, - ); if ( typeof input.int8 === "number" && Number.isInteger(input.int8) && diff --git a/languages/ts/ts-codegen/src/any.ts b/languages/ts/ts-codegen/src/any.ts new file mode 100644 index 00000000..bd1096c0 --- /dev/null +++ b/languages/ts/ts-codegen/src/any.ts @@ -0,0 +1,25 @@ +import { Schema } from "@arrirpc/codegen-utils"; + +import { CodegenContext, TsProperty } from "./common"; + +export function tsAnyFromSchema( + schema: Schema, + context: CodegenContext, +): TsProperty { + const typeName = "any"; + const defaultValue = "undefined"; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `${input} = ${target}`; + }, + toJsonTemplate(input, target) { + return `${target} += JSON.stringify(${input})`; + }, + toQueryStringTemplate(_input, _target, _key) { + return `console.warn("[WARNING] Cannot serialize any's to query string. Skipping property at ${context.instancePath}.")`; + }, + content: "", + }; +} diff --git a/languages/ts/ts-codegen/src/common.ts b/languages/ts/ts-codegen/src/common.ts new file mode 100644 index 00000000..3ec5ba14 --- /dev/null +++ b/languages/ts/ts-codegen/src/common.ts @@ -0,0 +1,80 @@ +import { + pascalCase, + removeDisallowedChars, + Schema, + stringStartsWithNumber, +} from "@arrirpc/codegen-utils"; + +export interface TsProperty { + typeName: string; + defaultValue: string; + fromJsonTemplate: (input: string, target: string) => string; + toJsonTemplate: (input: string, target: string) => string; + toQueryStringTemplate: ( + input: string, + target: string, + key: string, + ) => string; + content: string; +} + +export interface CodegenContext { + clientName: string; + typePrefix: string; + generatedTypes: string[]; + instancePath: string; + schemaPath: string; + discriminatorParent: string; + discriminatorKey: string; + discriminatorValue: string; + versionNumber: string; + hasSseProcedure: boolean; + hasWsProcedure: boolean; +} + +export function getJsDocComment(metadata: Schema["metadata"]) { + const descriptionParts: string[] = []; + + if (metadata?.description?.length) { + const parts = metadata.description.split("\n"); + for (const part of parts) { + descriptionParts.push(`* ${part}`); + } + } + if (metadata?.isDeprecated) { + descriptionParts.push("* @deprecated"); + } + if (descriptionParts.length === 0) { + return ""; + } + return `/** +${descriptionParts.join("\n")} +*/\n`; +} + +const illegalChars = "!#^&*()-+=?/][{}|\\~`'\""; + +export function validVarName(name: string): string { + if (stringStartsWithNumber(name)) { + return `_${removeDisallowedChars(name, illegalChars)}`; + } + return removeDisallowedChars(name, illegalChars); +} + +export function getTsTypeName(schema: Schema, context: CodegenContext): string { + if (schema.metadata?.id) { + const name = pascalCase(schema.metadata.id, { normalize: true }); + return validVarName(name); + } + if (context.discriminatorParent && context.discriminatorValue) { + const name = pascalCase( + `${context.discriminatorParent}_${context.discriminatorValue}`, + { normalize: true }, + ); + return validVarName(name); + } + const name = pascalCase(context.instancePath.split("/").join("_"), { + normalize: true, + }); + return validVarName(name); +} diff --git a/languages/ts/ts-codegen/src/enum.ts b/languages/ts/ts-codegen/src/enum.ts new file mode 100644 index 00000000..58e050dd --- /dev/null +++ b/languages/ts/ts-codegen/src/enum.ts @@ -0,0 +1,80 @@ +import { SchemaFormEnum } from "@arrirpc/codegen-utils"; + +import { + CodegenContext, + getJsDocComment, + getTsTypeName, + TsProperty, +} from "./common"; + +export function tsEnumFromSchema( + schema: SchemaFormEnum, + context: CodegenContext, +): TsProperty { + if (schema.enum.length === 0) + throw new Error( + `Error at ${context.schemaPath}. Enum schemas must have at least one enum value.`, + ); + const enumName = getTsTypeName(schema, context); + const typeName = schema.nullable ? `${enumName} | null` : enumName; + const defaultValue = schema.nullable ? "null" : schema.enum[0]!; + const result: TsProperty = { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if ($$${enumName}.validate(${input})) { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (typeof ${input} === 'string') { + ${target} += \`"\${${input}}"\`; + } else { + ${target} += 'null'; + }`; + } + return `${target} += \`"\${${input}}"\``; + }, + toQueryStringTemplate(input, target, key) { + return `${target}.push(\`${key}=\${${input}}\`)`; + }, + content: "", + }; + if (context.generatedTypes.includes(enumName)) { + return result; + } + const name = `${context.typePrefix}${enumName}`; + const valuesName = `$$${name}Values`; + result.content = `${getJsDocComment(schema.metadata)}export type ${name} = (typeof ${valuesName})[number]; +const ${valuesName} = [${schema.enum.map((val) => `"${val}"`).join(", ")}] as const; +export const $$${name}: ArriEnumValidator<${name}> = { + new(): ${name} { + return ${valuesName}[0]; + }, + validate(input): input is ${enumName} { + return ( + typeof input === 'string' && + ${valuesName}.includes(input as any) + ); + }, + values: ${valuesName}, + fromSerialValue(input): ${name} { + if (${valuesName}.includes(input as any)) { + return input as ${name}; + } + if (${valuesName}.includes(input.toLowerCase() as any) { + return input.toLowerCase() as ${name}; + } + if (${valuesName}.includes(input.toUpperCase() as any) { + return input.toUpperCase() as ${name}; + } + return "${schema.enum[0]}"; + } +} +`; + context.generatedTypes.push(enumName); + return result; +} diff --git a/languages/ts/ts-codegen/src/index.test.ts b/languages/ts/ts-codegen/src/index.test.ts index 954a951f..336a43a8 100644 --- a/languages/ts/ts-codegen/src/index.test.ts +++ b/languages/ts/ts-codegen/src/index.test.ts @@ -1,255 +1,3 @@ -import { - normalizeWhitespace, - type Schema, - type ServiceDefinition, -} from "@arrirpc/codegen-utils"; -import { TestAppDefinition } from "@arrirpc/codegen-utils/dist/testModels"; -import { a } from "@arrirpc/schema"; -import { existsSync, mkdirSync } from "fs"; -import path from "pathe"; -import prettier from "prettier"; +// TODO -import { - createTypescriptClient, - tsServiceFromDefinition, - tsTypeFromJtdSchema, -} from "./index"; - -const tempDir = path.resolve(__dirname, "../.temp"); - -beforeAll(() => { - if (!existsSync(tempDir)) { - mkdirSync(tempDir); - } -}); - -describe("Service Creation", () => { - test("Basic Service", async () => { - const Service: ServiceDefinition = { - getUser: { - transport: "http", - description: "Fetch a user by id", - path: "/get-user", - method: "get", - params: "GetUserParams", - response: "User", - isDeprecated: true, - }, - updateUser: { - transport: "http", - description: "Update a user", - path: "/update-user", - method: "post", - params: "UpdateUserParams", - response: "User", - }, - watchUser: { - transport: "http", - description: "Watch a user", - path: "/watch-user", - method: "get", - params: "GetUserParams", - response: "User", - isEventStream: true, - }, - createConnection: { - transport: "ws", - description: "Create a ws connection to send messages", - path: "/create-connection", - params: "User", - response: "User", - }, - }; - - const result = await prettier.format( - tsServiceFromDefinition("User", Service, { - clientName: "Client", - outputFile: "", - typesNeedingParser: [], - versionNumber: "1", - hasSseProcedures: true, - hasWsProcedures: true, - }), - { parser: "typescript" }, - ); - expect(normalizeWhitespace(result)).toBe( - normalizeWhitespace( - await prettier.format( - `export class UserService { - private readonly baseUrl: string; - private readonly headers: Record | (() => Record | Promise>); - private readonly clientVersion = '1'; - constructor(options: ClientOptions = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; - } - /** - * Fetch a user by id - * @deprecated - */ - getUser(params: GetUserParams) { - return arriRequest({ - url: \`\${this.baseUrl}/get-user\`, - method: "get", - headers: this.headers, - params, - parser: $$User.parse, - serializer: $$GetUserParams.serialize, - clientVersion: this.clientVersion, - }); - } - /** - * Update a user - */ - updateUser(params: UpdateUserParams) { - return arriRequest({ - url: \`\${this.baseUrl}/update-user\`, - method: "post", - headers: this.headers, - params, - parser: $$User.parse, - serializer: $$UpdateUserParams.serialize, - clientVersion: this.clientVersion, - }); - } - /** - * Watch a user - */ - watchUser(params: GetUserParams, options: SseOptions): EventSourceController { - return arriSseRequest({ - url: \`\${this.baseUrl}/watch-user\`, - method: "get", - headers: this.headers, - params, - parser: $$User.parse, - serializer: $$GetUserParams.serialize, - clientVersion: this.clientVersion, - }, options); - } - /** - * Create a ws connection to send messages - */ - createConnection(options: WsOptions = {}) { - return arriWsRequest({ - url: \`\${this.baseUrl}/create-connection\`, - headers: this.headers, - parser: $$User.parse, - serializer: $$User.serialize, - onOpen: options.onOpen, - onClose: options.onClose, - onError: options.onError, - onConnectionError: options.onConnectionError, - onMessage: options.onMessage, - clientVersion: this.clientVersion, - }); - } - }`, - { parser: "typescript" }, - ), - ), - ); - }); -}); - -describe("Model Creation", () => { - test("Basic Object", () => { - const User = a.object( - { - id: a.string(), - name: a.string(), - createdAt: a.timestamp(), - bio: a.optional(a.string()), - numFollowers: a.uint32(), - followedUsers: a.array(a.string(), { - isDeprecated: true, - }), - }, - { id: "User" }, - ); - const result = tsTypeFromJtdSchema( - "", - JSON.parse(JSON.stringify(User)) as Schema, - { - clientName: "TestClient", - outputFile: "", - versionNumber: "", - typesNeedingParser: ["User", "user"], - hasSseProcedures: false, - hasWsProcedures: false, - }, - { existingTypeNames: [], isOptional: false }, - ); - const CompiledValidator = a.compile(User); - expect(normalizeWhitespace(result.content)).toBe( - normalizeWhitespace(`export interface User { - id: string; - name: string; - createdAt: Date; - numFollowers: number; - /** - * @deprecated - */ - followedUsers: Array; - bio?: string; - } - export const $$User = { - parse(input: Record): User { - ${CompiledValidator.compiledCode.parse} - }, - serialize(input: User): string { - ${CompiledValidator.compiledCode.serialize} - } - }`), - ); - }); - test("Partial Object", () => { - const User = a.object( - { - id: a.string(), - name: a.string(), - createdAt: a.timestamp(), - }, - { id: "User" }, - ); - const PartialUser = a.partial(User, { id: "PartialUser" }); - const UserValidator = a.compile(PartialUser); - const result = tsTypeFromJtdSchema( - "", - PartialUser, - { - clientName: "TestClient", - outputFile: "", - versionNumber: "", - typesNeedingParser: ["User", "PartialUser"], - hasSseProcedures: false, - hasWsProcedures: false, - }, - { - existingTypeNames: [], - isOptional: false, - }, - ); - expect(normalizeWhitespace(result.content)).toBe( - normalizeWhitespace(`export interface PartialUser { - id?: string; - name?: string; - createdAt?: Date; - } - export const $$PartialUser = { - parse(input: Record): PartialUser { - ${UserValidator.compiledCode.parse} - }, - serialize(input: PartialUser): string { - ${UserValidator.compiledCode.serialize} - } - }`), - ); - }); -}); - -it("creates a client with valid ts syntax without throwing error", async () => { - await createTypescriptClient(TestAppDefinition, { - clientName: "TestClient", - outputFile: "testClient.rpc.ts", - }); -}); +test(() => {}); diff --git a/languages/ts/ts-codegen/src/index.ts b/languages/ts/ts-codegen/src/index.ts index 2d115360..ad9d7853 100644 --- a/languages/ts/ts-codegen/src/index.ts +++ b/languages/ts/ts-codegen/src/index.ts @@ -1,41 +1,29 @@ import { type AppDefinition, - camelCase, defineGeneratorPlugin, - type HttpRpcDefinition, - isRpcDefinition, - isSchemaFormDiscriminator, - isSchemaFormElements, isSchemaFormEnum, - isSchemaFormProperties, - isSchemaFormRef, isSchemaFormType, - isSchemaFormValues, - isServiceDefinition, - pascalCase, - type RpcDefinition, type Schema, - type SchemaFormDiscriminator, - type SchemaFormElements, - type SchemaFormEnum, - type SchemaFormProperties, - type SchemaFormRef, - type SchemaFormType, - type SchemaFormValues, - type ServiceDefinition, - unflattenProcedures, - type WsRpcDefinition, } from "@arrirpc/codegen-utils"; -import { - getSchemaParsingCode, - getSchemaSerializationCode, -} from "@arrirpc/schema"; import { writeFileSync } from "fs"; import prettier from "prettier"; +import { tsAnyFromSchema } from "./any"; +import { CodegenContext, TsProperty } from "./common"; +import { tsEnumFromSchema } from "./enum"; +import { + tsBigIntFromSchema, + tsBooleanFromSchema, + tsDateFromSchema, + tsFloatFromSchema, + tsIntFromSchema, + tsStringFromSchema, +} from "./primitives"; + export interface TypescriptGeneratorOptions { clientName: string; outputFile: string; + typePrefix?: string; prettierOptions?: Omit; } @@ -63,939 +51,44 @@ export const typescriptClientGenerator = defineGeneratorPlugin( export async function createTypescriptClient( def: AppDefinition, options: TypescriptGeneratorOptions, -): Promise { - const clientName = pascalCase(options.clientName); - const services = unflattenProcedures(def.procedures); - const serviceFieldParts: string[] = []; - const serviceInitializationParts: string[] = []; - const procedureParts: string[] = []; - const subContentParts: string[] = []; - const existingTypeNames: string[] = []; - const rpcOptions: RpcOptions = { - ...options, - versionNumber: def.info?.version ?? "", - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - typesNeedingParser: Object.keys(def.definitions), - hasSseProcedures: false, - hasWsProcedures: false, - }; - Object.keys(services).forEach((key) => { - const item = services[key]; - if (isRpcDefinition(item)) { - const rpc = tsRpcFromDefinition(key, item, rpcOptions); - if (rpc) { - procedureParts.push(rpc); - } - return; - } - if (isServiceDefinition(item)) { - const serviceName: string = pascalCase(`${clientName}_${key}`); - const service = tsServiceFromDefinition( - serviceName, - item, - rpcOptions, - ); - serviceFieldParts.push(`${key}: ${serviceName}Service;`); - serviceInitializationParts.push( - `this.${key} = new ${serviceName}Service(options);`, - ); - subContentParts.push(service); - // todo - } - }); - for (const key of rpcOptions.typesNeedingParser) { - const schema = def.definitions[key]; - if ( - isSchemaFormProperties(schema) || - isSchemaFormDiscriminator(schema) - ) { - const type = tsTypeFromJtdSchema(key, schema, rpcOptions, { - isOptional: false, - existingTypeNames, - }); - subContentParts.push(type.content); - } - } - const importParts: string[] = ["arriRequest"]; - if (rpcOptions.hasSseProcedures) { - importParts.push("arriSseRequest"); - importParts.push("type SseOptions"); - importParts.push("type EventSourceController"); - } - if (rpcOptions.hasWsProcedures) { - importParts.push("arriWsRequest"); - importParts.push("type WsOptions"); - } - - // generated only types if no procedures are found - if (procedureParts.length === 0 && serviceFieldParts.length === 0) { - const result = `/* eslint-disable */ -// @ts-nocheck -// this file was autogenerated by arri-codegen-ts - -${subContentParts.join("\n")}`; - return prettier.format(result, { - parser: "typescript", - ...options.prettierOptions, - }); - } - const result = `/* eslint-disable */ -// @ts-nocheck -// this file was autogenerated by arri-codegen-ts -import { ${importParts.join(", ")} } from '@arrirpc/client'; - -interface ${clientName}Options { - baseUrl?: string; - headers?: Record | (() => Record | Promise>); -} - -export class ${clientName} { - private readonly baseUrl: string; - private readonly headers: Record | (() => Record | Promise>) - private readonly clientVersion = '${rpcOptions.versionNumber}'; - ${serviceFieldParts.join("\n ")} - - constructor(options: ${clientName}Options = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; - ${serviceInitializationParts.join(";\n ")} - } - ${procedureParts.join("\n ")} -} - -${subContentParts.join("\n")} -`; - return await prettier.format(result, { - parser: "typescript", - ...options.prettierOptions, - }); -} - -interface RpcOptions extends TypescriptGeneratorOptions { - versionNumber: string; - typesNeedingParser: string[]; - hasSseProcedures: boolean; - hasWsProcedures: boolean; -} - -export function tsRpcFromDefinition( - key: string, - schema: RpcDefinition, - options: RpcOptions, -): string { - if (schema.transport === "http") { - return tsHttpRpcFromDefinition(key, schema, options); - } - if (schema.transport === "ws") { - return tsWsRpcFromDefinition(key, schema, options); - } - console.warn( - `[codegen-ts] Unsupported transport "${schema.transport}". Ignoring rpc.`, - ); - return ""; -} - -export function tsHttpRpcFromDefinition( - key: string, - schema: HttpRpcDefinition, - options: RpcOptions, -) { - const paramName = pascalCase(schema.params ?? ""); - const responseName = pascalCase(schema.response ?? ""); - const paramsInput = schema.params ? `params: ${paramName}` : ""; - const hasInput = paramName.length > 0; - const hasOutput = responseName.length > 0; - let serializerPart = `(_) => {}`; - let parserPart = `(_) => {}`; - if (hasInput) { - serializerPart = `$$${paramName}.serialize`; - } - if (hasOutput) { - parserPart = `$$${responseName}.parse`; - } - const paramsOutput = hasInput ? `params` : `params: undefined`; - if (schema.isEventStream) { - options.hasSseProcedures = true; - return `${getJsDocComment({ isDeprecated: schema.isDeprecated, description: schema.description })}${key}(${ - paramsInput.length ? `${paramsInput}, ` : "" - }options: SseOptions<${schema.response ?? "undefined"}>): EventSourceController { - return arriSseRequest<${schema.response ?? "undefined"}, ${ - schema.params ?? "undefined" - }>({ - url: \`\${this.baseUrl}${schema.path}\`, - method: "${schema.method}", - headers: this.headers, - ${paramsOutput}, - parser: ${parserPart}, - serializer: ${serializerPart}, - clientVersion: this.clientVersion, - }, options); - }`; - } - return `${getJsDocComment({ isDeprecated: schema.isDeprecated, description: schema.description })}${key}(${paramsInput}) { - return arriRequest<${schema.response ?? "undefined"}, ${ - schema.params ?? "undefined" - }>({ - url: \`\${this.baseUrl}${schema.path}\`, - method: "${schema.method}", - headers: this.headers, - ${paramsOutput}, - parser: ${parserPart}, - serializer: ${serializerPart}, - clientVersion: this.clientVersion, - }); - }`; -} -export function tsWsRpcFromDefinition( - key: string, - schema: WsRpcDefinition, - options: RpcOptions, -): string { - options.hasWsProcedures = true; - const paramName = schema.params ? pascalCase(schema.params) : "undefined"; - const responseName = schema.response - ? pascalCase(schema.response) - : "undefined"; - const hasInput = paramName.length > 0 && paramName !== "undefined"; - const hasOutput = responseName.length > 0 && paramName !== "undefined"; - let serializerPart = `(_) => {}`; - let parserPart = `(_) => {}`; - if (hasInput) { - serializerPart = `$$${paramName}.serialize`; - } - if (hasOutput) { - parserPart = `$$${responseName}.parse`; - } - return `${getJsDocComment(schema)}${key}(options: WsOptions<${responseName}> = {}) { - return arriWsRequest<${paramName}, ${responseName}>({ - url: \`\${this.baseUrl}${schema.path}\`, - headers: this.headers, - parser: ${parserPart}, - serializer: ${serializerPart}, - onOpen: options.onOpen, - onClose: options.onClose, - onError: options.onError, - onConnectionError: options.onConnectionError, - onMessage: options.onMessage, - clientVersion: this.clientVersion, - }) - }`; -} - -export function tsServiceFromDefinition( - name: string, - schema: ServiceDefinition, - options: RpcOptions, -): string { - const serviceFieldParts: string[] = []; - const serviceInitParts: string[] = []; - const serviceConstructorParts: string[] = []; - const subServiceContent: string[] = []; - const rpcContent: string[] = []; - - Object.keys(schema).forEach((key) => { - const def = schema[key]; - if (isRpcDefinition(def)) { - const rpc = tsRpcFromDefinition(key, def, options); - if (rpc) { - rpcContent.push(rpc); - } - return; - } - if (isServiceDefinition(def)) { - const serviceName: string = pascalCase(`${name}_${key}`); - const service = tsServiceFromDefinition(serviceName, def, options); - serviceFieldParts.push(`${key}: ${serviceName}Service;`); - serviceInitParts.push(`this.${key}.initClient(options);`); +): Promise {} - serviceConstructorParts.push( - `this.${key} = new ${serviceName}Service(options);`, - ); - subServiceContent.push(service); - } - }); - - return `export class ${name}Service { - private readonly baseUrl: string; - private readonly headers: Record | (() => Record | Promise>); - private readonly clientVersion = '${options.versionNumber}'; - ${serviceFieldParts.join("\n ")} - - constructor(options: ${pascalCase( - `${options.clientName}_Options`, - )} = {}) { - this.baseUrl = options.baseUrl ?? ''; - this.headers = options.headers ?? {}; - ${serviceConstructorParts.join("\n ")} - } - ${rpcContent.join("\n ")} - } - ${subServiceContent.join("\n")}`; -} - -interface AdditionalOptions { - isOptional: boolean; - existingTypeNames: string[]; - logDef?: boolean; -} - -interface TsProperty { - tsType: string; - schema: Schema; - fieldTemplate: string; - fromJsonTemplate: (input: string) => string; - toJsonTemplate: (input: string) => string; - content: string; -} - -export function tsTypeFromJtdSchema( - nodePath: string, - def: Schema, - options: RpcOptions, - additionalOptions: AdditionalOptions, +export function tsTypeFromSchema( + schema: Schema, + context: CodegenContext, ): TsProperty { - if (additionalOptions.logDef) { - console.log(def); - } - if (isSchemaFormType(def)) { - return tsScalarFromJtdSchema(nodePath, def, options, additionalOptions); - } - if (isSchemaFormProperties(def)) { - return tsObjectFromJtdSchema(nodePath, def, options, additionalOptions); - } - if (isSchemaFormEnum(def)) { - return tsEnumFromJtdSchema(nodePath, def, options, additionalOptions); - } - if (isSchemaFormElements(def)) { - return tsArrayFromJtdSchema(nodePath, def, options, additionalOptions); - } - if (isSchemaFormDiscriminator(def)) { - return tsDiscriminatedUnionFromJtdSchema( - nodePath, - def, - options, - additionalOptions, - ); - } - if (isSchemaFormValues(def)) { - return tsRecordFromJtdSchema(nodePath, def, options, additionalOptions); - } - if (isSchemaFormRef(def)) { - return tsRefFromJtdSchema(nodePath, def, options, additionalOptions); - } - - return tsAnyFromJtdSchema(nodePath, def, options, additionalOptions); -} - -export function maybeOptionalKey(keyName: string, isOptional = false) { - if (isOptional) { - return `${keyName}?`; - } - return keyName; -} - -export function maybeNullType(typeName: string, isNullable = false) { - if (isNullable) { - return `${typeName} | null`; - } - return typeName; -} - -export function tsAnyFromJtdSchema( - nodePath: string, - def: Schema, - options: TypescriptGeneratorOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const isNullable = def.nullable ?? false; - const isOptional = additionalOptions.isOptional; - return { - tsType: "any", - schema: def, - fieldTemplate: `${maybeOptionalKey(key, isOptional)}: ${maybeNullType( - "any", - isNullable, - )}`, - fromJsonTemplate(input) { - return input; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content: "", - }; -} - -export function getJsDocComment(metadata: Schema["metadata"]) { - const descriptionParts: string[] = []; - - if (metadata?.description?.length) { - const parts = metadata.description.split("\n"); - for (const part of parts) { - descriptionParts.push(`* ${part}`); + if (isSchemaFormType(schema)) { + switch (schema.type) { + case "string": + return tsStringFromSchema(schema, context); + case "boolean": + return tsBooleanFromSchema(schema, context); + case "timestamp": + return tsDateFromSchema(schema, context); + case "float32": + case "float64": + return tsFloatFromSchema(schema, context); + case "int8": + return tsIntFromSchema(schema, "int8", context); + case "uint8": + return tsIntFromSchema(schema, "uint8", context); + case "int16": + return tsIntFromSchema(schema, "int16", context); + case "uint16": + return tsIntFromSchema(schema, "uint16", context); + case "int32": + return tsIntFromSchema(schema, "int32", context); + case "uint32": + return tsIntFromSchema(schema, "uint32", context); + case "int64": + return tsBigIntFromSchema(schema, false, context); + case "uint64": + return tsBigIntFromSchema(schema, true, context); } } - if (metadata?.isDeprecated) { - descriptionParts.push("* @deprecated"); + if (isSchemaFormEnum(schema)) { + return tsEnumFromSchema(schema, context); } - if (descriptionParts.length === 0) { - return ""; - } - return `/** -${descriptionParts.join("\n")} -*/\n`; -} -export function tsScalarFromJtdSchema( - nodePath: string, - def: SchemaFormType, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const isNullable = def.nullable ?? false; - const isOptional = additionalOptions.isOptional; - switch (def.type) { - case "boolean": - return { - tsType: "boolean", - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - isOptional, - )}: ${maybeNullType("boolean", isNullable)}`, - fromJsonTemplate(input) { - if (isOptional) { - return `typeof ${input} === 'boolean' ? ${input} : undefined`; - } - if (isNullable) { - return `typeof ${input} === 'boolean' ? ${input} : null`; - } - return `typeof ${input} === 'boolean' ? ${input} : false`; - }, - toJsonTemplate(input) { - if (isNullable) { - return `typeof ${input} === 'boolean' ? ${input} : null`; - } - return `typeof ${input} === 'boolean' ? ${input} : false`; - }, - content: "", - }; - case "string": - return { - tsType: "string", - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - isOptional, - )}: ${maybeNullType("string", isNullable)}`, - fromJsonTemplate(input) { - if (isOptional) { - return `typeof ${input} === 'string' ? ${input} : undefined`; - } - if (isNullable) { - return `typeof ${input} === 'string' ? ${input} : null`; - } - return `typeof ${input} === 'string' ? ${input} : ''`; - }, - toJsonTemplate(input) { - if (isNullable) { - return `typeof ${input} === 'string' ? \`"${input}"\` : null`; - } - return `typeof ${input} === 'string' ? \`"${input}"\` : ""`; - }, - content: "", - }; - case "timestamp": - return { - tsType: "Date", - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - isOptional, - )}: ${maybeNullType("Date", isNullable)}`, - fromJsonTemplate(input) { - if (isOptional) { - return `typeof ${input} === 'string' ? new Date(${input}) : undefined`; - } - if (isNullable) { - return `typeof ${input} === 'string' ? new Date(${input}) : null`; - } - return `typeof ${input} === 'string' ? new Date(${input}) : new Date(0)`; - }, - toJsonTemplate(input) { - if (isOptional || isNullable) { - return `typeof ${input} === 'object' && ${input} instanceof Date ? "${input}.toISOString()" : null`; - } - return `"${input}.toISOString()"`; - }, - content: "", - }; - case "float32": - case "float64": - case "int8": - case "int16": - case "int32": - case "uint8": - case "uint16": - case "uint32": - return { - tsType: "number", - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - isOptional, - )}: ${maybeNullType("number", isNullable)}`, - fromJsonTemplate(input) { - if (isOptional) { - return `typeof ${input} === 'number' ? ${input} : undefined`; - } - if (isNullable) { - return `typeof ${input} === 'number' ? ${input} : null`; - } - return `typeof ${input} === 'number' ? ${input} : 0`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content: "", - }; - case "int64": - case "uint64": - return { - tsType: "bigint", - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - isOptional, - )}: ${maybeNullType("bigint", isNullable)}`, - fromJsonTemplate(input) { - if (isOptional) { - return `typeof ${input} === 'string' ? BigInt(${input}) : undefined`; - } - if (isNullable) { - return `typeof ${input} === 'string' ? BigInt(${input}) : null`; - } - return `typeof ${input} === 'string' ? BigInt(${input}) : BigInt("0")`; - }, - toJsonTemplate(input) { - if (isOptional || isNullable) { - return `${input}?.toString()`; - } - return `${input}.toString()`; - }, - content: "", - }; - default: - def.type satisfies never; - throw new Error(`Invalid type in SchemaFormType`); - } -} - -function getTypeName(nodePath: string, def: Schema) { - if (def.metadata?.id) { - return pascalCase(def.metadata.id); - } - return pascalCase(nodePath.split(".").join("_")); -} - -export function tsObjectFromJtdSchema( - nodePath: string, - def: SchemaFormProperties, - options: RpcOptions, - additionalOptions: AdditionalOptions & { - discriminatorKey?: string; - discriminatorKeyValue?: string; - }, -): TsProperty { - const typeName = getTypeName(nodePath, def); - const key = nodePath.split(".").pop() ?? ""; - const fieldNames: string[] = []; - const fieldParts: string[] = []; - const subContentParts: string[] = []; - const parserParts: string[] = []; - if ( - additionalOptions.discriminatorKey && - additionalOptions.discriminatorKeyValue - ) { - parserParts.push( - `${additionalOptions.discriminatorKey}: '${additionalOptions.discriminatorKeyValue}'`, - ); - fieldParts.push( - `${additionalOptions.discriminatorKey}: "${additionalOptions.discriminatorKeyValue}"`, - ); - fieldNames.push(additionalOptions.discriminatorKey); - } - if (def.properties) { - for (const propKey of Object.keys(def.properties)) { - const propSchema = def.properties[propKey]!; - const type = tsTypeFromJtdSchema( - `${nodePath}.${propKey}`, - propSchema, - options, - { - isOptional: false, - existingTypeNames: additionalOptions.existingTypeNames, - }, - ); - parserParts.push( - `${propKey}: ${type.fromJsonTemplate(`input.${propKey}`)}`, - ); - fieldParts.push(type.fieldTemplate); - fieldNames.push(propKey); - if (type.content) { - subContentParts.push(type.content); - } - } - } - if (def.optionalProperties) { - for (const propKey of Object.keys(def.optionalProperties)) { - const propSchema = def.optionalProperties[propKey]!; - const type = tsTypeFromJtdSchema( - `${nodePath}.${propKey}`, - propSchema, - options, - { - isOptional: true, - existingTypeNames: additionalOptions.existingTypeNames, - }, - ); - parserParts.push( - `${propKey}: ${type.fromJsonTemplate(`input.${propKey}`)}`, - ); - fieldParts.push(type.fieldTemplate); - fieldNames.push(propKey); - if (type.content) { - subContentParts.push(type.content); - } - } - } - let content = ""; - const modifiedDef = { - ...def, - metadata: { - id: def.metadata?.id ?? typeName, - description: def.metadata?.description, - }, - nullable: false, - } satisfies Schema; - let validatorPart = ""; - if (options.typesNeedingParser.includes(typeName)) { - const parsingCode = getSchemaParsingCode("input", modifiedDef); - const serializationCode = getSchemaSerializationCode( - "input", - modifiedDef, - ); - validatorPart = `export const $$${typeName} = { - parse(input: Record): ${typeName} { - ${parsingCode} - }, - serialize(input: ${typeName}): string { - ${serializationCode} - } - }`; - } - if (!additionalOptions.existingTypeNames.includes(typeName)) { - content = `${getJsDocComment(def.metadata)}export interface ${typeName} { - ${fieldParts.join(";\n ")}; - } - ${validatorPart} - ${subContentParts.join("\n")}`; - additionalOptions.existingTypeNames.push(typeName); - } - return { - tsType: typeName, - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - additionalOptions.isOptional, - )}: ${maybeNullType(typeName, def.nullable ?? false)}`, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : undefined`; - } - if (def.nullable) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : null`; - } - return `$$${typeName}.parse(${input})`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content, - }; -} - -export function tsEnumFromJtdSchema( - nodePath: string, - def: SchemaFormEnum, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const keyName = nodePath.split(".").pop() ?? ""; - const typeName = getTypeName(nodePath, def); - let content = `${getJsDocComment(def.metadata)}export type ${typeName} = ${def.enum - .map((val) => `"${val}"`) - .join(" | ")}`; - if (additionalOptions.existingTypeNames.includes(typeName)) { - content = ""; - } else { - additionalOptions.existingTypeNames.push(typeName); - } - return { - tsType: typeName, - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - keyName, - additionalOptions.isOptional, - )}: ${maybeNullType(typeName, def.nullable ?? false)}`, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'string' ? $$${typeName}.parse(${input}) : undefined`; - } - if (def.nullable) { - return `typeof ${input} === 'string' ? $$${typeName}.parse(${input}) : null`; - } - return `$$${typeName}.parse(${input})`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content, - }; -} - -export function tsArrayFromJtdSchema( - nodePath: string, - def: SchemaFormElements, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const subType = tsTypeFromJtdSchema( - `${nodePath}.item`, - def.elements, - options, - { - isOptional: false, - existingTypeNames: additionalOptions.existingTypeNames, - }, - ); - const tsType = `Array<${maybeNullType( - subType.tsType, - def.elements.nullable, - )}>`; - return { - tsType, - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - additionalOptions.isOptional ?? false, - )}: ${maybeNullType(tsType, def.nullable ?? false)}`, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `Array.isArray(${input}) ? ${input}.map((item) => ${subType.fromJsonTemplate( - "item", - )}) : undefined`; - } - if (def.nullable) { - return `Array.isArray(${input}) ? ${input}.map((item) => ${subType.fromJsonTemplate( - "item", - )}) : null`; - } - return `Array.isArray(${input}) ? ${input}.map((item) => ${subType.fromJsonTemplate( - "item", - )}) : []`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content: subType.content, - }; -} - -export function tsDiscriminatedUnionFromJtdSchema( - nodePath: string, - def: SchemaFormDiscriminator, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const typeName = getTypeName(nodePath, def); - const subTypeNames: string[] = []; - const subContentParts: string[] = []; - const parserParts: string[] = []; - for (const val of Object.keys(def.mapping)) { - const optionSchema = def.mapping[val]; - if (!isSchemaFormProperties(optionSchema)) { - continue; - } - const optionType = tsObjectFromJtdSchema( - `${nodePath}.${camelCase(val.toLowerCase())}`, - optionSchema, - options, - { - discriminatorKey: def.discriminator, - discriminatorKeyValue: val, - isOptional: false, - existingTypeNames: additionalOptions.existingTypeNames, - }, - ); - parserParts.push(`case '${val}': - return $$${optionType.tsType}.parse(input);`); - subTypeNames.push(optionType.tsType); - subContentParts.push(optionType.content); - } - let validatorPart = ""; - if (options.typesNeedingParser.includes(typeName)) { - const modifiedDef = { ...def, nullable: false }; - const parsingCode = getSchemaParsingCode( - "input", - modifiedDef as Schema, - ); - const serializationCode = getSchemaSerializationCode( - "input", - modifiedDef, - ); - validatorPart = `export const $$${typeName} = { - parse(input: Record): ${typeName} { - ${parsingCode} - }, - serialize(input: ${typeName}): string { - ${serializationCode} - } -}`; - } - let content = `${getJsDocComment(def.metadata)}export type ${typeName} = ${subTypeNames.join(" | ")}; -${validatorPart} - ${subContentParts.join("\n")}`; - if (additionalOptions.existingTypeNames.includes(typeName)) { - content = ""; - } else { - additionalOptions.existingTypeNames.push(typeName); - } - return { - tsType: typeName, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - additionalOptions.isOptional, - )}: ${maybeNullType(typeName, def.nullable)}`, - schema: def, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : undefined`; - } - if (def.nullable) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : null`; - } - return `$$${typeName}.parse(${input})`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content, - }; -} - -export function tsRecordFromJtdSchema( - nodePath: string, - def: SchemaFormValues, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const typeName = getTypeName(nodePath, def); - const subType = tsTypeFromJtdSchema( - `${nodePath}.value`, - def.values, - options, - { - isOptional: false, - existingTypeNames: additionalOptions.existingTypeNames, - }, - ); - let content = ""; - if (!additionalOptions.existingTypeNames.includes(typeName)) { - let validatorPart = ""; - if (options.typesNeedingParser.includes(typeName)) { - const modifiedDef = { ...def, nullable: false }; - const parsingCode = getSchemaParsingCode( - "input", - modifiedDef as Schema, - ); - const serializationCode = getSchemaSerializationCode( - "input", - modifiedDef as Schema, - ); - validatorPart = `export const $$${typeName} = { - parse(input: Record): ${typeName} { - ${parsingCode} - }, - serialize(input: ${typeName}): string { - ${serializationCode} - } -}`; - } - content = `${getJsDocComment(def.metadata)}export type ${typeName} = Record; -${validatorPart} -${subType.content}`; - } - return { - tsType: typeName, - schema: def, - fieldTemplate: `${getJsDocComment(def.metadata)}${maybeOptionalKey( - key, - additionalOptions.isOptional, - )}: ${maybeNullType(typeName, def.nullable)}`, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : undefined`; - } - if (def.nullable) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : null`; - } - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : {}`; - }, - toJsonTemplate(input) { - return `JSON.stringify(${input})`; - }, - content, - }; -} - -export function tsRefFromJtdSchema( - nodePath: string, - def: SchemaFormRef, - options: RpcOptions, - additionalOptions: AdditionalOptions, -): TsProperty { - const key = nodePath.split(".").pop() ?? ""; - const typeName = pascalCase(def.ref, { - normalize: true, - }); - return { - tsType: typeName, - schema: def, - fieldTemplate: `${maybeOptionalKey(key, additionalOptions.isOptional)}: ${maybeNullType(typeName, def.nullable)}`, - fromJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : undefined`; - } - if (def.nullable) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : null`; - } - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.parse(${input}) : {}`; - }, - toJsonTemplate(input) { - if (additionalOptions.isOptional) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.serialize(${input}) : 'undefined'`; - } - if (def.nullable) { - return `typeof ${input} === 'object' && ${input} !== null ? $$${typeName}.serialize(${input}) : 'null'`; - } - return `$$${typeName}.serialize(${input})`; - }, - content: "", - }; + return tsAnyFromSchema(schema, context); } diff --git a/languages/ts/ts-codegen/src/primitives.ts b/languages/ts/ts-codegen/src/primitives.ts new file mode 100644 index 00000000..5a002c04 --- /dev/null +++ b/languages/ts/ts-codegen/src/primitives.ts @@ -0,0 +1,251 @@ +import { SchemaFormType } from "@arrirpc/codegen-utils"; + +import { CodegenContext, TsProperty } from "./common"; + +export function tsStringFromSchema( + schema: SchemaFormType, + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? "string | null" : "string"; + const defaultValue = schema.nullable ? "null" : '""'; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if (typeof ${input} === 'string') { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (typeof ${input} === 'string') { + ${target} += serializeString(${input}); + } else { + ${target} += 'null'; + }`; + } + return `${target} += serializeString(${input});`; + }, + toQueryStringTemplate(input, target, key) { + return `${target}.push(\`${key}=\${${input}}\`);`; + }, + content: "", + }; +} + +export function tsBooleanFromSchema( + schema: SchemaFormType, + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? `boolean | null` : "boolean"; + const defaultValue = schema.nullable ? `null` : "false"; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if (typeof ${input} === 'boolean') { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (typeof ${input} === 'boolean') { + ${target} += ${input}.toString(); + } else { + ${target} += 'null'; + }`; + } + return `${target} += ${input}.toString()`; + }, + toQueryStringTemplate(input, target, key) { + return `${target}.push(\`${key}=\${${input}}\`)`; + }, + content: "", + }; +} + +export function tsDateFromSchema( + schema: SchemaFormType, + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? `Date | null` : "Date"; + const defaultValue = schema.nullable ? `null` : "new Date()"; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if (typeof ${input} === 'string') { + ${target} = new Date(${input}); + } else if (${input} instanceof Date) { + ${target} = ${input}; + } else { + ${target} = ${defaultValue} + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (${input} instanceof Date) { + ${target} += \`"\${${input}.toISOString()}"\` + } else { + ${target} += 'null'; + }`; + } + return `${target} += \`"\${${input}.toISOString()}"\``; + }, + toQueryStringTemplate(input, target, key) { + if (schema.nullable) { + return `${target}.push(\`${key}=\${${input}?.toISOString()}\`)`; + } + return `${target}.push(\`${key}=\${${input}.toISOString()}\`)`; + }, + content: "", + }; +} + +export function tsFloatFromSchema( + schema: SchemaFormType, + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? "number | null" : "number"; + const defaultValue = schema.nullable ? "null" : "0"; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if (typeof ${input} === 'number') { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (typeof ${input} === 'number') { + ${target} += ${input}.toString(); + } else { + ${target} += 'null'; + }`; + } + return `${target} += ${input}.toString()`; + }, + toQueryStringTemplate(input, target, key) { + return `${target}.push(\`${key}=\${${input}}\`)`; + }, + content: "", + }; +} + +export function tsIntFromSchema( + schema: SchemaFormType, + intType: "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32", + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? "number | null" : "number"; + const defaultValue = schema.nullable ? "null" : "0"; + let min: string; + let max: string; + switch (intType) { + case "int8": + min = "INT8_MIN"; + max = "INT8_MAX"; + break; + case "uint8": + min = "0"; + max = "UINT8_MAX"; + break; + case "int16": + min = "INT16_MIN"; + max = "INT16_MAX"; + break; + case "uint16": + min = "0"; + max = "UINT16_MAX"; + break; + case "int32": + min = "INT32_MIN"; + max = "INT32_MAX"; + break; + case "uint32": + min = "0"; + max = "UINT32_MAX"; + break; + default: + intType satisfies never; + break; + } + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + return `if ( + typeof ${input} === 'number' && + Number.isInteger(${input}) && + ${input} >= ${min} && + ${input} <= ${max} + ) { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + return `${target} += \`\${${input}}\``; + }, + toQueryStringTemplate(input, target, key) { + return `${target}.push(\`${key}=\${${input}}\`)`; + }, + content: "", + }; +} + +export function tsBigIntFromSchema( + schema: SchemaFormType, + isUnsigned: boolean, + _context: CodegenContext, +): TsProperty { + const typeName = schema.nullable ? `bigint | null` : `bigint`; + const defaultValue = schema.nullable ? `null` : "BigInt(0)"; + return { + typeName, + defaultValue, + fromJsonTemplate(input, target) { + if (isUnsigned) { + return `if (typeof ${input} === 'string' && BigInt(${input}) >= BigInt(0)) { + ${target} = BigInt(${input}); + } else if (typeof ${input} === 'bigint' && ${input} >= BigInt(0)) { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + } + return `if (typeof ${input} === 'string') { + ${target} = BigInt(${input}); + } else if (typeof ${input} === 'bigint') { + ${target} = ${input}; + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (typeof ${input} === 'bigint') { + ${target} += \`"\${${input}.toString()}"\` + } else { + ${target} += 'null'; + }`; + } + return `${target} += \`"\${${input}.toString()}"\``; + }, + toQueryStringTemplate(input, target, key) { + if (schema.nullable) { + return `${target}.push(\`${key}=\${${input}?.toString()}\`)`; + } + return `${target}.push(\`${key}=\${${input}.toString()}\`)`; + }, + content: "", + }; +} From 6b344ffbc598cd20c85976d30d61da475a5005ba Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sun, 21 Jul 2024 19:02:09 -0500 Subject: [PATCH 07/18] progress on object generation --- languages/ts/ts-codegen/src/any.ts | 5 +- languages/ts/ts-codegen/src/common.ts | 1 + languages/ts/ts-codegen/src/enum.ts | 8 +- languages/ts/ts-codegen/src/index.test.ts | 28 +++- languages/ts/ts-codegen/src/index.ts | 48 ++++++- languages/ts/ts-codegen/src/object.ts | 160 ++++++++++++++++++++++ languages/ts/ts-codegen/src/primitives.ts | 41 ++++++ 7 files changed, 286 insertions(+), 5 deletions(-) create mode 100644 languages/ts/ts-codegen/src/object.ts diff --git a/languages/ts/ts-codegen/src/any.ts b/languages/ts/ts-codegen/src/any.ts index bd1096c0..6bc34051 100644 --- a/languages/ts/ts-codegen/src/any.ts +++ b/languages/ts/ts-codegen/src/any.ts @@ -3,7 +3,7 @@ import { Schema } from "@arrirpc/codegen-utils"; import { CodegenContext, TsProperty } from "./common"; export function tsAnyFromSchema( - schema: Schema, + _schema: Schema, context: CodegenContext, ): TsProperty { const typeName = "any"; @@ -11,6 +11,9 @@ export function tsAnyFromSchema( return { typeName, defaultValue, + validationTemplate(_) { + return ""; + }, fromJsonTemplate(input, target) { return `${input} = ${target}`; }, diff --git a/languages/ts/ts-codegen/src/common.ts b/languages/ts/ts-codegen/src/common.ts index 3ec5ba14..84010ff2 100644 --- a/languages/ts/ts-codegen/src/common.ts +++ b/languages/ts/ts-codegen/src/common.ts @@ -8,6 +8,7 @@ import { export interface TsProperty { typeName: string; defaultValue: string; + validationTemplate: (input: string) => string; fromJsonTemplate: (input: string, target: string) => string; toJsonTemplate: (input: string, target: string) => string; toQueryStringTemplate: ( diff --git a/languages/ts/ts-codegen/src/enum.ts b/languages/ts/ts-codegen/src/enum.ts index 58e050dd..9e6d41bc 100644 --- a/languages/ts/ts-codegen/src/enum.ts +++ b/languages/ts/ts-codegen/src/enum.ts @@ -17,10 +17,16 @@ export function tsEnumFromSchema( ); const enumName = getTsTypeName(schema, context); const typeName = schema.nullable ? `${enumName} | null` : enumName; - const defaultValue = schema.nullable ? "null" : schema.enum[0]!; + const defaultValue = schema.nullable ? "null" : `"${schema.enum[0]!}"`; const result: TsProperty = { typeName, defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `($$${enumName}Values.includes(${input} as any) || ${input} === null)`; + } + return `$$${enumName}Values.includes(${input} as any)`; + }, fromJsonTemplate(input, target) { return `if ($$${enumName}.validate(${input})) { ${target} = ${input}; diff --git a/languages/ts/ts-codegen/src/index.test.ts b/languages/ts/ts-codegen/src/index.test.ts index 336a43a8..404eba26 100644 --- a/languages/ts/ts-codegen/src/index.test.ts +++ b/languages/ts/ts-codegen/src/index.test.ts @@ -1,3 +1,29 @@ // TODO -test(() => {}); +import { AppDefinition, normalizeWhitespace } from "@arrirpc/codegen-utils"; +import fs from "fs"; +import path from "path"; + +import { createTypescriptClient } from "./index"; + +const testDir = path.resolve(__dirname, "../../../../tests/test-files"); +const appDef = JSON.parse( + fs.readFileSync(path.resolve(testDir, "AppDefinition.json"), "utf8"), +) as AppDefinition; +const referenceFile = fs.readFileSync( + path.resolve( + __dirname, + "../../ts-codegen-reference/src/referenceClient.ts", + ), + "utf8", +); +test("Output matches reference file", async () => { + const result = await createTypescriptClient(appDef, { + clientName: "ExampleClient", + outputFile: "", + }); + fs.writeFileSync("blah.ts", result); + expect(normalizeWhitespace(result)).toEqual( + normalizeWhitespace(referenceFile), + ); +}); diff --git a/languages/ts/ts-codegen/src/index.ts b/languages/ts/ts-codegen/src/index.ts index ad9d7853..a46a70eb 100644 --- a/languages/ts/ts-codegen/src/index.ts +++ b/languages/ts/ts-codegen/src/index.ts @@ -2,6 +2,7 @@ import { type AppDefinition, defineGeneratorPlugin, isSchemaFormEnum, + isSchemaFormProperties, isSchemaFormType, type Schema, } from "@arrirpc/codegen-utils"; @@ -11,6 +12,7 @@ import prettier from "prettier"; import { tsAnyFromSchema } from "./any"; import { CodegenContext, TsProperty } from "./common"; import { tsEnumFromSchema } from "./enum"; +import { tsObjectFromSchema } from "./object"; import { tsBigIntFromSchema, tsBooleanFromSchema, @@ -51,7 +53,47 @@ export const typescriptClientGenerator = defineGeneratorPlugin( export async function createTypescriptClient( def: AppDefinition, options: TypescriptGeneratorOptions, -): Promise {} +): Promise { + const types: string[] = []; + const context: CodegenContext = { + clientName: options.clientName, + typePrefix: options.typePrefix ?? "", + generatedTypes: [], + instancePath: "", + schemaPath: "", + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: def.info?.version ?? "", + hasSseProcedure: false, + hasWsProcedure: false, + }; + for (const key of Object.keys(def.definitions)) { + const typeDef = def.definitions[key]!; + const result = tsTypeFromSchema(typeDef, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `/${key}`, + schemaPath: `/${key}`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + if (result.content) { + types.push(result.content); + } + } + + const result = `${types.join("\n")}`; + return await prettier.format(result, { + ...options.prettierOptions, + parser: "typescript", + }); +} export function tsTypeFromSchema( schema: Schema, @@ -89,6 +131,8 @@ export function tsTypeFromSchema( if (isSchemaFormEnum(schema)) { return tsEnumFromSchema(schema, context); } - + if (isSchemaFormProperties(schema)) { + return tsObjectFromSchema(schema, context); + } return tsAnyFromSchema(schema, context); } diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts new file mode 100644 index 00000000..054a7f89 --- /dev/null +++ b/languages/ts/ts-codegen/src/object.ts @@ -0,0 +1,160 @@ +import { camelCase, SchemaFormProperties } from "@arrirpc/codegen-utils"; + +import { tsTypeFromSchema } from "."; +import { + CodegenContext, + getJsDocComment, + getTsTypeName, + TsProperty, + validVarName, +} from "./common"; + +export function tsObjectFromSchema( + schema: SchemaFormProperties, + context: CodegenContext, +): TsProperty { + const typeName = getTsTypeName(schema, context); + const defaultValue = schema.nullable ? "null" : `$$${typeName}.new()`; + const result: TsProperty = { + typeName: schema.nullable + ? `${context.typePrefix}${typeName} | null` + : `${context.typePrefix}${typeName}`, + defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `($$${typeName}.validate(${input}) || ${input} === null)`; + } + return `$$${typeName}.validate(${input})`; + }, + fromJsonTemplate(input, target) { + return `if (isObject(${input})) { + ${target} = $$${context.typePrefix}${typeName}.fromJson(${input}); + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (${input} == null) { + ${target} += 'null'; + } else { + ${target} += $$${context.typePrefix}${typeName}.toJsonString(${input}); + }`; + } + return `${target} += $$${context.typePrefix}${typeName}.toJsonString(${input});`; + }, + toQueryStringTemplate(_input, _target) { + return `console.warn("[WARNING] Nested objects cannot be serialized to query string. Skipping property at ${context.instancePath}.")`; + }, + content: "", + }; + if (context.generatedTypes.includes(typeName)) { + return result; + } + const newParts: string[] = []; + const fieldParts: string[] = []; + const fromJsonParts: string[] = []; + const constructionParts: string[] = []; + const toJsonParts: string[] = []; + const toQueryParts: string[] = []; + const validationParts: string[] = ["isObject(input)"]; + const subContentParts: string[] = []; + let hasKey = false; + if ( + context.discriminatorParent && + context.discriminatorValue && + context.discriminatorKey + ) { + const key = validVarName(camelCase(context.discriminatorKey)); + fieldParts.push(`${key}: "${context.discriminatorValue}",`); + fromJsonParts.push(`let _${key} = "${context.discriminatorValue}"`); + toJsonParts.push( + `json += \`"${key}":"${context.discriminatorValue}"\``, + ); + toQueryParts.push( + `queryParts.push(\`${context.discriminatorKey}=${context.discriminatorValue}\`);`, + ); + validationParts.push( + `input.${key} === '${context.discriminatorValue}'`, + ); + newParts.push(`${key}: "${context.discriminatorValue}",`); + constructionParts.push(`${key}: _${key},`); + } + for (const key of Object.keys(schema.properties)) { + const subSchema = schema.properties[key]!; + const prop = tsTypeFromSchema(subSchema, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `${context.instancePath}/${key}`, + schemaPath: `${context.schemaPath}/properties/${key}`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + if (prop.content) subContentParts.push(prop.content); + const fieldName = validVarName(camelCase(key)); + fieldParts.push(`${fieldName}: ${prop.typeName},`); + newParts.push(`${fieldName}: ${prop.defaultValue},`); + const tempKey = `_${validVarName(key)}`; + fromJsonParts.push(`let ${tempKey}: ${prop.typeName};`); + fromJsonParts.push(prop.fromJsonTemplate(`input.${key}`, tempKey)); + if (hasKey) { + toJsonParts.push(`json += ',"${key}":';`); + } else { + toJsonParts.push(`json += '"${key}":';`); + } + toJsonParts.push(prop.toJsonTemplate(`input.${fieldName}`, "json")); + toQueryParts.push( + prop.toQueryStringTemplate(`queryParts`, `input.${fieldName}`, key), + ); + const validationPart = prop.validationTemplate(`input.${fieldName}`); + if (validationPart) validationParts.push(validationPart); + constructionParts.push(`${fieldName}: ${tempKey},`); + hasKey = true; + } + const prefixedTypeName = `${context.typePrefix}${typeName}`; + + result.content = `${getJsDocComment(schema.metadata)}export interface ${prefixedTypeName} { +${fieldParts.map((part) => ` ${part}`).join("\n")} +} +export const $$${prefixedTypeName}: ArriModelValidator<${prefixedTypeName}> = { + new(): ${prefixedTypeName} { + return { +${newParts.map((part) => ` ${part}`).join("\n")} + }; + }, + validate(input): input is ${prefixedTypeName} { + return ( +${validationParts.map((part) => ` ${part}`).join("&& \n")} + ) + }, + fromJson(input): ${prefixedTypeName} { +${fromJsonParts.map((part) => ` ${part}`).join("\n")} + return { +${constructionParts.map((part) => ` ${part}`).join("\n")} + } + }, + fromJsonString(input): ${prefixedTypeName} { + return $$${prefixedTypeName}.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; +${toJsonParts.map((part) => ` ${part}`).join("\n")} + json += "}"; + return json; + }, + toUrlQueryString(input): string { + let queryParts: string[] = []; +${toQueryParts.map((part) => ` ${part}`).join("\n")} + return queryParts.join("&"); + } +} + +${subContentParts.join("\n")}`; + context.generatedTypes.push(typeName); + return result; +} diff --git a/languages/ts/ts-codegen/src/primitives.ts b/languages/ts/ts-codegen/src/primitives.ts index 5a002c04..c50f1465 100644 --- a/languages/ts/ts-codegen/src/primitives.ts +++ b/languages/ts/ts-codegen/src/primitives.ts @@ -11,6 +11,12 @@ export function tsStringFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `(typeof ${input} === 'string' || ${input} === null)`; + } + return `typeof ${input} === 'string'`; + }, fromJsonTemplate(input, target) { return `if (typeof ${input} === 'string') { ${target} = ${input}; @@ -44,6 +50,12 @@ export function tsBooleanFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `(typeof ${input} === 'boolean' || ${input} === null)`; + } + return `typeof ${input} === 'boolean'`; + }, fromJsonTemplate(input, target) { return `if (typeof ${input} === 'boolean') { ${target} = ${input}; @@ -77,6 +89,12 @@ export function tsDateFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `(${input} instanceof Date || ${input} === null)`; + } + return `${input} instanceof Date`; + }, fromJsonTemplate(input, target) { return `if (typeof ${input} === 'string') { ${target} = new Date(${input}); @@ -115,6 +133,12 @@ export function tsFloatFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `(typeof ${input} === 'number' || ${input} === null)`; + } + return `typeof ${input} === 'number'`; + }, fromJsonTemplate(input, target) { return `if (typeof ${input} === 'number') { ${target} = ${input}; @@ -180,6 +204,13 @@ export function tsIntFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + const mainPart = `typeof ${input} === 'number' && Number.isInteger(${input}) && ${input} >= ${min} && ${input} <= ${max}`; + if (schema.nullable) { + return `((${mainPart}) || ${input} === null)`; + } + return mainPart; + }, fromJsonTemplate(input, target) { return `if ( typeof ${input} === 'number' && @@ -212,6 +243,16 @@ export function tsBigIntFromSchema( return { typeName, defaultValue, + validationTemplate(input) { + const mainPart = isUnsigned + ? `typeof ${input} === 'bigint' && ${input} >= BigInt(0)` + : `typeof ${input} === 'bigint'`; + if (schema.nullable) { + return `((${mainPart}) || ${input} === null)`; + } + return mainPart; + }, + fromJsonTemplate(input, target) { if (isUnsigned) { return `if (typeof ${input} === 'string' && BigInt(${input}) >= BigInt(0)) { From 68c1b4b1e353e8646492bb40748454dd52829f6e Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sun, 21 Jul 2024 22:06:36 -0500 Subject: [PATCH 08/18] progress --- languages/ts/ts-codegen/src/enum.ts | 4 ++-- languages/ts/ts-codegen/src/index.ts | 24 +++++++++++++++++++++++- languages/ts/ts-codegen/src/object.ts | 4 ++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/languages/ts/ts-codegen/src/enum.ts b/languages/ts/ts-codegen/src/enum.ts index 9e6d41bc..0c622e39 100644 --- a/languages/ts/ts-codegen/src/enum.ts +++ b/languages/ts/ts-codegen/src/enum.ts @@ -71,10 +71,10 @@ export const $$${name}: ArriEnumValidator<${name}> = { if (${valuesName}.includes(input as any)) { return input as ${name}; } - if (${valuesName}.includes(input.toLowerCase() as any) { + if (${valuesName}.includes(input.toLowerCase() as any)) { return input.toLowerCase() as ${name}; } - if (${valuesName}.includes(input.toUpperCase() as any) { + if (${valuesName}.includes(input.toUpperCase() as any)) { return input.toUpperCase() as ${name}; } return "${schema.enum[0]}"; diff --git a/languages/ts/ts-codegen/src/index.ts b/languages/ts/ts-codegen/src/index.ts index a46a70eb..409be4cc 100644 --- a/languages/ts/ts-codegen/src/index.ts +++ b/languages/ts/ts-codegen/src/index.ts @@ -88,7 +88,29 @@ export async function createTypescriptClient( } } - const result = `${types.join("\n")}`; + const result = ` +import { + ArriEnumValidator, + ArriModelValidator, + arriRequest, + arriSseRequest, + arriWsRequest, + INT8_MAX, + INT8_MIN, + INT16_MAX, + INT16_MIN, + INT32_MAX, + INT32_MIN, + isObject, + serializeString, + SseOptions, + UINT8_MAX, + UINT16_MAX, + UINT32_MAX, + WsOptions, +} from "@arrirpc/client"; + +${types.join("\n")}`; return await prettier.format(result, { ...options.prettierOptions, parser: "typescript", diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index 054a7f89..d325edeb 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -109,7 +109,7 @@ export function tsObjectFromSchema( } toJsonParts.push(prop.toJsonTemplate(`input.${fieldName}`, "json")); toQueryParts.push( - prop.toQueryStringTemplate(`queryParts`, `input.${fieldName}`, key), + prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key), ); const validationPart = prop.validationTemplate(`input.${fieldName}`); if (validationPart) validationParts.push(validationPart); @@ -148,7 +148,7 @@ ${toJsonParts.map((part) => ` ${part}`).join("\n")} return json; }, toUrlQueryString(input): string { - let queryParts: string[] = []; + const queryParts: string[] = []; ${toQueryParts.map((part) => ` ${part}`).join("\n")} return queryParts.join("&"); } From 02cc9488ddf1d3e3028363fd0ec6e2e7dce7b35e Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sun, 21 Jul 2024 23:37:58 -0500 Subject: [PATCH 09/18] get optional keys working --- languages/ts/ts-codegen/src/object.ts | 48 +++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index d325edeb..a3e2f932 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -65,6 +65,7 @@ export function tsObjectFromSchema( context.discriminatorValue && context.discriminatorKey ) { + hasKey = true; const key = validVarName(camelCase(context.discriminatorKey)); fieldParts.push(`${key}: "${context.discriminatorValue}",`); fromJsonParts.push(`let _${key} = "${context.discriminatorValue}"`); @@ -86,8 +87,8 @@ export function tsObjectFromSchema( clientName: context.clientName, typePrefix: context.typePrefix, generatedTypes: context.generatedTypes, - instancePath: `${context.instancePath}/${key}`, - schemaPath: `${context.schemaPath}/properties/${key}`, + instancePath: `/${typeName}/${key}`, + schemaPath: `/${typeName}/properties/${key}`, discriminatorParent: "", discriminatorKey: "", discriminatorValue: "", @@ -116,6 +117,49 @@ export function tsObjectFromSchema( constructionParts.push(`${fieldName}: ${tempKey},`); hasKey = true; } + if (!hasKey) { + toJsonParts.push(`let _hasKey = false;`); + } + for (const key of Object.keys(schema.optionalProperties ?? {})) { + const subSchema = schema.optionalProperties![key]!; + const prop = tsTypeFromSchema(subSchema, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `/${typeName}/${key}`, + schemaPath: `/${typeName}/optionalProperties/${key}`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + if (prop.content) subContentParts.push(prop.content); + const fieldName = validVarName(camelCase(key)); + fieldParts.push(`${fieldName}?: ${prop.typeName},`); + const tempKey = `_${validVarName(key)}`; + fromJsonParts.push(`let ${tempKey}: ${prop.typeName} | undefined;`); + fromJsonParts.push(`if (typeof input.${key} !== 'undefined') { + ${prop.fromJsonTemplate(`input.${key}`, tempKey)} + }`); + toJsonParts.push(`if (typeof input.${key} !== 'undefined') { + if (_hasKey) json += ','; + json += \`"${key}":\`; + ${prop.toJsonTemplate(`input.${key}`, "json")} + _hasKey = true; + }`); + toQueryParts.push(`if (typeof input.${fieldName} !== 'undefined') { + ${prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key)} + }`); + const validationPart = prop.validationTemplate(`input.${fieldName}`); + if (validationPart) { + validationParts.push( + `(typeof input.${fieldName} === 'undefined' || ${validationPart})`, + ); + } + constructionParts.push(`${fieldName}: ${tempKey},`); + } const prefixedTypeName = `${context.typePrefix}${typeName}`; result.content = `${getJsDocComment(schema.metadata)}export interface ${prefixedTypeName} { From 6c28885887ee83e098c54bd6759e1c065637d41e Mon Sep 17 00:00:00 2001 From: joshmossas Date: Sun, 21 Jul 2024 23:39:27 -0500 Subject: [PATCH 10/18] better optional handling --- languages/ts/ts-codegen/src/object.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index a3e2f932..763cd4ef 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -143,12 +143,19 @@ export function tsObjectFromSchema( fromJsonParts.push(`if (typeof input.${key} !== 'undefined') { ${prop.fromJsonTemplate(`input.${key}`, tempKey)} }`); - toJsonParts.push(`if (typeof input.${key} !== 'undefined') { + if (hasKey) { + toJsonParts.push(`if (typeof input.${key} !== 'undefined') { + json += \`,"${key}":\`; + ${prop.toJsonTemplate(`input.${key}`, "json")} + }`); + } else { + toJsonParts.push(`if (typeof input.${key} !== 'undefined') { if (_hasKey) json += ','; json += \`"${key}":\`; ${prop.toJsonTemplate(`input.${key}`, "json")} _hasKey = true; }`); + } toQueryParts.push(`if (typeof input.${fieldName} !== 'undefined') { ${prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key)} }`); From 74d2cb6d09a3505c5ca03e5d5c58d9e3a3dcb499 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Mon, 22 Jul 2024 17:50:18 -0500 Subject: [PATCH 11/18] setup discriminator and array and record types --- .../src/referenceClient.ts | 22 +-- languages/ts/ts-codegen/build.config.ts | 2 +- languages/ts/ts-codegen/package.json | 17 ++- .../src/{index.test.ts => _index.test.ts} | 3 +- .../ts/ts-codegen/src/{index.ts => _index.ts} | 10 ++ languages/ts/ts-codegen/src/array.ts | 72 ++++++++++ languages/ts/ts-codegen/src/common.ts | 2 +- languages/ts/ts-codegen/src/discriminator.ts | 126 ++++++++++++++++++ languages/ts/ts-codegen/src/object.ts | 14 +- languages/ts/ts-codegen/src/record.ts | 90 +++++++++++++ 10 files changed, 336 insertions(+), 22 deletions(-) rename languages/ts/ts-codegen/src/{index.test.ts => _index.test.ts} (89%) rename languages/ts/ts-codegen/src/{index.ts => _index.ts} (93%) create mode 100644 languages/ts/ts-codegen/src/array.ts create mode 100644 languages/ts/ts-codegen/src/discriminator.ts create mode 100644 languages/ts/ts-codegen/src/record.ts diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index 37cf68e0..65f8a0a0 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -509,12 +509,14 @@ export const $$ObjectWithEveryType: ArriModelValidator = { let _array: boolean[]; if (Array.isArray(input.array)) { _array = []; - for (const _element of input.array) { - if (typeof _element === "boolean") { - _array.push(_element); + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; } else { - _array.push(false); + _arrayElValue = false; } + _array.push(_arrayElValue); } } else { _array = []; @@ -522,12 +524,14 @@ export const $$ObjectWithEveryType: ArriModelValidator = { let _record: Record; if (isObject(input.record)) { _record = {}; - for (const key of Object.keys(input.record)) { - if (typeof input.record[key] === "boolean") { - _record[key] = input.record[key]; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean; + if (typeof _value === "boolean") { + _recordValue = _value; } else { - _record[key] = false; + _recordValue = false; } + _record[_key] = _recordValue; } } else { _record = {}; @@ -743,7 +747,7 @@ export const $$Discriminator: ArriModelValidator = { case "C": return $$DiscriminatorC.toUrlQueryString(input); default: - throw new Error(`Unhandled case`); + throw new Error("Unhandled case"); } }, }; diff --git a/languages/ts/ts-codegen/build.config.ts b/languages/ts/ts-codegen/build.config.ts index 2cf0c050..0a926f78 100644 --- a/languages/ts/ts-codegen/build.config.ts +++ b/languages/ts/ts-codegen/build.config.ts @@ -12,7 +12,7 @@ const packageJson = JSON.parse( const deps = Object.keys(packageJson.dependencies as Record); export default defineBuildConfig({ - entries: ["./src/index"], + entries: [{ input: "./src/_index", name: "index" }], rollup: { emitCJS: true, dts: { diff --git a/languages/ts/ts-codegen/package.json b/languages/ts/ts-codegen/package.json index 788c64ef..8512ab6d 100644 --- a/languages/ts/ts-codegen/package.json +++ b/languages/ts/ts-codegen/package.json @@ -3,8 +3,13 @@ "version": "0.56.0", "type": "module", "license": "MIT", - "author": { "name": "joshmossas", "url": "https://github.com/joshmossas" }, - "bugs": { "url": "https://github.com/modiimedia/arri/issues" }, + "author": { + "name": "joshmossas", + "url": "https://github.com/joshmossas" + }, + "bugs": { + "url": "https://github.com/modiimedia/arri/issues" + }, "repository": { "type": "git", "url": "https://github.com/modiimedia/arri.git", @@ -13,11 +18,15 @@ "main": "./dist/index.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", - "files": ["dist"], + "files": [ + "dist" + ], "dependencies": { "@arrirpc/codegen-utils": "workspace:*", "@arrirpc/schema": "workspace:*", "prettier": "^3.3.3" }, - "devDependencies": { "@arrirpc/client": "workspace:*" } + "devDependencies": { + "@arrirpc/client": "workspace:*" + } } diff --git a/languages/ts/ts-codegen/src/index.test.ts b/languages/ts/ts-codegen/src/_index.test.ts similarity index 89% rename from languages/ts/ts-codegen/src/index.test.ts rename to languages/ts/ts-codegen/src/_index.test.ts index 404eba26..80ba5590 100644 --- a/languages/ts/ts-codegen/src/index.test.ts +++ b/languages/ts/ts-codegen/src/_index.test.ts @@ -4,7 +4,7 @@ import { AppDefinition, normalizeWhitespace } from "@arrirpc/codegen-utils"; import fs from "fs"; import path from "path"; -import { createTypescriptClient } from "./index"; +import { createTypescriptClient } from "./_index"; const testDir = path.resolve(__dirname, "../../../../tests/test-files"); const appDef = JSON.parse( @@ -22,7 +22,6 @@ test("Output matches reference file", async () => { clientName: "ExampleClient", outputFile: "", }); - fs.writeFileSync("blah.ts", result); expect(normalizeWhitespace(result)).toEqual( normalizeWhitespace(referenceFile), ); diff --git a/languages/ts/ts-codegen/src/index.ts b/languages/ts/ts-codegen/src/_index.ts similarity index 93% rename from languages/ts/ts-codegen/src/index.ts rename to languages/ts/ts-codegen/src/_index.ts index 409be4cc..a25e3364 100644 --- a/languages/ts/ts-codegen/src/index.ts +++ b/languages/ts/ts-codegen/src/_index.ts @@ -1,15 +1,18 @@ import { type AppDefinition, defineGeneratorPlugin, + isSchemaFormElements, isSchemaFormEnum, isSchemaFormProperties, isSchemaFormType, + isSchemaFormValues, type Schema, } from "@arrirpc/codegen-utils"; import { writeFileSync } from "fs"; import prettier from "prettier"; import { tsAnyFromSchema } from "./any"; +import { tsArrayFromSchema } from "./array"; import { CodegenContext, TsProperty } from "./common"; import { tsEnumFromSchema } from "./enum"; import { tsObjectFromSchema } from "./object"; @@ -21,6 +24,7 @@ import { tsIntFromSchema, tsStringFromSchema, } from "./primitives"; +import { tsRecordFromSchema } from "./record"; export interface TypescriptGeneratorOptions { clientName: string; @@ -156,5 +160,11 @@ export function tsTypeFromSchema( if (isSchemaFormProperties(schema)) { return tsObjectFromSchema(schema, context); } + if (isSchemaFormElements(schema)) { + return tsArrayFromSchema(schema, context); + } + if (isSchemaFormValues(schema)) { + return tsRecordFromSchema(schema, context); + } return tsAnyFromSchema(schema, context); } diff --git a/languages/ts/ts-codegen/src/array.ts b/languages/ts/ts-codegen/src/array.ts new file mode 100644 index 00000000..265551aa --- /dev/null +++ b/languages/ts/ts-codegen/src/array.ts @@ -0,0 +1,72 @@ +import { SchemaFormElements } from "@arrirpc/codegen-utils"; + +import { tsTypeFromSchema } from "./_index"; +import { CodegenContext, TsProperty } from "./common"; + +export function tsArrayFromSchema( + schema: SchemaFormElements, + context: CodegenContext, +): TsProperty { + const innerType = tsTypeFromSchema(schema.elements, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `${context.instancePath}/[element]`, + schemaPath: `${context.schemaPath}/elements`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + const typeName = `(${innerType.typeName})[]`; + const defaultValue = schema.nullable ? "null" : "[]"; + return { + typeName: schema.nullable ? `${typeName} | null` : typeName, + defaultValue, + validationTemplate(input) { + const mainPart = `Array.isArray(${input}) && ${input}.every((_element) => ${innerType.validationTemplate("_element")})`; + if (schema.nullable) { + return `((${mainPart}) || ${input} === null)`; + } + return mainPart; + }, + fromJsonTemplate(input, target) { + return `if (Array.isArray(${input})) { + ${target} = []; + for (const ${target}El of ${input}) { + let ${target}ElValue: ${innerType.typeName}; + ${innerType.fromJsonTemplate(`${target}El`, `${target}ElValue`)} + ${target}.push(${target}ElValue); + } + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target) { + if (schema.nullable) { + return `if (Array.isArray(${input})) { + ${target} += '['; + for (let i = 0; i < ${input}.length; i++) { + let _element = input[i]; + ${innerType.toJsonTemplate(`_element`, target, "_elementKey")} + } + ${target} += ']'; + } else { + ${target} += 'null'; + }`; + } + return `${target} += '['; + for (let i = 0; i < ${input}.length; i++) { + let _element = input[i]; + ${innerType.toJsonTemplate("_element", target, `_elementKey`)} + } + ${target} += ']';`; + }, + toQueryStringTemplate(_input, _target, _key) { + return `console.warn('[WARNING] Cannot serialize arrays to query string. Ignoring property at ${context.instancePath}.')`; + }, + content: innerType.content, + }; +} diff --git a/languages/ts/ts-codegen/src/common.ts b/languages/ts/ts-codegen/src/common.ts index 84010ff2..853df6be 100644 --- a/languages/ts/ts-codegen/src/common.ts +++ b/languages/ts/ts-codegen/src/common.ts @@ -10,7 +10,7 @@ export interface TsProperty { defaultValue: string; validationTemplate: (input: string) => string; fromJsonTemplate: (input: string, target: string) => string; - toJsonTemplate: (input: string, target: string) => string; + toJsonTemplate: (input: string, target: string, key: string) => string; toQueryStringTemplate: ( input: string, target: string, diff --git a/languages/ts/ts-codegen/src/discriminator.ts b/languages/ts/ts-codegen/src/discriminator.ts new file mode 100644 index 00000000..ff874847 --- /dev/null +++ b/languages/ts/ts-codegen/src/discriminator.ts @@ -0,0 +1,126 @@ +import { SchemaFormDiscriminator } from "@arrirpc/codegen-utils"; + +import { CodegenContext, getTsTypeName, TsProperty } from "./common"; +import { tsObjectFromSchema } from "./object"; + +export function tsTaggedUnionFromSchema( + schema: SchemaFormDiscriminator, + context: CodegenContext, +): TsProperty { + const typeName = getTsTypeName(schema, context); + const prefixedTypeName = `${context.typePrefix}${typeName}`; + const defaultValue = schema.nullable + ? "null" + : `$$${prefixedTypeName}.new()`; + + const result: TsProperty = { + typeName: schema.nullable + ? `${prefixedTypeName} | null` + : prefixedTypeName, + defaultValue, + validationTemplate(input: string): string { + const mainPart = `$$${prefixedTypeName}.validate(${input})`; + if (schema.nullable) { + return `(${mainPart} || ${input} === 'null')`; + } + return mainPart; + }, + fromJsonTemplate(input: string, target: string): string { + return `if (isObject(${input})) { + ${target} = $$${prefixedTypeName}.fromJson(${input}); + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input: string, target: string, _key: string): string { + if (schema.nullable) { + return `if (${input} != null) { + ${target} += $$${prefixedTypeName}.toJsonString(${input}); + } else { + ${target} += 'null'; + }`; + } + return `${target} += $$${prefixedTypeName}.toJsonString(${input});`; + }, + toQueryStringTemplate(_: string, __: string, ___: string): string { + return `[WARNING] Cannot serialize nested objects to query params. Ignoring property at ${context.instancePath}`; + }, + content: "", + }; + if (!context.generatedTypes.includes(typeName)) return result; + const subTypes: { value: string; data: TsProperty }[] = []; + const discriminatorKey = schema.discriminator; + for (const key of Object.keys(schema.mapping)) { + const subSchema = schema.mapping[key]!; + const subType = tsObjectFromSchema(subSchema, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: context.instancePath, + schemaPath: `${context.schemaPath}/mapping/${key}`, + discriminatorParent: typeName, + discriminatorKey: discriminatorKey, + discriminatorValue: key, + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + subTypes.push({ value: key, data: subType }); + } + result.content = `export type ${prefixedTypeName} = ${subTypes.map((type) => type.data.typeName).join(" |")}; +export const $$${prefixedTypeName}: ArriModelValidator<${subTypes[0]!.data.typeName}> = { + new(): ${prefixedTypeName} { + return $$${subTypes[0]!.data.typeName}.new(); + }, + validate(input): input is ${prefixedTypeName} { + if (!isObject(input)) { + return false; + } + if (typeof input.${discriminatorKey} !== 'string') { + return false; + } + switch (input.${discriminatorKey}) { +${subTypes.map( + (type) => ` case "${type.value}": + return $$${type.data.typeName}.validate(input);`, +)} + default: + return false; + } + }, + fromJson(input): ${prefixedTypeName} { + switch (input.${discriminatorKey}) { +${subTypes.map( + (type) => ` case "${type.value}": + return $$${type.data.typeName}.fromJson(input);`, +)} + default: + return $$${subTypes[0]!.data.typeName}.new(); + } + }, + toJsonString(input): string { + switch (input.${discriminatorKey}) { +${subTypes.map( + (type) => ` case "${type.value}": + return $$${type.data.typeName}.toJsonString(input); + default: + input satisfied never; + throw new Error(\`Unhandled case "\${(input as any).${discriminatorKey}}"\`);`, +)} + } + }, + toUrlQueryString(input): string { + switch (input.${discriminatorKey}) { +${subTypes.map( + (type) => ` case "${type.value}": + return $$${type.data.typeName}.toUrlQueryString(input);`, +)} + default: + throw new Error('Unhandled case'); + } + } +} +`; + context.generatedTypes.push(typeName); + return result; +} diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index 763cd4ef..6dd57499 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -1,6 +1,6 @@ import { camelCase, SchemaFormProperties } from "@arrirpc/codegen-utils"; -import { tsTypeFromSchema } from "."; +import { tsTypeFromSchema } from "./_index"; import { CodegenContext, getJsDocComment, @@ -66,7 +66,9 @@ export function tsObjectFromSchema( context.discriminatorKey ) { hasKey = true; - const key = validVarName(camelCase(context.discriminatorKey)); + const key = validVarName( + camelCase(context.discriminatorKey, { normalize: true }), + ); fieldParts.push(`${key}: "${context.discriminatorValue}",`); fromJsonParts.push(`let _${key} = "${context.discriminatorValue}"`); toJsonParts.push( @@ -108,7 +110,9 @@ export function tsObjectFromSchema( } else { toJsonParts.push(`json += '"${key}":';`); } - toJsonParts.push(prop.toJsonTemplate(`input.${fieldName}`, "json")); + toJsonParts.push( + prop.toJsonTemplate(`input.${fieldName}`, "json", key), + ); toQueryParts.push( prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key), ); @@ -146,13 +150,13 @@ export function tsObjectFromSchema( if (hasKey) { toJsonParts.push(`if (typeof input.${key} !== 'undefined') { json += \`,"${key}":\`; - ${prop.toJsonTemplate(`input.${key}`, "json")} + ${prop.toJsonTemplate(`input.${key}`, "json", key)} }`); } else { toJsonParts.push(`if (typeof input.${key} !== 'undefined') { if (_hasKey) json += ','; json += \`"${key}":\`; - ${prop.toJsonTemplate(`input.${key}`, "json")} + ${prop.toJsonTemplate(`input.${key}`, "json", key)} _hasKey = true; }`); } diff --git a/languages/ts/ts-codegen/src/record.ts b/languages/ts/ts-codegen/src/record.ts new file mode 100644 index 00000000..8e227f73 --- /dev/null +++ b/languages/ts/ts-codegen/src/record.ts @@ -0,0 +1,90 @@ +import { SchemaFormValues } from "@arrirpc/codegen-utils"; + +import { tsTypeFromSchema } from "./_index"; +import { CodegenContext, TsProperty, validVarName } from "./common"; + +export function tsRecordFromSchema( + schema: SchemaFormValues, + context: CodegenContext, +): TsProperty { + const innerType = tsTypeFromSchema(schema.values, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `${context.instancePath}/[value]`, + schemaPath: `${context.schemaPath}/values`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + hasSseProcedure: context.hasSseProcedure, + hasWsProcedure: context.hasWsProcedure, + }); + const typeName = `Record`; + const defaultValue = schema.nullable ? "null" : "{}"; + return { + typeName: schema.nullable ? `${typeName} | null` : typeName, + defaultValue, + validationTemplate(input) { + const mainPart = `isObject(${input}) && Object.entries(${input}).every( + ([_, value]) => ${innerType.validationTemplate("value")}, + )`; + if (schema.nullable) { + return `((${mainPart}) || ${input} === null)`; + } + return mainPart; + }, + fromJsonTemplate(input, target) { + return `if (isObject(${input})) { + ${target} = {}; + for (const [_key, _value] of Object.entries(input.record)) { + ${target}Value: ${innerType.typeName}; + if (typeof _value === 'boolean') { + ${target}Value = _value; + } else { + ${target}Value = false; + } + ${target}[_key] = ${target}Value; + } + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target, key) { + const countVal = `_${validVarName(key)}PropertyCount`; + if (schema.nullable) { + return `if (isObject(${input})) { + ${target} += '{'; + let ${countVal} = 0; + for (const [_key, _value] of Object.entries(${target})) { + if (${countVal} !== 0) { + ${target} += ','; + } + ${target} += \`"\${_key}":\`; + ${innerType.toJsonTemplate("_value", target, "_key")} + ${countVal}++; + } + ${target} += '}'; + } else { + ${target} += 'null'; + }`; + } + return `${target} += '{' + let ${countVal} = 0; + for (const [_key, _value] of Object.entries(${target})) { + if (${countVal} !== 0) { + ${target} += ','; + } + ${target} += \`"\${_key}":\`; + ${innerType.toJsonTemplate("_value", target, "_key")}; + ${countVal}++; + } + ${target} += '}'; + `; + }, + toQueryStringTemplate(_, __, ___) { + return `console.warn('[WARNING] Cannot serialize nested objects to query params. Skipping property at ${context.instancePath}.')`; + }, + content: innerType.content, + }; +} From 4b224b6f95c2d7ac02221a2b87a72169cab11511 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Mon, 22 Jul 2024 18:47:10 -0500 Subject: [PATCH 12/18] further progress on refs and objects --- .../src/referenceClient.ts | 93 ++++++++++++++++--- languages/ts/ts-codegen/src/_index.ts | 5 + languages/ts/ts-codegen/src/any.ts | 2 +- languages/ts/ts-codegen/src/object.ts | 10 +- languages/ts/ts-codegen/src/ref.ts | 45 +++++++++ 5 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 languages/ts/ts-codegen/src/ref.ts diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index 65f8a0a0..bce848ec 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -964,6 +964,68 @@ export const $$ObjectWithOptionalFields: ArriModelValidator= INT8_MIN && + input.int8 <= INT8_MAX) || + typeof input.int8 === "undefined") && + ((typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX) || + typeof input.uint8 === "undefined") && + ((typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX) || + typeof input.int16 === "undefined") && + ((typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX) || + typeof input.uint16 === "undefined") && + ((typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX) || + typeof input.int32 === "undefined") && + ((typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX) || + typeof input.uint32 === "undefined") && + ($$Enumerator.validate(input.enum) || + typeof input.enum === "string") && + ($$NestedObject.validate(input.object) || + typeof input.object === "undefined") && + ((Array.isArray(input.array) && + input.array.every( + (_element) => typeof _element === "boolean", + )) || + typeof input.array === "undefined") && + ((isObject(input.record) && + Object.values(input.record).every( + (_value) => typeof _value === "boolean", + )) || + typeof input.record === "undefined") && + ($$Discriminator.validate(input.discriminator) || + typeof input.discriminator === "undefined") && + true + ); + }, }; export interface ObjectWithNullableFields { @@ -1028,26 +1090,26 @@ export const $$RecursiveObject: ArriModelValidator = { validate(input): input is RecursiveObject { return ( isObject(input) && - (input.left === null || $$RecursiveObject.validate(input.left)) && - (input.right === null || $$RecursiveObject.validate(input.right)) + ($$RecursiveObject.validate(input.left) || input.left === null) && + ($$RecursiveObject.validate(input.right) || input.right === null) ); }, fromJson(input): RecursiveObject { - let left: RecursiveObject | null; + let _left: RecursiveObject | null; if (isObject(input.left)) { - left = $$RecursiveObject.fromJson(input.left); + _left = $$RecursiveObject.fromJson(input.left); } else { - left = null; + _left = null; } - let right: RecursiveObject | null; + let _right: RecursiveObject | null; if (isObject(input.right)) { - right = $$RecursiveObject.fromJson(input.right); + _right = $$RecursiveObject.fromJson(input.right); } else { - right = null; + _right = null; } return { - left, - right, + left: _left, + right: _right, }; }, fromJsonString(input): RecursiveObject { @@ -1056,13 +1118,13 @@ export const $$RecursiveObject: ArriModelValidator = { toJsonString(input): string { let json = "{"; json += '"left":'; - if (input.left) { + if (input.left !== null) { json += $$RecursiveObject.toJsonString(input.left); } else { json += "null"; } json += ',"right":'; - if (input.right) { + if (input.right !== null) { json += $$RecursiveObject.toJsonString(input.right); } else { json += "null"; @@ -1072,7 +1134,12 @@ export const $$RecursiveObject: ArriModelValidator = { }, toUrlQueryString(input): string { const queryParts: string[] = []; - // TODO: + console.warn( + "[WARNING] Nested objects cannot be serialized to query params. Ignoring property at /RecursiveObject/left.", + ); + console.warn( + "[WARNING] Nested objects cannot be serialized to query params. Ignoring property at /RecursiveObject/right.", + ); return queryParts.join("&"); }, }; diff --git a/languages/ts/ts-codegen/src/_index.ts b/languages/ts/ts-codegen/src/_index.ts index a25e3364..9e4f8a57 100644 --- a/languages/ts/ts-codegen/src/_index.ts +++ b/languages/ts/ts-codegen/src/_index.ts @@ -4,6 +4,7 @@ import { isSchemaFormElements, isSchemaFormEnum, isSchemaFormProperties, + isSchemaFormRef, isSchemaFormType, isSchemaFormValues, type Schema, @@ -25,6 +26,7 @@ import { tsStringFromSchema, } from "./primitives"; import { tsRecordFromSchema } from "./record"; +import { tsRefFromSchema } from "./ref"; export interface TypescriptGeneratorOptions { clientName: string; @@ -166,5 +168,8 @@ export function tsTypeFromSchema( if (isSchemaFormValues(schema)) { return tsRecordFromSchema(schema, context); } + if (isSchemaFormRef(schema)) { + return tsRefFromSchema(schema, context); + } return tsAnyFromSchema(schema, context); } diff --git a/languages/ts/ts-codegen/src/any.ts b/languages/ts/ts-codegen/src/any.ts index 6bc34051..6b301b09 100644 --- a/languages/ts/ts-codegen/src/any.ts +++ b/languages/ts/ts-codegen/src/any.ts @@ -12,7 +12,7 @@ export function tsAnyFromSchema( typeName, defaultValue, validationTemplate(_) { - return ""; + return "true"; }, fromJsonTemplate(input, target) { return `${input} = ${target}`; diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index 6dd57499..a7d8b830 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -117,7 +117,7 @@ export function tsObjectFromSchema( prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key), ); const validationPart = prop.validationTemplate(`input.${fieldName}`); - if (validationPart) validationParts.push(validationPart); + validationParts.push(validationPart); constructionParts.push(`${fieldName}: ${tempKey},`); hasKey = true; } @@ -164,11 +164,9 @@ export function tsObjectFromSchema( ${prop.toQueryStringTemplate(`input.${fieldName}`, "queryParts", key)} }`); const validationPart = prop.validationTemplate(`input.${fieldName}`); - if (validationPart) { - validationParts.push( - `(typeof input.${fieldName} === 'undefined' || ${validationPart})`, - ); - } + validationParts.push( + `(typeof input.${fieldName} === 'undefined' || ${validationPart})`, + ); constructionParts.push(`${fieldName}: ${tempKey},`); } const prefixedTypeName = `${context.typePrefix}${typeName}`; diff --git a/languages/ts/ts-codegen/src/ref.ts b/languages/ts/ts-codegen/src/ref.ts new file mode 100644 index 00000000..76ceda1a --- /dev/null +++ b/languages/ts/ts-codegen/src/ref.ts @@ -0,0 +1,45 @@ +import { pascalCase, SchemaFormRef } from "@arrirpc/codegen-utils"; + +import { CodegenContext, TsProperty, validVarName } from "./common"; + +export function tsRefFromSchema( + schema: SchemaFormRef, + context: CodegenContext, +): TsProperty { + const typeName = pascalCase(validVarName(schema.ref), { normalize: true }); + const prefixedTypeName = `${context.typePrefix}${typeName}`; + const defaultValue = schema.nullable ? "null" : `${prefixedTypeName}.new()`; + return { + typeName: schema.nullable + ? `${prefixedTypeName} | null` + : prefixedTypeName, + defaultValue, + validationTemplate(input) { + if (schema.nullable) { + return `($$${prefixedTypeName}.validate(${input}) || ${input} === null)`; + } + return `$$${prefixedTypeName}.validate(${input})`; + }, + fromJsonTemplate(input, target) { + return `if (isObject(${input})) { + ${target} = $$${prefixedTypeName}.fromJson(${input}); + } else { + ${target} = ${defaultValue}; + }`; + }, + toJsonTemplate(input, target, _key) { + if (schema.nullable) { + return `if (${input} !== null) { + ${target} += $$${prefixedTypeName}.toJsonString(${input}); + } else { + ${target} += 'null'; + }`; + } + return `${target} += $$${prefixedTypeName}.toJsonString(${input});`; + }, + toQueryStringTemplate(_, __, ___) { + return `console.warn("[WARNING] Nested objects cannot be serialized to query params. Ignoring property at ${context.instancePath}.");`; + }, + content: "", + }; +} From e95abec65126727a4f15648c073e4b3764dc0c91 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Mon, 22 Jul 2024 22:47:09 -0500 Subject: [PATCH 13/18] finish ObjectWithNullableFields --- .../src/referenceClient.test.ts | 74 ++++ .../src/referenceClient.ts | 389 +++++++++++++++++- languages/ts/ts-codegen/src/_index.test.ts | 4 + languages/ts/ts-codegen/src/_index.ts | 5 + languages/ts/ts-codegen/src/any.ts | 6 +- languages/ts/ts-codegen/src/array.ts | 22 +- languages/ts/ts-codegen/src/discriminator.ts | 4 +- languages/ts/ts-codegen/src/enum.ts | 9 +- languages/ts/ts-codegen/src/object.ts | 8 +- languages/ts/ts-codegen/src/primitives.ts | 25 +- languages/ts/ts-codegen/src/record.ts | 14 +- 11 files changed, 512 insertions(+), 48 deletions(-) diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts index 1b3342c9..599b0569 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts @@ -4,9 +4,11 @@ import path from "node:path"; import { $$Book, $$ObjectWithEveryType, + $$ObjectWithNullableFields, $$RecursiveObject, Book, ObjectWithEveryType, + ObjectWithNullableFields, RecursiveObject, } from "./referenceClient"; @@ -37,6 +39,8 @@ describe("Book", () => { }); }); +describe("NestedObject", () => {}); + describe("ObjectWithEveryType", () => { const targetValue: ObjectWithEveryType = { string: "", @@ -89,6 +93,76 @@ describe("ObjectWithEveryType", () => { }); }); +describe("ObjectWithNullableFields", () => { + const allNullTargetValue: ObjectWithNullableFields = { + string: null, + boolean: null, + timestamp: null, + float32: null, + float64: null, + int8: null, + uint8: null, + int16: null, + uint16: null, + int32: null, + uint32: null, + int64: null, + uint64: null, + enum: null, + object: null, + array: null, + record: null, + discriminator: null, + any: null, + }; + const noNullTargetValue: ObjectWithNullableFields = { + string: "", + boolean: true, + timestamp: testDate, + float32: 1.5, + float64: 1.5, + int8: 1, + uint8: 1, + int16: 10, + uint16: 10, + int32: 100, + uint32: 100, + int64: 1000n, + uint64: 1000n, + enum: "BAZ", + object: { + id: "", + content: "", + }, + array: [true, false, false], + record: { + A: true, + B: false, + }, + discriminator: { + typeName: "C", + id: "", + name: "", + date: testDate, + }, + any: { message: "hello world" }, + }; + const allNullJsonReference = testFile( + "ObjectWithNullableFields_AllNull.json", + ); + const noNullJsonReference = testFile( + "ObjectWithNullableFields_NoNull.json", + ); + test("JSON parsing", () => { + const allNullResult = + $$ObjectWithNullableFields.fromJsonString(allNullJsonReference); + const noNullResult = + $$ObjectWithNullableFields.fromJsonString(noNullJsonReference); + expect(allNullResult).toStrictEqual(allNullTargetValue); + expect(noNullResult).toStrictEqual(noNullTargetValue); + }); +}); + describe("RecursiveObject", () => { const targetValue: RecursiveObject = { left: { diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index bce848ec..75319ab9 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -617,7 +617,7 @@ export const $$ObjectWithEveryType: ArriModelValidator = { json += ","; } json += `"${_key}":`; - json += _value.toString(); + json += `${_value}`; _recordPropertyCount++; } json += "}"; @@ -1074,6 +1074,393 @@ export const $$ObjectWithNullableFields: ArriModelValidator= INT8_MIN && + input.int8 <= INT8_MAX) || + input.int8 === null) && + ((typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX) || + input.uint8 === null) && + ((typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX) || + input.int16 === null) && + ((typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX) || + input.uint16 === null) && + ((typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX) || + input.int32 === null) && + ((typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX) || + input.uint32 === null) && + (typeof input.int64 === "bigint" || input.int64 === null) && + ((typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0)) || + input.uint64 === null) && + ($$Enumerator.validate(input.enum) || input.enum === null) && + ($$NestedObject.validate(input.object) || + input.object === null) && + ((Array.isArray(input.array) && + input.array.every( + (_element) => typeof _element === "boolean", + )) || + input.array === null) && + ((isObject(input.record) && + Object.values(input.record).every( + (_value) => typeof _value === "boolean", + )) || + input.record === null) && + ($$Discriminator.validate(input.discriminator) || + input.discriminator === null) && + true + ); + }, + fromJson(input): ObjectWithNullableFields { + let _string: string | null; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = null; + } + let _boolean: boolean | null; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + let _float32: number | null; + if (typeof input.float32 === "number") { + _float32 = input.float32; + } else { + _float32 = null; + } + let _float64: number | null; + if (typeof input.float64 === "number") { + _float64 = input.float64; + } else { + _float64 = null; + } + let _int8: number | null; + if ( + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX + ) { + _int8 = input.int8; + } else { + _int8 = null; + } + let _uint8: number | null; + if ( + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX + ) { + _uint8 = input.uint8; + } else { + _uint8 = null; + } + let _int16: number | null; + if ( + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX + ) { + _int16 = input.int16; + } else { + _int16 = null; + } + let _uint16: number | null; + if ( + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX + ) { + _uint16 = input.uint16; + } else { + _uint16 = null; + } + let _int32: number | null; + if ( + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX + ) { + _int32 = input.int32; + } else { + _int32 = null; + } + let _uint32: number | null; + if ( + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX + ) { + _uint32 = input.uint32; + } else { + _uint32 = null; + } + let _int64: bigint | null; + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); + } else if (typeof input.int64 === "bigint") { + _int64 = input.int64; + } else { + _int64 = null; + } + let _uint64: bigint | null; + if ( + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) + ) { + _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; + } else { + _uint64 = null; + } + let _enum: Enumerator | null; + if (typeof input.enum === "string") { + _enum = $$Enumerator.fromSerialValue(input.enum); + } else { + _enum = null; + } + let _object: NestedObject | null; + if (isObject(input.object)) { + _object = $$NestedObject.fromJson(input.object); + } else { + _object = null; + } + let _array: boolean[] | null; + if (Array.isArray(input.array)) { + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; + } else { + _arrayElValue = false; + } + _array.push(_arrayElValue); + } + } else { + _array = null; + } + let _record: Record | null; + if (isObject(input.record)) { + _record = {}; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean; + if (typeof _value === "boolean") { + _recordValue = _value; + } else { + _recordValue = false; + } + _record[_key] = _recordValue; + } + } else { + _record = null; + } + let _discriminator: Discriminator | null; + if (isObject(input.discriminator)) { + _discriminator = $$Discriminator.fromJson(input.discriminator); + } else { + _discriminator = null; + } + let _any: any; + _any = input.any; + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enum: _enum, + object: _object, + array: _array, + record: _record, + discriminator: _discriminator, + any: _any, + }; + }, + fromJsonString(input): ObjectWithNullableFields { + return $$ObjectWithNullableFields.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + if (typeof input.string === "string") { + json += serializeString(input.string); + } else { + json += "null"; + } + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += ',"float32":'; + json += `${input.float32}`; + json += ',"float64":'; + json += `${input.float64}`; + json += ',"int8":'; + json += `${input.int8}`; + json += ',"uint8":'; + json += `${input.uint8}`; + json += ',"int16":'; + json += `${input.int16}`; + json += ',"uint16":'; + json += `${input.uint16}`; + json += ',"int32":'; + json += `${input.int32}`; + json += ',"uint32":'; + json += `${input.uint32}`; + json += ',"int64":'; + if (typeof input.int64 === "bigint") { + json += `"${input.int64.toString()}"`; + } else { + json += "null"; + } + json += ',"uint64":'; + if (typeof input.uint64 === "bigint") { + json += `"${input.uint64.toString()}"`; + } else { + json += "null"; + } + json += ',"enum":'; + if (typeof input.enum === "string") { + json += `"${input.enum}"`; + } else { + json += "null"; + } + json += ',"object":'; + if (input.object !== null) { + json += $$NestedObject.toJsonString(input.object); + } else { + json += "null"; + } + json += ',"array":'; + if (input.array !== null) { + json += "["; + for (let i = 0; i < input.array.length; i++) { + if (i !== 0) { + json += ","; + } + const _element = input.array[i]; + json += `${_element}`; + } + json += "]"; + } else { + json += "null"; + } + json += ',"record":'; + if (input.record !== null) { + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.record)) { + if (_recordPropertyCount !== 0) { + json += ","; + } + json += `"${_key}":`; + json += `${_value}`; + _recordPropertyCount++; + } + json += "}"; + } else { + json += "null"; + } + json += ',"discriminator":'; + if (input.discriminator != null) { + json += $$Discriminator.toJsonString(input.discriminator); + } else { + json += "null"; + } + json += ',"any":'; + json += JSON.stringify(input.any); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + queryParts.push(`float32=${input.float32}`); + queryParts.push(`float64=${input.float64}`); + queryParts.push(`int8=${input.int8}`); + queryParts.push(`uint8=${input.uint8}`); + queryParts.push(`int16=${input.int16}`); + queryParts.push(`uint16=${input.uint16}`); + queryParts.push(`int32=${input.int32}`); + queryParts.push(`uint32=${input.uint32}`); + queryParts.push(`int64=${input.int64}`); + queryParts.push(`uint64=${input.uint64}`); + queryParts.push(`enum=${input.enum}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithNullableFields/object.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithNullableFields/array.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithNullableFields/record.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithNullableFields/discriminator.", + ); + console.warn( + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithNullableFields/any.", + ); + return queryParts.join("&"); + }, }; export interface RecursiveObject { diff --git a/languages/ts/ts-codegen/src/_index.test.ts b/languages/ts/ts-codegen/src/_index.test.ts index 80ba5590..eb010154 100644 --- a/languages/ts/ts-codegen/src/_index.test.ts +++ b/languages/ts/ts-codegen/src/_index.test.ts @@ -21,6 +21,10 @@ test("Output matches reference file", async () => { const result = await createTypescriptClient(appDef, { clientName: "ExampleClient", outputFile: "", + prettierOptions: { + tabWidth: 4, + endOfLine: "lf", + }, }); expect(normalizeWhitespace(result)).toEqual( normalizeWhitespace(referenceFile), diff --git a/languages/ts/ts-codegen/src/_index.ts b/languages/ts/ts-codegen/src/_index.ts index 9e4f8a57..1c0dde7a 100644 --- a/languages/ts/ts-codegen/src/_index.ts +++ b/languages/ts/ts-codegen/src/_index.ts @@ -1,6 +1,7 @@ import { type AppDefinition, defineGeneratorPlugin, + isSchemaFormDiscriminator, isSchemaFormElements, isSchemaFormEnum, isSchemaFormProperties, @@ -15,6 +16,7 @@ import prettier from "prettier"; import { tsAnyFromSchema } from "./any"; import { tsArrayFromSchema } from "./array"; import { CodegenContext, TsProperty } from "./common"; +import { tsTaggedUnionFromSchema } from "./discriminator"; import { tsEnumFromSchema } from "./enum"; import { tsObjectFromSchema } from "./object"; import { @@ -168,6 +170,9 @@ export function tsTypeFromSchema( if (isSchemaFormValues(schema)) { return tsRecordFromSchema(schema, context); } + if (isSchemaFormDiscriminator(schema)) { + return tsTaggedUnionFromSchema(schema, context); + } if (isSchemaFormRef(schema)) { return tsRefFromSchema(schema, context); } diff --git a/languages/ts/ts-codegen/src/any.ts b/languages/ts/ts-codegen/src/any.ts index 6b301b09..f37728ee 100644 --- a/languages/ts/ts-codegen/src/any.ts +++ b/languages/ts/ts-codegen/src/any.ts @@ -3,11 +3,11 @@ import { Schema } from "@arrirpc/codegen-utils"; import { CodegenContext, TsProperty } from "./common"; export function tsAnyFromSchema( - _schema: Schema, + schema: Schema, context: CodegenContext, ): TsProperty { const typeName = "any"; - const defaultValue = "undefined"; + const defaultValue = schema.nullable ? "null" : "undefined"; return { typeName, defaultValue, @@ -15,7 +15,7 @@ export function tsAnyFromSchema( return "true"; }, fromJsonTemplate(input, target) { - return `${input} = ${target}`; + return `${target} = ${input}`; }, toJsonTemplate(input, target) { return `${target} += JSON.stringify(${input})`; diff --git a/languages/ts/ts-codegen/src/array.ts b/languages/ts/ts-codegen/src/array.ts index 265551aa..b4a5af57 100644 --- a/languages/ts/ts-codegen/src/array.ts +++ b/languages/ts/ts-codegen/src/array.ts @@ -26,9 +26,13 @@ export function tsArrayFromSchema( typeName: schema.nullable ? `${typeName} | null` : typeName, defaultValue, validationTemplate(input) { - const mainPart = `Array.isArray(${input}) && ${input}.every((_element) => ${innerType.validationTemplate("_element")})`; + const mainPart = `Array.isArray(${input}) + && ${input}.every( + (_element) => ${innerType.validationTemplate("_element")} + )`; if (schema.nullable) { - return `((${mainPart}) || ${input} === null)`; + return `((${mainPart}) || + ${input} === null)`; } return mainPart; }, @@ -46,10 +50,13 @@ export function tsArrayFromSchema( }, toJsonTemplate(input, target) { if (schema.nullable) { - return `if (Array.isArray(${input})) { + return `if (${input} !== null) { ${target} += '['; for (let i = 0; i < ${input}.length; i++) { - let _element = input[i]; + if (i !== 0) { + ${target} += ','; + } + const _element = ${input}[i]; ${innerType.toJsonTemplate(`_element`, target, "_elementKey")} } ${target} += ']'; @@ -59,13 +66,16 @@ export function tsArrayFromSchema( } return `${target} += '['; for (let i = 0; i < ${input}.length; i++) { - let _element = input[i]; + if (i !== 0) { + ${target} += ','; + } + const _element = ${input}[i]; ${innerType.toJsonTemplate("_element", target, `_elementKey`)} } ${target} += ']';`; }, toQueryStringTemplate(_input, _target, _key) { - return `console.warn('[WARNING] Cannot serialize arrays to query string. Ignoring property at ${context.instancePath}.')`; + return `console.warn('[WARNING] Cannot serialize arrays to query string. Skipping property at ${context.instancePath}.')`; }, content: innerType.content, }; diff --git a/languages/ts/ts-codegen/src/discriminator.ts b/languages/ts/ts-codegen/src/discriminator.ts index ff874847..ba62f67a 100644 --- a/languages/ts/ts-codegen/src/discriminator.ts +++ b/languages/ts/ts-codegen/src/discriminator.ts @@ -21,7 +21,7 @@ export function tsTaggedUnionFromSchema( validationTemplate(input: string): string { const mainPart = `$$${prefixedTypeName}.validate(${input})`; if (schema.nullable) { - return `(${mainPart} || ${input} === 'null')`; + return `(${mainPart} || ${input} === null)`; } return mainPart; }, @@ -43,7 +43,7 @@ export function tsTaggedUnionFromSchema( return `${target} += $$${prefixedTypeName}.toJsonString(${input});`; }, toQueryStringTemplate(_: string, __: string, ___: string): string { - return `[WARNING] Cannot serialize nested objects to query params. Ignoring property at ${context.instancePath}`; + return `console.warn("[WARNING] Cannot serialize nested objects to query string. Skipping property at ${context.instancePath}.");`; }, content: "", }; diff --git a/languages/ts/ts-codegen/src/enum.ts b/languages/ts/ts-codegen/src/enum.ts index 0c622e39..16ad9d53 100644 --- a/languages/ts/ts-codegen/src/enum.ts +++ b/languages/ts/ts-codegen/src/enum.ts @@ -16,6 +16,7 @@ export function tsEnumFromSchema( `Error at ${context.schemaPath}. Enum schemas must have at least one enum value.`, ); const enumName = getTsTypeName(schema, context); + const prefixedEnumName = `${context.typePrefix}${enumName}`; const typeName = schema.nullable ? `${enumName} | null` : enumName; const defaultValue = schema.nullable ? "null" : `"${schema.enum[0]!}"`; const result: TsProperty = { @@ -23,13 +24,13 @@ export function tsEnumFromSchema( defaultValue, validationTemplate(input) { if (schema.nullable) { - return `($$${enumName}Values.includes(${input} as any) || ${input} === null)`; + return `($$${prefixedEnumName}.validate(${input}) || ${input} === null)`; } - return `$$${enumName}Values.includes(${input} as any)`; + return `$$${prefixedEnumName}.validate(${input})`; }, fromJsonTemplate(input, target) { - return `if ($$${enumName}.validate(${input})) { - ${target} = ${input}; + return `if (typeof ${input} === 'string') { + ${target} = $$${prefixedEnumName}.fromSerialValue(${input}); } else { ${target} = ${defaultValue}; }`; diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index a7d8b830..3290c50b 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -35,16 +35,16 @@ export function tsObjectFromSchema( }, toJsonTemplate(input, target) { if (schema.nullable) { - return `if (${input} == null) { - ${target} += 'null'; - } else { + return `if (${input} !== null) { ${target} += $$${context.typePrefix}${typeName}.toJsonString(${input}); + } else { + ${target} += 'null'; }`; } return `${target} += $$${context.typePrefix}${typeName}.toJsonString(${input});`; }, toQueryStringTemplate(_input, _target) { - return `console.warn("[WARNING] Nested objects cannot be serialized to query string. Skipping property at ${context.instancePath}.")`; + return `console.warn("[WARNING] Cannot serialize nested objects to query string. Skipping property at ${context.instancePath}.")`; }, content: "", }; diff --git a/languages/ts/ts-codegen/src/primitives.ts b/languages/ts/ts-codegen/src/primitives.ts index c50f1465..3f9526cb 100644 --- a/languages/ts/ts-codegen/src/primitives.ts +++ b/languages/ts/ts-codegen/src/primitives.ts @@ -64,17 +64,10 @@ export function tsBooleanFromSchema( }`; }, toJsonTemplate(input, target) { - if (schema.nullable) { - return `if (typeof ${input} === 'boolean') { - ${target} += ${input}.toString(); - } else { - ${target} += 'null'; - }`; - } - return `${target} += ${input}.toString()`; + return `${target} += \`\${${input}}\`;`; }, toQueryStringTemplate(input, target, key) { - return `${target}.push(\`${key}=\${${input}}\`)`; + return `${target}.push(\`${key}=\${${input}}\`);`; }, content: "", }; @@ -147,14 +140,7 @@ export function tsFloatFromSchema( }`; }, toJsonTemplate(input, target) { - if (schema.nullable) { - return `if (typeof ${input} === 'number') { - ${target} += ${input}.toString(); - } else { - ${target} += 'null'; - }`; - } - return `${target} += ${input}.toString()`; + return `${target} += \`\${${input}}\``; }, toQueryStringTemplate(input, target, key) { return `${target}.push(\`${key}=\${${input}}\`)`; @@ -282,10 +268,7 @@ export function tsBigIntFromSchema( return `${target} += \`"\${${input}.toString()}"\``; }, toQueryStringTemplate(input, target, key) { - if (schema.nullable) { - return `${target}.push(\`${key}=\${${input}?.toString()}\`)`; - } - return `${target}.push(\`${key}=\${${input}.toString()}\`)`; + return `${target}.push(\`${key}=\${${input}}\`)`; }, content: "", }; diff --git a/languages/ts/ts-codegen/src/record.ts b/languages/ts/ts-codegen/src/record.ts index 8e227f73..4c7a3d01 100644 --- a/languages/ts/ts-codegen/src/record.ts +++ b/languages/ts/ts-codegen/src/record.ts @@ -26,8 +26,8 @@ export function tsRecordFromSchema( typeName: schema.nullable ? `${typeName} | null` : typeName, defaultValue, validationTemplate(input) { - const mainPart = `isObject(${input}) && Object.entries(${input}).every( - ([_, value]) => ${innerType.validationTemplate("value")}, + const mainPart = `isObject(${input}) && Object.values(${input}).every( + (_value) => ${innerType.validationTemplate("_value")}, )`; if (schema.nullable) { return `((${mainPart}) || ${input} === null)`; @@ -37,8 +37,8 @@ export function tsRecordFromSchema( fromJsonTemplate(input, target) { return `if (isObject(${input})) { ${target} = {}; - for (const [_key, _value] of Object.entries(input.record)) { - ${target}Value: ${innerType.typeName}; + for (const [_key, _value] of Object.entries(${input})) { + let ${target}Value: ${innerType.typeName}; if (typeof _value === 'boolean') { ${target}Value = _value; } else { @@ -53,10 +53,10 @@ export function tsRecordFromSchema( toJsonTemplate(input, target, key) { const countVal = `_${validVarName(key)}PropertyCount`; if (schema.nullable) { - return `if (isObject(${input})) { + return `if (${input} !== null) { ${target} += '{'; let ${countVal} = 0; - for (const [_key, _value] of Object.entries(${target})) { + for (const [_key, _value] of Object.entries(${input})) { if (${countVal} !== 0) { ${target} += ','; } @@ -83,7 +83,7 @@ export function tsRecordFromSchema( `; }, toQueryStringTemplate(_, __, ___) { - return `console.warn('[WARNING] Cannot serialize nested objects to query params. Skipping property at ${context.instancePath}.')`; + return `console.warn('[WARNING] Cannot serialize nested objects to query string. Skipping property at ${context.instancePath}.')`; }, content: innerType.content, }; From 1e744386a757ec6cfcbe2a00427532828877135f Mon Sep 17 00:00:00 2001 From: joshmossas Date: Tue, 23 Jul 2024 00:56:36 -0500 Subject: [PATCH 14/18] further progress on ts codegen --- .vscode/settings.json | 1 + languages/ts/ts-client/src/request.ts | 3 + .../src/referenceClient.ts | 508 +++++++++++++++++- languages/ts/ts-codegen/src/enum.ts | 8 +- languages/ts/ts-codegen/src/object.ts | 10 +- languages/ts/ts-codegen/src/primitives.ts | 8 +- 6 files changed, 506 insertions(+), 32 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f23f93ed..c7508e98 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -31,6 +31,7 @@ "middlewares", "modii", "nitropack", + "nocheck", "ofetch", "pathe", "postversion", diff --git a/languages/ts/ts-client/src/request.ts b/languages/ts/ts-client/src/request.ts index a9c8b7d1..4a8b884f 100644 --- a/languages/ts/ts-client/src/request.ts +++ b/languages/ts/ts-client/src/request.ts @@ -152,6 +152,9 @@ export const UINT16_MAX = 65535; export const INT32_MIN = -2147483648; export const INT32_MAX = 2147483647; export const UINT32_MAX = 4294967295; +export const INT64_MIN = BigInt("9223372036854775808"); +export const INT64_MAX = BigInt("9223372036854775807"); +export const UINT64_MAX = BigInt("18446744073709551615"); export function isObject(input: unknown): input is Record { return typeof input === "object" && input !== null; diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index 75319ab9..0e6179fe 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -1,3 +1,5 @@ +/* eslint-disable */ +// @ts-nocheck import { ArriEnumValidator, ArriModelValidator, @@ -10,12 +12,15 @@ import { INT16_MIN, INT32_MAX, INT32_MIN, + INT64_MAX, + INT64_MIN, isObject, serializeString, SseOptions, UINT8_MAX, UINT16_MAX, UINT32_MAX, + UINT64_MAX, WsOptions, } from "@arrirpc/client"; @@ -101,9 +106,9 @@ export class ExampleClientBooksService { headers: this._headers, parser: $$Book.fromJsonString, serializer: $$BookParams.toJsonString, - onOpen: options.onOpen, - onClose: options.onClose, - onError: options.onError, + onOpen: () => options.onOpen(), + onClose: () => options.onClose(), + onError: (err) => options.onError(err), onConnectionError: options.onConnectionError, onMessage: options.onMessage, clientVersion: "20", @@ -370,7 +375,11 @@ export const $$ObjectWithEveryType: ArriModelValidator = { (input.uint32 as number) >= 0 && (input.uint32 as number) <= UINT32_MAX && typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX && typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX && (input.uint64 as bigint) >= BigInt(0) && $$Enumerator.validate(input.enum) && $$NestedObject.validate(input.object) && @@ -574,29 +583,29 @@ export const $$ObjectWithEveryType: ArriModelValidator = { json += '"string":'; json += serializeString(input.string); json += ',"boolean":'; - json += input.boolean.toString(); + json += `${input.boolean}`; json += ',"timestamp":'; json += `"${input.timestamp.toISOString()}"`; json += ',"float32":'; - json += input.float32.toString(); + json += `${input.float32}`; json += ',"float64":'; - json += input.float64.toString(); + json += `${input.float64}`; json += ',"int8":'; - json += input.int8.toString(); + json += `${input.int8}`; json += ',"uint8":'; - json += input.uint8.toString(); + json += `${input.uint8}`; json += ',"int16":'; - json += input.int16.toString(); + json += `${input.int16}`; json += ',"uint16":'; - json += input.uint16.toString(); + json += `${input.uint16}`; json += ',"int32":'; - json += input.int32.toString(); + json += `${input.int32}`; json += ',"uint32":'; - json += input.uint32.toString(); + json += `${input.uint32}`; json += ',"int64":'; - json += `"${input.int64.toString()}"`; + json += `"${input.int64}"`; json += ',"uint64":'; - json += `"${input.uint64.toString()}"`; + json += `"${input.uint64}"`; json += ',"enum":'; json += `"${input.enum}"`; json += ',"object":'; @@ -952,6 +961,8 @@ export interface ObjectWithOptionalFields { uint16?: number; int32?: number; uint32?: number; + int64?: bigint; + uint64?: bigint; enum?: Enumerator; object?: NestedObject; array?: boolean[]; @@ -1007,8 +1018,16 @@ export const $$ObjectWithOptionalFields: ArriModelValidator= 0 && input.uint32 <= UINT32_MAX) || typeof input.uint32 === "undefined") && + ((typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX) || + typeof input.int64 === "undefined") && + ((typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX) || + typeof input.uint64 === "undefined") && ($$Enumerator.validate(input.enum) || - typeof input.enum === "string") && + typeof input.enum === "undefined") && ($$NestedObject.validate(input.object) || typeof input.object === "undefined") && ((Array.isArray(input.array) && @@ -1023,9 +1042,454 @@ export const $$ObjectWithOptionalFields: ArriModelValidator= INT8_MIN && + input.int8 <= INT8_MAX + ) { + _int8 = input.int8; + } else { + _int8 = 0; + } + } + let _uint8: number | undefined; + if (typeof input.uint8 !== "undefined") { + if ( + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX + ) { + _uint8 = input.uint8; + } else { + _uint8 = 0; + } + } + let _int16: number | undefined; + if (typeof input.int16 !== "undefined") { + if ( + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX + ) { + _int16 = input.int16; + } else { + _int16 = 0; + } + } + let _uint16: number | undefined; + if (typeof input.uint16 !== "undefined") { + if ( + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX + ) { + _uint16 = input.uint16; + } else { + _uint16 = 0; + } + } + let _int32: number | undefined; + if (typeof input.int32 !== "undefined") { + if ( + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX + ) { + _int32 = input.int32; + } else { + _int32 = 0; + } + } + let _uint32: number | undefined; + if (typeof input.uint32 !== "undefined") { + if ( + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX + ) { + _uint32 = input.uint32; + } else { + _uint32 = 0; + } + } + let _int64: bigint | undefined; + if (typeof input.int64 !== "undefined") { + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); + } else if (typeof input.int64 === "bigint") { + _int64 = input.int64; + } else { + _int64 = BigInt(0); + } + } + let _uint64: bigint | undefined; + if (typeof input.uint64 !== "undefined") { + if ( + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) + ) { + _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; + } else { + _uint64 = BigInt(0); + } + } + let _enum: Enumerator | undefined; + if (typeof input.enum !== "undefined") { + if (typeof input.enum === "string") { + _enum = $$Enumerator.fromSerialValue(input.enum); + } else { + _enum = $$Enumerator.new(); + } + } + let _object: NestedObject | undefined; + if (typeof input.object !== "undefined") { + if (isObject(input.object)) { + _object = $$NestedObject.fromJson(input.object); + } else { + _object = $$NestedObject.new(); + } + } + let _array: boolean[] | undefined; + if (typeof input.array !== "undefined") { + if (Array.isArray(input.array)) { + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; + } else { + _arrayElValue = false; + } + _array.push(_arrayElValue); + } + } else { + _array = []; + } + } + let _record: Record | undefined; + if (typeof input.record !== "undefined") { + if (isObject(input.record)) { + _record = {}; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean; + if (typeof _value === "boolean") { + _recordValue = _value; + } else { + _recordValue = false; + } + _record[_key] = _recordValue; + } + } else { + _record = {}; + } + } + let _discriminator: Discriminator | undefined; + if (typeof input.discriminator !== "undefined") { + if (isObject(input.discriminator)) { + _discriminator = $$Discriminator.fromJson( + input.discriminator, + ); + } else { + _discriminator = $$Discriminator.new(); + } + } + let _any: any | undefined; + if (typeof input.any !== "undefined") { + _any = input.any; + } + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enum: _enum, + object: _object, + array: _array, + record: _record, + discriminator: _discriminator, + any: _any, + }; + }, + fromJsonString(input): ObjectWithOptionalFields { + return $$ObjectWithOptionalFields.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + let _hasKey = false; + if (typeof input.string !== "undefined") { + if (_hasKey) json += ","; + json += '"string":'; + json += serializeString(input.string); + _hasKey = true; + } + if (typeof input.boolean !== "undefined") { + if (_hasKey) json += ","; + json += '"boolean":'; + json += `${input.boolean}`; + _hasKey = true; + } + if (typeof input.timestamp !== "undefined") { + if (_hasKey) json += ","; + json += '"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + _hasKey = true; + } + if (typeof input.float32 !== "undefined") { + if (_hasKey) json += ","; + json += '"float32":'; + json += `${input.float32}`; + _hasKey = true; + } + if (typeof input.float64 !== "undefined") { + if (_hasKey) json += ","; + json += '"float64":'; + json += `${input.float64}`; + _hasKey = true; + } + if (typeof input.int8 !== "undefined") { + if (_hasKey) json += ","; + json += '"int8":'; + json += `${input.int8}`; + _hasKey = true; + } + if (typeof input.uint8 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint8":'; + json += `${input.uint8}`; + _hasKey = true; + } + if (typeof input.int16 !== "undefined") { + if (_hasKey) json += ","; + json += '"int16":'; + json += `${input.int16}`; + _hasKey = true; + } + if (typeof input.uint16 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint16":'; + json += `${input.uint16}`; + _hasKey = true; + } + if (typeof input.int32 !== "undefined") { + if (_hasKey) json += ","; + json += '"int32":'; + json += `${input.int32}`; + _hasKey = true; + } + if (typeof input.uint32 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint32":'; + json += `${input.uint32}`; + _hasKey = true; + } + if (typeof input.int64 !== "undefined") { + if (_hasKey) json += ","; + json += '"int64":'; + json += `"${input.int64}"`; + _hasKey = true; + } + if (typeof input.uint64 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint64":'; + json += `"${input.uint64}"`; + _hasKey = true; + } + if (typeof input.enum !== "undefined") { + if (_hasKey) json += ","; + json += '"enum":'; + json += `"${input.enum}"`; + _hasKey = true; + } + if (typeof input.object !== "undefined") { + if (_hasKey) json += ","; + json += '"object":'; + json += $$NestedObject.toJsonString(input.object); + _hasKey = true; + } + if (typeof input.array !== "undefined") { + if (_hasKey) json += ","; + json += '"array":'; + json += "["; + for (let i = 0; i < input.array.length; i++) { + if (i !== 0) { + json += ","; + } + const _element = input.array[i]; + json += `${_element}`; + } + json += "]"; + _hasKey = true; + } + if (typeof input.record !== "undefined") { + if (_hasKey) json += ","; + json += '"record":'; + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(json)) { + if (_recordPropertyCount !== 0) { + json += ","; + } + json += `"${_key}":`; + json += `${_value}`; + _recordPropertyCount++; + } + json += "}"; + _hasKey = true; + } + if (typeof input.discriminator !== "undefined") { + if (_hasKey) json += ","; + json += '"discriminator":'; + json += $$Discriminator.toJsonString(input.discriminator); + _hasKey = true; + } + if (typeof input.any !== "undefined") { + if (_hasKey) json += ","; + json += '"any":'; + json += JSON.stringify(input.any); + _hasKey = true; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + if (typeof input.string !== "undefined") { + queryParts.push(`string=${input.string}`); + } + if (typeof input.boolean !== "undefined") { + queryParts.push(`boolean=${input.boolean}`); + } + if (typeof input.timestamp !== "undefined") { + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + } + if (typeof input.float32 !== "undefined") { + queryParts.push(`float32=${input.float32}`); + } + if (typeof input.float64 !== "undefined") { + queryParts.push(`float64=${input.float64}`); + } + if (typeof input.int8 !== "undefined") { + queryParts.push(`int8=${input.int8}`); + } + if (typeof input.uint8 !== "undefined") { + queryParts.push(`uint8=${input.uint8}`); + } + if (typeof input.int16 !== "undefined") { + queryParts.push(`int16=${input.int16}`); + } + if (typeof input.uint16 !== "undefined") { + queryParts.push(`uint16=${input.uint16}`); + } + if (typeof input.int32 !== "undefined") { + queryParts.push(`int32=${input.int32}`); + } + if (typeof input.uint32 !== "undefined") { + queryParts.push(`uint32=${input.uint32}`); + } + if (typeof input.int64 !== "undefined") { + queryParts.push(`int64=${input.int64}`); + } + if (typeof input.uint64 !== "undefined") { + queryParts.push(`uint64=${input.uint64}`); + } + if (typeof input.enum !== "undefined") { + queryParts.push(`enum=${input.enum}`); + } + if (typeof input.object !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithOptionalFields/object.", + ); + } + if (typeof input.array !== "undefined") { + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithOptionalFields/array.", + ); + } + if (typeof input.record !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithOptionalFields/record.", + ); + } + if (typeof input.discriminator !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithOptionalFields/discriminator.", + ); + } + if (typeof input.any !== "undefined") { + console.warn( + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithOptionalFields/any.", + ); + } + return queryParts.join("&"); + }, }; export interface ObjectWithNullableFields { @@ -1113,9 +1577,13 @@ export const $$ObjectWithNullableFields: ArriModelValidator= 0 && input.uint32 <= UINT32_MAX) || input.uint32 === null) && - (typeof input.int64 === "bigint" || input.int64 === null) && + ((typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX) || + input.int64 === null) && ((typeof input.uint64 === "bigint" && - input.uint64 >= BigInt(0)) || + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX) || input.uint64 === null) && ($$Enumerator.validate(input.enum) || input.enum === null) && ($$NestedObject.validate(input.object) || @@ -1365,13 +1833,13 @@ export const $$ObjectWithNullableFields: ArriModelValidator= BigInt(0)` - : `typeof ${input} === 'bigint'`; + ? `typeof ${input} === 'bigint' && ${input} >= BigInt(0) && ${input} <= UINT64_MAX` + : `typeof ${input} === 'bigint' && ${input} >= INT64_MIN && ${input} <= INT64_MAX`; if (schema.nullable) { return `((${mainPart}) || ${input} === null)`; } @@ -260,12 +260,12 @@ export function tsBigIntFromSchema( toJsonTemplate(input, target) { if (schema.nullable) { return `if (typeof ${input} === 'bigint') { - ${target} += \`"\${${input}.toString()}"\` + ${target} += \`"\${${input}}"\` } else { ${target} += 'null'; }`; } - return `${target} += \`"\${${input}.toString()}"\``; + return `${target} += \`"\${${input}}"\``; }, toQueryStringTemplate(input, target, key) { return `${target}.push(\`${key}=\${${input}}\`)`; From 1847167b0519669752791aa2b0f232406b37a024 Mon Sep 17 00:00:00 2001 From: joshmossas Date: Tue, 23 Jul 2024 00:59:14 -0500 Subject: [PATCH 15/18] updates --- languages/ts/ts-codegen-reference/src/referenceClient.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index 0e6179fe..f55f264c 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -101,14 +101,14 @@ export class ExampleClientBooksService { ); } async createConnection(options: WsOptions = {}) { - return arriWsRequest({ + return arriWsRequest({ url: `${this._baseUrl}/books/create-connection`, headers: this._headers, parser: $$Book.fromJsonString, serializer: $$BookParams.toJsonString, - onOpen: () => options.onOpen(), - onClose: () => options.onClose(), - onError: (err) => options.onError(err), + onOpen: options.onOpen, + onClose: options.onClose, + onError: options.onError, onConnectionError: options.onConnectionError, onMessage: options.onMessage, clientVersion: "20", From b7668ce1b4d9a8a5cc087a1bc039e6fc5970f6ad Mon Sep 17 00:00:00 2001 From: Joshua Sosso Date: Tue, 23 Jul 2024 08:01:08 -0500 Subject: [PATCH 16/18] getting codegen more in alignment with reference --- languages/ts/ts-client/src/ws.ts | 2 +- .../src/referenceClient.ts | 247 +++++++++--------- languages/ts/ts-codegen/project.json | 7 + languages/ts/ts-codegen/src/array.ts | 8 +- languages/ts/ts-codegen/src/discriminator.ts | 47 ++-- languages/ts/ts-codegen/src/object.ts | 24 +- languages/ts/ts-codegen/src/record.ts | 2 +- languages/ts/ts-codegen/src/ref.ts | 2 +- languages/ts/ts-codegen/tsconfig.json | 20 +- languages/ts/ts-codegen/tsconfig.lib.json | 10 - languages/ts/ts-codegen/tsconfig.spec.json | 19 -- languages/ts/ts-codegen/vite.config.ts | 3 +- 12 files changed, 186 insertions(+), 205 deletions(-) delete mode 100644 languages/ts/ts-codegen/tsconfig.lib.json delete mode 100644 languages/ts/ts-codegen/tsconfig.spec.json diff --git a/languages/ts/ts-client/src/ws.ts b/languages/ts/ts-client/src/ws.ts index be1b67c3..da1fdb79 100644 --- a/languages/ts/ts-client/src/ws.ts +++ b/languages/ts/ts-client/src/ws.ts @@ -94,7 +94,7 @@ export async function arriWsRequest< type WsErrorHook = (err: ArriErrorInstance) => void; type WsMessageHook = (msg: TResponse) => any; -class WsController { +export class WsController { url: string; private _ws?: NodeWebsocket | WebSocket; private readonly _serializer: (input: TParams) => string; diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index f55f264c..bd5e4e7f 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -131,55 +131,55 @@ export const $$Book: ArriModelValidator = { updatedAt: new Date(), }; }, - validate(input: unknown): input is Book { + validate(input): input is Book { return ( isObject(input) && - input.id === "string" && - input.name === "string" && + typeof input.id === "string" && + typeof input.name === "string" && input.createdAt instanceof Date && input.updatedAt instanceof Date ); }, - fromJson(input: Record): Book { - let id: string; + fromJson(input): Book { + let _id: string; if (typeof input.id === "string") { - id = input.id; + _id = input.id; } else { - id = ""; + _id = ""; } - let name: string; + let _name: string; if (typeof input.name === "string") { - name = input.name; + _name = input.name; } else { - name = ""; + _name = ""; } - let createdAt: Date; + let _createdAt: Date; if (typeof input.createdAt === "string") { - createdAt = new Date(input.createdAt); + _createdAt = new Date(input.createdAt); } else if (input.createdAt instanceof Date) { - createdAt = input.createdAt; + _createdAt = input.createdAt; } else { - createdAt = new Date(); + _createdAt = new Date(); } - let updatedAt: Date; + let _updatedAt: Date; if (typeof input.updatedAt === "string") { - updatedAt = new Date(input.updatedAt); + _updatedAt = new Date(input.updatedAt); } else if (input.updatedAt instanceof Date) { - updatedAt = input.updatedAt; + _updatedAt = input.updatedAt; } else { - updatedAt = new Date(); + _updatedAt = new Date(); } return { - id, - name, - createdAt, - updatedAt, + id: _id, + name: _name, + createdAt: _createdAt, + updatedAt: _updatedAt, }; }, - fromJsonString(input: string): Book { + fromJsonString(input): Book { return $$Book.fromJson(JSON.parse(input)); }, - toJsonString(input: Book): string { + toJsonString(input): string { let json = "{"; json += '"id":'; json += serializeString(input.id); @@ -187,7 +187,7 @@ export const $$Book: ArriModelValidator = { json += serializeString(input.name); json += ',"createdAt":'; json += `"${input.createdAt.toISOString()}"`; - json += `,"updatedAt":`; + json += ',"updatedAt":'; json += `"${input.updatedAt.toISOString()}"`; json += "}"; return json; @@ -211,26 +211,26 @@ export const $$BookParams: ArriModelValidator = { bookId: "", }; }, - validate(input: unknown): input is BookParams { + validate(input): input is BookParams { return isObject(input) && typeof input.bookId === "string"; }, - fromJson(input: Record): BookParams { - let bookId: string; + fromJson(input): BookParams { + let _bookId: string; if (typeof input.bookId === "string") { - bookId = input.bookId; + _bookId = input.bookId; } else { - bookId = ""; + _bookId = ""; } return { - bookId, + bookId: _bookId, }; }, - fromJsonString(input: string): BookParams { + fromJsonString(input): BookParams { return $$BookParams.fromJson(JSON.parse(input)); }, - toJsonString(input: BookParams): string { + toJsonString(input): string { let json = "{"; - json += `"bookId":`; + json += '"bookId":'; json += serializeString(input.bookId); json += "}"; return json; @@ -253,35 +253,35 @@ export const $$NestedObject: ArriModelValidator = { content: "", }; }, - validate(input: unknown): input is NestedObject { + validate(input): input is NestedObject { return ( isObject(input) && typeof input.id === "string" && typeof input.content === "string" ); }, - fromJson(input: Record): NestedObject { - let id: string; + fromJson(input): NestedObject { + let _id: string; if (typeof input.id === "string") { - id = input.id; + _id = input.id; } else { - id = ""; + _id = ""; } - let content: string; + let _content: string; if (typeof input.content === "string") { - content = input.content; + _content = input.content; } else { - content = ""; + _content = ""; } return { - id, - content, + id: _id, + content: _content, }; }, - fromJsonString(input: string): NestedObject { + fromJsonString(input): NestedObject { return $$NestedObject.fromJson(JSON.parse(input)); }, - toJsonString(input: NestedObject): string { + toJsonString(input): string { let json = "{"; json += '"id":'; json += serializeString(input.id); @@ -335,7 +335,7 @@ export const $$ObjectWithEveryType: ArriModelValidator = { uint32: 0, int64: BigInt(0), uint64: BigInt(0), - enum: "FOO", + enum: $$Enumerator.new(), object: $$NestedObject.new(), array: [], record: {}, @@ -353,43 +353,44 @@ export const $$ObjectWithEveryType: ArriModelValidator = { typeof input.float64 === "number" && typeof input.int8 === "number" && Number.isInteger(input.int8) && - (input.int8 as number) >= INT8_MIN && - (input.int8 as number) <= INT8_MAX && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX && typeof input.uint8 === "number" && - (input.uint8 as number) >= 0 && - (input.uint8 as number) <= UINT8_MAX && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX && typeof input.int16 === "number" && Number.isInteger(input.int16) && - (input.int16 as number) >= INT16_MIN && - (input.int16 as number) <= INT16_MAX && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX && typeof input.uint16 === "number" && Number.isInteger(input.uint16) && - (input.uint16 as number) >= 0 && - (input.uint16 as number) <= UINT16_MAX && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX && typeof input.int32 === "number" && Number.isInteger(input.int32) && - (input.int32 as number) >= INT32_MIN && - (input.int32 as number) <= UINT32_MAX && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX && typeof input.uint32 === "number" && Number.isInteger(input.uint32) && - (input.uint32 as number) >= 0 && - (input.uint32 as number) <= UINT32_MAX && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX && typeof input.int64 === "bigint" && input.int64 >= INT64_MIN && input.int64 <= INT64_MAX && typeof input.uint64 === "bigint" && input.uint64 >= BigInt(0) && input.uint64 <= UINT64_MAX && - (input.uint64 as bigint) >= BigInt(0) && $$Enumerator.validate(input.enum) && $$NestedObject.validate(input.object) && Array.isArray(input.array) && - input.array.every((value) => typeof value === "boolean") && + input.array.every((_element) => typeof _element === "boolean") && isObject(input.record) && - Object.entries(input.record).every( - ([_, value]) => typeof value === "boolean", + Object.values(input.record).every( + (_value) => typeof _value === "boolean", ) && - $$Discriminator.validate(input.discriminator) + $$Discriminator.validate(input.discriminator) && + true ); }, fromJson(input): ObjectWithEveryType { @@ -408,8 +409,8 @@ export const $$ObjectWithEveryType: ArriModelValidator = { let _timestamp: Date; if (typeof input.timestamp === "string") { _timestamp = new Date(input.timestamp); - } else if (input instanceof Date) { - _timestamp = input; + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { _timestamp = new Date(); } @@ -494,20 +495,30 @@ export const $$ObjectWithEveryType: ArriModelValidator = { let _int64: bigint; if (typeof input.int64 === "string") { _int64 = BigInt(input.int64); + } else if (typeof input.int64 === "bigint") { + _int64 = input.int64; } else { _int64 = BigInt(0); } let _uint64: bigint; - if (typeof input.uint64 === "string") { + if ( + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) + ) { _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; } else { _uint64 = BigInt(0); } let _enum: Enumerator; - if ($$Enumerator.validate(input.enum)) { - _enum = input.enum; + if (typeof input.enum === "string") { + _enum = $$Enumerator.fromSerialValue(input.enum); } else { - _enum = "FOO"; + _enum = $$Enumerator.new(); } let _object: NestedObject; if (isObject(input.object)) { @@ -613,9 +624,9 @@ export const $$ObjectWithEveryType: ArriModelValidator = { json += ',"array":'; json += "["; for (let i = 0; i < input.array.length; i++) { - const _element = input.array[i]!; if (i !== 0) json += ","; - json += _element.toString(); + const _element = input.array[i]; + json += `${_element}`; } json += "]"; json += ',"record":'; @@ -654,16 +665,19 @@ export const $$ObjectWithEveryType: ArriModelValidator = { queryParts.push(`uint64=${input.uint64}`); queryParts.push(`enum=${input.enum}`); console.warn( - `[WARNING] Cannot serialize nested objects to query params. Ignoring property at /ObjectWithEveryType/object.`, + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/object.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryType/array.", ); console.warn( - `[WARNING] Cannot serialize arrays to query params. Ignoring property at /ObjectWithEveryType/array.`, + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/record.", ); console.warn( - `[WARNING] Cannot serialize nested objects to query params. Ignoring property at /ObjectWithEveryType/record.`, + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/discriminator.", ); console.warn( - `[WARNING] Cannot serialize any's to query params. Ignoring property at /ObjectWithEveryType/any.`, + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithEveryType/any.", ); return queryParts.join("&"); }, @@ -743,7 +757,6 @@ export const $$Discriminator: ArriModelValidator = { case "C": return $$DiscriminatorC.toJsonString(input); default: - input satisfies never; throw new Error(`Unhandled case "${(input as any).typeName}"`); } }, @@ -779,16 +792,16 @@ const $$DiscriminatorA: ArriModelValidator = { ); }, fromJson(input): DiscriminatorA { - const typeName = "A"; - let id: string; + const _typeName = "A"; + let _id: string; if (typeof input.id === "string") { - id = input.id; + _id = input.id; } else { - id = ""; + _id = ""; } return { - typeName, - id, + typeName: _typeName, + id: _id, }; }, fromJsonString(input): DiscriminatorA { @@ -804,7 +817,7 @@ const $$DiscriminatorA: ArriModelValidator = { }, toUrlQueryString(input): string { const queryParts: string[] = []; - queryParts.push(`typeName=A`); + queryParts.push("typeName=A"); queryParts.push(`id=${input.id}`); return queryParts.join("&"); }, @@ -831,23 +844,23 @@ const $$DiscriminatorB: ArriModelValidator = { ); }, fromJson(input): DiscriminatorB { - const typeName = "B"; - let id: string; + const _typeName = "B"; + let _id: string; if (typeof input.id === "string") { - id = input.id; + _id = input.id; } else { - id = ""; + _id = ""; } - let name: string; + let _name: string; if (typeof input.name === "string") { - name = input.name; + _name = input.name; } else { - name = ""; + _name = ""; } return { - typeName, - id, - name, + typeName: _typeName, + id: _id, + name: _name, }; }, fromJsonString(input): DiscriminatorB { @@ -896,32 +909,32 @@ const $$DiscriminatorC: ArriModelValidator = { ); }, fromJson(input): DiscriminatorC { - const typeName = "C"; - let id: string; + const _typeName = "C"; + let _id: string; if (typeof input.id === "string") { - id = input.id; + _id = input.id; } else { - id = ""; + _id = ""; } - let name: string; + let _name: string; if (typeof input.name === "string") { - name = input.name; + _name = input.name; } else { - name = ""; + _name = ""; } - let date: Date; + let _date: Date; if (typeof input.date === "string") { - date = new Date(input.date); + _date = new Date(input.date); } else if (input.date instanceof Date) { - date = input.date; + _date = input.date; } else { - date = new Date(); + _date = new Date(); } return { - typeName, - id, - name, - date, + typeName: _typeName, + id: _id, + name: _name, + date: _date, }; }, fromJsonString(input): DiscriminatorC { @@ -985,7 +998,7 @@ export const $$ObjectWithOptionalFields: ArriModelValidator = { toUrlQueryString(input): string { const queryParts: string[] = []; console.warn( - "[WARNING] Nested objects cannot be serialized to query params. Ignoring property at /RecursiveObject/left.", + "[WARNING] Nested objects cannot be serialized to query string. Ignoring property at /RecursiveObject/left.", ); console.warn( - "[WARNING] Nested objects cannot be serialized to query params. Ignoring property at /RecursiveObject/right.", + "[WARNING] Nested objects cannot be serialized to query string. Ignoring property at /RecursiveObject/right.", ); return queryParts.join("&"); }, diff --git a/languages/ts/ts-codegen/project.json b/languages/ts/ts-codegen/project.json index 0db65bb2..80766f16 100644 --- a/languages/ts/ts-codegen/project.json +++ b/languages/ts/ts-codegen/project.json @@ -34,6 +34,13 @@ "reportsDirectory": "../../coverage/languages/ts/ts-codegen" } }, + "show-test-results": { + "executor": "nx:run-commands", + "options": { + "command": "vite preview --outDir .temp/test-results", + "cwd": "languages/ts/ts-codegen" + } + }, "typecheck": { "executor": "nx:run-commands", "options": { diff --git a/languages/ts/ts-codegen/src/array.ts b/languages/ts/ts-codegen/src/array.ts index b4a5af57..43605912 100644 --- a/languages/ts/ts-codegen/src/array.ts +++ b/languages/ts/ts-codegen/src/array.ts @@ -53,9 +53,7 @@ export function tsArrayFromSchema( return `if (${input} !== null) { ${target} += '['; for (let i = 0; i < ${input}.length; i++) { - if (i !== 0) { - ${target} += ','; - } + if (i !== 0) ${target} += ','; const _element = ${input}[i]; ${innerType.toJsonTemplate(`_element`, target, "_elementKey")} } @@ -66,9 +64,7 @@ export function tsArrayFromSchema( } return `${target} += '['; for (let i = 0; i < ${input}.length; i++) { - if (i !== 0) { - ${target} += ','; - } + if (i !== 0) ${target} += ','; const _element = ${input}[i]; ${innerType.toJsonTemplate("_element", target, `_elementKey`)} } diff --git a/languages/ts/ts-codegen/src/discriminator.ts b/languages/ts/ts-codegen/src/discriminator.ts index ba62f67a..1e5fb504 100644 --- a/languages/ts/ts-codegen/src/discriminator.ts +++ b/languages/ts/ts-codegen/src/discriminator.ts @@ -47,7 +47,7 @@ export function tsTaggedUnionFromSchema( }, content: "", }; - if (!context.generatedTypes.includes(typeName)) return result; + if (context.generatedTypes.includes(typeName)) return result; const subTypes: { value: string; data: TsProperty }[] = []; const discriminatorKey = schema.discriminator; for (const key of Object.keys(schema.mapping)) { @@ -68,7 +68,7 @@ export function tsTaggedUnionFromSchema( subTypes.push({ value: key, data: subType }); } result.content = `export type ${prefixedTypeName} = ${subTypes.map((type) => type.data.typeName).join(" |")}; -export const $$${prefixedTypeName}: ArriModelValidator<${subTypes[0]!.data.typeName}> = { +export const $$${prefixedTypeName}: ArriModelValidator<${prefixedTypeName}> = { new(): ${prefixedTypeName} { return $$${subTypes[0]!.data.typeName}.new(); }, @@ -80,46 +80,57 @@ export const $$${prefixedTypeName}: ArriModelValidator<${subTypes[0]!.data.typeN return false; } switch (input.${discriminatorKey}) { -${subTypes.map( - (type) => ` case "${type.value}": +${subTypes + .map( + (type) => ` case "${type.value}": return $$${type.data.typeName}.validate(input);`, -)} + ) + .join("\n")} default: return false; } }, fromJson(input): ${prefixedTypeName} { switch (input.${discriminatorKey}) { -${subTypes.map( - (type) => ` case "${type.value}": +${subTypes + .map( + (type) => ` case "${type.value}": return $$${type.data.typeName}.fromJson(input);`, -)} + ) + .join("\n")} default: return $$${subTypes[0]!.data.typeName}.new(); } }, + fromJsonString(input): ${prefixedTypeName} { + return $$${prefixedTypeName}.fromJson(JSON.parse(input)); + }, toJsonString(input): string { switch (input.${discriminatorKey}) { -${subTypes.map( - (type) => ` case "${type.value}": - return $$${type.data.typeName}.toJsonString(input); +${subTypes + .map( + (type) => ` case "${type.value}": + return $$${type.data.typeName}.toJsonString(input);`, + ) + .join("\n")} default: - input satisfied never; - throw new Error(\`Unhandled case "\${(input as any).${discriminatorKey}}"\`);`, -)} + throw new Error(\`Unhandled case "\${(input as any).${discriminatorKey}}"\`); } }, toUrlQueryString(input): string { switch (input.${discriminatorKey}) { -${subTypes.map( - (type) => ` case "${type.value}": +${subTypes + .map( + (type) => ` case "${type.value}": return $$${type.data.typeName}.toUrlQueryString(input);`, -)} + ) + .join("\n")} default: throw new Error('Unhandled case'); } } -} +} +${subTypes.map((type) => type.data.content).join("\n")} `; context.generatedTypes.push(typeName); return result; diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index 46e016c9..5804cc20 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -14,21 +14,24 @@ export function tsObjectFromSchema( context: CodegenContext, ): TsProperty { const typeName = getTsTypeName(schema, context); - const defaultValue = schema.nullable ? "null" : `$$${typeName}.new()`; + const prefixedTypeName = `${context.typePrefix}${typeName}`; + const defaultValue = schema.nullable + ? "null" + : `$$${prefixedTypeName}.new()`; const result: TsProperty = { typeName: schema.nullable - ? `${context.typePrefix}${typeName} | null` - : `${context.typePrefix}${typeName}`, + ? `${prefixedTypeName} | null` + : prefixedTypeName, defaultValue, validationTemplate(input) { if (schema.nullable) { - return `($$${typeName}.validate(${input}) || ${input} === null)`; + return `($$${prefixedTypeName}.validate(${input}) || ${input} === null)`; } - return `$$${typeName}.validate(${input})`; + return `$$${prefixedTypeName}.validate(${input})`; }, fromJsonTemplate(input, target) { return `if (isObject(${input})) { - ${target} = $$${context.typePrefix}${typeName}.fromJson(${input}); + ${target} = $$${prefixedTypeName}.fromJson(${input}); } else { ${target} = ${defaultValue}; }`; @@ -36,12 +39,12 @@ export function tsObjectFromSchema( toJsonTemplate(input, target) { if (schema.nullable) { return `if (${input} !== null) { - ${target} += $$${context.typePrefix}${typeName}.toJsonString(${input}); + ${target} += $$${prefixedTypeName}.toJsonString(${input}); } else { ${target} += 'null'; }`; } - return `${target} += $$${context.typePrefix}${typeName}.toJsonString(${input});`; + return `${target} += $$${prefixedTypeName}.toJsonString(${input});`; }, toQueryStringTemplate(_input, _target) { return `console.warn("[WARNING] Cannot serialize nested objects to query string. Skipping property at ${context.instancePath}.")`; @@ -70,7 +73,7 @@ export function tsObjectFromSchema( camelCase(context.discriminatorKey, { normalize: true }), ); fieldParts.push(`${key}: "${context.discriminatorValue}",`); - fromJsonParts.push(`let _${key} = "${context.discriminatorValue}"`); + fromJsonParts.push(`const _${key} = "${context.discriminatorValue}"`); toJsonParts.push(`json += '"${key}":"${context.discriminatorValue}"'`); toQueryParts.push( `queryParts.push('${context.discriminatorKey}=${context.discriminatorValue}');`, @@ -167,12 +170,11 @@ export function tsObjectFromSchema( ); constructionParts.push(`${fieldName}: ${tempKey},`); } - const prefixedTypeName = `${context.typePrefix}${typeName}`; result.content = `${getJsDocComment(schema.metadata)}export interface ${prefixedTypeName} { ${fieldParts.map((part) => ` ${part}`).join("\n")} } -export const $$${prefixedTypeName}: ArriModelValidator<${prefixedTypeName}> = { +${context.discriminatorParent && context.discriminatorValue ? "" : "export "}const $$${prefixedTypeName}: ArriModelValidator<${prefixedTypeName}> = { new(): ${prefixedTypeName} { return { ${newParts.map((part) => ` ${part}`).join("\n")} diff --git a/languages/ts/ts-codegen/src/record.ts b/languages/ts/ts-codegen/src/record.ts index 4c7a3d01..b950002a 100644 --- a/languages/ts/ts-codegen/src/record.ts +++ b/languages/ts/ts-codegen/src/record.ts @@ -71,7 +71,7 @@ export function tsRecordFromSchema( } return `${target} += '{' let ${countVal} = 0; - for (const [_key, _value] of Object.entries(${target})) { + for (const [_key, _value] of Object.entries(${input})) { if (${countVal} !== 0) { ${target} += ','; } diff --git a/languages/ts/ts-codegen/src/ref.ts b/languages/ts/ts-codegen/src/ref.ts index 76ceda1a..bcf02b1c 100644 --- a/languages/ts/ts-codegen/src/ref.ts +++ b/languages/ts/ts-codegen/src/ref.ts @@ -38,7 +38,7 @@ export function tsRefFromSchema( return `${target} += $$${prefixedTypeName}.toJsonString(${input});`; }, toQueryStringTemplate(_, __, ___) { - return `console.warn("[WARNING] Nested objects cannot be serialized to query params. Ignoring property at ${context.instancePath}.");`; + return `console.warn("[WARNING] Nested objects cannot be serialized to query string. Ignoring property at ${context.instancePath}.");`; }, content: "", }; diff --git a/languages/ts/ts-codegen/tsconfig.json b/languages/ts/ts-codegen/tsconfig.json index c9f34274..d000c5be 100644 --- a/languages/ts/ts-codegen/tsconfig.json +++ b/languages/ts/ts-codegen/tsconfig.json @@ -1,22 +1,6 @@ { "extends": "../../../tsconfig.base.json", "compilerOptions": { - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": false, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": false, - "types": ["vitest"] - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] + "types": ["vitest", "vitest/globals", "vitest/importMeta", "node"] + } } diff --git a/languages/ts/ts-codegen/tsconfig.lib.json b/languages/ts/ts-codegen/tsconfig.lib.json deleted file mode 100644 index 33eca2c2..00000000 --- a/languages/ts/ts-codegen/tsconfig.lib.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "declaration": true, - "types": ["node"] - }, - "include": ["src/**/*.ts"], - "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] -} diff --git a/languages/ts/ts-codegen/tsconfig.spec.json b/languages/ts/ts-codegen/tsconfig.spec.json deleted file mode 100644 index 6d3be742..00000000 --- a/languages/ts/ts-codegen/tsconfig.spec.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] - }, - "include": [ - "vite.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.test.tsx", - "src/**/*.spec.tsx", - "src/**/*.test.js", - "src/**/*.spec.js", - "src/**/*.test.jsx", - "src/**/*.spec.jsx", - "src/**/*.d.ts" - ] -} diff --git a/languages/ts/ts-codegen/vite.config.ts b/languages/ts/ts-codegen/vite.config.ts index 41f0cfad..946768c8 100644 --- a/languages/ts/ts-codegen/vite.config.ts +++ b/languages/ts/ts-codegen/vite.config.ts @@ -27,7 +27,8 @@ export default defineConfig({ }, }, globals: true, - reporters: ["default"], + reporters: ["default", "html"], + outputFile: ".temp/test-results/index.html", cache: { dir: "../../../node_modules/.vitest", }, From 77d2eab0a2ee122ad38345e74b37f49246d3c45a Mon Sep 17 00:00:00 2001 From: Joshua Sosso Date: Tue, 23 Jul 2024 11:08:24 -0500 Subject: [PATCH 17/18] finalize ts-codegen v2 --- languages/ts/ts-client/src/index.test.ts | 5 +- languages/ts/ts-client/src/request.ts | 5 +- languages/ts/ts-client/src/sse.ts | 2 +- languages/ts/ts-client/src/ws.ts | 11 +- .../src/referenceClient.test.ts | 88 + .../src/referenceClient.ts | 65 +- languages/ts/ts-codegen/src/_index.ts | 44 +- languages/ts/ts-codegen/src/array.ts | 17 +- languages/ts/ts-codegen/src/common.ts | 6 +- languages/ts/ts-codegen/src/discriminator.ts | 3 +- languages/ts/ts-codegen/src/object.ts | 6 +- languages/ts/ts-codegen/src/record.ts | 3 +- languages/ts/ts-codegen/src/rpc.ts | 104 + languages/ts/ts-codegen/src/service.ts | 105 + tests/clients/ts/testClient.rpc.ts | 18355 ++++++---------- tests/clients/ts/testClient.test.ts | 23 +- 16 files changed, 6771 insertions(+), 12071 deletions(-) create mode 100644 languages/ts/ts-codegen/src/rpc.ts create mode 100644 languages/ts/ts-codegen/src/service.ts diff --git a/languages/ts/ts-client/src/index.test.ts b/languages/ts/ts-client/src/index.test.ts index a8af07c3..9b37441a 100644 --- a/languages/ts/ts-client/src/index.test.ts +++ b/languages/ts/ts-client/src/index.test.ts @@ -4,10 +4,13 @@ test("error messages", async () => { const request = await arriSafeRequest({ url: "http://thisurldoesntexist.blah", method: "get", - parser() {}, + responseFromJson() {}, + responseFromString() {}, serializer() { return undefined; }, + headers: undefined, + clientVersion: "", }); expect(!request.success); if (!request.success) { diff --git a/languages/ts/ts-client/src/request.ts b/languages/ts/ts-client/src/request.ts index 4a8b884f..de06c72d 100644 --- a/languages/ts/ts-client/src/request.ts +++ b/languages/ts/ts-client/src/request.ts @@ -13,7 +13,8 @@ export interface ArriRequestOpts< method: HttpMethod; headers: EventSourcePlusOptions["headers"]; params?: TParams; - parser: (input: string) => TType; + responseFromJson: (input: Record) => TType; + responseFromString: (input: string) => TType; serializer: ( input: TParams, ) => TParams extends undefined ? undefined : string; @@ -50,7 +51,7 @@ export async function arriRequest< body, headers, }); - return opts.parser(result); + return opts.responseFromJson(result); } catch (err) { const error = err as any as FetchError; if (isArriError(error.data)) { diff --git a/languages/ts/ts-client/src/sse.ts b/languages/ts/ts-client/src/sse.ts index d1fd7985..2d264dbd 100644 --- a/languages/ts/ts-client/src/sse.ts +++ b/languages/ts/ts-client/src/sse.ts @@ -84,7 +84,7 @@ export function arriSseRequest< message.event === undefined || message.event === "" ) { - options.onMessage?.(opts.parser(message.data)); + options.onMessage?.(opts.responseFromString(message.data)); return; } if (message.event === "done") { diff --git a/languages/ts/ts-client/src/ws.ts b/languages/ts/ts-client/src/ws.ts index da1fdb79..0d247744 100644 --- a/languages/ts/ts-client/src/ws.ts +++ b/languages/ts/ts-client/src/ws.ts @@ -11,7 +11,8 @@ function isBrowser() { interface WsControllerOptions { url: string; serializer: (input: TParams) => string; - parser: (input: string) => TResponse; + responseFromJson: (input: Record) => TResponse; + responseFromString: (input: string) => TResponse; onMessage?: WsMessageHook; onErrorMessage?: WsErrorHook; onConnectionError?: WsErrorHook; @@ -31,7 +32,8 @@ interface ArriWsRequestOptions { url: string; headers?: EventSourcePlusOptions["headers"]; params?: TParams; - parser: (input: string) => TResponse; + responseFromJson: (input: Record) => TResponse; + responseFromString: (input: string) => TResponse; serializer: (input: TParams) => string; onMessage?: WsMessageHook; onError?: WsErrorHook; @@ -72,7 +74,8 @@ export async function arriWsRequest< try { const controller = new WsController({ url, - parser: opts.parser, + responseFromJson: opts.responseFromJson, + responseFromString: opts.responseFromString, serializer: opts.serializer ?? ((_) => ""), onOpen: opts.onOpen, onClose: opts.onClose, @@ -107,7 +110,7 @@ export class WsController { constructor(opts: WsControllerOptions) { this.url = opts.url; this._serializer = opts.serializer; - this._parser = opts.parser; + this._parser = opts.responseFromString; this.onOpen = opts.onOpen; this.onClose = opts.onClose; this.onErrorMessage = opts.onErrorMessage; diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts index 599b0569..d90eff4d 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.test.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.test.ts @@ -5,10 +5,12 @@ import { $$Book, $$ObjectWithEveryType, $$ObjectWithNullableFields, + $$ObjectWithOptionalFields, $$RecursiveObject, Book, ObjectWithEveryType, ObjectWithNullableFields, + ObjectWithOptionalFields, RecursiveObject, } from "./referenceClient"; @@ -93,6 +95,84 @@ describe("ObjectWithEveryType", () => { }); }); +describe("ObjectWithOptionalFields", () => { + const allUndefinedTargetValue: ObjectWithOptionalFields = { + string: undefined, + boolean: undefined, + timestamp: undefined, + float32: undefined, + float64: undefined, + int8: undefined, + uint8: undefined, + int16: undefined, + uint16: undefined, + int32: undefined, + uint32: undefined, + int64: undefined, + uint64: undefined, + enum: undefined, + object: undefined, + array: undefined, + record: undefined, + discriminator: undefined, + any: undefined, + }; + const noUndefinedTargetValue: ObjectWithOptionalFields = { + string: "", + boolean: false, + timestamp: testDate, + float32: 1.5, + float64: 1.5, + int8: 1, + uint8: 1, + int16: 10, + uint16: 10, + int32: 100, + uint32: 100, + int64: 1000n, + uint64: 1000n, + enum: "BAZ", + object: { + id: "1", + content: "hello world", + }, + array: [true, false, false], + record: { + A: true, + B: false, + }, + discriminator: { + typeName: "C", + id: "", + name: "", + date: testDate, + }, + any: "hello world", + }; + const allUndefinedJson = testFile( + "ObjectWithOptionalFields_AllUndefined.json", + ); + const noUndefinedJson = testFile( + "ObjectWithOptionalFields_NoUndefined.json", + ); + test("JSON parsing", () => { + expect( + $$ObjectWithOptionalFields.fromJsonString(allUndefinedJson), + ).toStrictEqual(allUndefinedTargetValue); + expect( + $$ObjectWithOptionalFields.fromJsonString(noUndefinedJson), + ).toStrictEqual(noUndefinedTargetValue); + }); + test("JSON output", () => { + expect( + $$ObjectWithOptionalFields.toJsonString(allUndefinedTargetValue), + ).toEqual(allUndefinedJson); + expect( + $$ObjectWithOptionalFields.toJsonString(noUndefinedTargetValue), + ).toEqual(noUndefinedJson); + }); +}); + describe("ObjectWithNullableFields", () => { const allNullTargetValue: ObjectWithNullableFields = { string: null, @@ -161,6 +241,14 @@ describe("ObjectWithNullableFields", () => { expect(allNullResult).toStrictEqual(allNullTargetValue); expect(noNullResult).toStrictEqual(noNullTargetValue); }); + test("JSON output", () => { + expect( + $$ObjectWithNullableFields.toJsonString(allNullTargetValue), + ).toEqual(allNullJsonReference); + expect( + $$ObjectWithNullableFields.toJsonString(noNullTargetValue), + ).toEqual(noNullJsonReference); + }); }); describe("RecursiveObject", () => { diff --git a/languages/ts/ts-codegen-reference/src/referenceClient.ts b/languages/ts/ts-codegen-reference/src/referenceClient.ts index bd5e4e7f..5ddcb100 100644 --- a/languages/ts/ts-codegen-reference/src/referenceClient.ts +++ b/languages/ts/ts-codegen-reference/src/referenceClient.ts @@ -1,3 +1,6 @@ +// This file was autogenerated by @arrirpc/codegen-ts. Do not modify directly. +// For more information visit https://github.com/modiimedia/arri + /* eslint-disable */ // @ts-nocheck import { @@ -6,6 +9,7 @@ import { arriRequest, arriSseRequest, arriWsRequest, + type EventSourceController, INT8_MAX, INT8_MIN, INT16_MAX, @@ -16,36 +20,42 @@ import { INT64_MIN, isObject, serializeString, - SseOptions, + type SseOptions, UINT8_MAX, UINT16_MAX, UINT32_MAX, UINT64_MAX, - WsOptions, + type WsController, + type WsOptions, } from "@arrirpc/client"; type HeaderMap = Record; export class ExampleClient { private readonly _baseUrl: string; - private readonly _headers: HeaderMap | (() => HeaderMap); + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); + books: ExampleClientBooksService; constructor( options: { baseUrl?: string; - headers?: HeaderMap | (() => HeaderMap); + headers?: HeaderMap | (() => HeaderMap | Promise); } = {}, ) { this._baseUrl = options.baseUrl ?? ""; this._headers = options.headers ?? {}; + this.books = new ExampleClientBooksService(options); } - async sendObject(params: NestedObject) { + async sendObject(params: NestedObject): Promise { return arriRequest({ url: `${this._baseUrl}/send-object`, method: "post", headers: this._headers, params: params, - parser: $$NestedObject.fromJsonString, + responseFromJson: $$NestedObject.fromJson, + responseFromString: $$NestedObject.fromJsonString, serializer: $$NestedObject.toJsonString, clientVersion: "20", }); @@ -54,57 +64,68 @@ export class ExampleClient { export class ExampleClientBooksService { private readonly _baseUrl: string; - private readonly _headers: HeaderMap | (() => HeaderMap); + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); constructor( options: { baseUrl?: string; - headers?: HeaderMap | (() => HeaderMap); + headers?: HeaderMap | (() => HeaderMap | Promise); } = {}, ) { this._baseUrl = options.baseUrl ?? ""; this._headers = options.headers ?? {}; } - async getBook(params: BookParams) { + async getBook(params: BookParams): Promise { return arriRequest({ url: `${this._baseUrl}/books/get-book`, method: "get", headers: this._headers, params: params, - parser: $$Book.fromJsonString, + responseFromJson: $$Book.fromJson, + responseFromString: $$Book.fromJsonString, serializer: $$BookParams.toUrlQueryString, clientVersion: "20", }); } - async createBook(params: Book) { + async createBook(params: Book): Promise { return arriRequest({ url: `${this._baseUrl}/books/create-book`, method: "post", headers: this._headers, params: params, - parser: $$Book.fromJsonString, + responseFromJson: $$Book.fromJson, + responseFromString: $$Book.fromJsonString, serializer: $$Book.toJsonString, clientVersion: "20", }); } - async watchBook(params: BookParams, options: SseOptions = {}) { + watchBook( + params: BookParams, + options: SseOptions = {}, + ): EventSourceController { return arriSseRequest( { url: `${this._baseUrl}/books/watch-book`, method: "get", headers: this._headers, params: params, - parser: $$Book.fromJsonString, + responseFromJson: $$Book.fromJson, + responseFromString: $$Book.fromJsonString, serializer: $$BookParams.toUrlQueryString, clientVersion: "20", }, options, ); } - async createConnection(options: WsOptions = {}) { + async createConnection( + options: WsOptions = {}, + ): Promise> { return arriWsRequest({ url: `${this._baseUrl}/books/create-connection`, headers: this._headers, - parser: $$Book.fromJsonString, + responseFromJson: $$Book.fromJson, + responseFromString: $$Book.fromJsonString, serializer: $$BookParams.toJsonString, onOpen: options.onOpen, onClose: options.onClose, @@ -625,8 +646,8 @@ export const $$ObjectWithEveryType: ArriModelValidator = { json += "["; for (let i = 0; i < input.array.length; i++) { if (i !== 0) json += ","; - const _element = input.array[i]; - json += `${_element}`; + const _inputArrayEl = input.array[i]; + json += `${_inputArrayEl}`; } json += "]"; json += ',"record":'; @@ -1393,8 +1414,8 @@ export const $$ObjectWithOptionalFields: ArriModelValidator;`; + if (!mainService.content) { + const result = `${imports} + +${types.join("\n")}`; + return await prettier.format(result, { + ...options.prettierOptions, + parser: "typescript", + }); + } + const result = `${imports} +${mainService.content} + ${types.join("\n")}`; return await prettier.format(result, { ...options.prettierOptions, diff --git a/languages/ts/ts-codegen/src/array.ts b/languages/ts/ts-codegen/src/array.ts index 43605912..4d366604 100644 --- a/languages/ts/ts-codegen/src/array.ts +++ b/languages/ts/ts-codegen/src/array.ts @@ -1,7 +1,7 @@ -import { SchemaFormElements } from "@arrirpc/codegen-utils"; +import { camelCase, SchemaFormElements } from "@arrirpc/codegen-utils"; import { tsTypeFromSchema } from "./_index"; -import { CodegenContext, TsProperty } from "./common"; +import { CodegenContext, TsProperty, validVarName } from "./common"; export function tsArrayFromSchema( schema: SchemaFormElements, @@ -17,8 +17,7 @@ export function tsArrayFromSchema( discriminatorKey: "", discriminatorValue: "", versionNumber: context.versionNumber, - hasSseProcedure: context.hasSseProcedure, - hasWsProcedure: context.hasWsProcedure, + usedFeatures: context.usedFeatures, }); const typeName = `(${innerType.typeName})[]`; const defaultValue = schema.nullable ? "null" : "[]"; @@ -49,13 +48,15 @@ export function tsArrayFromSchema( }`; }, toJsonTemplate(input, target) { + const elVar = `_${camelCase(validVarName(input.split(".").join("_")), { normalize: true })}El`; + const elKeyVar = `${elVar}Key`; if (schema.nullable) { return `if (${input} !== null) { ${target} += '['; for (let i = 0; i < ${input}.length; i++) { if (i !== 0) ${target} += ','; - const _element = ${input}[i]; - ${innerType.toJsonTemplate(`_element`, target, "_elementKey")} + const ${elVar} = ${input}[i]; + ${innerType.toJsonTemplate(elVar, target, elKeyVar)} } ${target} += ']'; } else { @@ -65,8 +66,8 @@ export function tsArrayFromSchema( return `${target} += '['; for (let i = 0; i < ${input}.length; i++) { if (i !== 0) ${target} += ','; - const _element = ${input}[i]; - ${innerType.toJsonTemplate("_element", target, `_elementKey`)} + const ${elVar} = ${input}[i]; + ${innerType.toJsonTemplate(elVar, target, elKeyVar)} } ${target} += ']';`; }, diff --git a/languages/ts/ts-codegen/src/common.ts b/languages/ts/ts-codegen/src/common.ts index 853df6be..d596c6fd 100644 --- a/languages/ts/ts-codegen/src/common.ts +++ b/languages/ts/ts-codegen/src/common.ts @@ -29,8 +29,10 @@ export interface CodegenContext { discriminatorKey: string; discriminatorValue: string; versionNumber: string; - hasSseProcedure: boolean; - hasWsProcedure: boolean; + usedFeatures: { + sse: boolean; + ws: boolean; + }; } export function getJsDocComment(metadata: Schema["metadata"]) { diff --git a/languages/ts/ts-codegen/src/discriminator.ts b/languages/ts/ts-codegen/src/discriminator.ts index 1e5fb504..5ecd80f2 100644 --- a/languages/ts/ts-codegen/src/discriminator.ts +++ b/languages/ts/ts-codegen/src/discriminator.ts @@ -62,8 +62,7 @@ export function tsTaggedUnionFromSchema( discriminatorKey: discriminatorKey, discriminatorValue: key, versionNumber: context.versionNumber, - hasSseProcedure: context.hasSseProcedure, - hasWsProcedure: context.hasWsProcedure, + usedFeatures: context.usedFeatures, }); subTypes.push({ value: key, data: subType }); } diff --git a/languages/ts/ts-codegen/src/object.ts b/languages/ts/ts-codegen/src/object.ts index 5804cc20..0f8c82f5 100644 --- a/languages/ts/ts-codegen/src/object.ts +++ b/languages/ts/ts-codegen/src/object.ts @@ -96,8 +96,7 @@ export function tsObjectFromSchema( discriminatorKey: "", discriminatorValue: "", versionNumber: context.versionNumber, - hasSseProcedure: context.hasSseProcedure, - hasWsProcedure: context.hasWsProcedure, + usedFeatures: context.usedFeatures, }); if (prop.content) subContentParts.push(prop.content); const fieldName = validVarName(camelCase(key)); @@ -137,8 +136,7 @@ export function tsObjectFromSchema( discriminatorKey: "", discriminatorValue: "", versionNumber: context.versionNumber, - hasSseProcedure: context.hasSseProcedure, - hasWsProcedure: context.hasWsProcedure, + usedFeatures: context.usedFeatures, }); if (prop.content) subContentParts.push(prop.content); const fieldName = validVarName(camelCase(key)); diff --git a/languages/ts/ts-codegen/src/record.ts b/languages/ts/ts-codegen/src/record.ts index b950002a..26a90190 100644 --- a/languages/ts/ts-codegen/src/record.ts +++ b/languages/ts/ts-codegen/src/record.ts @@ -17,8 +17,7 @@ export function tsRecordFromSchema( discriminatorKey: "", discriminatorValue: "", versionNumber: context.versionNumber, - hasSseProcedure: context.hasSseProcedure, - hasWsProcedure: context.hasWsProcedure, + usedFeatures: context.usedFeatures, }); const typeName = `Record`; const defaultValue = schema.nullable ? "null" : "{}"; diff --git a/languages/ts/ts-codegen/src/rpc.ts b/languages/ts/ts-codegen/src/rpc.ts new file mode 100644 index 00000000..0df8b640 --- /dev/null +++ b/languages/ts/ts-codegen/src/rpc.ts @@ -0,0 +1,104 @@ +import { + HttpRpcDefinition, + pascalCase, + RpcDefinition, + WsRpcDefinition, +} from "@arrirpc/codegen-utils"; + +import { CodegenContext, validVarName } from "./common"; + +export function tsRpcFromDefinition( + def: RpcDefinition, + context: CodegenContext, +): string { + switch (def.transport) { + case "http": + return httpRpcFromDefinition(def, context); + case "ws": + return wsRpcFromDefinition(def, context); + default: + console.warn( + `[ts-codegen] Warning: unsupported transport "${def.transport}". Ignoring ${context.instancePath}.`, + ); + return ""; + } +} + +export function httpRpcFromDefinition( + def: HttpRpcDefinition, + context: CodegenContext, +): string { + const key = getRpcKey(context); + const params = def.params + ? `${context.typePrefix}${pascalCase(validVarName(def.params))}` + : undefined; + const response = def.response + ? `${context.typePrefix}${pascalCase(validVarName(def.response), { normalize: true })}` + : undefined; + const serializerMethod = + def.method === "get" ? "toUrlQueryString" : "toJsonString"; + if (def.isEventStream) { + context.usedFeatures.sse = true; + return ` ${key}(${params ? `params: ${params},` : ""} options: SseOptions<${response ?? "undefined"}> = {}): EventSourceController { + return arriSseRequest<${response ?? "undefined"}, ${params ?? "undefined"}>( + { + url: \`\${this._baseUrl}${def.path}\`, + method: "${def.method.toLowerCase()}", + headers: this._headers, + ${params ? "params: params," : ""} + responseFromJson: ${response ? `$$${response}.fromJson` : "() => {}"}, + responseFromString: ${response ? `$$${response}.fromJsonString` : "() => {}"}, + serializer: ${params ? `$$${params}.${serializerMethod}` : "() => {}"}, + clientVersion: "${context.versionNumber}", + }, + options, + ) + }`; + } + return ` async ${key}(${params ? `params: ${params}` : ""}): Promise<${response ?? "undefined"}> { + return arriRequest<${response ?? "undefined"}, ${params ?? "undefined"}>({ + url: \`\${this._baseUrl}${def.path}\`, + method: "${def.method.toLowerCase()}", + headers: this._headers, + ${params ? "params: params," : ""} + responseFromJson: ${response ? `$$${response}.fromJson` : "() => {}"}, + responseFromString: ${response ? `$$${response}.fromJsonString` : "() => {}"}, + serializer: ${params ? `$$${params}.${serializerMethod}` : "() => {}"}, + clientVersion: "${context.versionNumber}", + }); + }`; +} + +export function wsRpcFromDefinition( + def: WsRpcDefinition, + context: CodegenContext, +): string { + context.usedFeatures.ws = true; + const key = getRpcKey(context); + const params = def.params + ? `${context.typePrefix}${pascalCase(validVarName(def.params))}` + : undefined; + const response = def.response + ? `${context.typePrefix}${pascalCase(validVarName(def.response), { normalize: true })}` + : undefined; + return ` async ${key}(options: WsOptions<${response ?? "undefined"}> = {}): Promise> { + return arriWsRequest<${params ?? "undefined"}, ${response ?? "undefined"}>({ + url: \`\${this._baseUrl}${def.path}\`, + headers: this._headers, + responseFromJson: ${response ? `$$${response}.fromJson` : "() => {}"}, + responseFromString: ${response ? `$$${response}.fromJsonString` : "() => {}"}, + serializer: ${params ? `$$${params}.toJsonString` : "() => {}"}, + onOpen: options.onOpen, + onClose: options.onClose, + onError: options.onError, + onConnectionError: options.onConnectionError, + onMessage: options.onMessage, + clientVersion: "${context.versionNumber}", + }); + }`; +} + +export function getRpcKey(context: CodegenContext): string { + const name = context.instancePath.split(".").pop() ?? ""; + return validVarName(name); +} diff --git a/languages/ts/ts-codegen/src/service.ts b/languages/ts/ts-codegen/src/service.ts new file mode 100644 index 00000000..cfde448a --- /dev/null +++ b/languages/ts/ts-codegen/src/service.ts @@ -0,0 +1,105 @@ +import { + isRpcDefinition, + isServiceDefinition, + pascalCase, + ServiceDefinition, +} from "@arrirpc/codegen-utils"; + +import { CodegenContext, validVarName } from "./common"; +import { tsRpcFromDefinition } from "./rpc"; + +export function tsServiceFromDefinition( + def: ServiceDefinition, + context: CodegenContext, +): { key: string; name: string; content: string } { + const key = getServiceKey(context); + const serviceName = getServiceName(context); + const rpcParts: string[] = []; + const subServices: { key: string; name: string; content: string }[] = []; + for (const key of Object.keys(def)) { + const subDef = def[key]; + if (isServiceDefinition(subDef)) { + const subService = tsServiceFromDefinition(subDef, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `${context.instancePath}.${key}`, + schemaPath: `${context.instancePath}.${key}`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + usedFeatures: context.usedFeatures, + }); + if (subService.content) { + subServices.push(subService); + } + continue; + } + if (isRpcDefinition(subDef)) { + const rpc = tsRpcFromDefinition(subDef, { + clientName: context.clientName, + typePrefix: context.typePrefix, + generatedTypes: context.generatedTypes, + instancePath: `${context.instancePath}.${key}`, + schemaPath: `${context.schemaPath}.${key}`, + discriminatorParent: "", + discriminatorKey: "", + discriminatorValue: "", + versionNumber: context.versionNumber, + usedFeatures: context.usedFeatures, + }); + if (rpc) { + rpcParts.push(rpc); + } + continue; + } + console.warn( + `Invalid definition found at procedures.${context.schemaPath}`, + ); + } + if (subServices.length === 0 && rpcParts.length === 0) { + return { + key, + name: serviceName, + content: "", + }; + } + return { + key, + name: serviceName, + content: `export class ${serviceName} { + private readonly _baseUrl: string; + private readonly _headers: HeaderMap | (() => HeaderMap | Promise); +${subServices.map((service) => ` ${service.key}: ${service.name};`).join("\n")} + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap | Promise); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; +${subServices.map((service) => ` this.${service.key} = new ${service.name}(options);`).join("\n")} + } +${rpcParts.map((rpc) => ` ${rpc}`).join("\n")} +} + +${subServices.map((service) => service.content).join("\n")}`, + }; +} + +export function getServiceKey(context: CodegenContext): string { + const name = context.instancePath.split(".").pop() ?? ""; + return validVarName(name); +} + +export function getServiceName(context: CodegenContext): string { + if (context.instancePath.length === 0) { + return context.clientName; + } + const serviceName = pascalCase(context.instancePath.split(".").join("_"), { + normalize: true, + }); + return `${context.clientName}${serviceName}Service`; +} diff --git a/tests/clients/ts/testClient.rpc.ts b/tests/clients/ts/testClient.rpc.ts index 02439dcb..248db465 100644 --- a/tests/clients/ts/testClient.rpc.ts +++ b/tests/clients/ts/testClient.rpc.ts @@ -1,39 +1,51 @@ +// This file was autogenerated by @arrirpc/codegen-ts. Do not modify directly. +// For more information visit https://github.com/modiimedia/arri + /* eslint-disable */ // @ts-nocheck -// this file was autogenerated by arri-codegen-ts import { + ArriEnumValidator, + ArriModelValidator, arriRequest, arriSseRequest, - type SseOptions, - type EventSourceController, arriWsRequest, + type EventSourceController, + INT8_MAX, + INT8_MIN, + INT16_MAX, + INT16_MIN, + INT32_MAX, + INT32_MIN, + INT64_MAX, + INT64_MIN, + isObject, + serializeString, + type SseOptions, + UINT8_MAX, + UINT16_MAX, + UINT32_MAX, + UINT64_MAX, + type WsController, type WsOptions, } from "@arrirpc/client"; -interface TestClientOptions { - baseUrl?: string; - headers?: - | Record - | (() => - | Record - | Promise>); -} - +type HeaderMap = Record; export class TestClient { - private readonly baseUrl: string; - private readonly headers: - | Record - | (() => - | Record - | Promise>); - private readonly clientVersion = "10"; + private readonly _baseUrl: string; + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); tests: TestClientTestsService; adapters: TestClientAdaptersService; users: TestClientUsersService; - - constructor(options: TestClientOptions = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap | Promise); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; this.tests = new TestClientTestsService(options); this.adapters = new TestClientAdaptersService(options); this.users = new TestClientUsersService(options); @@ -41,347 +53,374 @@ export class TestClient { } export class TestClientTestsService { - private readonly baseUrl: string; - private readonly headers: - | Record - | (() => - | Record - | Promise>); - private readonly clientVersion = "10"; - - constructor(options: TestClientOptions = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; + private readonly _baseUrl: string; + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); + + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap | Promise); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; } - emptyParamsGetRequest() { + async emptyParamsGetRequest(): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/empty-params-get-request`, + url: `${this._baseUrl}/rpcs/tests/empty-params-get-request`, method: "get", - headers: this.headers, - params: undefined, - parser: $$DefaultPayload.parse, - serializer: (_) => {}, - clientVersion: this.clientVersion, + headers: this._headers, + + responseFromJson: $$DefaultPayload.fromJson, + responseFromString: $$DefaultPayload.fromJsonString, + serializer: () => {}, + clientVersion: "10", }); } - emptyParamsPostRequest() { + async emptyParamsPostRequest(): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/empty-params-post-request`, + url: `${this._baseUrl}/rpcs/tests/empty-params-post-request`, method: "post", - headers: this.headers, - params: undefined, - parser: $$DefaultPayload.parse, - serializer: (_) => {}, - clientVersion: this.clientVersion, + headers: this._headers, + + responseFromJson: $$DefaultPayload.fromJson, + responseFromString: $$DefaultPayload.fromJsonString, + serializer: () => {}, + clientVersion: "10", }); } - emptyResponseGetRequest(params: DefaultPayload) { + async emptyResponseGetRequest(params: DefaultPayload): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/empty-response-get-request`, + url: `${this._baseUrl}/rpcs/tests/empty-response-get-request`, method: "get", - headers: this.headers, - params, - parser: (_) => {}, - serializer: $$DefaultPayload.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: () => {}, + responseFromString: () => {}, + serializer: $$DefaultPayload.toUrlQueryString, + clientVersion: "10", }); } - emptyResponsePostRequest(params: DefaultPayload) { + async emptyResponsePostRequest(params: DefaultPayload): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/empty-response-post-request`, + url: `${this._baseUrl}/rpcs/tests/empty-response-post-request`, method: "post", - headers: this.headers, - params, - parser: (_) => {}, - serializer: $$DefaultPayload.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: () => {}, + responseFromString: () => {}, + serializer: $$DefaultPayload.toJsonString, + clientVersion: "10", }); } - /** - * If the target language supports it. Generated code should mark this procedure as deprecated. - * @deprecated - */ - deprecatedRpc(params: DeprecatedRpcParams) { + async deprecatedRpc(params: DeprecatedRpcParams): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/deprecated-rpc`, + url: `${this._baseUrl}/rpcs/tests/deprecated-rpc`, method: "post", - headers: this.headers, - params, - parser: (_) => {}, - serializer: $$DeprecatedRpcParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: () => {}, + responseFromString: () => {}, + serializer: $$DeprecatedRpcParams.toJsonString, + clientVersion: "10", }); } - sendError(params: SendErrorParams) { + async sendError(params: SendErrorParams): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/send-error`, + url: `${this._baseUrl}/rpcs/tests/send-error`, method: "post", - headers: this.headers, - params, - parser: (_) => {}, - serializer: $$SendErrorParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: () => {}, + responseFromString: () => {}, + serializer: $$SendErrorParams.toJsonString, + clientVersion: "10", }); } - sendObject(params: ObjectWithEveryType) { + async sendObject( + params: ObjectWithEveryType, + ): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/send-object`, + url: `${this._baseUrl}/rpcs/tests/send-object`, method: "post", - headers: this.headers, - params, - parser: $$ObjectWithEveryType.parse, - serializer: $$ObjectWithEveryType.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$ObjectWithEveryType.fromJson, + responseFromString: $$ObjectWithEveryType.fromJsonString, + serializer: $$ObjectWithEveryType.toJsonString, + clientVersion: "10", }); } - sendObjectWithNullableFields(params: ObjectWithEveryNullableType) { + async sendObjectWithNullableFields( + params: ObjectWithEveryNullableType, + ): Promise { return arriRequest< ObjectWithEveryNullableType, ObjectWithEveryNullableType >({ - url: `${this.baseUrl}/rpcs/tests/send-object-with-nullable-fields`, + url: `${this._baseUrl}/rpcs/tests/send-object-with-nullable-fields`, method: "post", - headers: this.headers, - params, - parser: $$ObjectWithEveryNullableType.parse, - serializer: $$ObjectWithEveryNullableType.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$ObjectWithEveryNullableType.fromJson, + responseFromString: $$ObjectWithEveryNullableType.fromJsonString, + serializer: $$ObjectWithEveryNullableType.toJsonString, + clientVersion: "10", }); } - sendPartialObject(params: ObjectWithEveryOptionalType) { + async sendPartialObject( + params: ObjectWithEveryOptionalType, + ): Promise { return arriRequest< ObjectWithEveryOptionalType, ObjectWithEveryOptionalType >({ - url: `${this.baseUrl}/rpcs/tests/send-partial-object`, + url: `${this._baseUrl}/rpcs/tests/send-partial-object`, method: "post", - headers: this.headers, - params, - parser: $$ObjectWithEveryOptionalType.parse, - serializer: $$ObjectWithEveryOptionalType.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$ObjectWithEveryOptionalType.fromJson, + responseFromString: $$ObjectWithEveryOptionalType.fromJsonString, + serializer: $$ObjectWithEveryOptionalType.toJsonString, + clientVersion: "10", }); } - sendRecursiveObject(params: RecursiveObject) { + async sendRecursiveObject( + params: RecursiveObject, + ): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/send-recursive-object`, + url: `${this._baseUrl}/rpcs/tests/send-recursive-object`, method: "post", - headers: this.headers, - params, - parser: $$RecursiveObject.parse, - serializer: $$RecursiveObject.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$RecursiveObject.fromJson, + responseFromString: $$RecursiveObject.fromJsonString, + serializer: $$RecursiveObject.toJsonString, + clientVersion: "10", }); } - sendRecursiveUnion(params: RecursiveUnion) { + async sendRecursiveUnion(params: RecursiveUnion): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/tests/send-recursive-union`, + url: `${this._baseUrl}/rpcs/tests/send-recursive-union`, method: "post", - headers: this.headers, - params, - parser: $$RecursiveUnion.parse, - serializer: $$RecursiveUnion.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$RecursiveUnion.fromJson, + responseFromString: $$RecursiveUnion.fromJsonString, + serializer: $$RecursiveUnion.toJsonString, + clientVersion: "10", }); } streamAutoReconnect( params: AutoReconnectParams, - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest( { - url: `${this.baseUrl}/rpcs/tests/stream-auto-reconnect`, + url: `${this._baseUrl}/rpcs/tests/stream-auto-reconnect`, method: "get", - headers: this.headers, - params, - parser: $$AutoReconnectResponse.parse, - serializer: $$AutoReconnectParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$AutoReconnectResponse.fromJson, + responseFromString: $$AutoReconnectResponse.fromJsonString, + serializer: $$AutoReconnectParams.toUrlQueryString, + clientVersion: "10", }, options, ); } - /** - * This route will always return an error. The client should automatically retry with exponential backoff. - */ streamConnectionErrorTest( params: StreamConnectionErrorTestParams, - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest< StreamConnectionErrorTestResponse, StreamConnectionErrorTestParams >( { - url: `${this.baseUrl}/rpcs/tests/stream-connection-error-test`, + url: `${this._baseUrl}/rpcs/tests/stream-connection-error-test`, method: "get", - headers: this.headers, - params, - parser: $$StreamConnectionErrorTestResponse.parse, - serializer: $$StreamConnectionErrorTestParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$StreamConnectionErrorTestResponse.fromJson, + responseFromString: + $$StreamConnectionErrorTestResponse.fromJsonString, + serializer: $$StreamConnectionErrorTestParams.toUrlQueryString, + clientVersion: "10", }, options, ); } - /** - * Test to ensure that the client can handle receiving streams of large objects. When objects are large messages will sometimes get sent in chunks. Meaning you have to handle receiving a partial message - */ streamLargeObjects( - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest( { - url: `${this.baseUrl}/rpcs/tests/stream-large-objects`, + url: `${this._baseUrl}/rpcs/tests/stream-large-objects`, method: "get", - headers: this.headers, - params: undefined, - parser: $$StreamLargeObjectsResponse.parse, - serializer: (_) => {}, - clientVersion: this.clientVersion, + headers: this._headers, + + responseFromJson: $$StreamLargeObjectsResponse.fromJson, + responseFromString: $$StreamLargeObjectsResponse.fromJsonString, + serializer: () => {}, + clientVersion: "10", }, options, ); } streamMessages( params: ChatMessageParams, - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest( { - url: `${this.baseUrl}/rpcs/tests/stream-messages`, + url: `${this._baseUrl}/rpcs/tests/stream-messages`, method: "get", - headers: this.headers, - params, - parser: $$ChatMessage.parse, - serializer: $$ChatMessageParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$ChatMessage.fromJson, + responseFromString: $$ChatMessage.fromJsonString, + serializer: $$ChatMessageParams.toUrlQueryString, + clientVersion: "10", }, options, ); } streamRetryWithNewCredentials( - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest< TestsStreamRetryWithNewCredentialsResponse, undefined >( { - url: `${this.baseUrl}/rpcs/tests/stream-retry-with-new-credentials`, + url: `${this._baseUrl}/rpcs/tests/stream-retry-with-new-credentials`, method: "get", - headers: this.headers, - params: undefined, - parser: $$TestsStreamRetryWithNewCredentialsResponse.parse, - serializer: (_) => {}, - clientVersion: this.clientVersion, + headers: this._headers, + + responseFromJson: + $$TestsStreamRetryWithNewCredentialsResponse.fromJson, + responseFromString: + $$TestsStreamRetryWithNewCredentialsResponse.fromJsonString, + serializer: () => {}, + clientVersion: "10", }, options, ); } - /** - * When the client receives the 'done' event, it should close the connection and NOT reconnect - */ streamTenEventsThenEnd( - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest( { - url: `${this.baseUrl}/rpcs/tests/stream-ten-events-then-end`, + url: `${this._baseUrl}/rpcs/tests/stream-ten-events-then-end`, method: "get", - headers: this.headers, - params: undefined, - parser: $$ChatMessage.parse, - serializer: (_) => {}, - clientVersion: this.clientVersion, + headers: this._headers, + + responseFromJson: $$ChatMessage.fromJson, + responseFromString: $$ChatMessage.fromJsonString, + serializer: () => {}, + clientVersion: "10", }, options, ); } - websocketRpc(options: WsOptions = {}) { + async websocketRpc( + options: WsOptions = {}, + ): Promise> { return arriWsRequest({ - url: `${this.baseUrl}/rpcs/tests/websocket-rpc`, - headers: this.headers, - parser: $$WsMessageResponse.parse, - serializer: $$WsMessageParams.serialize, + url: `${this._baseUrl}/rpcs/tests/websocket-rpc`, + headers: this._headers, + responseFromJson: $$WsMessageResponse.fromJson, + responseFromString: $$WsMessageResponse.fromJsonString, + serializer: $$WsMessageParams.toJsonString, onOpen: options.onOpen, onClose: options.onClose, onError: options.onError, onConnectionError: options.onConnectionError, onMessage: options.onMessage, - clientVersion: this.clientVersion, + clientVersion: "10", }); } - websocketRpcSendTenLargeMessages( + async websocketRpcSendTenLargeMessages( options: WsOptions = {}, - ) { + ): Promise> { return arriWsRequest({ - url: `${this.baseUrl}/rpcs/tests/websocket-rpc-send-ten-large-messages`, - headers: this.headers, - parser: (_) => {}, - serializer: (_) => {}, + url: `${this._baseUrl}/rpcs/tests/websocket-rpc-send-ten-large-messages`, + headers: this._headers, + responseFromJson: $$StreamLargeObjectsResponse.fromJson, + responseFromString: $$StreamLargeObjectsResponse.fromJsonString, + serializer: () => {}, onOpen: options.onOpen, onClose: options.onClose, onError: options.onError, onConnectionError: options.onConnectionError, onMessage: options.onMessage, - clientVersion: this.clientVersion, + clientVersion: "10", }); } } export class TestClientAdaptersService { - private readonly baseUrl: string; - private readonly headers: - | Record - | (() => - | Record - | Promise>); - private readonly clientVersion = "10"; - - constructor(options: TestClientOptions = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; + private readonly _baseUrl: string; + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); + + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap | Promise); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; } - typebox(params: TypeBoxObject) { + async typebox(params: TypeBoxObject): Promise { return arriRequest({ - url: `${this.baseUrl}/rpcs/adapters/typebox`, + url: `${this._baseUrl}/rpcs/adapters/typebox`, method: "post", - headers: this.headers, - params, - parser: $$TypeBoxObject.parse, - serializer: $$TypeBoxObject.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$TypeBoxObject.fromJson, + responseFromString: $$TypeBoxObject.fromJsonString, + serializer: $$TypeBoxObject.toJsonString, + clientVersion: "10", }); } } export class TestClientUsersService { - private readonly baseUrl: string; - private readonly headers: - | Record - | (() => - | Record - | Promise>); - private readonly clientVersion = "10"; - - constructor(options: TestClientOptions = {}) { - this.baseUrl = options.baseUrl ?? ""; - this.headers = options.headers ?? {}; + private readonly _baseUrl: string; + private readonly _headers: + | HeaderMap + | (() => HeaderMap | Promise); + + constructor( + options: { + baseUrl?: string; + headers?: HeaderMap | (() => HeaderMap | Promise); + } = {}, + ) { + this._baseUrl = options.baseUrl ?? ""; + this._headers = options.headers ?? {}; } watchUser( params: UsersWatchUserParams, - options: SseOptions, + options: SseOptions = {}, ): EventSourceController { return arriSseRequest( { - url: `${this.baseUrl}/rpcs/users/watch-user`, + url: `${this._baseUrl}/rpcs/users/watch-user`, method: "get", - headers: this.headers, - params, - parser: $$UsersWatchUserResponse.parse, - serializer: $$UsersWatchUserParams.serialize, - clientVersion: this.clientVersion, + headers: this._headers, + params: params, + responseFromJson: $$UsersWatchUserResponse.fromJson, + responseFromString: $$UsersWatchUserResponse.fromJsonString, + serializer: $$UsersWatchUserParams.toUrlQueryString, + clientVersion: "10", }, options, ); @@ -391,196 +430,81 @@ export class TestClientUsersService { export interface ManuallyAddedModel { hello: string; } -export const $$ManuallyAddedModel = { - parse(input: Record): ManuallyAddedModel { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.hello === "string") { - __D1.hello = json.hello; - } else { - $fallback( - "/hello", - "/properties/hello/type", - "Expected string at /hello", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.hello === "string") { - __D1.hello = input.hello; - } else { - $fallback( - "/hello", - "/properties/hello/type", - "Expected string at /hello", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; +export const $$ManuallyAddedModel: ArriModelValidator = { + new(): ManuallyAddedModel { + return { + hello: "", + }; }, - serialize(input: ManuallyAddedModel): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"hello":`; - if (input.hello.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.hello.length; i++) { - __point__ = input.hello.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.hello); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.hello.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.hello}"`; - } else { - json += `"${__result__}${input.hello.slice(__last__)}"`; - } - } - } else if (input.hello.length < 5000 && !STR_ESCAPE.test(input.hello)) { - json += `"${input.hello}"`; + validate(input): input is ManuallyAddedModel { + return isObject(input) && typeof input.hello === "string"; + }, + fromJson(input): ManuallyAddedModel { + let _hello: string; + if (typeof input.hello === "string") { + _hello = input.hello; } else { - json += JSON.stringify(input.hello); + _hello = ""; } + return { + hello: _hello, + }; + }, + fromJsonString(input): ManuallyAddedModel { + return $$ManuallyAddedModel.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"hello":'; + json += serializeString(input.hello); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`hello=${input.hello}`); + return queryParts.join("&"); + }, }; export interface DefaultPayload { message: string; } -export const $$DefaultPayload = { - parse(input: Record): DefaultPayload { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.message === "string") { - __D1.message = json.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.message === "string") { - __D1.message = input.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; +export const $$DefaultPayload: ArriModelValidator = { + new(): DefaultPayload { + return { + message: "", + }; }, - serialize(input: DefaultPayload): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"message":`; - if (input.message.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.message.length; i++) { - __point__ = input.message.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.message); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.message.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.message}"`; - } else { - json += `"${__result__}${input.message.slice(__last__)}"`; - } - } - } else if ( - input.message.length < 5000 && - !STR_ESCAPE.test(input.message) - ) { - json += `"${input.message}"`; + validate(input): input is DefaultPayload { + return isObject(input) && typeof input.message === "string"; + }, + fromJson(input): DefaultPayload { + let _message: string; + if (typeof input.message === "string") { + _message = input.message; } else { - json += JSON.stringify(input.message); + _message = ""; } + return { + message: _message, + }; + }, + fromJsonString(input): DefaultPayload { + return $$DefaultPayload.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"message":'; + json += serializeString(input.message); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`message=${input.message}`); + return queryParts.join("&"); + }, }; export interface TypeBoxObject { @@ -590,658 +514,351 @@ export interface TypeBoxObject { number: number; enumField: TypeBoxObjectEnumField; object: TypeBoxObjectObject; - array: Array; + array: boolean[]; optionalString?: string; } -export const $$TypeBoxObject = { - parse(input: Record): TypeBoxObject { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.string === "string") { - __D1.string = json.string; - } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); - } - if (typeof json.boolean === "boolean") { - __D1.boolean = json.boolean; - } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", - ); - } - if ( - typeof json.integer === "number" && - Number.isInteger(json.integer) && - json.integer >= -2147483648 && - json.integer <= 2147483647 - ) { - __D1.integer = json.integer; - } else { - $fallback( - "/integer", - "/properties/integer", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - if ( - typeof json.number === "number" && - !Number.isNaN(json.number) - ) { - __D1.number = json.number; - } else { - $fallback( - "/number", - "/properties/number/type", - "Expected number at /number", - ); - } - if (typeof json.enumField === "string") { - if ( - json.enumField === "A" || - json.enumField === "B" || - json.enumField === "C" - ) { - __D1.enumField = json.enumField; - } else { - $fallback( - "/enumField", - "/properties/enumField", - "Expected one of the following values: [A, B, C] at /enumField.", - ); - } - } else { - $fallback( - "/enumField", - "/properties/enumField", - "Expected one of the following values: [A, B, C] at /enumField.", - ); - } - if (typeof json.object === "object" && json.object !== null) { - const __D2 = {}; - if (typeof json.object.string === "string") { - __D2.string = json.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - __D1.object = __D2; - } else { - $fallback( - "/object", - "/properties/object", - "Expected object", - ); - } - if (Array.isArray(json.array)) { - const __D2 = []; - for (const __D2AItem of json.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback("/array", "/properties/array", "Expected Array"); - } - if (typeof json.optionalString === "undefined") { - // ignore undefined - } else { - if (typeof json.optionalString === "string") { - __D1.optionalString = json.optionalString; - } else { - $fallback( - "/optionalString", - "/optionalProperties/optionalString/type", - "Expected string at /optionalString", - ); - } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; +export const $$TypeBoxObject: ArriModelValidator = { + new(): TypeBoxObject { + return { + string: "", + boolean: false, + integer: 0, + number: 0, + enumField: $$TypeBoxObjectEnumField.new(), + object: $$TypeBoxObjectObject.new(), + array: [], + }; + }, + validate(input): input is TypeBoxObject { + return ( + isObject(input) && + typeof input.string === "string" && + typeof input.boolean === "boolean" && + typeof input.integer === "number" && + Number.isInteger(input.integer) && + input.integer >= INT32_MIN && + input.integer <= INT32_MAX && + typeof input.number === "number" && + $$TypeBoxObjectEnumField.validate(input.enumField) && + $$TypeBoxObjectObject.validate(input.object) && + Array.isArray(input.array) && + input.array.every((_element) => typeof _element === "boolean") && + (typeof input.optionalString === "string" || + typeof input.optionalString === "undefined") + ); + }, + fromJson(input): TypeBoxObject { + let _string: string; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = ""; } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.string === "string") { - __D1.string = input.string; - } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); - } - if (typeof input.boolean === "boolean") { - __D1.boolean = input.boolean; - } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", - ); - } - if ( - typeof input.integer === "number" && - Number.isInteger(input.integer) && - input.integer >= -2147483648 && - input.integer <= 2147483647 - ) { - __D1.integer = input.integer; - } else { - $fallback( - "/integer", - "/properties/integer", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - if ( - typeof input.number === "number" && - !Number.isNaN(input.number) - ) { - __D1.number = input.number; - } else { - $fallback( - "/number", - "/properties/number/type", - "Expected number at /number", - ); - } - if (typeof input.enumField === "string") { - if ( - input.enumField === "A" || - input.enumField === "B" || - input.enumField === "C" - ) { - __D1.enumField = input.enumField; - } else { - $fallback( - "/enumField", - "/properties/enumField", - "Expected one of the following values: [A, B, C] at /enumField.", - ); - } - } else { - $fallback( - "/enumField", - "/properties/enumField", - "Expected one of the following values: [A, B, C] at /enumField.", - ); - } - if (typeof input.object === "object" && input.object !== null) { - const __D2 = {}; - if (typeof input.object.string === "string") { - __D2.string = input.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - __D1.object = __D2; - } else { - $fallback("/object", "/properties/object", "Expected object"); - } - if (Array.isArray(input.array)) { - const __D2 = []; - for (const __D2AItem of input.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback("/array", "/properties/array", "Expected Array"); - } - if (typeof input.optionalString === "undefined") { - // ignore undefined - } else { - if (typeof input.optionalString === "string") { - __D1.optionalString = input.optionalString; - } else { - $fallback( - "/optionalString", - "/optionalProperties/optionalString/type", - "Expected string at /optionalString", - ); - } - } - result = __D1; + let _boolean: boolean; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; } else { - $fallback("", "", "Expected object"); + _boolean = false; } - return result; - }, - serialize(input: TypeBoxObject): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"string":`; - if (input.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.string.length; i++) { - __point__ = input.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.string}"`; - } else { - json += `"${__result__}${input.string.slice(__last__)}"`; - } - } - } else if ( - input.string.length < 5000 && - !STR_ESCAPE.test(input.string) + let _integer: number; + if ( + typeof input.integer === "number" && + Number.isInteger(input.integer) && + input.integer >= INT32_MIN && + input.integer <= INT32_MAX ) { - json += `"${input.string}"`; + _integer = input.integer; } else { - json += JSON.stringify(input.string); + _integer = 0; } - json += `,"boolean":${input.boolean}`; - - if (Number.isNaN(input.integer)) { - throw new Error("Expected number at /integer got NaN"); + let _number: number; + if (typeof input.number === "number") { + _number = input.number; + } else { + _number = 0; } - json += `,"integer":${input.integer}`; - - if (Number.isNaN(input.number)) { - throw new Error("Expected number at /number got NaN"); + let _enumField: TypeBoxObjectEnumField; + if (typeof input.enumField === "string") { + _enumField = $$TypeBoxObjectEnumField.fromSerialValue( + input.enumField, + ); + } else { + _enumField = $$TypeBoxObjectEnumField.new(); } - json += `,"number":${input.number}`; - json += `,"enumField":"${input.enumField}"`; - - json += ',"object":'; - json += "{"; - json += `"string":`; - if (input.object.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.object.string.length; i++) { - __point__ = input.object.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.object.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.object.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.object.string}"`; + let _object: TypeBoxObjectObject; + if (isObject(input.object)) { + _object = $$TypeBoxObjectObject.fromJson(input.object); + } else { + _object = $$TypeBoxObjectObject.new(); + } + let _array: boolean[]; + if (Array.isArray(input.array)) { + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; } else { - json += `"${__result__}${input.object.string.slice(__last__)}"`; + _arrayElValue = false; } + _array.push(_arrayElValue); } - } else if ( - input.object.string.length < 5000 && - !STR_ESCAPE.test(input.object.string) - ) { - json += `"${input.object.string}"`; } else { - json += JSON.stringify(input.object.string); + _array = []; } - json += "}"; - json += ',"array":['; + let _optionalString: string | undefined; + if (typeof input.optionalString !== "undefined") { + if (typeof input.optionalString === "string") { + _optionalString = input.optionalString; + } else { + _optionalString = ""; + } + } + return { + string: _string, + boolean: _boolean, + integer: _integer, + number: _number, + enumField: _enumField, + object: _object, + array: _array, + optionalString: _optionalString, + }; + }, + fromJsonString(input): TypeBoxObject { + return $$TypeBoxObject.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + json += serializeString(input.string); + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"integer":'; + json += `${input.integer}`; + json += ',"number":'; + json += `${input.number}`; + json += ',"enumField":'; + json += `"${input.enumField}"`; + json += ',"object":'; + json += $$TypeBoxObjectObject.toJsonString(input.object); + json += ',"array":'; + json += "["; for (let i = 0; i < input.array.length; i++) { - const valArrayItem = input.array[i]; - if (i !== 0) { - json += ","; - } - json += `${valArrayItem}`; + if (i !== 0) json += ","; + const _inputArrayEl = input.array[i]; + json += `${_inputArrayEl}`; } json += "]"; if (typeof input.optionalString !== "undefined") { json += `,"optionalString":`; - if (input.optionalString.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.optionalString.length; i++) { - __point__ = input.optionalString.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.optionalString); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.optionalString.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.optionalString}"`; - } else { - json += `"${__result__}${input.optionalString.slice(__last__)}"`; - } - } - } else if ( - input.optionalString.length < 5000 && - !STR_ESCAPE.test(input.optionalString) - ) { - json += `"${input.optionalString}"`; - } else { - json += JSON.stringify(input.optionalString); - } + json += serializeString(input.optionalString); } json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`integer=${input.integer}`); + queryParts.push(`number=${input.number}`); + queryParts.push(`enumField=${input.enumField}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /TypeBoxObject/object.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /TypeBoxObject/array.", + ); + if (typeof input.optionalString !== "undefined") { + queryParts.push(`optionalString=${input.optionalString}`); + } + return queryParts.join("&"); + }, }; -export type TypeBoxObjectEnumField = "A" | "B" | "C"; + +export type TypeBoxObjectEnumField = + (typeof $$TypeBoxObjectEnumFieldValues)[number]; +const $$TypeBoxObjectEnumFieldValues = ["A", "B", "C"] as const; +export const $$TypeBoxObjectEnumField: ArriEnumValidator = + { + new(): TypeBoxObjectEnumField { + return $$TypeBoxObjectEnumFieldValues[0]; + }, + validate(input): input is TypeBoxObjectEnumField { + return ( + typeof input === "string" && + $$TypeBoxObjectEnumFieldValues.includes(input as any) + ); + }, + values: $$TypeBoxObjectEnumFieldValues, + fromSerialValue(input): TypeBoxObjectEnumField { + if ($$TypeBoxObjectEnumFieldValues.includes(input as any)) { + return input as TypeBoxObjectEnumField; + } + if ( + $$TypeBoxObjectEnumFieldValues.includes( + input.toLowerCase() as any, + ) + ) { + return input.toLowerCase() as TypeBoxObjectEnumField; + } + if ( + $$TypeBoxObjectEnumFieldValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as TypeBoxObjectEnumField; + } + return "A"; + }, + }; + export interface TypeBoxObjectObject { string: string; } +export const $$TypeBoxObjectObject: ArriModelValidator = { + new(): TypeBoxObjectObject { + return { + string: "", + }; + }, + validate(input): input is TypeBoxObjectObject { + return isObject(input) && typeof input.string === "string"; + }, + fromJson(input): TypeBoxObjectObject { + let _string: string; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = ""; + } + return { + string: _string, + }; + }, + fromJsonString(input): TypeBoxObjectObject { + return $$TypeBoxObjectObject.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + json += serializeString(input.string); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + return queryParts.join("&"); + }, +}; /** * @deprecated */ export interface DeprecatedRpcParams { - /** - * @deprecated - */ deprecatedField: string; } -export const $$DeprecatedRpcParams = { - parse(input: Record): DeprecatedRpcParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); +export const $$DeprecatedRpcParams: ArriModelValidator = { + new(): DeprecatedRpcParams { + return { + deprecatedField: "", + }; + }, + validate(input): input is DeprecatedRpcParams { + return isObject(input) && typeof input.deprecatedField === "string"; + }, + fromJson(input): DeprecatedRpcParams { + let _deprecatedField: string; + if (typeof input.deprecatedField === "string") { + _deprecatedField = input.deprecatedField; + } else { + _deprecatedField = ""; } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.deprecatedField === "string") { - __D1.deprecatedField = json.deprecatedField; - } else { - $fallback( - "/deprecatedField", - "/properties/deprecatedField/type", - "Expected string at /deprecatedField", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.deprecatedField === "string") { - __D1.deprecatedField = input.deprecatedField; - } else { - $fallback( - "/deprecatedField", - "/properties/deprecatedField/type", - "Expected string at /deprecatedField", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; + return { + deprecatedField: _deprecatedField, + }; }, - serialize(input: DeprecatedRpcParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"deprecatedField":`; - if (input.deprecatedField.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.deprecatedField.length; i++) { - __point__ = input.deprecatedField.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.deprecatedField); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.deprecatedField.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.deprecatedField}"`; - } else { - json += `"${__result__}${input.deprecatedField.slice(__last__)}"`; - } - } - } else if ( - input.deprecatedField.length < 5000 && - !STR_ESCAPE.test(input.deprecatedField) - ) { - json += `"${input.deprecatedField}"`; - } else { - json += JSON.stringify(input.deprecatedField); - } + fromJsonString(input): DeprecatedRpcParams { + return $$DeprecatedRpcParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"deprecatedField":'; + json += serializeString(input.deprecatedField); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`deprecatedField=${input.deprecatedField}`); + return queryParts.join("&"); + }, }; export interface SendErrorParams { code: number; message: string; } -export const $$SendErrorParams = { - parse(input: Record): SendErrorParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if ( - typeof json.code === "number" && - Number.isInteger(json.code) && - json.code >= 0 && - json.code <= 65535 - ) { - __D1.code = json.code; - } else { - $fallback( - "/code", - "/properties/code", - "Expected valid integer between 0 and 65535", - ); - } - if (typeof json.message === "string") { - __D1.message = json.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if ( - typeof input.code === "number" && - Number.isInteger(input.code) && - input.code >= 0 && - input.code <= 65535 - ) { - __D1.code = input.code; - } else { - $fallback( - "/code", - "/properties/code", - "Expected valid integer between 0 and 65535", - ); - } - if (typeof input.message === "string") { - __D1.message = input.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; +export const $$SendErrorParams: ArriModelValidator = { + new(): SendErrorParams { + return { + code: 0, + message: "", + }; }, - serialize(input: SendErrorParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - - if (Number.isNaN(input.code)) { - throw new Error("Expected number at /code got NaN"); - } - json += `"code":${input.code}`; - json += `,"message":`; - if (input.message.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.message.length; i++) { - __point__ = input.message.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.message); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.message.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.message}"`; - } else { - json += `"${__result__}${input.message.slice(__last__)}"`; - } - } - } else if ( - input.message.length < 5000 && - !STR_ESCAPE.test(input.message) + validate(input): input is SendErrorParams { + return ( + isObject(input) && + typeof input.code === "number" && + Number.isInteger(input.code) && + input.code >= 0 && + input.code <= UINT16_MAX && + typeof input.message === "string" + ); + }, + fromJson(input): SendErrorParams { + let _code: number; + if ( + typeof input.code === "number" && + Number.isInteger(input.code) && + input.code >= 0 && + input.code <= UINT16_MAX ) { - json += `"${input.message}"`; + _code = input.code; + } else { + _code = 0; + } + let _message: string; + if (typeof input.message === "string") { + _message = input.message; } else { - json += JSON.stringify(input.message); + _message = ""; } + return { + code: _code, + message: _message, + }; + }, + fromJsonString(input): SendErrorParams { + return $$SendErrorParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"code":'; + json += `${input.code}`; + json += ',"message":'; + json += serializeString(input.message); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`code=${input.code}`); + queryParts.push(`message=${input.message}`); + return queryParts.join("&"); + }, }; export interface ObjectWithEveryType { @@ -1260,9030 +877,4523 @@ export interface ObjectWithEveryType { int64: bigint; uint64: bigint; enumerator: ObjectWithEveryTypeEnumerator; - array: Array; + array: boolean[]; object: ObjectWithEveryTypeObject; - record: ObjectWithEveryTypeRecord; + record: Record; discriminator: ObjectWithEveryTypeDiscriminator; nestedObject: ObjectWithEveryTypeNestedObject; - nestedArray: Array>; + nestedArray: ObjectWithEveryTypeNestedArrayelementelement[][]; } -export const $$ObjectWithEveryType = { - parse(input: Record): ObjectWithEveryType { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, +export const $$ObjectWithEveryType: ArriModelValidator = { + new(): ObjectWithEveryType { + return { + any: undefined, + boolean: false, + string: "", + timestamp: new Date(), + float32: 0, + float64: 0, + int8: 0, + uint8: 0, + int16: 0, + uint16: 0, + int32: 0, + uint32: 0, + int64: BigInt(0), + uint64: BigInt(0), + enumerator: $$ObjectWithEveryTypeEnumerator.new(), + array: [], + object: $$ObjectWithEveryTypeObject.new(), + record: {}, + discriminator: $$ObjectWithEveryTypeDiscriminator.new(), + nestedObject: $$ObjectWithEveryTypeNestedObject.new(), + nestedArray: [], + }; + }, + validate(input): input is ObjectWithEveryType { + return ( + isObject(input) && + true && + typeof input.boolean === "boolean" && + typeof input.string === "string" && + input.timestamp instanceof Date && + typeof input.float32 === "number" && + typeof input.float64 === "number" && + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX && + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX && + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX && + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX && + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX && + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX && + typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX && + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX && + $$ObjectWithEveryTypeEnumerator.validate(input.enumerator) && + Array.isArray(input.array) && + input.array.every((_element) => typeof _element === "boolean") && + $$ObjectWithEveryTypeObject.validate(input.object) && + isObject(input.record) && + Object.values(input.record).every( + (_value) => typeof _value === "boolean", + ) && + $$ObjectWithEveryTypeDiscriminator.validate(input.discriminator) && + $$ObjectWithEveryTypeNestedObject.validate(input.nestedObject) && + Array.isArray(input.nestedArray) && + input.nestedArray.every( + (_element) => + Array.isArray(_element) && + _element.every((_element) => + $$ObjectWithEveryTypeNestedArrayelementelement.validate( + _element, + ), + ), + ) + ); + }, + fromJson(input): ObjectWithEveryType { + let _any: any; + _any = input.any; + let _boolean: boolean; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = false; + } + let _string: string; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = ""; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + let _float32: number; + if (typeof input.float32 === "number") { + _float32 = input.float32; + } else { + _float32 = 0; + } + let _float64: number; + if (typeof input.float64 === "number") { + _float64 = input.float64; + } else { + _float64 = 0; + } + let _int8: number; + if ( + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX + ) { + _int8 = input.int8; + } else { + _int8 = 0; + } + let _uint8: number; + if ( + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX + ) { + _uint8 = input.uint8; + } else { + _uint8 = 0; + } + let _int16: number; + if ( + typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX + ) { + _int16 = input.int16; + } else { + _int16 = 0; + } + let _uint16: number; + if ( + typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX + ) { + _uint16 = input.uint16; + } else { + _uint16 = 0; + } + let _int32: number; + if ( + typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX + ) { + _int32 = input.int32; + } else { + _int32 = 0; + } + let _uint32: number; + if ( + typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX + ) { + _uint32 = input.uint32; + } else { + _uint32 = 0; + } + let _int64: bigint; + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); + } else if (typeof input.int64 === "bigint") { + _int64 = input.int64; + } else { + _int64 = BigInt(0); + } + let _uint64: bigint; + if ( + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) + ) { + _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; + } else { + _uint64 = BigInt(0); + } + let _enumerator: ObjectWithEveryTypeEnumerator; + if (typeof input.enumerator === "string") { + _enumerator = $$ObjectWithEveryTypeEnumerator.fromSerialValue( + input.enumerator, ); + } else { + _enumerator = $$ObjectWithEveryTypeEnumerator.new(); } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.any = json.any; - if (typeof json.boolean === "boolean") { - __D1.boolean = json.boolean; - } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", - ); - } - if (typeof json.string === "string") { - __D1.string = json.string; - } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); - } - if ( - typeof json.timestamp === "object" && - json.timestamp instanceof Date - ) { - __D1.timestamp = json.timestamp; - } else if (typeof json.timestamp === "string") { - __D1.timestamp = new Date(json.timestamp); - } else { - $fallback( - "/timestamp", - "/properties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", - ); - } - if ( - typeof json.float32 === "number" && - !Number.isNaN(json.float32) - ) { - __D1.float32 = json.float32; + let _array: boolean[]; + if (Array.isArray(input.array)) { + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; } else { - $fallback( - "/float32", - "/properties/float32/type", - "Expected number at /float32", - ); + _arrayElValue = false; } - if ( - typeof json.float64 === "number" && - !Number.isNaN(json.float64) - ) { - __D1.float64 = json.float64; + _array.push(_arrayElValue); + } + } else { + _array = []; + } + let _object: ObjectWithEveryTypeObject; + if (isObject(input.object)) { + _object = $$ObjectWithEveryTypeObject.fromJson(input.object); + } else { + _object = $$ObjectWithEveryTypeObject.new(); + } + let _record: Record; + if (isObject(input.record)) { + _record = {}; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean; + if (typeof _value === "boolean") { + _recordValue = _value; } else { - $fallback( - "/float64", - "/properties/float64/type", - "Expected number at /float64", - ); + _recordValue = false; } - if ( - typeof json.int8 === "number" && - Number.isInteger(json.int8) && - json.int8 >= -128 && - json.int8 <= 127 - ) { - __D1.int8 = json.int8; + _record[_key] = _recordValue; + } + } else { + _record = {}; + } + let _discriminator: ObjectWithEveryTypeDiscriminator; + if (isObject(input.discriminator)) { + _discriminator = $$ObjectWithEveryTypeDiscriminator.fromJson( + input.discriminator, + ); + } else { + _discriminator = $$ObjectWithEveryTypeDiscriminator.new(); + } + let _nestedObject: ObjectWithEveryTypeNestedObject; + if (isObject(input.nestedObject)) { + _nestedObject = $$ObjectWithEveryTypeNestedObject.fromJson( + input.nestedObject, + ); + } else { + _nestedObject = $$ObjectWithEveryTypeNestedObject.new(); + } + let _nestedArray: ObjectWithEveryTypeNestedArrayelementelement[][]; + if (Array.isArray(input.nestedArray)) { + _nestedArray = []; + for (const _nestedArrayEl of input.nestedArray) { + let _nestedArrayElValue: ObjectWithEveryTypeNestedArrayelementelement[]; + if (Array.isArray(_nestedArrayEl)) { + _nestedArrayElValue = []; + for (const _nestedArrayElValueEl of _nestedArrayEl) { + let _nestedArrayElValueElValue: ObjectWithEveryTypeNestedArrayelementelement; + if (isObject(_nestedArrayElValueEl)) { + _nestedArrayElValueElValue = + $$ObjectWithEveryTypeNestedArrayelementelement.fromJson( + _nestedArrayElValueEl, + ); + } else { + _nestedArrayElValueElValue = + $$ObjectWithEveryTypeNestedArrayelementelement.new(); + } + _nestedArrayElValue.push(_nestedArrayElValueElValue); + } } else { - $fallback( - "/int8", - "/properties/int8", - "Expected valid integer between -128 and 127", - ); + _nestedArrayElValue = []; } - if ( - typeof json.uint8 === "number" && - Number.isInteger(json.uint8) && - json.uint8 >= 0 && - json.uint8 <= 255 - ) { - __D1.uint8 = json.uint8; - } else { - $fallback( - "/uint8", - "/properties/uint8", - "Expected valid integer between 0 and 255", + _nestedArray.push(_nestedArrayElValue); + } + } else { + _nestedArray = []; + } + return { + any: _any, + boolean: _boolean, + string: _string, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enumerator: _enumerator, + array: _array, + object: _object, + record: _record, + discriminator: _discriminator, + nestedObject: _nestedObject, + nestedArray: _nestedArray, + }; + }, + fromJsonString(input): ObjectWithEveryType { + return $$ObjectWithEveryType.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"any":'; + json += JSON.stringify(input.any); + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"string":'; + json += serializeString(input.string); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"float32":'; + json += `${input.float32}`; + json += ',"float64":'; + json += `${input.float64}`; + json += ',"int8":'; + json += `${input.int8}`; + json += ',"uint8":'; + json += `${input.uint8}`; + json += ',"int16":'; + json += `${input.int16}`; + json += ',"uint16":'; + json += `${input.uint16}`; + json += ',"int32":'; + json += `${input.int32}`; + json += ',"uint32":'; + json += `${input.uint32}`; + json += ',"int64":'; + json += `"${input.int64}"`; + json += ',"uint64":'; + json += `"${input.uint64}"`; + json += ',"enumerator":'; + json += `"${input.enumerator}"`; + json += ',"array":'; + json += "["; + for (let i = 0; i < input.array.length; i++) { + if (i !== 0) json += ","; + const _inputArrayEl = input.array[i]; + json += `${_inputArrayEl}`; + } + json += "]"; + json += ',"object":'; + json += $$ObjectWithEveryTypeObject.toJsonString(input.object); + json += ',"record":'; + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.record)) { + if (_recordPropertyCount !== 0) { + json += ","; + } + json += `"${_key}":`; + json += `${_value}`; + _recordPropertyCount++; + } + json += "}"; + + json += ',"discriminator":'; + json += $$ObjectWithEveryTypeDiscriminator.toJsonString( + input.discriminator, + ); + json += ',"nestedObject":'; + json += $$ObjectWithEveryTypeNestedObject.toJsonString( + input.nestedObject, + ); + json += ',"nestedArray":'; + json += "["; + for (let i = 0; i < input.nestedArray.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayEl = input.nestedArray[i]; + json += "["; + for (let i = 0; i < _inputNestedArrayEl.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayElEl = _inputNestedArrayEl[i]; + json += + $$ObjectWithEveryTypeNestedArrayelementelement.toJsonString( + _inputNestedArrayElEl, ); - } - if ( - typeof json.int16 === "number" && - Number.isInteger(json.int16) && - json.int16 >= -32768 && - json.int16 <= 32767 - ) { - __D1.int16 = json.int16; - } else { - $fallback( - "/int16", - "/properties/int16", - "Expected valid integer between -32768 and 32767", + } + json += "]"; + } + json += "]"; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + console.warn( + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithEveryType/any.", + ); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`string=${input.string}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + queryParts.push(`float32=${input.float32}`); + queryParts.push(`float64=${input.float64}`); + queryParts.push(`int8=${input.int8}`); + queryParts.push(`uint8=${input.uint8}`); + queryParts.push(`int16=${input.int16}`); + queryParts.push(`uint16=${input.uint16}`); + queryParts.push(`int32=${input.int32}`); + queryParts.push(`uint32=${input.uint32}`); + queryParts.push(`int64=${input.int64}`); + queryParts.push(`uint64=${input.uint64}`); + queryParts.push(`enumerator=${input.enumerator}`); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryType/array.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/object.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/record.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/discriminator.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryType/nestedObject.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryType/nestedArray.", + ); + return queryParts.join("&"); + }, +}; + +export type ObjectWithEveryTypeEnumerator = + (typeof $$ObjectWithEveryTypeEnumeratorValues)[number]; +const $$ObjectWithEveryTypeEnumeratorValues = ["A", "B", "C"] as const; +export const $$ObjectWithEveryTypeEnumerator: ArriEnumValidator = + { + new(): ObjectWithEveryTypeEnumerator { + return $$ObjectWithEveryTypeEnumeratorValues[0]; + }, + validate(input): input is ObjectWithEveryTypeEnumerator { + return ( + typeof input === "string" && + $$ObjectWithEveryTypeEnumeratorValues.includes(input as any) + ); + }, + values: $$ObjectWithEveryTypeEnumeratorValues, + fromSerialValue(input): ObjectWithEveryTypeEnumerator { + if ($$ObjectWithEveryTypeEnumeratorValues.includes(input as any)) { + return input as ObjectWithEveryTypeEnumerator; + } + if ( + $$ObjectWithEveryTypeEnumeratorValues.includes( + input.toLowerCase() as any, + ) + ) { + return input.toLowerCase() as ObjectWithEveryTypeEnumerator; + } + if ( + $$ObjectWithEveryTypeEnumeratorValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as ObjectWithEveryTypeEnumerator; + } + return "A"; + }, + }; + +export interface ObjectWithEveryTypeObject { + string: string; + boolean: boolean; + timestamp: Date; +} +export const $$ObjectWithEveryTypeObject: ArriModelValidator = + { + new(): ObjectWithEveryTypeObject { + return { + string: "", + boolean: false, + timestamp: new Date(), + }; + }, + validate(input): input is ObjectWithEveryTypeObject { + return ( + isObject(input) && + typeof input.string === "string" && + typeof input.boolean === "boolean" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryTypeObject { + let _string: string; + if (typeof input.string === "string") { + _string = input.string; + } else { + _string = ""; + } + let _boolean: boolean; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = false; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryTypeObject { + return $$ObjectWithEveryTypeObject.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + json += serializeString(input.string); + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export type ObjectWithEveryTypeDiscriminator = + | ObjectWithEveryTypeDiscriminatorA + | ObjectWithEveryTypeDiscriminatorB; +export const $$ObjectWithEveryTypeDiscriminator: ArriModelValidator = + { + new(): ObjectWithEveryTypeDiscriminator { + return $$ObjectWithEveryTypeDiscriminatorA.new(); + }, + validate(input): input is ObjectWithEveryTypeDiscriminator { + if (!isObject(input)) { + return false; + } + if (typeof input.type !== "string") { + return false; + } + switch (input.type) { + case "A": + return $$ObjectWithEveryTypeDiscriminatorA.validate(input); + case "B": + return $$ObjectWithEveryTypeDiscriminatorB.validate(input); + default: + return false; + } + }, + fromJson(input): ObjectWithEveryTypeDiscriminator { + switch (input.type) { + case "A": + return $$ObjectWithEveryTypeDiscriminatorA.fromJson(input); + case "B": + return $$ObjectWithEveryTypeDiscriminatorB.fromJson(input); + default: + return $$ObjectWithEveryTypeDiscriminatorA.new(); + } + }, + fromJsonString(input): ObjectWithEveryTypeDiscriminator { + return $$ObjectWithEveryTypeDiscriminator.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryTypeDiscriminatorA.toJsonString( + input, ); - } - if ( - typeof json.uint16 === "number" && - Number.isInteger(json.uint16) && - json.uint16 >= 0 && - json.uint16 <= 65535 - ) { - __D1.uint16 = json.uint16; - } else { - $fallback( - "/uint16", - "/properties/uint16", - "Expected valid integer between 0 and 65535", + case "B": + return $$ObjectWithEveryTypeDiscriminatorB.toJsonString( + input, ); - } - if ( - typeof json.int32 === "number" && - Number.isInteger(json.int32) && - json.int32 >= -2147483648 && - json.int32 <= 2147483647 - ) { - __D1.int32 = json.int32; - } else { - $fallback( - "/int32", - "/properties/int32", - "Expected valid integer between -2147483648 and 2147483647", + default: + throw new Error(`Unhandled case "${(input as any).type}"`); + } + }, + toUrlQueryString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryTypeDiscriminatorA.toUrlQueryString( + input, ); - } - if ( - typeof json.uint32 === "number" && - Number.isInteger(json.uint32) && - json.uint32 >= 0 && - json.uint32 <= 4294967295 - ) { - __D1.uint32 = json.uint32; - } else { - $fallback( - "/uint32", - "/properties/uint32", - "Expected valid integer between 0 and 4294967295", + case "B": + return $$ObjectWithEveryTypeDiscriminatorB.toUrlQueryString( + input, ); - } - if ( - typeof json.int64 === "string" || - typeof json.int64 === "number" - ) { - try { - const val = BigInt(json.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/properties/int64", - "Unable to parse BigInt from json.int64.", - ); - } - } else if (typeof json.int64 === "bigint") { - __D1.int64 = json.int64; - } else { - $fallback( - "/int64", - "/properties/int64", - "Expected BigInt or Integer string. Got ${json.int64}", - ); - } - if ( - typeof json.uint64 === "string" || - typeof json.uint64 === "number" - ) { - try { - const val = BigInt(json.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/properties/uint64", - "Unable to parse BigInt from json.uint64.", - ); - } - } else if (typeof json.uint64 === "bigint") { - if (json.uint64 >= BigInt("0")) { - __D1.uint64 = json.uint64; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Expected BigInt or Integer string. Got ${json.uint64}", - ); - } - if (typeof json.enumerator === "string") { - if ( - json.enumerator === "A" || - json.enumerator === "B" || - json.enumerator === "C" - ) { - __D1.enumerator = json.enumerator; - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - if (Array.isArray(json.array)) { - const __D2 = []; - for (const __D2AItem of json.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback("/array", "/properties/array", "Expected Array"); - } - if (typeof json.object === "object" && json.object !== null) { - const __D2 = {}; - if (typeof json.object.string === "string") { - __D2.string = json.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - if (typeof json.object.boolean === "boolean") { - __D2.boolean = json.object.boolean; - } else { - $fallback( - "/object/boolean", - "/properties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); - } - if ( - typeof json.object.timestamp === "object" && - json.object.timestamp instanceof Date - ) { - __D2.timestamp = json.object.timestamp; - } else if (typeof json.object.timestamp === "string") { - __D2.timestamp = new Date(json.object.timestamp); - } else { - $fallback( - "/object/timestamp", - "/properties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - __D1.object = __D2; - } else { - $fallback( - "/object", - "/properties/object", - "Expected object", - ); - } - if (typeof json.record === "object" && json.record !== null) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(json.record)) { - let __D2RKeyRVal; - if (typeof json.record[__D2RKey] === "boolean") { - __D2RKeyRVal = json.record[__D2RKey]; - } else { - $fallback( - "/record/[key]", - "/properties/record/values/type", - "Expected boolean for /record/[key]", - ); - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.record = __D2RResult; - } else { - $fallback( - "/record", - "/properties/record", - "Expected object.", - ); - } - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - switch (json.discriminator.type) { - case "A": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if ( - typeof json.discriminator.title === "string" - ) { - __D2.title = json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if ( - typeof json.discriminator.title === "string" - ) { - __D2.title = json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - if ( - typeof json.discriminator.description === - "string" - ) { - __D2.description = - json.discriminator.description; - } else { - $fallback( - "/discriminator/description", - "/properties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "json.discriminator.type did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/discriminator", - "/properties/discriminator", - "Expected Object.", - ); - } - if ( - typeof json.nestedObject === "object" && - json.nestedObject !== null - ) { - const __D2 = {}; - if (typeof json.nestedObject.id === "string") { - __D2.id = json.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/properties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - if ( - typeof json.nestedObject.timestamp === "object" && - json.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = json.nestedObject.timestamp; - } else if ( - typeof json.nestedObject.timestamp === "string" - ) { - __D2.timestamp = new Date(json.nestedObject.timestamp); - } else { - $fallback( - "/nestedObject/timestamp", - "/properties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - if ( - typeof json.nestedObject.data === "object" && - json.nestedObject.data !== null - ) { - const __D3 = {}; - if (typeof json.nestedObject.data.id === "string") { - __D3.id = json.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/properties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - if ( - typeof json.nestedObject.data.timestamp === - "object" && - json.nestedObject.data.timestamp instanceof Date - ) { - __D3.timestamp = json.nestedObject.data.timestamp; - } else if ( - typeof json.nestedObject.data.timestamp === "string" - ) { - __D3.timestamp = new Date( - json.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/properties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - if ( - typeof json.nestedObject.data.data === "object" && - json.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - typeof json.nestedObject.data.data.id === - "string" - ) { - __D4.id = json.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/properties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - if ( - typeof json.nestedObject.data.data.timestamp === - "object" && - json.nestedObject.data.data.timestamp instanceof - Date - ) { - __D4.timestamp = - json.nestedObject.data.data.timestamp; - } else if ( - typeof json.nestedObject.data.data.timestamp === - "string" - ) { - __D4.timestamp = new Date( - json.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/properties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - __D3.data = __D4; - } else { - $fallback( - "/nestedObject/data/data", - "/properties/nestedObject/properties/data/properties/data", - "Expected object", - ); - } - __D2.data = __D3; - } else { - $fallback( - "/nestedObject/data", - "/properties/nestedObject/properties/data", - "Expected object", - ); - } - __D1.nestedObject = __D2; - } else { - $fallback( - "/nestedObject", - "/properties/nestedObject", - "Expected object", - ); - } - if (Array.isArray(json.nestedArray)) { - const __D2 = []; - for (const __D2AItem of json.nestedArray) { - let __D2AItemAResult; - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (typeof __D3AItem.id === "string") { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/properties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - if ( - typeof __D3AItem.timestamp === - "object" && - __D3AItem.timestamp instanceof Date - ) { - __D4.timestamp = __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === "string" - ) { - __D4.timestamp = new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/properties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", - ); - } - __D3AItemAResult = __D4; - } else { - $fallback( - "/nestedArray/[0]/[0]", - "/properties/nestedArray/elements/elements", - "Expected object", - ); - } - __D3.push(__D3AItemAResult); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/nestedArray/[0]", - "/properties/nestedArray/elements", - "Expected Array", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.nestedArray = __D2; - } else { - $fallback( - "/nestedArray", - "/properties/nestedArray", - "Expected Array", - ); - } - result = __D1; + default: + throw new Error("Unhandled case"); + } + }, + }; +export interface ObjectWithEveryTypeDiscriminatorA { + type: "A"; + title: string; +} +const $$ObjectWithEveryTypeDiscriminatorA: ArriModelValidator = + { + new(): ObjectWithEveryTypeDiscriminatorA { + return { + type: "A", + title: "", + }; + }, + validate(input): input is ObjectWithEveryTypeDiscriminatorA { + return ( + isObject(input) && + input.type === "A" && + typeof input.title === "string" + ); + }, + fromJson(input): ObjectWithEveryTypeDiscriminatorA { + const _type = "A"; + let _title: string; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = ""; + } + return { + type: _type, + title: _title, + }; + }, + fromJsonString(input): ObjectWithEveryTypeDiscriminatorA { + return $$ObjectWithEveryTypeDiscriminatorA.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"A"'; + json += ',"title":'; + json += serializeString(input.title); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=A"); + queryParts.push(`title=${input.title}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryTypeDiscriminatorB { + type: "B"; + title: string; + description: string; +} +const $$ObjectWithEveryTypeDiscriminatorB: ArriModelValidator = + { + new(): ObjectWithEveryTypeDiscriminatorB { + return { + type: "B", + title: "", + description: "", + }; + }, + validate(input): input is ObjectWithEveryTypeDiscriminatorB { + return ( + isObject(input) && + input.type === "B" && + typeof input.title === "string" && + typeof input.description === "string" + ); + }, + fromJson(input): ObjectWithEveryTypeDiscriminatorB { + const _type = "B"; + let _title: string; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = ""; + } + let _description: string; + if (typeof input.description === "string") { + _description = input.description; + } else { + _description = ""; + } + return { + type: _type, + title: _title, + description: _description, + }; + }, + fromJsonString(input): ObjectWithEveryTypeDiscriminatorB { + return $$ObjectWithEveryTypeDiscriminatorB.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"B"'; + json += ',"title":'; + json += serializeString(input.title); + json += ',"description":'; + json += serializeString(input.description); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=B"); + queryParts.push(`title=${input.title}`); + queryParts.push(`description=${input.description}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryTypeNestedObject { + id: string; + timestamp: Date; + data: ObjectWithEveryTypeNestedObjectData; +} +export const $$ObjectWithEveryTypeNestedObject: ArriModelValidator = + { + new(): ObjectWithEveryTypeNestedObject { + return { + id: "", + timestamp: new Date(), + data: $$ObjectWithEveryTypeNestedObjectData.new(), + }; + }, + validate(input): input is ObjectWithEveryTypeNestedObject { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date && + $$ObjectWithEveryTypeNestedObjectData.validate(input.data) + ); + }, + fromJson(input): ObjectWithEveryTypeNestedObject { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; } else { - $fallback("", "", "Expected object"); + _id = ""; } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.any = input.any; - if (typeof input.boolean === "boolean") { - __D1.boolean = input.boolean; + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", + _timestamp = new Date(); + } + let _data: ObjectWithEveryTypeNestedObjectData; + if (isObject(input.data)) { + _data = $$ObjectWithEveryTypeNestedObjectData.fromJson( + input.data, ); + } else { + _data = $$ObjectWithEveryTypeNestedObjectData.new(); + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryTypeNestedObject { + return $$ObjectWithEveryTypeNestedObject.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"data":'; + json += $$ObjectWithEveryTypeNestedObjectData.toJsonString( + input.data, + ); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryTypeNestedObject/data.", + ); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryTypeNestedObjectData { + id: string; + timestamp: Date; + data: ObjectWithEveryTypeNestedObjectDataData; +} +export const $$ObjectWithEveryTypeNestedObjectData: ArriModelValidator = + { + new(): ObjectWithEveryTypeNestedObjectData { + return { + id: "", + timestamp: new Date(), + data: $$ObjectWithEveryTypeNestedObjectDataData.new(), + }; + }, + validate(input): input is ObjectWithEveryTypeNestedObjectData { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date && + $$ObjectWithEveryTypeNestedObjectDataData.validate(input.data) + ); + }, + fromJson(input): ObjectWithEveryTypeNestedObjectData { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; } - if (typeof input.string === "string") { - __D1.string = input.string; + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); + _timestamp = new Date(); } - if ( - typeof input.timestamp === "object" && - input.timestamp instanceof Date - ) { - __D1.timestamp = input.timestamp; - } else if (typeof input.timestamp === "string") { - __D1.timestamp = new Date(input.timestamp); - } else { - $fallback( - "/timestamp", - "/properties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", + let _data: ObjectWithEveryTypeNestedObjectDataData; + if (isObject(input.data)) { + _data = $$ObjectWithEveryTypeNestedObjectDataData.fromJson( + input.data, ); + } else { + _data = $$ObjectWithEveryTypeNestedObjectDataData.new(); + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryTypeNestedObjectData { + return $$ObjectWithEveryTypeNestedObjectData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"data":'; + json += $$ObjectWithEveryTypeNestedObjectDataData.toJsonString( + input.data, + ); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryTypeNestedObjectData/data.", + ); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryTypeNestedObjectDataData { + id: string; + timestamp: Date; +} +export const $$ObjectWithEveryTypeNestedObjectDataData: ArriModelValidator = + { + new(): ObjectWithEveryTypeNestedObjectDataData { + return { + id: "", + timestamp: new Date(), + }; + }, + validate(input): input is ObjectWithEveryTypeNestedObjectDataData { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryTypeNestedObjectDataData { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryTypeNestedObjectDataData { + return $$ObjectWithEveryTypeNestedObjectDataData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryTypeNestedArrayelementelement { + id: string; + timestamp: Date; +} +export const $$ObjectWithEveryTypeNestedArrayelementelement: ArriModelValidator = + { + new(): ObjectWithEveryTypeNestedArrayelementelement { + return { + id: "", + timestamp: new Date(), + }; + }, + validate(input): input is ObjectWithEveryTypeNestedArrayelementelement { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryTypeNestedArrayelementelement { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryTypeNestedArrayelementelement { + return $$ObjectWithEveryTypeNestedArrayelementelement.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryNullableType { + any: any; + boolean: boolean | null; + string: string | null; + timestamp: Date | null; + float32: number | null; + float64: number | null; + int8: number | null; + uint8: number | null; + int16: number | null; + uint16: number | null; + int32: number | null; + uint32: number | null; + int64: bigint | null; + uint64: bigint | null; + enumerator: ObjectWithEveryNullableTypeEnumerator | null; + array: (boolean | null)[] | null; + object: ObjectWithEveryNullableTypeObject | null; + record: Record | null; + discriminator: ObjectWithEveryNullableTypeDiscriminator | null; + nestedObject: ObjectWithEveryNullableTypeNestedObject | null; + nestedArray: + | ( + | (ObjectWithEveryNullableTypeNestedArrayelementelement | null)[] + | null + )[] + | null; +} +export const $$ObjectWithEveryNullableType: ArriModelValidator = + { + new(): ObjectWithEveryNullableType { + return { + any: null, + boolean: null, + string: null, + timestamp: null, + float32: null, + float64: null, + int8: null, + uint8: null, + int16: null, + uint16: null, + int32: null, + uint32: null, + int64: null, + uint64: null, + enumerator: null, + array: null, + object: null, + record: null, + discriminator: null, + nestedObject: null, + nestedArray: null, + }; + }, + validate(input): input is ObjectWithEveryNullableType { + return ( + isObject(input) && + true && + (typeof input.boolean === "boolean" || + input.boolean === null) && + (typeof input.string === "string" || input.string === null) && + (input.timestamp instanceof Date || input.timestamp === null) && + (typeof input.float32 === "number" || input.float32 === null) && + (typeof input.float64 === "number" || input.float64 === null) && + ((typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX) || + input.int8 === null) && + ((typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX) || + input.uint8 === null) && + ((typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX) || + input.int16 === null) && + ((typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX) || + input.uint16 === null) && + ((typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX) || + input.int32 === null) && + ((typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX) || + input.uint32 === null) && + ((typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX) || + input.int64 === null) && + ((typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX) || + input.uint64 === null) && + ($$ObjectWithEveryNullableTypeEnumerator.validate( + input.enumerator, + ) || + input.enumerator === null) && + ((Array.isArray(input.array) && + input.array.every( + (_element) => + typeof _element === "boolean" || _element === null, + )) || + input.array === null) && + ($$ObjectWithEveryNullableTypeObject.validate(input.object) || + input.object === null) && + ((isObject(input.record) && + Object.values(input.record).every( + (_value) => + typeof _value === "boolean" || _value === null, + )) || + input.record === null) && + ($$ObjectWithEveryNullableTypeDiscriminator.validate( + input.discriminator, + ) || + input.discriminator === null) && + ($$ObjectWithEveryNullableTypeNestedObject.validate( + input.nestedObject, + ) || + input.nestedObject === null) && + ((Array.isArray(input.nestedArray) && + input.nestedArray.every( + (_element) => + (Array.isArray(_element) && + _element.every( + (_element) => + $$ObjectWithEveryNullableTypeNestedArrayelementelement.validate( + _element, + ) || _element === null, + )) || + _element === null, + )) || + input.nestedArray === null) + ); + }, + fromJson(input): ObjectWithEveryNullableType { + let _any: any; + _any = input.any; + let _boolean: boolean | null; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = null; } - if ( - typeof input.float32 === "number" && - !Number.isNaN(input.float32) - ) { - __D1.float32 = input.float32; + let _string: string | null; + if (typeof input.string === "string") { + _string = input.string; } else { - $fallback( - "/float32", - "/properties/float32/type", - "Expected number at /float32", - ); + _string = null; } - if ( - typeof input.float64 === "number" && - !Number.isNaN(input.float64) - ) { - __D1.float64 = input.float64; + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { - $fallback( - "/float64", - "/properties/float64/type", - "Expected number at /float64", - ); + _timestamp = null; + } + let _float32: number | null; + if (typeof input.float32 === "number") { + _float32 = input.float32; + } else { + _float32 = null; } + let _float64: number | null; + if (typeof input.float64 === "number") { + _float64 = input.float64; + } else { + _float64 = null; + } + let _int8: number | null; if ( typeof input.int8 === "number" && Number.isInteger(input.int8) && - input.int8 >= -128 && - input.int8 <= 127 + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX ) { - __D1.int8 = input.int8; + _int8 = input.int8; } else { - $fallback( - "/int8", - "/properties/int8", - "Expected valid integer between -128 and 127", - ); + _int8 = null; } + let _uint8: number | null; if ( typeof input.uint8 === "number" && Number.isInteger(input.uint8) && input.uint8 >= 0 && - input.uint8 <= 255 + input.uint8 <= UINT8_MAX ) { - __D1.uint8 = input.uint8; + _uint8 = input.uint8; } else { - $fallback( - "/uint8", - "/properties/uint8", - "Expected valid integer between 0 and 255", - ); + _uint8 = null; } + let _int16: number | null; if ( typeof input.int16 === "number" && Number.isInteger(input.int16) && - input.int16 >= -32768 && - input.int16 <= 32767 + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX ) { - __D1.int16 = input.int16; + _int16 = input.int16; } else { - $fallback( - "/int16", - "/properties/int16", - "Expected valid integer between -32768 and 32767", - ); + _int16 = null; } + let _uint16: number | null; if ( typeof input.uint16 === "number" && Number.isInteger(input.uint16) && input.uint16 >= 0 && - input.uint16 <= 65535 + input.uint16 <= UINT16_MAX ) { - __D1.uint16 = input.uint16; + _uint16 = input.uint16; } else { - $fallback( - "/uint16", - "/properties/uint16", - "Expected valid integer between 0 and 65535", - ); + _uint16 = null; } + let _int32: number | null; if ( typeof input.int32 === "number" && Number.isInteger(input.int32) && - input.int32 >= -2147483648 && - input.int32 <= 2147483647 + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX ) { - __D1.int32 = input.int32; + _int32 = input.int32; } else { - $fallback( - "/int32", - "/properties/int32", - "Expected valid integer between -2147483648 and 2147483647", - ); + _int32 = null; } + let _uint32: number | null; if ( typeof input.uint32 === "number" && Number.isInteger(input.uint32) && input.uint32 >= 0 && - input.uint32 <= 4294967295 + input.uint32 <= UINT32_MAX ) { - __D1.uint32 = input.uint32; + _uint32 = input.uint32; } else { - $fallback( - "/uint32", - "/properties/uint32", - "Expected valid integer between 0 and 4294967295", - ); + _uint32 = null; } - if ( - typeof input.int64 === "string" || - typeof input.int64 === "number" - ) { - try { - const val = BigInt(input.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/properties/int64", - "Unable to parse BigInt from input.int64.", - ); - } + let _int64: bigint | null; + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); } else if (typeof input.int64 === "bigint") { - __D1.int64 = input.int64; + _int64 = input.int64; } else { - $fallback( - "/int64", - "/properties/int64", - "Expected BigInt or Integer string. Got ${input.int64}", - ); + _int64 = null; } + let _uint64: bigint | null; if ( - typeof input.uint64 === "string" || - typeof input.uint64 === "number" + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) ) { - try { - const val = BigInt(input.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/properties/uint64", - "Unable to parse BigInt from input.uint64.", - ); - } - } else if (typeof input.uint64 === "bigint") { - if (input.uint64 >= BigInt("0")) { - __D1.uint64 = input.uint64; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } + _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; } else { - $fallback( - "/uint64", - "/properties/uint64", - "Expected BigInt or Integer string. Got ${input.uint64}", - ); + _uint64 = null; } + let _enumerator: ObjectWithEveryNullableTypeEnumerator | null; if (typeof input.enumerator === "string") { - if ( - input.enumerator === "A" || - input.enumerator === "B" || - input.enumerator === "C" - ) { - __D1.enumerator = input.enumerator; - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", + _enumerator = + $$ObjectWithEveryNullableTypeEnumerator.fromSerialValue( + input.enumerator, ); - } } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); + _enumerator = null; } + let _array: (boolean | null)[] | null; if (Array.isArray(input.array)) { - const __D2 = []; - for (const __D2AItem of input.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean | null; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); + _arrayElValue = null; } - __D2.push(__D2AItemAResult); + _array.push(_arrayElValue); } - __D1.array = __D2; } else { - $fallback("/array", "/properties/array", "Expected Array"); + _array = null; } - if (typeof input.object === "object" && input.object !== null) { - const __D2 = {}; - if (typeof input.object.string === "string") { - __D2.string = input.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - if (typeof input.object.boolean === "boolean") { - __D2.boolean = input.object.boolean; - } else { - $fallback( - "/object/boolean", - "/properties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); - } - if ( - typeof input.object.timestamp === "object" && - input.object.timestamp instanceof Date - ) { - __D2.timestamp = input.object.timestamp; - } else if (typeof input.object.timestamp === "string") { - __D2.timestamp = new Date(input.object.timestamp); - } else { - $fallback( - "/object/timestamp", - "/properties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - __D1.object = __D2; + let _object: ObjectWithEveryNullableTypeObject | null; + if (isObject(input.object)) { + _object = $$ObjectWithEveryNullableTypeObject.fromJson( + input.object, + ); } else { - $fallback("/object", "/properties/object", "Expected object"); + _object = null; } - if (typeof input.record === "object" && input.record !== null) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(input.record)) { - let __D2RKeyRVal; - if (typeof input.record[__D2RKey] === "boolean") { - __D2RKeyRVal = input.record[__D2RKey]; + let _record: Record | null; + if (isObject(input.record)) { + _record = {}; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean | null; + if (typeof _value === "boolean") { + _recordValue = _value; } else { - $fallback( - "/record/[key]", - "/properties/record/values/type", - "Expected boolean for /record/[key]", - ); + _recordValue = false; } - __D2RResult[__D2RKey] = __D2RKeyRVal; + _record[_key] = _recordValue; } - __D1.record = __D2RResult; } else { - $fallback("/record", "/properties/record", "Expected object."); + _record = null; } - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - switch (input.discriminator.type) { - case "A": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if (typeof input.discriminator.title === "string") { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if (typeof input.discriminator.title === "string") { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - if ( - typeof input.discriminator.description === - "string" - ) { - __D2.description = - input.discriminator.description; + let _discriminator: ObjectWithEveryNullableTypeDiscriminator | null; + if (isObject(input.discriminator)) { + _discriminator = + $$ObjectWithEveryNullableTypeDiscriminator.fromJson( + input.discriminator, + ); + } else { + _discriminator = null; + } + let _nestedObject: ObjectWithEveryNullableTypeNestedObject | null; + if (isObject(input.nestedObject)) { + _nestedObject = + $$ObjectWithEveryNullableTypeNestedObject.fromJson( + input.nestedObject, + ); + } else { + _nestedObject = null; + } + let _nestedArray: + | ( + | (ObjectWithEveryNullableTypeNestedArrayelementelement | null)[] + | null + )[] + | null; + if (Array.isArray(input.nestedArray)) { + _nestedArray = []; + for (const _nestedArrayEl of input.nestedArray) { + let _nestedArrayElValue: + | (ObjectWithEveryNullableTypeNestedArrayelementelement | null)[] + | null; + if (Array.isArray(_nestedArrayEl)) { + _nestedArrayElValue = []; + for (const _nestedArrayElValueEl of _nestedArrayEl) { + let _nestedArrayElValueElValue: ObjectWithEveryNullableTypeNestedArrayelementelement | null; + if (isObject(_nestedArrayElValueEl)) { + _nestedArrayElValueElValue = + $$ObjectWithEveryNullableTypeNestedArrayelementelement.fromJson( + _nestedArrayElValueEl, + ); } else { - $fallback( - "/discriminator/description", - "/properties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); + _nestedArrayElValueElValue = null; } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", + _nestedArrayElValue.push( + _nestedArrayElValueElValue, ); } - break; - } - default: - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "input.discriminator.type did not match one of the specified values", - ); - break; + } else { + _nestedArrayElValue = null; + } + _nestedArray.push(_nestedArrayElValue); + } + } else { + _nestedArray = null; + } + return { + any: _any, + boolean: _boolean, + string: _string, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enumerator: _enumerator, + array: _array, + object: _object, + record: _record, + discriminator: _discriminator, + nestedObject: _nestedObject, + nestedArray: _nestedArray, + }; + }, + fromJsonString(input): ObjectWithEveryNullableType { + return $$ObjectWithEveryNullableType.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"any":'; + json += JSON.stringify(input.any); + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"string":'; + if (typeof input.string === "string") { + json += serializeString(input.string); + } else { + json += "null"; + } + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += ',"float32":'; + json += `${input.float32}`; + json += ',"float64":'; + json += `${input.float64}`; + json += ',"int8":'; + json += `${input.int8}`; + json += ',"uint8":'; + json += `${input.uint8}`; + json += ',"int16":'; + json += `${input.int16}`; + json += ',"uint16":'; + json += `${input.uint16}`; + json += ',"int32":'; + json += `${input.int32}`; + json += ',"uint32":'; + json += `${input.uint32}`; + json += ',"int64":'; + if (typeof input.int64 === "bigint") { + json += `"${input.int64}"`; + } else { + json += "null"; + } + json += ',"uint64":'; + if (typeof input.uint64 === "bigint") { + json += `"${input.uint64}"`; + } else { + json += "null"; + } + json += ',"enumerator":'; + if (typeof input.enumerator === "string") { + json += `"${input.enumerator}"`; + } else { + json += "null"; + } + json += ',"array":'; + if (input.array !== null) { + json += "["; + for (let i = 0; i < input.array.length; i++) { + if (i !== 0) json += ","; + const _inputArrayEl = input.array[i]; + json += `${_inputArrayEl}`; } + json += "]"; } else { - $fallback( - "/discriminator", - "/properties/discriminator", - "Expected Object.", + json += "null"; + } + json += ',"object":'; + if (input.object !== null) { + json += $$ObjectWithEveryNullableTypeObject.toJsonString( + input.object, ); + } else { + json += "null"; } - if ( - typeof input.nestedObject === "object" && - input.nestedObject !== null - ) { - const __D2 = {}; - if (typeof input.nestedObject.id === "string") { - __D2.id = input.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/properties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - if ( - typeof input.nestedObject.timestamp === "object" && - input.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = input.nestedObject.timestamp; - } else if (typeof input.nestedObject.timestamp === "string") { - __D2.timestamp = new Date(input.nestedObject.timestamp); - } else { - $fallback( - "/nestedObject/timestamp", - "/properties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - if ( - typeof input.nestedObject.data === "object" && - input.nestedObject.data !== null - ) { - const __D3 = {}; - if (typeof input.nestedObject.data.id === "string") { - __D3.id = input.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/properties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - if ( - typeof input.nestedObject.data.timestamp === "object" && - input.nestedObject.data.timestamp instanceof Date - ) { - __D3.timestamp = input.nestedObject.data.timestamp; - } else if ( - typeof input.nestedObject.data.timestamp === "string" - ) { - __D3.timestamp = new Date( - input.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/properties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - if ( - typeof input.nestedObject.data.data === "object" && - input.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - typeof input.nestedObject.data.data.id === "string" - ) { - __D4.id = input.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/properties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - if ( - typeof input.nestedObject.data.data.timestamp === - "object" && - input.nestedObject.data.data.timestamp instanceof - Date - ) { - __D4.timestamp = - input.nestedObject.data.data.timestamp; - } else if ( - typeof input.nestedObject.data.data.timestamp === - "string" - ) { - __D4.timestamp = new Date( - input.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/properties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - __D3.data = __D4; - } else { - $fallback( - "/nestedObject/data/data", - "/properties/nestedObject/properties/data/properties/data", - "Expected object", - ); + json += ',"record":'; + if (input.record !== null) { + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.record)) { + if (_recordPropertyCount !== 0) { + json += ","; } - __D2.data = __D3; - } else { - $fallback( - "/nestedObject/data", - "/properties/nestedObject/properties/data", - "Expected object", - ); + json += `"${_key}":`; + json += `${_value}`; + _recordPropertyCount++; } - __D1.nestedObject = __D2; + json += "}"; } else { - $fallback( - "/nestedObject", - "/properties/nestedObject", - "Expected object", + json += "null"; + } + json += ',"discriminator":'; + if (input.discriminator != null) { + json += $$ObjectWithEveryNullableTypeDiscriminator.toJsonString( + input.discriminator, ); + } else { + json += "null"; } - if (Array.isArray(input.nestedArray)) { - const __D2 = []; - for (const __D2AItem of input.nestedArray) { - let __D2AItemAResult; - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (typeof __D3AItem.id === "string") { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/properties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - if ( - typeof __D3AItem.timestamp === "object" && - __D3AItem.timestamp instanceof Date - ) { - __D4.timestamp = __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === "string" - ) { - __D4.timestamp = new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/properties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", + json += ',"nestedObject":'; + if (input.nestedObject !== null) { + json += $$ObjectWithEveryNullableTypeNestedObject.toJsonString( + input.nestedObject, + ); + } else { + json += "null"; + } + json += ',"nestedArray":'; + if (input.nestedArray !== null) { + json += "["; + for (let i = 0; i < input.nestedArray.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayEl = input.nestedArray[i]; + if (_inputNestedArrayEl !== null) { + json += "["; + for (let i = 0; i < _inputNestedArrayEl.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayElEl = + _inputNestedArrayEl[i]; + if (_inputNestedArrayElEl !== null) { + json += + $$ObjectWithEveryNullableTypeNestedArrayelementelement.toJsonString( + _inputNestedArrayElEl, ); - } - __D3AItemAResult = __D4; } else { - $fallback( - "/nestedArray/[0]/[0]", - "/properties/nestedArray/elements/elements", - "Expected object", - ); + json += "null"; } - __D3.push(__D3AItemAResult); } - __D2AItemAResult = __D3; + json += "]"; } else { - $fallback( - "/nestedArray/[0]", - "/properties/nestedArray/elements", - "Expected Array", - ); + json += "null"; } - __D2.push(__D2AItemAResult); } - __D1.nestedArray = __D2; + json += "]"; } else { - $fallback( - "/nestedArray", - "/properties/nestedArray", - "Expected Array", - ); + json += "null"; } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: ObjectWithEveryType): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - if (typeof input.any !== "undefined") { - json += '"any":' + JSON.stringify(input.any); - } - json += `,"boolean":${input.boolean}`; - json += `,"string":`; - if (input.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.string.length; i++) { - __point__ = input.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.string.slice(__last__, i) + "\\"; - __last__ = i; - } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + console.warn( + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithEveryNullableType/any.", + ); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`string=${input.string}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + queryParts.push(`float32=${input.float32}`); + queryParts.push(`float64=${input.float64}`); + queryParts.push(`int8=${input.int8}`); + queryParts.push(`uint8=${input.uint8}`); + queryParts.push(`int16=${input.int16}`); + queryParts.push(`uint16=${input.uint16}`); + queryParts.push(`int32=${input.int32}`); + queryParts.push(`uint32=${input.uint32}`); + queryParts.push(`int64=${input.int64}`); + queryParts.push(`uint64=${input.uint64}`); + queryParts.push(`enumerator=${input.enumerator}`); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryNullableType/array.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableType/object.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableType/record.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableType/discriminator.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableType/nestedObject.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryNullableType/nestedArray.", + ); + return queryParts.join("&"); + }, + }; + +export type ObjectWithEveryNullableTypeEnumerator = + (typeof $$ObjectWithEveryNullableTypeEnumeratorValues)[number]; +const $$ObjectWithEveryNullableTypeEnumeratorValues = ["A", "B", "C"] as const; +export const $$ObjectWithEveryNullableTypeEnumerator: ArriEnumValidator = + { + new(): ObjectWithEveryNullableTypeEnumerator { + return $$ObjectWithEveryNullableTypeEnumeratorValues[0]; + }, + validate(input): input is ObjectWithEveryNullableTypeEnumerator { + return ( + typeof input === "string" && + $$ObjectWithEveryNullableTypeEnumeratorValues.includes( + input as any, + ) + ); + }, + values: $$ObjectWithEveryNullableTypeEnumeratorValues, + fromSerialValue(input): ObjectWithEveryNullableTypeEnumerator { + if ( + $$ObjectWithEveryNullableTypeEnumeratorValues.includes( + input as any, + ) + ) { + return input as ObjectWithEveryNullableTypeEnumerator; } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.string}"`; - } else { - json += `"${__result__}${input.string.slice(__last__)}"`; - } + if ( + $$ObjectWithEveryNullableTypeEnumeratorValues.includes( + input.toLowerCase() as any, + ) + ) { + return input.toLowerCase() as ObjectWithEveryNullableTypeEnumerator; } - } else if ( - input.string.length < 5000 && - !STR_ESCAPE.test(input.string) - ) { - json += `"${input.string}"`; - } else { - json += JSON.stringify(input.string); - } - json += `,"timestamp":"${input.timestamp.toISOString()}"`; - - if (Number.isNaN(input.float32)) { - throw new Error("Expected number at /float32 got NaN"); - } - json += `,"float32":${input.float32}`; - - if (Number.isNaN(input.float64)) { - throw new Error("Expected number at /float64 got NaN"); - } - json += `,"float64":${input.float64}`; - - if (Number.isNaN(input.int8)) { - throw new Error("Expected number at /int8 got NaN"); - } - json += `,"int8":${input.int8}`; - - if (Number.isNaN(input.uint8)) { - throw new Error("Expected number at /uint8 got NaN"); - } - json += `,"uint8":${input.uint8}`; - - if (Number.isNaN(input.int16)) { - throw new Error("Expected number at /int16 got NaN"); - } - json += `,"int16":${input.int16}`; - - if (Number.isNaN(input.uint16)) { - throw new Error("Expected number at /uint16 got NaN"); - } - json += `,"uint16":${input.uint16}`; - - if (Number.isNaN(input.int32)) { - throw new Error("Expected number at /int32 got NaN"); - } - json += `,"int32":${input.int32}`; - - if (Number.isNaN(input.uint32)) { - throw new Error("Expected number at /uint32 got NaN"); - } - json += `,"uint32":${input.uint32}`; - json += `,"int64":"${input.int64.toString()}"`; - json += `,"uint64":"${input.uint64.toString()}"`; - json += `,"enumerator":"${input.enumerator}"`; - json += ',"array":['; - for (let i = 0; i < input.array.length; i++) { - const valArrayItem = input.array[i]; - if (i !== 0) { - json += ","; + if ( + $$ObjectWithEveryNullableTypeEnumeratorValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as ObjectWithEveryNullableTypeEnumerator; } - json += `${valArrayItem}`; - } - json += "]"; + return "A"; + }, + }; - json += ',"object":'; - json += "{"; - json += `"string":`; - if (input.object.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.object.string.length; i++) { - __point__ = input.object.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.object.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.object.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.object.string}"`; - } else { - json += `"${__result__}${input.object.string.slice(__last__)}"`; - } - } - } else if ( - input.object.string.length < 5000 && - !STR_ESCAPE.test(input.object.string) - ) { - json += `"${input.object.string}"`; - } else { - json += JSON.stringify(input.object.string); - } - json += `,"boolean":${input.object.boolean}`; - json += `,"timestamp":"${input.object.timestamp.toISOString()}"`; - json += "}"; - const recordKeys = Object.keys(input.record); - json += ',"record":{'; - for (let i = 0; i < recordKeys.length; i++) { - const key = recordKeys[i]; - const innerVal = input.record[key]; - if (i !== 0) { - json += `,"${key}":`; +export interface ObjectWithEveryNullableTypeObject { + string: string | null; + boolean: boolean | null; + timestamp: Date | null; +} +export const $$ObjectWithEveryNullableTypeObject: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeObject { + return { + string: null, + boolean: null, + timestamp: null, + }; + }, + validate(input): input is ObjectWithEveryNullableTypeObject { + return ( + isObject(input) && + (typeof input.string === "string" || input.string === null) && + (typeof input.boolean === "boolean" || + input.boolean === null) && + (input.timestamp instanceof Date || input.timestamp === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeObject { + let _string: string | null; + if (typeof input.string === "string") { + _string = input.string; } else { - json += `"${key}":`; + _string = null; } - json += `${innerVal}`; - } - json += "}"; - switch (input.discriminator.type) { - case "A": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"A"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.discriminator.title.length; i++) { - __point__ = input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.discriminator.title); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += "}"; - break; + let _boolean: boolean | null; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeObject { + return $$ObjectWithEveryNullableTypeObject.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + if (typeof input.string === "string") { + json += serializeString(input.string); + } else { + json += "null"; } - case "B": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"B"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.discriminator.title.length; i++) { - __point__ = input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.discriminator.title); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += `,"description":`; - if (input.discriminator.description.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.description.length; - i++ - ) { - __point__ = - input.discriminator.description.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.description, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.description.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.description}"`; - } else { - json += `"${__result__}${input.discriminator.description.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.description.length < 5000 && - !STR_ESCAPE.test(input.discriminator.description) - ) { - json += `"${input.discriminator.description}"`; - } else { - json += JSON.stringify(input.discriminator.description); - } - json += "}"; - break; + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; } - } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + return queryParts.join("&"); + }, + }; - json += ',"nestedObject":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.id.length; i++) { - __point__ = input.nestedObject.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.id}"`; - } else { - json += `"${__result__}${input.nestedObject.id.slice(__last__)}"`; - } +export type ObjectWithEveryNullableTypeDiscriminator = + | ObjectWithEveryNullableTypeDiscriminatorA + | ObjectWithEveryNullableTypeDiscriminatorB; +export const $$ObjectWithEveryNullableTypeDiscriminator: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeDiscriminator { + return $$ObjectWithEveryNullableTypeDiscriminatorA.new(); + }, + validate(input): input is ObjectWithEveryNullableTypeDiscriminator { + if (!isObject(input)) { + return false; + } + if (typeof input.type !== "string") { + return false; } - } else if ( - input.nestedObject.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.id) - ) { - json += `"${input.nestedObject.id}"`; - } else { - json += JSON.stringify(input.nestedObject.id); - } - json += `,"timestamp":"${input.nestedObject.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.data.id.length; i++) { - __point__ = input.nestedObject.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.data.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.id.slice(__last__, i) + "\\"; - __last__ = i; - } + switch (input.type) { + case "A": + return $$ObjectWithEveryNullableTypeDiscriminatorA.validate( + input, + ); + case "B": + return $$ObjectWithEveryNullableTypeDiscriminatorB.validate( + input, + ); + default: + return false; } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.id.slice(__last__)}"`; - } + }, + fromJson(input): ObjectWithEveryNullableTypeDiscriminator { + switch (input.type) { + case "A": + return $$ObjectWithEveryNullableTypeDiscriminatorA.fromJson( + input, + ); + case "B": + return $$ObjectWithEveryNullableTypeDiscriminatorB.fromJson( + input, + ); + default: + return $$ObjectWithEveryNullableTypeDiscriminatorA.new(); } - } else if ( - input.nestedObject.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.id) - ) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.data.data.id.length; i++) { - __point__ = input.nestedObject.data.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.data.data.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.data.id.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.data.id) - ) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.data.timestamp.toISOString()}"`; - json += "}"; - json += "}"; - json += "}"; - json += ',"nestedArray":['; - for (let i = 0; i < input.nestedArray.length; i++) { - const valNestedArrayItem = input.nestedArray[i]; - if (i !== 0) { - json += ","; + }, + fromJsonString(input): ObjectWithEveryNullableTypeDiscriminator { + return $$ObjectWithEveryNullableTypeDiscriminator.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryNullableTypeDiscriminatorA.toJsonString( + input, + ); + case "B": + return $$ObjectWithEveryNullableTypeDiscriminatorB.toJsonString( + input, + ); + default: + throw new Error(`Unhandled case "${(input as any).type}"`); } - json += "["; - for (let i = 0; i < valNestedArrayItem.length; i++) { - const valNestedArrayItemItem = valNestedArrayItem[i]; - if (i !== 0) { - json += ","; - } - - json += ""; - json += "{"; - json += `"id":`; - if (valNestedArrayItemItem.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < valNestedArrayItemItem.id.length; i++) { - __point__ = valNestedArrayItemItem.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(valNestedArrayItemItem.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valNestedArrayItemItem.id.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += `"${__result__}${valNestedArrayItemItem.id.slice(__last__)}"`; - } - } - } else if ( - valNestedArrayItemItem.id.length < 5000 && - !STR_ESCAPE.test(valNestedArrayItemItem.id) - ) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += JSON.stringify(valNestedArrayItemItem.id); - } - json += `,"timestamp":"${valNestedArrayItemItem.timestamp.toISOString()}"`; - json += "}"; + }, + toUrlQueryString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryNullableTypeDiscriminatorA.toUrlQueryString( + input, + ); + case "B": + return $$ObjectWithEveryNullableTypeDiscriminatorB.toUrlQueryString( + input, + ); + default: + throw new Error("Unhandled case"); } - json += "]"; - } - json += "]"; - json += "}"; - return json; - }, -}; -export type ObjectWithEveryTypeEnumerator = "A" | "B" | "C"; -export interface ObjectWithEveryTypeObject { - string: string; - boolean: boolean; - timestamp: Date; -} - -export type ObjectWithEveryTypeRecord = Record; - -export type ObjectWithEveryTypeDiscriminator = - | ObjectWithEveryTypeDiscriminatorA - | ObjectWithEveryTypeDiscriminatorB; - -export interface ObjectWithEveryTypeDiscriminatorA { + }, + }; +export interface ObjectWithEveryNullableTypeDiscriminatorA { type: "A"; - title: string; + title: string | null; } +const $$ObjectWithEveryNullableTypeDiscriminatorA: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeDiscriminatorA { + return { + type: "A", + title: null, + }; + }, + validate(input): input is ObjectWithEveryNullableTypeDiscriminatorA { + return ( + isObject(input) && + input.type === "A" && + (typeof input.title === "string" || input.title === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeDiscriminatorA { + const _type = "A"; + let _title: string | null; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = null; + } + return { + type: _type, + title: _title, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeDiscriminatorA { + return $$ObjectWithEveryNullableTypeDiscriminatorA.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"A"'; + json += ',"title":'; + if (typeof input.title === "string") { + json += serializeString(input.title); + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=A"); + queryParts.push(`title=${input.title}`); + return queryParts.join("&"); + }, + }; -export interface ObjectWithEveryTypeDiscriminatorB { +export interface ObjectWithEveryNullableTypeDiscriminatorB { type: "B"; - title: string; - description: string; -} - -export interface ObjectWithEveryTypeNestedObject { - id: string; - timestamp: Date; - data: ObjectWithEveryTypeNestedObjectData; + title: string | null; + description: string | null; } +const $$ObjectWithEveryNullableTypeDiscriminatorB: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeDiscriminatorB { + return { + type: "B", + title: null, + description: null, + }; + }, + validate(input): input is ObjectWithEveryNullableTypeDiscriminatorB { + return ( + isObject(input) && + input.type === "B" && + (typeof input.title === "string" || input.title === null) && + (typeof input.description === "string" || + input.description === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeDiscriminatorB { + const _type = "B"; + let _title: string | null; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = null; + } + let _description: string | null; + if (typeof input.description === "string") { + _description = input.description; + } else { + _description = null; + } + return { + type: _type, + title: _title, + description: _description, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeDiscriminatorB { + return $$ObjectWithEveryNullableTypeDiscriminatorB.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"B"'; + json += ',"title":'; + if (typeof input.title === "string") { + json += serializeString(input.title); + } else { + json += "null"; + } + json += ',"description":'; + if (typeof input.description === "string") { + json += serializeString(input.description); + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=B"); + queryParts.push(`title=${input.title}`); + queryParts.push(`description=${input.description}`); + return queryParts.join("&"); + }, + }; -export interface ObjectWithEveryTypeNestedObjectData { - id: string; - timestamp: Date; - data: ObjectWithEveryTypeNestedObjectDataData; +export interface ObjectWithEveryNullableTypeNestedObject { + id: string | null; + timestamp: Date | null; + data: ObjectWithEveryNullableTypeNestedObjectData | null; } +export const $$ObjectWithEveryNullableTypeNestedObject: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeNestedObject { + return { + id: null, + timestamp: null, + data: null, + }; + }, + validate(input): input is ObjectWithEveryNullableTypeNestedObject { + return ( + isObject(input) && + (typeof input.id === "string" || input.id === null) && + (input.timestamp instanceof Date || input.timestamp === null) && + ($$ObjectWithEveryNullableTypeNestedObjectData.validate( + input.data, + ) || + input.data === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeNestedObject { + let _id: string | null; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + let _data: ObjectWithEveryNullableTypeNestedObjectData | null; + if (isObject(input.data)) { + _data = $$ObjectWithEveryNullableTypeNestedObjectData.fromJson( + input.data, + ); + } else { + _data = null; + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeNestedObject { + return $$ObjectWithEveryNullableTypeNestedObject.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + if (typeof input.id === "string") { + json += serializeString(input.id); + } else { + json += "null"; + } + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += ',"data":'; + if (input.data !== null) { + json += + $$ObjectWithEveryNullableTypeNestedObjectData.toJsonString( + input.data, + ); + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableTypeNestedObject/data.", + ); + return queryParts.join("&"); + }, + }; -export interface ObjectWithEveryTypeNestedObjectDataData { - id: string; - timestamp: Date; +export interface ObjectWithEveryNullableTypeNestedObjectData { + id: string | null; + timestamp: Date | null; + data: ObjectWithEveryNullableTypeNestedObjectDataData | null; } +export const $$ObjectWithEveryNullableTypeNestedObjectData: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeNestedObjectData { + return { + id: null, + timestamp: null, + data: null, + }; + }, + validate(input): input is ObjectWithEveryNullableTypeNestedObjectData { + return ( + isObject(input) && + (typeof input.id === "string" || input.id === null) && + (input.timestamp instanceof Date || input.timestamp === null) && + ($$ObjectWithEveryNullableTypeNestedObjectDataData.validate( + input.data, + ) || + input.data === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeNestedObjectData { + let _id: string | null; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + let _data: ObjectWithEveryNullableTypeNestedObjectDataData | null; + if (isObject(input.data)) { + _data = + $$ObjectWithEveryNullableTypeNestedObjectDataData.fromJson( + input.data, + ); + } else { + _data = null; + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeNestedObjectData { + return $$ObjectWithEveryNullableTypeNestedObjectData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + if (typeof input.id === "string") { + json += serializeString(input.id); + } else { + json += "null"; + } + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += ',"data":'; + if (input.data !== null) { + json += + $$ObjectWithEveryNullableTypeNestedObjectDataData.toJsonString( + input.data, + ); + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryNullableTypeNestedObjectData/data.", + ); + return queryParts.join("&"); + }, + }; -export interface ObjectWithEveryTypeNestedArrayItemItem { - id: string; - timestamp: Date; +export interface ObjectWithEveryNullableTypeNestedObjectDataData { + id: string | null; + timestamp: Date | null; } - -export interface ObjectWithEveryNullableType { - any: any | null; - boolean: boolean | null; - string: string | null; +export const $$ObjectWithEveryNullableTypeNestedObjectDataData: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeNestedObjectDataData { + return { + id: null, + timestamp: null, + }; + }, + validate( + input, + ): input is ObjectWithEveryNullableTypeNestedObjectDataData { + return ( + isObject(input) && + (typeof input.id === "string" || input.id === null) && + (input.timestamp instanceof Date || input.timestamp === null) + ); + }, + fromJson(input): ObjectWithEveryNullableTypeNestedObjectDataData { + let _id: string | null; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryNullableTypeNestedObjectDataData { + return $$ObjectWithEveryNullableTypeNestedObjectDataData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + if (typeof input.id === "string") { + json += serializeString(input.id); + } else { + json += "null"; + } + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryNullableTypeNestedArrayelementelement { + id: string | null; timestamp: Date | null; - float32: number | null; - float64: number | null; - int8: number | null; - uint8: number | null; - int16: number | null; - uint16: number | null; - int32: number | null; - uint32: number | null; - int64: bigint | null; - uint64: bigint | null; - enumerator: ObjectWithEveryNullableTypeEnumerator | null; - array: Array | null; - object: ObjectWithEveryNullableTypeObject | null; - record: ObjectWithEveryNullableTypeRecord | null; - discriminator: ObjectWithEveryNullableTypeDiscriminator | null; - nestedObject: ObjectWithEveryNullableTypeNestedObject | null; - nestedArray: Array | null> | null; } -export const $$ObjectWithEveryNullableType = { - parse(input: Record): ObjectWithEveryNullableType { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, +export const $$ObjectWithEveryNullableTypeNestedArrayelementelement: ArriModelValidator = + { + new(): ObjectWithEveryNullableTypeNestedArrayelementelement { + return { + id: null, + timestamp: null, + }; + }, + validate( + input, + ): input is ObjectWithEveryNullableTypeNestedArrayelementelement { + return ( + isObject(input) && + (typeof input.id === "string" || input.id === null) && + (input.timestamp instanceof Date || input.timestamp === null) ); - } + }, + fromJson(input): ObjectWithEveryNullableTypeNestedArrayelementelement { + let _id: string | null; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = null; + } + let _timestamp: Date | null; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = null; + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString( + input, + ): ObjectWithEveryNullableTypeNestedArrayelementelement { + return $$ObjectWithEveryNullableTypeNestedArrayelementelement.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + if (typeof input.id === "string") { + json += serializeString(input.id); + } else { + json += "null"; + } + json += ',"timestamp":'; + if (input.timestamp instanceof Date) { + json += `"${input.timestamp.toISOString()}"`; + } else { + json += "null"; + } + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp?.toISOString()}`); + return queryParts.join("&"); + }, + }; - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.any = json.any; - if (json.boolean === null) { - __D1.boolean = null; +export interface ObjectWithEveryOptionalType { + any?: any; + boolean?: boolean; + string?: string; + timestamp?: Date; + float32?: number; + float64?: number; + int8?: number; + uint8?: number; + int16?: number; + uint16?: number; + int32?: number; + uint32?: number; + int64?: bigint; + uint64?: bigint; + enumerator?: ObjectWithEveryOptionalTypeEnumerator; + array?: boolean[]; + object?: ObjectWithEveryOptionalTypeObject; + record?: Record; + discriminator?: ObjectWithEveryOptionalTypeDiscriminator; + nestedObject?: ObjectWithEveryOptionalTypeNestedObject; + nestedArray?: ObjectWithEveryOptionalTypeNestedArrayelementelement[][]; +} +export const $$ObjectWithEveryOptionalType: ArriModelValidator = + { + new(): ObjectWithEveryOptionalType { + return {}; + }, + validate(input): input is ObjectWithEveryOptionalType { + return ( + isObject(input) && + (true || typeof input.any === "undefined") && + (typeof input.boolean === "boolean" || + typeof input.boolean === "undefined") && + (typeof input.string === "string" || + typeof input.string === "undefined") && + (input.timestamp instanceof Date || + typeof input.timestamp === "undefined") && + (typeof input.float32 === "number" || + typeof input.float32 === "undefined") && + (typeof input.float64 === "number" || + typeof input.float64 === "undefined") && + ((typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX) || + typeof input.int8 === "undefined") && + ((typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX) || + typeof input.uint8 === "undefined") && + ((typeof input.int16 === "number" && + Number.isInteger(input.int16) && + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX) || + typeof input.int16 === "undefined") && + ((typeof input.uint16 === "number" && + Number.isInteger(input.uint16) && + input.uint16 >= 0 && + input.uint16 <= UINT16_MAX) || + typeof input.uint16 === "undefined") && + ((typeof input.int32 === "number" && + Number.isInteger(input.int32) && + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX) || + typeof input.int32 === "undefined") && + ((typeof input.uint32 === "number" && + Number.isInteger(input.uint32) && + input.uint32 >= 0 && + input.uint32 <= UINT32_MAX) || + typeof input.uint32 === "undefined") && + ((typeof input.int64 === "bigint" && + input.int64 >= INT64_MIN && + input.int64 <= INT64_MAX) || + typeof input.int64 === "undefined") && + ((typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) && + input.uint64 <= UINT64_MAX) || + typeof input.uint64 === "undefined") && + ($$ObjectWithEveryOptionalTypeEnumerator.validate( + input.enumerator, + ) || + typeof input.enumerator === "undefined") && + ((Array.isArray(input.array) && + input.array.every( + (_element) => typeof _element === "boolean", + )) || + typeof input.array === "undefined") && + ($$ObjectWithEveryOptionalTypeObject.validate(input.object) || + typeof input.object === "undefined") && + ((isObject(input.record) && + Object.values(input.record).every( + (_value) => typeof _value === "boolean", + )) || + typeof input.record === "undefined") && + ($$ObjectWithEveryOptionalTypeDiscriminator.validate( + input.discriminator, + ) || + typeof input.discriminator === "undefined") && + ($$ObjectWithEveryOptionalTypeNestedObject.validate( + input.nestedObject, + ) || + typeof input.nestedObject === "undefined") && + ((Array.isArray(input.nestedArray) && + input.nestedArray.every( + (_element) => + Array.isArray(_element) && + _element.every((_element) => + $$ObjectWithEveryOptionalTypeNestedArrayelementelement.validate( + _element, + ), + ), + )) || + typeof input.nestedArray === "undefined") + ); + }, + fromJson(input): ObjectWithEveryOptionalType { + let _any: any | undefined; + if (typeof input.any !== "undefined") { + _any = input.any; + } + let _boolean: boolean | undefined; + if (typeof input.boolean !== "undefined") { + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; } else { - if (typeof json.boolean === "boolean") { - __D1.boolean = json.boolean; - } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", - ); - } + _boolean = false; } - if (json.string === null) { - __D1.string = json.string; + } + let _string: string | undefined; + if (typeof input.string !== "undefined") { + if (typeof input.string === "string") { + _string = input.string; } else { - if (typeof json.string === "string") { - __D1.string = json.string; - } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); - } + _string = ""; } - if (json.timestamp === null) { - __D1.timestamp = null; + } + let _timestamp: Date | undefined; + if (typeof input.timestamp !== "undefined") { + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { - if ( - typeof json.timestamp === "object" && - json.timestamp instanceof Date - ) { - __D1.timestamp = json.timestamp; - } else if (typeof json.timestamp === "string") { - __D1.timestamp = new Date(json.timestamp); - } else { - $fallback( - "/timestamp", - "/properties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", - ); - } + _timestamp = new Date(); } - if (json.float32 === null) { - __D1.float32 = null; + } + let _float32: number | undefined; + if (typeof input.float32 !== "undefined") { + if (typeof input.float32 === "number") { + _float32 = input.float32; } else { - if ( - typeof json.float32 === "number" && - !Number.isNaN(json.float32) - ) { - __D1.float32 = json.float32; - } else { - $fallback( - "/float32", - "/properties/float32/type", - "Expected number at /float32", - ); - } + _float32 = 0; } - if (json.float64 === null) { - __D1.float64 = null; + } + let _float64: number | undefined; + if (typeof input.float64 !== "undefined") { + if (typeof input.float64 === "number") { + _float64 = input.float64; } else { - if ( - typeof json.float64 === "number" && - !Number.isNaN(json.float64) - ) { - __D1.float64 = json.float64; - } else { - $fallback( - "/float64", - "/properties/float64/type", - "Expected number at /float64", - ); - } + _float64 = 0; } - if (json.int8 === null) { - __D1.int8 = null; + } + let _int8: number | undefined; + if (typeof input.int8 !== "undefined") { + if ( + typeof input.int8 === "number" && + Number.isInteger(input.int8) && + input.int8 >= INT8_MIN && + input.int8 <= INT8_MAX + ) { + _int8 = input.int8; } else { - if ( - typeof json.int8 === "number" && - Number.isInteger(json.int8) && - json.int8 >= -128 && - json.int8 <= 127 - ) { - __D1.int8 = json.int8; - } else { - $fallback( - "/int8", - "/properties/int8", - "Expected valid integer between -128 and 127", - ); - } + _int8 = 0; } - if (json.uint8 === null) { - __D1.uint8 = null; + } + let _uint8: number | undefined; + if (typeof input.uint8 !== "undefined") { + if ( + typeof input.uint8 === "number" && + Number.isInteger(input.uint8) && + input.uint8 >= 0 && + input.uint8 <= UINT8_MAX + ) { + _uint8 = input.uint8; } else { - if ( - typeof json.uint8 === "number" && - Number.isInteger(json.uint8) && - json.uint8 >= 0 && - json.uint8 <= 255 - ) { - __D1.uint8 = json.uint8; - } else { - $fallback( - "/uint8", - "/properties/uint8", - "Expected valid integer between 0 and 255", - ); - } - } - if (json.int16 === null) { - __D1.int16 = null; - } else { - if ( - typeof json.int16 === "number" && - Number.isInteger(json.int16) && - json.int16 >= -32768 && - json.int16 <= 32767 - ) { - __D1.int16 = json.int16; - } else { - $fallback( - "/int16", - "/properties/int16", - "Expected valid integer between -32768 and 32767", - ); - } - } - if (json.uint16 === null) { - __D1.uint16 = null; - } else { - if ( - typeof json.uint16 === "number" && - Number.isInteger(json.uint16) && - json.uint16 >= 0 && - json.uint16 <= 65535 - ) { - __D1.uint16 = json.uint16; - } else { - $fallback( - "/uint16", - "/properties/uint16", - "Expected valid integer between 0 and 65535", - ); - } - } - if (json.int32 === null) { - __D1.int32 = null; - } else { - if ( - typeof json.int32 === "number" && - Number.isInteger(json.int32) && - json.int32 >= -2147483648 && - json.int32 <= 2147483647 - ) { - __D1.int32 = json.int32; - } else { - $fallback( - "/int32", - "/properties/int32", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - } - if (json.uint32 === null) { - __D1.uint32 = null; - } else { - if ( - typeof json.uint32 === "number" && - Number.isInteger(json.uint32) && - json.uint32 >= 0 && - json.uint32 <= 4294967295 - ) { - __D1.uint32 = json.uint32; - } else { - $fallback( - "/uint32", - "/properties/uint32", - "Expected valid integer between 0 and 4294967295", - ); - } - } - if ( - typeof json.int64 === "string" || - typeof json.int64 === "number" - ) { - try { - const val = BigInt(json.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/properties/int64", - "Unable to parse BigInt from json.int64.", - ); - } - } else if (typeof json.int64 === "bigint") { - __D1.int64 = json.int64; - } else if (json.int64 === null) { - __D1.int64 = null; - } else { - $fallback( - "/int64", - "/properties/int64", - "Expected BigInt or Integer string. Got ${json.int64}", - ); - } - if ( - typeof json.uint64 === "string" || - typeof json.uint64 === "number" - ) { - try { - const val = BigInt(json.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/properties/uint64", - "Unable to parse BigInt from json.uint64.", - ); - } - } else if (typeof json.uint64 === "bigint") { - if (json.uint64 >= BigInt("0")) { - __D1.uint64 = json.uint64; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else if (json.uint64 === null) { - __D1.uint64 = null; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Expected BigInt or Integer string. Got ${json.uint64}", - ); - } - if (json.enumerator === null) { - __D1.enumerator = null; - } else { - if (typeof json.enumerator === "string") { - if ( - json.enumerator === "A" || - json.enumerator === "B" || - json.enumerator === "C" - ) { - __D1.enumerator = json.enumerator; - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } - if (json.array === null) { - __D1.array = null; - } else { - if (Array.isArray(json.array)) { - const __D2 = []; - for (const __D2AItem of json.array) { - let __D2AItemAResult; - if (__D2AItem === null) { - __D2AItemAResult = null; - } else { - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback( - "/array", - "/properties/array", - "Expected Array", - ); - } - } - if (json.object === null) { - __D1.object = null; - } else { - if ( - typeof json.object === "object" && - json.object !== null - ) { - const __D2 = {}; - if (json.object.string === null) { - __D2.string = json.object.string; - } else { - if (typeof json.object.string === "string") { - __D2.string = json.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - } - if (json.object.boolean === null) { - __D2.boolean = null; - } else { - if (typeof json.object.boolean === "boolean") { - __D2.boolean = json.object.boolean; - } else { - $fallback( - "/object/boolean", - "/properties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); - } - } - if (json.object.timestamp === null) { - __D2.timestamp = null; - } else { - if ( - typeof json.object.timestamp === "object" && - json.object.timestamp instanceof Date - ) { - __D2.timestamp = json.object.timestamp; - } else if ( - typeof json.object.timestamp === "string" - ) { - __D2.timestamp = new Date( - json.object.timestamp, - ); - } else { - $fallback( - "/object/timestamp", - "/properties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - } - __D1.object = __D2; - } else { - $fallback( - "/object", - "/properties/object", - "Expected object", - ); - } - } - if (json.record === null) { - __D1.record = null; - } else { - if ( - typeof json.record === "object" && - json.record !== null - ) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(json.record)) { - let __D2RKeyRVal; - if (json.record[__D2RKey] === null) { - __D2RKeyRVal = null; - } else { - if ( - typeof json.record[__D2RKey] === "boolean" - ) { - __D2RKeyRVal = json.record[__D2RKey]; - } else { - $fallback( - "/record/[key]", - "/properties/record/values/type", - "Expected boolean for /record/[key]", - ); - } - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.record = __D2RResult; - } else { - $fallback( - "/record", - "/properties/record", - "Expected object.", - ); - } - } - if (json.discriminator === null) { - __D1.discriminator = null; - } else { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - switch (json.discriminator.type) { - case "A": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if (json.discriminator.title === null) { - __D2.title = json.discriminator.title; - } else { - if ( - typeof json.discriminator.title === - "string" - ) { - __D2.title = - json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if (json.discriminator.title === null) { - __D2.title = json.discriminator.title; - } else { - if ( - typeof json.discriminator.title === - "string" - ) { - __D2.title = - json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - } - if ( - json.discriminator.description === null - ) { - __D2.description = - json.discriminator.description; - } else { - if ( - typeof json.discriminator - .description === "string" - ) { - __D2.description = - json.discriminator.description; - } else { - $fallback( - "/discriminator/description", - "/properties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); - } - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "json.discriminator.type did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/discriminator", - "/properties/discriminator", - "Expected Object.", - ); - } - } - if (json.nestedObject === null) { - __D1.nestedObject = null; - } else { - if ( - typeof json.nestedObject === "object" && - json.nestedObject !== null - ) { - const __D2 = {}; - if (json.nestedObject.id === null) { - __D2.id = json.nestedObject.id; - } else { - if (typeof json.nestedObject.id === "string") { - __D2.id = json.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/properties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - } - if (json.nestedObject.timestamp === null) { - __D2.timestamp = null; - } else { - if ( - typeof json.nestedObject.timestamp === - "object" && - json.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = json.nestedObject.timestamp; - } else if ( - typeof json.nestedObject.timestamp === "string" - ) { - __D2.timestamp = new Date( - json.nestedObject.timestamp, - ); - } else { - $fallback( - "/nestedObject/timestamp", - "/properties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - } - if (json.nestedObject.data === null) { - __D2.data = null; - } else { - if ( - typeof json.nestedObject.data === "object" && - json.nestedObject.data !== null - ) { - const __D3 = {}; - if (json.nestedObject.data.id === null) { - __D3.id = json.nestedObject.data.id; - } else { - if ( - typeof json.nestedObject.data.id === - "string" - ) { - __D3.id = json.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/properties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - } - if (json.nestedObject.data.timestamp === null) { - __D3.timestamp = null; - } else { - if ( - typeof json.nestedObject.data - .timestamp === "object" && - json.nestedObject.data - .timestamp instanceof Date - ) { - __D3.timestamp = - json.nestedObject.data.timestamp; - } else if ( - typeof json.nestedObject.data - .timestamp === "string" - ) { - __D3.timestamp = new Date( - json.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/properties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - } - if (json.nestedObject.data.data === null) { - __D3.data = null; - } else { - if ( - typeof json.nestedObject.data.data === - "object" && - json.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - json.nestedObject.data.data.id === - null - ) { - __D4.id = - json.nestedObject.data.data.id; - } else { - if ( - typeof json.nestedObject.data - .data.id === "string" - ) { - __D4.id = - json.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/properties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - } - if ( - json.nestedObject.data.data - .timestamp === null - ) { - __D4.timestamp = null; - } else { - if ( - typeof json.nestedObject.data - .data.timestamp === - "object" && - json.nestedObject.data.data - .timestamp instanceof Date - ) { - __D4.timestamp = - json.nestedObject.data.data.timestamp; - } else if ( - typeof json.nestedObject.data - .data.timestamp === "string" - ) { - __D4.timestamp = new Date( - json.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/properties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - } - __D3.data = __D4; - } else { - $fallback( - "/nestedObject/data/data", - "/properties/nestedObject/properties/data/properties/data", - "Expected object", - ); - } - } - __D2.data = __D3; - } else { - $fallback( - "/nestedObject/data", - "/properties/nestedObject/properties/data", - "Expected object", - ); - } - } - __D1.nestedObject = __D2; - } else { - $fallback( - "/nestedObject", - "/properties/nestedObject", - "Expected object", - ); - } - } - if (json.nestedArray === null) { - __D1.nestedArray = null; - } else { - if (Array.isArray(json.nestedArray)) { - const __D2 = []; - for (const __D2AItem of json.nestedArray) { - let __D2AItemAResult; - if (__D2AItem === null) { - __D2AItemAResult = null; - } else { - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if (__D3AItem === null) { - __D3AItemAResult = null; - } else { - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (__D3AItem.id === null) { - __D4.id = __D3AItem.id; - } else { - if ( - typeof __D3AItem.id === - "string" - ) { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/properties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - } - if ( - __D3AItem.timestamp === null - ) { - __D4.timestamp = null; - } else { - if ( - typeof __D3AItem.timestamp === - "object" && - __D3AItem.timestamp instanceof - Date - ) { - __D4.timestamp = - __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === - "string" - ) { - __D4.timestamp = - new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/properties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", - ); - } - } - __D3AItemAResult = __D4; - } else { - $fallback( - "/nestedArray/[0]/[0]", - "/properties/nestedArray/elements/elements", - "Expected object", - ); - } - } - __D3.push(__D3AItemAResult); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/nestedArray/[0]", - "/properties/nestedArray/elements", - "Expected Array", - ); - } - } - __D2.push(__D2AItemAResult); - } - __D1.nestedArray = __D2; - } else { - $fallback( - "/nestedArray", - "/properties/nestedArray", - "Expected Array", - ); - } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.any = input.any; - if (input.boolean === null) { - __D1.boolean = null; - } else { - if (typeof input.boolean === "boolean") { - __D1.boolean = input.boolean; - } else { - $fallback( - "/boolean", - "/properties/boolean/type", - "Expected boolean for /boolean", - ); - } - } - if (input.string === null) { - __D1.string = input.string; - } else { - if (typeof input.string === "string") { - __D1.string = input.string; - } else { - $fallback( - "/string", - "/properties/string/type", - "Expected string at /string", - ); - } - } - if (input.timestamp === null) { - __D1.timestamp = null; - } else { - if ( - typeof input.timestamp === "object" && - input.timestamp instanceof Date - ) { - __D1.timestamp = input.timestamp; - } else if (typeof input.timestamp === "string") { - __D1.timestamp = new Date(input.timestamp); - } else { - $fallback( - "/timestamp", - "/properties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", - ); - } - } - if (input.float32 === null) { - __D1.float32 = null; - } else { - if ( - typeof input.float32 === "number" && - !Number.isNaN(input.float32) - ) { - __D1.float32 = input.float32; - } else { - $fallback( - "/float32", - "/properties/float32/type", - "Expected number at /float32", - ); - } - } - if (input.float64 === null) { - __D1.float64 = null; - } else { - if ( - typeof input.float64 === "number" && - !Number.isNaN(input.float64) - ) { - __D1.float64 = input.float64; - } else { - $fallback( - "/float64", - "/properties/float64/type", - "Expected number at /float64", - ); - } - } - if (input.int8 === null) { - __D1.int8 = null; - } else { - if ( - typeof input.int8 === "number" && - Number.isInteger(input.int8) && - input.int8 >= -128 && - input.int8 <= 127 - ) { - __D1.int8 = input.int8; - } else { - $fallback( - "/int8", - "/properties/int8", - "Expected valid integer between -128 and 127", - ); - } - } - if (input.uint8 === null) { - __D1.uint8 = null; - } else { - if ( - typeof input.uint8 === "number" && - Number.isInteger(input.uint8) && - input.uint8 >= 0 && - input.uint8 <= 255 - ) { - __D1.uint8 = input.uint8; - } else { - $fallback( - "/uint8", - "/properties/uint8", - "Expected valid integer between 0 and 255", - ); + _uint8 = 0; } } - if (input.int16 === null) { - __D1.int16 = null; - } else { + let _int16: number | undefined; + if (typeof input.int16 !== "undefined") { if ( typeof input.int16 === "number" && Number.isInteger(input.int16) && - input.int16 >= -32768 && - input.int16 <= 32767 + input.int16 >= INT16_MIN && + input.int16 <= INT16_MAX ) { - __D1.int16 = input.int16; + _int16 = input.int16; } else { - $fallback( - "/int16", - "/properties/int16", - "Expected valid integer between -32768 and 32767", - ); + _int16 = 0; } } - if (input.uint16 === null) { - __D1.uint16 = null; - } else { + let _uint16: number | undefined; + if (typeof input.uint16 !== "undefined") { if ( typeof input.uint16 === "number" && Number.isInteger(input.uint16) && input.uint16 >= 0 && - input.uint16 <= 65535 + input.uint16 <= UINT16_MAX ) { - __D1.uint16 = input.uint16; + _uint16 = input.uint16; } else { - $fallback( - "/uint16", - "/properties/uint16", - "Expected valid integer between 0 and 65535", - ); + _uint16 = 0; } } - if (input.int32 === null) { - __D1.int32 = null; - } else { + let _int32: number | undefined; + if (typeof input.int32 !== "undefined") { if ( typeof input.int32 === "number" && Number.isInteger(input.int32) && - input.int32 >= -2147483648 && - input.int32 <= 2147483647 + input.int32 >= INT32_MIN && + input.int32 <= INT32_MAX ) { - __D1.int32 = input.int32; + _int32 = input.int32; } else { - $fallback( - "/int32", - "/properties/int32", - "Expected valid integer between -2147483648 and 2147483647", - ); + _int32 = 0; } } - if (input.uint32 === null) { - __D1.uint32 = null; - } else { + let _uint32: number | undefined; + if (typeof input.uint32 !== "undefined") { if ( typeof input.uint32 === "number" && Number.isInteger(input.uint32) && input.uint32 >= 0 && - input.uint32 <= 4294967295 + input.uint32 <= UINT32_MAX ) { - __D1.uint32 = input.uint32; + _uint32 = input.uint32; } else { - $fallback( - "/uint32", - "/properties/uint32", - "Expected valid integer between 0 and 4294967295", - ); + _uint32 = 0; } } - if ( - typeof input.int64 === "string" || - typeof input.int64 === "number" - ) { - try { - const val = BigInt(input.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/properties/int64", - "Unable to parse BigInt from input.int64.", - ); + let _int64: bigint | undefined; + if (typeof input.int64 !== "undefined") { + if (typeof input.int64 === "string") { + _int64 = BigInt(input.int64); + } else if (typeof input.int64 === "bigint") { + _int64 = input.int64; + } else { + _int64 = BigInt(0); } - } else if (typeof input.int64 === "bigint") { - __D1.int64 = input.int64; - } else if (input.int64 === null) { - __D1.int64 = null; - } else { - $fallback( - "/int64", - "/properties/int64", - "Expected BigInt or Integer string. Got ${input.int64}", - ); } - if ( - typeof input.uint64 === "string" || - typeof input.uint64 === "number" - ) { - try { - const val = BigInt(input.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/properties/uint64", - "Unable to parse BigInt from input.uint64.", - ); - } - } else if (typeof input.uint64 === "bigint") { - if (input.uint64 >= BigInt("0")) { - __D1.uint64 = input.uint64; + let _uint64: bigint | undefined; + if (typeof input.uint64 !== "undefined") { + if ( + typeof input.uint64 === "string" && + BigInt(input.uint64) >= BigInt(0) + ) { + _uint64 = BigInt(input.uint64); + } else if ( + typeof input.uint64 === "bigint" && + input.uint64 >= BigInt(0) + ) { + _uint64 = input.uint64; } else { - $fallback( - "/uint64", - "/properties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); + _uint64 = BigInt(0); } - } else if (input.uint64 === null) { - __D1.uint64 = null; - } else { - $fallback( - "/uint64", - "/properties/uint64", - "Expected BigInt or Integer string. Got ${input.uint64}", - ); } - if (input.enumerator === null) { - __D1.enumerator = null; - } else { + let _enumerator: ObjectWithEveryOptionalTypeEnumerator | undefined; + if (typeof input.enumerator !== "undefined") { if (typeof input.enumerator === "string") { - if ( - input.enumerator === "A" || - input.enumerator === "B" || - input.enumerator === "C" - ) { - __D1.enumerator = input.enumerator; - } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", + _enumerator = + $$ObjectWithEveryOptionalTypeEnumerator.fromSerialValue( + input.enumerator, ); - } } else { - $fallback( - "/enumerator", - "/properties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); + _enumerator = $$ObjectWithEveryOptionalTypeEnumerator.new(); } } - if (input.array === null) { - __D1.array = null; - } else { + let _array: boolean[] | undefined; + if (typeof input.array !== "undefined") { if (Array.isArray(input.array)) { - const __D2 = []; - for (const __D2AItem of input.array) { - let __D2AItemAResult; - if (__D2AItem === null) { - __D2AItemAResult = null; + _array = []; + for (const _arrayEl of input.array) { + let _arrayElValue: boolean; + if (typeof _arrayEl === "boolean") { + _arrayElValue = _arrayEl; } else { - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/properties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } + _arrayElValue = false; } - __D2.push(__D2AItemAResult); + _array.push(_arrayElValue); } - __D1.array = __D2; } else { - $fallback("/array", "/properties/array", "Expected Array"); + _array = []; } } - if (input.object === null) { - __D1.object = null; - } else { - if (typeof input.object === "object" && input.object !== null) { - const __D2 = {}; - if (input.object.string === null) { - __D2.string = input.object.string; - } else { - if (typeof input.object.string === "string") { - __D2.string = input.object.string; - } else { - $fallback( - "/object/string", - "/properties/object/properties/string/type", - "Expected string at /object/string", - ); - } - } - if (input.object.boolean === null) { - __D2.boolean = null; - } else { - if (typeof input.object.boolean === "boolean") { - __D2.boolean = input.object.boolean; + let _object: ObjectWithEveryOptionalTypeObject | undefined; + if (typeof input.object !== "undefined") { + if (isObject(input.object)) { + _object = $$ObjectWithEveryOptionalTypeObject.fromJson( + input.object, + ); + } else { + _object = $$ObjectWithEveryOptionalTypeObject.new(); + } + } + let _record: Record | undefined; + if (typeof input.record !== "undefined") { + if (isObject(input.record)) { + _record = {}; + for (const [_key, _value] of Object.entries(input.record)) { + let _recordValue: boolean; + if (typeof _value === "boolean") { + _recordValue = _value; } else { - $fallback( - "/object/boolean", - "/properties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); + _recordValue = false; } + _record[_key] = _recordValue; } - if (input.object.timestamp === null) { - __D2.timestamp = null; - } else { - if ( - typeof input.object.timestamp === "object" && - input.object.timestamp instanceof Date - ) { - __D2.timestamp = input.object.timestamp; - } else if (typeof input.object.timestamp === "string") { - __D2.timestamp = new Date(input.object.timestamp); - } else { - $fallback( - "/object/timestamp", - "/properties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - } - __D1.object = __D2; } else { - $fallback( - "/object", - "/properties/object", - "Expected object", - ); + _record = {}; } } - if (input.record === null) { - __D1.record = null; - } else { - if (typeof input.record === "object" && input.record !== null) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(input.record)) { - let __D2RKeyRVal; - if (input.record[__D2RKey] === null) { - __D2RKeyRVal = null; - } else { - if (typeof input.record[__D2RKey] === "boolean") { - __D2RKeyRVal = input.record[__D2RKey]; - } else { - $fallback( - "/record/[key]", - "/properties/record/values/type", - "Expected boolean for /record/[key]", - ); - } - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.record = __D2RResult; + let _discriminator: + | ObjectWithEveryOptionalTypeDiscriminator + | undefined; + if (typeof input.discriminator !== "undefined") { + if (isObject(input.discriminator)) { + _discriminator = + $$ObjectWithEveryOptionalTypeDiscriminator.fromJson( + input.discriminator, + ); } else { - $fallback( - "/record", - "/properties/record", - "Expected object.", - ); + _discriminator = + $$ObjectWithEveryOptionalTypeDiscriminator.new(); } } - if (input.discriminator === null) { - __D1.discriminator = null; - } else { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - switch (input.discriminator.type) { - case "A": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if (input.discriminator.title === null) { - __D2.title = input.discriminator.title; - } else { - if ( - typeof input.discriminator.title === - "string" - ) { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if (input.discriminator.title === null) { - __D2.title = input.discriminator.title; - } else { - if ( - typeof input.discriminator.title === - "string" - ) { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/properties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - } - if (input.discriminator.description === null) { - __D2.description = - input.discriminator.description; - } else { - if ( - typeof input.discriminator - .description === "string" - ) { - __D2.description = - input.discriminator.description; - } else { - $fallback( - "/discriminator/description", - "/properties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); - } - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/discriminator", - "/properties/discriminator/mapping", - "input.discriminator.type did not match one of the specified values", - ); - break; - } + let _nestedObject: + | ObjectWithEveryOptionalTypeNestedObject + | undefined; + if (typeof input.nestedObject !== "undefined") { + if (isObject(input.nestedObject)) { + _nestedObject = + $$ObjectWithEveryOptionalTypeNestedObject.fromJson( + input.nestedObject, + ); } else { - $fallback( - "/discriminator", - "/properties/discriminator", - "Expected Object.", - ); + _nestedObject = + $$ObjectWithEveryOptionalTypeNestedObject.new(); } } - if (input.nestedObject === null) { - __D1.nestedObject = null; - } else { - if ( - typeof input.nestedObject === "object" && - input.nestedObject !== null - ) { - const __D2 = {}; - if (input.nestedObject.id === null) { - __D2.id = input.nestedObject.id; - } else { - if (typeof input.nestedObject.id === "string") { - __D2.id = input.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/properties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - } - if (input.nestedObject.timestamp === null) { - __D2.timestamp = null; - } else { - if ( - typeof input.nestedObject.timestamp === "object" && - input.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = input.nestedObject.timestamp; - } else if ( - typeof input.nestedObject.timestamp === "string" - ) { - __D2.timestamp = new Date( - input.nestedObject.timestamp, - ); - } else { - $fallback( - "/nestedObject/timestamp", - "/properties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - } - if (input.nestedObject.data === null) { - __D2.data = null; - } else { - if ( - typeof input.nestedObject.data === "object" && - input.nestedObject.data !== null - ) { - const __D3 = {}; - if (input.nestedObject.data.id === null) { - __D3.id = input.nestedObject.data.id; - } else { - if ( - typeof input.nestedObject.data.id === - "string" - ) { - __D3.id = input.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/properties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - } - if (input.nestedObject.data.timestamp === null) { - __D3.timestamp = null; - } else { - if ( - typeof input.nestedObject.data.timestamp === - "object" && - input.nestedObject.data.timestamp instanceof - Date - ) { - __D3.timestamp = - input.nestedObject.data.timestamp; - } else if ( - typeof input.nestedObject.data.timestamp === - "string" - ) { - __D3.timestamp = new Date( - input.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/properties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - } - if (input.nestedObject.data.data === null) { - __D3.data = null; - } else { - if ( - typeof input.nestedObject.data.data === - "object" && - input.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - input.nestedObject.data.data.id === null - ) { - __D4.id = - input.nestedObject.data.data.id; - } else { - if ( - typeof input.nestedObject.data.data - .id === "string" - ) { - __D4.id = - input.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/properties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - } - if ( - input.nestedObject.data.data - .timestamp === null - ) { - __D4.timestamp = null; - } else { - if ( - typeof input.nestedObject.data.data - .timestamp === "object" && - input.nestedObject.data.data - .timestamp instanceof Date - ) { - __D4.timestamp = - input.nestedObject.data.data.timestamp; - } else if ( - typeof input.nestedObject.data.data - .timestamp === "string" - ) { - __D4.timestamp = new Date( - input.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/properties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - } - __D3.data = __D4; + let _nestedArray: + | ObjectWithEveryOptionalTypeNestedArrayelementelement[][] + | undefined; + if (typeof input.nestedArray !== "undefined") { + if (Array.isArray(input.nestedArray)) { + _nestedArray = []; + for (const _nestedArrayEl of input.nestedArray) { + let _nestedArrayElValue: ObjectWithEveryOptionalTypeNestedArrayelementelement[]; + if (Array.isArray(_nestedArrayEl)) { + _nestedArrayElValue = []; + for (const _nestedArrayElValueEl of _nestedArrayEl) { + let _nestedArrayElValueElValue: ObjectWithEveryOptionalTypeNestedArrayelementelement; + if (isObject(_nestedArrayElValueEl)) { + _nestedArrayElValueElValue = + $$ObjectWithEveryOptionalTypeNestedArrayelementelement.fromJson( + _nestedArrayElValueEl, + ); } else { - $fallback( - "/nestedObject/data/data", - "/properties/nestedObject/properties/data/properties/data", - "Expected object", - ); + _nestedArrayElValueElValue = + $$ObjectWithEveryOptionalTypeNestedArrayelementelement.new(); } + _nestedArrayElValue.push( + _nestedArrayElValueElValue, + ); } - __D2.data = __D3; } else { - $fallback( - "/nestedObject/data", - "/properties/nestedObject/properties/data", - "Expected object", - ); - } - } - __D1.nestedObject = __D2; - } else { - $fallback( - "/nestedObject", - "/properties/nestedObject", - "Expected object", - ); + _nestedArrayElValue = []; + } + _nestedArray.push(_nestedArrayElValue); + } + } else { + _nestedArray = []; + } + } + return { + any: _any, + boolean: _boolean, + string: _string, + timestamp: _timestamp, + float32: _float32, + float64: _float64, + int8: _int8, + uint8: _uint8, + int16: _int16, + uint16: _uint16, + int32: _int32, + uint32: _uint32, + int64: _int64, + uint64: _uint64, + enumerator: _enumerator, + array: _array, + object: _object, + record: _record, + discriminator: _discriminator, + nestedObject: _nestedObject, + nestedArray: _nestedArray, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalType { + return $$ObjectWithEveryOptionalType.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + let _hasKey = false; + if (typeof input.any !== "undefined") { + if (_hasKey) json += ","; + json += '"any":'; + json += JSON.stringify(input.any); + _hasKey = true; + } + if (typeof input.boolean !== "undefined") { + if (_hasKey) json += ","; + json += '"boolean":'; + json += `${input.boolean}`; + _hasKey = true; + } + if (typeof input.string !== "undefined") { + if (_hasKey) json += ","; + json += '"string":'; + json += serializeString(input.string); + _hasKey = true; + } + if (typeof input.timestamp !== "undefined") { + if (_hasKey) json += ","; + json += '"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + _hasKey = true; + } + if (typeof input.float32 !== "undefined") { + if (_hasKey) json += ","; + json += '"float32":'; + json += `${input.float32}`; + _hasKey = true; + } + if (typeof input.float64 !== "undefined") { + if (_hasKey) json += ","; + json += '"float64":'; + json += `${input.float64}`; + _hasKey = true; + } + if (typeof input.int8 !== "undefined") { + if (_hasKey) json += ","; + json += '"int8":'; + json += `${input.int8}`; + _hasKey = true; + } + if (typeof input.uint8 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint8":'; + json += `${input.uint8}`; + _hasKey = true; + } + if (typeof input.int16 !== "undefined") { + if (_hasKey) json += ","; + json += '"int16":'; + json += `${input.int16}`; + _hasKey = true; + } + if (typeof input.uint16 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint16":'; + json += `${input.uint16}`; + _hasKey = true; + } + if (typeof input.int32 !== "undefined") { + if (_hasKey) json += ","; + json += '"int32":'; + json += `${input.int32}`; + _hasKey = true; + } + if (typeof input.uint32 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint32":'; + json += `${input.uint32}`; + _hasKey = true; + } + if (typeof input.int64 !== "undefined") { + if (_hasKey) json += ","; + json += '"int64":'; + json += `"${input.int64}"`; + _hasKey = true; + } + if (typeof input.uint64 !== "undefined") { + if (_hasKey) json += ","; + json += '"uint64":'; + json += `"${input.uint64}"`; + _hasKey = true; + } + if (typeof input.enumerator !== "undefined") { + if (_hasKey) json += ","; + json += '"enumerator":'; + json += `"${input.enumerator}"`; + _hasKey = true; + } + if (typeof input.array !== "undefined") { + if (_hasKey) json += ","; + json += '"array":'; + json += "["; + for (let i = 0; i < input.array.length; i++) { + if (i !== 0) json += ","; + const _inputArrayEl = input.array[i]; + json += `${_inputArrayEl}`; } + json += "]"; + _hasKey = true; } - if (input.nestedArray === null) { - __D1.nestedArray = null; - } else { - if (Array.isArray(input.nestedArray)) { - const __D2 = []; - for (const __D2AItem of input.nestedArray) { - let __D2AItemAResult; - if (__D2AItem === null) { - __D2AItemAResult = null; - } else { - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if (__D3AItem === null) { - __D3AItemAResult = null; - } else { - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (__D3AItem.id === null) { - __D4.id = __D3AItem.id; - } else { - if ( - typeof __D3AItem.id === - "string" - ) { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/properties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - } - if (__D3AItem.timestamp === null) { - __D4.timestamp = null; - } else { - if ( - typeof __D3AItem.timestamp === - "object" && - __D3AItem.timestamp instanceof - Date - ) { - __D4.timestamp = - __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === - "string" - ) { - __D4.timestamp = new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/properties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", - ); - } - } - __D3AItemAResult = __D4; - } else { - $fallback( - "/nestedArray/[0]/[0]", - "/properties/nestedArray/elements/elements", - "Expected object", - ); - } - } - __D3.push(__D3AItemAResult); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/nestedArray/[0]", - "/properties/nestedArray/elements", - "Expected Array", - ); - } - } - __D2.push(__D2AItemAResult); + if (typeof input.object !== "undefined") { + if (_hasKey) json += ","; + json += '"object":'; + json += $$ObjectWithEveryOptionalTypeObject.toJsonString( + input.object, + ); + _hasKey = true; + } + if (typeof input.record !== "undefined") { + if (_hasKey) json += ","; + json += '"record":'; + json += "{"; + let _recordPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.record)) { + if (_recordPropertyCount !== 0) { + json += ","; } - __D1.nestedArray = __D2; - } else { - $fallback( - "/nestedArray", - "/properties/nestedArray", - "Expected Array", - ); + json += `"${_key}":`; + json += `${_value}`; + _recordPropertyCount++; } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: ObjectWithEveryNullableType): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + json += "}"; - json += ""; - json += "{"; - if (input.any === null) { - json += '"any":null'; - } else { - if (typeof input.any !== "undefined") { - json += '"any":' + JSON.stringify(input.any); + _hasKey = true; } - } - if (typeof input.boolean === "boolean") { - json += `,"boolean":${input.boolean}`; - } else { - json += ',"boolean":null'; - } - if (typeof input.string === "string") { - json += `,"string":`; - if (input.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.string.length; i++) { - __point__ = input.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.string}"`; - } else { - json += `"${__result__}${input.string.slice(__last__)}"`; + if (typeof input.discriminator !== "undefined") { + if (_hasKey) json += ","; + json += '"discriminator":'; + json += $$ObjectWithEveryOptionalTypeDiscriminator.toJsonString( + input.discriminator, + ); + _hasKey = true; + } + if (typeof input.nestedObject !== "undefined") { + if (_hasKey) json += ","; + json += '"nestedObject":'; + json += $$ObjectWithEveryOptionalTypeNestedObject.toJsonString( + input.nestedObject, + ); + _hasKey = true; + } + if (typeof input.nestedArray !== "undefined") { + if (_hasKey) json += ","; + json += '"nestedArray":'; + json += "["; + for (let i = 0; i < input.nestedArray.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayEl = input.nestedArray[i]; + json += "["; + for (let i = 0; i < _inputNestedArrayEl.length; i++) { + if (i !== 0) json += ","; + const _inputNestedArrayElEl = _inputNestedArrayEl[i]; + json += + $$ObjectWithEveryOptionalTypeNestedArrayelementelement.toJsonString( + _inputNestedArrayElEl, + ); } + json += "]"; } - } else if ( - input.string.length < 5000 && - !STR_ESCAPE.test(input.string) - ) { - json += `"${input.string}"`; - } else { - json += JSON.stringify(input.string); + json += "]"; + _hasKey = true; } - } else { - json += ',"string":null'; - } - if ( - typeof input.timestamp === "object" && - input.timestamp instanceof Date - ) { - json += `,"timestamp":"${input.timestamp.toISOString()}"`; - } else { - json += ',"timestamp":null'; - } - if (typeof input.float32 === "number" && !Number.isNaN(input.float32)) { - if (Number.isNaN(input.float32)) { - throw new Error("Expected number at /float32 got NaN"); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + if (typeof input.any !== "undefined") { + console.warn( + "[WARNING] Cannot serialize any's to query string. Skipping property at /ObjectWithEveryOptionalType/any.", + ); } - json += `,"float32":${input.float32}`; - } else { - json += ',"float32":null'; - } - if (typeof input.float64 === "number" && !Number.isNaN(input.float64)) { - if (Number.isNaN(input.float64)) { - throw new Error("Expected number at /float64 got NaN"); + if (typeof input.boolean !== "undefined") { + queryParts.push(`boolean=${input.boolean}`); } - json += `,"float64":${input.float64}`; - } else { - json += ',"float64":null'; - } - if (typeof input.int8 === "number" && !Number.isNaN(input.int8)) { - if (Number.isNaN(input.int8)) { - throw new Error("Expected number at /int8 got NaN"); + if (typeof input.string !== "undefined") { + queryParts.push(`string=${input.string}`); } - json += `,"int8":${input.int8}`; - } else { - json += ',"int8":null'; - } - if (typeof input.uint8 === "number" && !Number.isNaN(input.uint8)) { - if (Number.isNaN(input.uint8)) { - throw new Error("Expected number at /uint8 got NaN"); + if (typeof input.timestamp !== "undefined") { + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); } - json += `,"uint8":${input.uint8}`; - } else { - json += ',"uint8":null'; - } - if (typeof input.int16 === "number" && !Number.isNaN(input.int16)) { - if (Number.isNaN(input.int16)) { - throw new Error("Expected number at /int16 got NaN"); + if (typeof input.float32 !== "undefined") { + queryParts.push(`float32=${input.float32}`); } - json += `,"int16":${input.int16}`; - } else { - json += ',"int16":null'; - } - if (typeof input.uint16 === "number" && !Number.isNaN(input.uint16)) { - if (Number.isNaN(input.uint16)) { - throw new Error("Expected number at /uint16 got NaN"); + if (typeof input.float64 !== "undefined") { + queryParts.push(`float64=${input.float64}`); } - json += `,"uint16":${input.uint16}`; - } else { - json += ',"uint16":null'; - } - if (typeof input.int32 === "number" && !Number.isNaN(input.int32)) { - if (Number.isNaN(input.int32)) { - throw new Error("Expected number at /int32 got NaN"); + if (typeof input.int8 !== "undefined") { + queryParts.push(`int8=${input.int8}`); } - json += `,"int32":${input.int32}`; - } else { - json += ',"int32":null'; - } - if (typeof input.uint32 === "number" && !Number.isNaN(input.uint32)) { - if (Number.isNaN(input.uint32)) { - throw new Error("Expected number at /uint32 got NaN"); + if (typeof input.uint8 !== "undefined") { + queryParts.push(`uint8=${input.uint8}`); } - json += `,"uint32":${input.uint32}`; - } else { - json += ',"uint32":null'; - } - if (typeof input.int64 === "bigint") { - json += `,"int64":"${input.int64.toString()}"`; - } else { - json += ',"int64":null'; - } - if (typeof input.uint64 === "bigint") { - json += `,"uint64":"${input.uint64.toString()}"`; - } else { - json += ',"uint64":null'; - } - if (typeof input.enumerator === "string") { - json += `,"enumerator":"${input.enumerator}"`; - } else { - json += ',"enumerator":null'; - } - if (Array.isArray(input.array)) { - json += ',"array":['; - for (let i = 0; i < input.array.length; i++) { - const valArrayItem = input.array[i]; - if (i !== 0) { - json += ","; - } - if (typeof valArrayItem === "boolean") { - json += `${valArrayItem}`; - } else { - json += "null"; - } + if (typeof input.int16 !== "undefined") { + queryParts.push(`int16=${input.int16}`); } - json += "]"; - } else { - json += ',"array":null'; - } - if (typeof input.object === "object" && input.object !== null) { - json += ',"object":'; - json += "{"; - if (typeof input.object.string === "string") { - json += `"string":`; - if (input.object.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.object.string.length; i++) { - __point__ = input.object.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.object.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.object.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.object.string}"`; - } else { - json += `"${__result__}${input.object.string.slice(__last__)}"`; - } - } - } else if ( - input.object.string.length < 5000 && - !STR_ESCAPE.test(input.object.string) - ) { - json += `"${input.object.string}"`; - } else { - json += JSON.stringify(input.object.string); - } - } else { - json += '"string":null'; + if (typeof input.uint16 !== "undefined") { + queryParts.push(`uint16=${input.uint16}`); } - if (typeof input.object.boolean === "boolean") { - json += `,"boolean":${input.object.boolean}`; - } else { - json += ',"boolean":null'; + if (typeof input.int32 !== "undefined") { + queryParts.push(`int32=${input.int32}`); + } + if (typeof input.uint32 !== "undefined") { + queryParts.push(`uint32=${input.uint32}`); + } + if (typeof input.int64 !== "undefined") { + queryParts.push(`int64=${input.int64}`); + } + if (typeof input.uint64 !== "undefined") { + queryParts.push(`uint64=${input.uint64}`); + } + if (typeof input.enumerator !== "undefined") { + queryParts.push(`enumerator=${input.enumerator}`); + } + if (typeof input.array !== "undefined") { + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryOptionalType/array.", + ); + } + if (typeof input.object !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalType/object.", + ); + } + if (typeof input.record !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalType/record.", + ); + } + if (typeof input.discriminator !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalType/discriminator.", + ); + } + if (typeof input.nestedObject !== "undefined") { + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalType/nestedObject.", + ); + } + if (typeof input.nestedArray !== "undefined") { + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /ObjectWithEveryOptionalType/nestedArray.", + ); + } + return queryParts.join("&"); + }, + }; + +export type ObjectWithEveryOptionalTypeEnumerator = + (typeof $$ObjectWithEveryOptionalTypeEnumeratorValues)[number]; +const $$ObjectWithEveryOptionalTypeEnumeratorValues = ["A", "B", "C"] as const; +export const $$ObjectWithEveryOptionalTypeEnumerator: ArriEnumValidator = + { + new(): ObjectWithEveryOptionalTypeEnumerator { + return $$ObjectWithEveryOptionalTypeEnumeratorValues[0]; + }, + validate(input): input is ObjectWithEveryOptionalTypeEnumerator { + return ( + typeof input === "string" && + $$ObjectWithEveryOptionalTypeEnumeratorValues.includes( + input as any, + ) + ); + }, + values: $$ObjectWithEveryOptionalTypeEnumeratorValues, + fromSerialValue(input): ObjectWithEveryOptionalTypeEnumerator { + if ( + $$ObjectWithEveryOptionalTypeEnumeratorValues.includes( + input as any, + ) + ) { + return input as ObjectWithEveryOptionalTypeEnumerator; } if ( - typeof input.object.timestamp === "object" && - input.object.timestamp instanceof Date + $$ObjectWithEveryOptionalTypeEnumeratorValues.includes( + input.toLowerCase() as any, + ) ) { - json += `,"timestamp":"${input.object.timestamp.toISOString()}"`; + return input.toLowerCase() as ObjectWithEveryOptionalTypeEnumerator; + } + if ( + $$ObjectWithEveryOptionalTypeEnumeratorValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as ObjectWithEveryOptionalTypeEnumerator; + } + return "A"; + }, + }; + +export interface ObjectWithEveryOptionalTypeObject { + string: string; + boolean: boolean; + timestamp: Date; +} +export const $$ObjectWithEveryOptionalTypeObject: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeObject { + return { + string: "", + boolean: false, + timestamp: new Date(), + }; + }, + validate(input): input is ObjectWithEveryOptionalTypeObject { + return ( + isObject(input) && + typeof input.string === "string" && + typeof input.boolean === "boolean" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryOptionalTypeObject { + let _string: string; + if (typeof input.string === "string") { + _string = input.string; } else { - json += ',"timestamp":null'; + _string = ""; } + let _boolean: boolean; + if (typeof input.boolean === "boolean") { + _boolean = input.boolean; + } else { + _boolean = false; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + string: _string, + boolean: _boolean, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeObject { + return $$ObjectWithEveryOptionalTypeObject.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"string":'; + json += serializeString(input.string); + json += ',"boolean":'; + json += `${input.boolean}`; + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; json += "}"; - } else { - json += ',"object":null'; - } - if (typeof input.record === "object" && input.record !== null) { - const recordKeys = Object.keys(input.record); - json += ',"record":{'; - for (let i = 0; i < recordKeys.length; i++) { - const key = recordKeys[i]; - const innerVal = input.record[key]; - if (i !== 0) { - json += `,"${key}":`; - } else { - json += `"${key}":`; - } - if (typeof innerVal === "boolean") { - json += `${innerVal}`; - } else { - json += "null"; - } + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`string=${input.string}`); + queryParts.push(`boolean=${input.boolean}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export type ObjectWithEveryOptionalTypeDiscriminator = + | ObjectWithEveryOptionalTypeDiscriminatorA + | ObjectWithEveryOptionalTypeDiscriminatorB; +export const $$ObjectWithEveryOptionalTypeDiscriminator: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeDiscriminator { + return $$ObjectWithEveryOptionalTypeDiscriminatorA.new(); + }, + validate(input): input is ObjectWithEveryOptionalTypeDiscriminator { + if (!isObject(input)) { + return false; + } + if (typeof input.type !== "string") { + return false; + } + switch (input.type) { + case "A": + return $$ObjectWithEveryOptionalTypeDiscriminatorA.validate( + input, + ); + case "B": + return $$ObjectWithEveryOptionalTypeDiscriminatorB.validate( + input, + ); + default: + return false; + } + }, + fromJson(input): ObjectWithEveryOptionalTypeDiscriminator { + switch (input.type) { + case "A": + return $$ObjectWithEveryOptionalTypeDiscriminatorA.fromJson( + input, + ); + case "B": + return $$ObjectWithEveryOptionalTypeDiscriminatorB.fromJson( + input, + ); + default: + return $$ObjectWithEveryOptionalTypeDiscriminatorA.new(); + } + }, + fromJsonString(input): ObjectWithEveryOptionalTypeDiscriminator { + return $$ObjectWithEveryOptionalTypeDiscriminator.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryOptionalTypeDiscriminatorA.toJsonString( + input, + ); + case "B": + return $$ObjectWithEveryOptionalTypeDiscriminatorB.toJsonString( + input, + ); + default: + throw new Error(`Unhandled case "${(input as any).type}"`); + } + }, + toUrlQueryString(input): string { + switch (input.type) { + case "A": + return $$ObjectWithEveryOptionalTypeDiscriminatorA.toUrlQueryString( + input, + ); + case "B": + return $$ObjectWithEveryOptionalTypeDiscriminatorB.toUrlQueryString( + input, + ); + default: + throw new Error("Unhandled case"); } + }, + }; +export interface ObjectWithEveryOptionalTypeDiscriminatorA { + type: "A"; + title: string; +} +const $$ObjectWithEveryOptionalTypeDiscriminatorA: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeDiscriminatorA { + return { + type: "A", + title: "", + }; + }, + validate(input): input is ObjectWithEveryOptionalTypeDiscriminatorA { + return ( + isObject(input) && + input.type === "A" && + typeof input.title === "string" + ); + }, + fromJson(input): ObjectWithEveryOptionalTypeDiscriminatorA { + const _type = "A"; + let _title: string; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = ""; + } + return { + type: _type, + title: _title, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeDiscriminatorA { + return $$ObjectWithEveryOptionalTypeDiscriminatorA.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"A"'; + json += ',"title":'; + json += serializeString(input.title); json += "}"; - } else { - json += ',"record":null'; - } - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - switch (input.discriminator.type) { - case "A": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"A"`; - if (typeof input.discriminator.title === "string") { - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - } else { - json += ',"title":null'; - } - json += "}"; - break; - } - case "B": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"B"`; - if (typeof input.discriminator.title === "string") { - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - } else { - json += ',"title":null'; - } - if (typeof input.discriminator.description === "string") { - json += `,"description":`; - if (input.discriminator.description.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.description.length; - i++ - ) { - __point__ = - input.discriminator.description.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.description, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.description.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.description}"`; - } else { - json += `"${__result__}${input.discriminator.description.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.description.length < 5000 && - !STR_ESCAPE.test(input.discriminator.description) - ) { - json += `"${input.discriminator.description}"`; - } else { - json += JSON.stringify( - input.discriminator.description, - ); - } - } else { - json += ',"description":null'; - } - json += "}"; - break; - } - } - } else { - json += ',"discriminator":null'; - } - if ( - typeof input.nestedObject === "object" && - input.nestedObject !== null - ) { - json += ',"nestedObject":'; - json += "{"; - if (typeof input.nestedObject.id === "string") { - json += `"id":`; - if (input.nestedObject.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.id.length; i++) { - __point__ = input.nestedObject.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.id}"`; - } else { - json += `"${__result__}${input.nestedObject.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.id) - ) { - json += `"${input.nestedObject.id}"`; - } else { - json += JSON.stringify(input.nestedObject.id); - } - } else { - json += '"id":null'; - } - if ( - typeof input.nestedObject.timestamp === "object" && - input.nestedObject.timestamp instanceof Date - ) { - json += `,"timestamp":"${input.nestedObject.timestamp.toISOString()}"`; - } else { - json += ',"timestamp":null'; - } - if ( - typeof input.nestedObject.data === "object" && - input.nestedObject.data !== null - ) { - json += ',"data":'; - json += "{"; - if (typeof input.nestedObject.data.id === "string") { - json += `"id":`; - if (input.nestedObject.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.id.length; - i++ - ) { - __point__ = - input.nestedObject.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.nestedObject.data.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.id) - ) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.id); - } - } else { - json += '"id":null'; - } - if ( - typeof input.nestedObject.data.timestamp === "object" && - input.nestedObject.data.timestamp instanceof Date - ) { - json += `,"timestamp":"${input.nestedObject.data.timestamp.toISOString()}"`; - } else { - json += ',"timestamp":null'; - } - if ( - typeof input.nestedObject.data.data === "object" && - input.nestedObject.data.data !== null - ) { - json += ',"data":'; - json += "{"; - if (typeof input.nestedObject.data.data.id === "string") { - json += `"id":`; - if (input.nestedObject.data.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.data.id.length; - i++ - ) { - __point__ = - input.nestedObject.data.data.id.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.nestedObject.data.data.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.data.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.data.id) - ) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += JSON.stringify( - input.nestedObject.data.data.id, - ); - } - } else { - json += '"id":null'; - } - if ( - typeof input.nestedObject.data.data.timestamp === - "object" && - input.nestedObject.data.data.timestamp instanceof Date - ) { - json += `,"timestamp":"${input.nestedObject.data.data.timestamp.toISOString()}"`; - } else { - json += ',"timestamp":null'; - } - json += "}"; - } else { - json += ',"data":null'; - } - json += "}"; - } else { - json += ',"data":null'; - } - json += "}"; - } else { - json += ',"nestedObject":null'; - } - if (Array.isArray(input.nestedArray)) { - json += ',"nestedArray":['; - for (let i = 0; i < input.nestedArray.length; i++) { - const valNestedArrayItem = input.nestedArray[i]; - if (i !== 0) { - json += ","; - } - if (Array.isArray(valNestedArrayItem)) { - json += "["; - for (let i = 0; i < valNestedArrayItem.length; i++) { - const valNestedArrayItemItem = valNestedArrayItem[i]; - if (i !== 0) { - json += ","; - } - if ( - typeof valNestedArrayItemItem === "object" && - valNestedArrayItemItem !== null - ) { - json += ""; - json += "{"; - if (typeof valNestedArrayItemItem.id === "string") { - json += `"id":`; - if (valNestedArrayItemItem.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valNestedArrayItemItem.id.length; - i++ - ) { - __point__ = - valNestedArrayItemItem.id.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && - __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valNestedArrayItemItem.id, - ); - __finished__ = true; - break; - } - if ( - __point__ === 0x22 || - __point__ === 0x5c - ) { - __last__ === -1 && (__last__ = 0); - __result__ += - valNestedArrayItemItem.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += `"${__result__}${valNestedArrayItemItem.id.slice(__last__)}"`; - } - } - } else if ( - valNestedArrayItemItem.id.length < 5000 && - !STR_ESCAPE.test(valNestedArrayItemItem.id) - ) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += JSON.stringify( - valNestedArrayItemItem.id, - ); - } - } else { - json += '"id":null'; - } - if ( - typeof valNestedArrayItemItem.timestamp === - "object" && - valNestedArrayItemItem.timestamp instanceof Date - ) { - json += `,"timestamp":"${valNestedArrayItemItem.timestamp.toISOString()}"`; - } else { - json += ',"timestamp":null'; - } - json += "}"; - } else { - json += "null"; - } - } - json += "]"; - } else { - json += "null"; - } - } - json += "]"; - } else { - json += ',"nestedArray":null'; - } - json += "}"; - return json; - }, -}; -export type ObjectWithEveryNullableTypeEnumerator = "A" | "B" | "C"; -export interface ObjectWithEveryNullableTypeObject { - string: string | null; - boolean: boolean | null; - timestamp: Date | null; -} - -export type ObjectWithEveryNullableTypeRecord = Record; - -export type ObjectWithEveryNullableTypeDiscriminator = - | ObjectWithEveryNullableTypeDiscriminatorA - | ObjectWithEveryNullableTypeDiscriminatorB; - -export interface ObjectWithEveryNullableTypeDiscriminatorA { - type: "A"; - title: string | null; -} - -export interface ObjectWithEveryNullableTypeDiscriminatorB { - type: "B"; - title: string | null; - description: string | null; -} - -export interface ObjectWithEveryNullableTypeNestedObject { - id: string | null; - timestamp: Date | null; - data: ObjectWithEveryNullableTypeNestedObjectData | null; -} - -export interface ObjectWithEveryNullableTypeNestedObjectData { - id: string | null; - timestamp: Date | null; - data: ObjectWithEveryNullableTypeNestedObjectDataData | null; -} - -export interface ObjectWithEveryNullableTypeNestedObjectDataData { - id: string | null; - timestamp: Date | null; -} - -export interface ObjectWithEveryNullableTypeNestedArrayItemItem { - id: string | null; - timestamp: Date | null; -} - -export interface ObjectWithEveryOptionalType { - any?: any; - boolean?: boolean; - string?: string; - timestamp?: Date; - float32?: number; - float64?: number; - int8?: number; - uint8?: number; - int16?: number; - uint16?: number; - int32?: number; - uint32?: number; - int64?: bigint; - uint64?: bigint; - enumerator?: ObjectWithEveryOptionalTypeEnumerator; - array?: Array; - object?: ObjectWithEveryOptionalTypeObject; - record?: ObjectWithEveryOptionalTypeRecord; - discriminator?: ObjectWithEveryOptionalTypeDiscriminator; - nestedObject?: ObjectWithEveryOptionalTypeNestedObject; - nestedArray?: Array>; -} -export const $$ObjectWithEveryOptionalType = { - parse(input: Record): ObjectWithEveryOptionalType { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.any === "undefined") { - // ignore undefined - } else { - __D1.any = json.any; - } - if (typeof json.boolean === "undefined") { - // ignore undefined - } else { - if (typeof json.boolean === "boolean") { - __D1.boolean = json.boolean; - } else { - $fallback( - "/boolean", - "/optionalProperties/boolean/type", - "Expected boolean for /boolean", - ); - } - } - if (typeof json.string === "undefined") { - // ignore undefined - } else { - if (typeof json.string === "string") { - __D1.string = json.string; - } else { - $fallback( - "/string", - "/optionalProperties/string/type", - "Expected string at /string", - ); - } - } - if (typeof json.timestamp === "undefined") { - // ignore undefined - } else { - if ( - typeof json.timestamp === "object" && - json.timestamp instanceof Date - ) { - __D1.timestamp = json.timestamp; - } else if (typeof json.timestamp === "string") { - __D1.timestamp = new Date(json.timestamp); - } else { - $fallback( - "/timestamp", - "/optionalProperties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", - ); - } - } - if (typeof json.float32 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.float32 === "number" && - !Number.isNaN(json.float32) - ) { - __D1.float32 = json.float32; - } else { - $fallback( - "/float32", - "/optionalProperties/float32/type", - "Expected number at /float32", - ); - } - } - if (typeof json.float64 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.float64 === "number" && - !Number.isNaN(json.float64) - ) { - __D1.float64 = json.float64; - } else { - $fallback( - "/float64", - "/optionalProperties/float64/type", - "Expected number at /float64", - ); - } - } - if (typeof json.int8 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.int8 === "number" && - Number.isInteger(json.int8) && - json.int8 >= -128 && - json.int8 <= 127 - ) { - __D1.int8 = json.int8; - } else { - $fallback( - "/int8", - "/optionalProperties/int8", - "Expected valid integer between -128 and 127", - ); - } - } - if (typeof json.uint8 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.uint8 === "number" && - Number.isInteger(json.uint8) && - json.uint8 >= 0 && - json.uint8 <= 255 - ) { - __D1.uint8 = json.uint8; - } else { - $fallback( - "/uint8", - "/optionalProperties/uint8", - "Expected valid integer between 0 and 255", - ); - } - } - if (typeof json.int16 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.int16 === "number" && - Number.isInteger(json.int16) && - json.int16 >= -32768 && - json.int16 <= 32767 - ) { - __D1.int16 = json.int16; - } else { - $fallback( - "/int16", - "/optionalProperties/int16", - "Expected valid integer between -32768 and 32767", - ); - } - } - if (typeof json.uint16 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.uint16 === "number" && - Number.isInteger(json.uint16) && - json.uint16 >= 0 && - json.uint16 <= 65535 - ) { - __D1.uint16 = json.uint16; - } else { - $fallback( - "/uint16", - "/optionalProperties/uint16", - "Expected valid integer between 0 and 65535", - ); - } - } - if (typeof json.int32 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.int32 === "number" && - Number.isInteger(json.int32) && - json.int32 >= -2147483648 && - json.int32 <= 2147483647 - ) { - __D1.int32 = json.int32; - } else { - $fallback( - "/int32", - "/optionalProperties/int32", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - } - if (typeof json.uint32 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.uint32 === "number" && - Number.isInteger(json.uint32) && - json.uint32 >= 0 && - json.uint32 <= 4294967295 - ) { - __D1.uint32 = json.uint32; - } else { - $fallback( - "/uint32", - "/optionalProperties/uint32", - "Expected valid integer between 0 and 4294967295", - ); - } - } - if (typeof json.int64 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.int64 === "string" || - typeof json.int64 === "number" - ) { - try { - const val = BigInt(json.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/optionalProperties/int64", - "Unable to parse BigInt from json.int64.", - ); - } - } else if (typeof json.int64 === "bigint") { - __D1.int64 = json.int64; - } else { - $fallback( - "/int64", - "/optionalProperties/int64", - "Expected BigInt or Integer string. Got ${json.int64}", - ); - } - } - if (typeof json.uint64 === "undefined") { - // ignore undefined - } else { - if ( - typeof json.uint64 === "string" || - typeof json.uint64 === "number" - ) { - try { - const val = BigInt(json.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unable to parse BigInt from json.uint64.", - ); - } - } else if (typeof json.uint64 === "bigint") { - if (json.uint64 >= BigInt("0")) { - __D1.uint64 = json.uint64; - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Expected BigInt or Integer string. Got ${json.uint64}", - ); - } - } - if (typeof json.enumerator === "undefined") { - // ignore undefined - } else { - if (typeof json.enumerator === "string") { - if ( - json.enumerator === "A" || - json.enumerator === "B" || - json.enumerator === "C" - ) { - __D1.enumerator = json.enumerator; - } else { - $fallback( - "/enumerator", - "/optionalProperties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } else { - $fallback( - "/enumerator", - "/optionalProperties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } - if (typeof json.array === "undefined") { - // ignore undefined - } else { - if (Array.isArray(json.array)) { - const __D2 = []; - for (const __D2AItem of json.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/optionalProperties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback( - "/array", - "/optionalProperties/array", - "Expected Array", - ); - } - } - if (typeof json.object === "undefined") { - // ignore undefined - } else { - if ( - typeof json.object === "object" && - json.object !== null - ) { - const __D2 = {}; - if (typeof json.object.string === "string") { - __D2.string = json.object.string; - } else { - $fallback( - "/object/string", - "/optionalProperties/object/properties/string/type", - "Expected string at /object/string", - ); - } - if (typeof json.object.boolean === "boolean") { - __D2.boolean = json.object.boolean; - } else { - $fallback( - "/object/boolean", - "/optionalProperties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); - } - if ( - typeof json.object.timestamp === "object" && - json.object.timestamp instanceof Date - ) { - __D2.timestamp = json.object.timestamp; - } else if (typeof json.object.timestamp === "string") { - __D2.timestamp = new Date(json.object.timestamp); - } else { - $fallback( - "/object/timestamp", - "/optionalProperties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - __D1.object = __D2; - } else { - $fallback( - "/object", - "/optionalProperties/object", - "Expected object", - ); - } - } - if (typeof json.record === "undefined") { - // ignore undefined - } else { - if ( - typeof json.record === "object" && - json.record !== null - ) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(json.record)) { - let __D2RKeyRVal; - if (typeof json.record[__D2RKey] === "boolean") { - __D2RKeyRVal = json.record[__D2RKey]; - } else { - $fallback( - "/record/[key]", - "/optionalProperties/record/values/type", - "Expected boolean for /record/[key]", - ); - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.record = __D2RResult; - } else { - $fallback( - "/record", - "/optionalProperties/record", - "Expected object.", - ); - } - } - if (typeof json.discriminator === "undefined") { - // ignore undefined - } else { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - switch (json.discriminator.type) { - case "A": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if ( - typeof json.discriminator.title === - "string" - ) { - __D2.title = json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/optionalProperties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof json.discriminator === "object" && - json.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if ( - typeof json.discriminator.title === - "string" - ) { - __D2.title = json.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/optionalProperties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - if ( - typeof json.discriminator - .description === "string" - ) { - __D2.description = - json.discriminator.description; - } else { - $fallback( - "/discriminator/description", - "/optionalProperties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "json.discriminator.type did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator", - "Expected Object.", - ); - } - } - if (typeof json.nestedObject === "undefined") { - // ignore undefined - } else { - if ( - typeof json.nestedObject === "object" && - json.nestedObject !== null - ) { - const __D2 = {}; - if (typeof json.nestedObject.id === "string") { - __D2.id = json.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/optionalProperties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - if ( - typeof json.nestedObject.timestamp === "object" && - json.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = json.nestedObject.timestamp; - } else if ( - typeof json.nestedObject.timestamp === "string" - ) { - __D2.timestamp = new Date( - json.nestedObject.timestamp, - ); - } else { - $fallback( - "/nestedObject/timestamp", - "/optionalProperties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - if ( - typeof json.nestedObject.data === "object" && - json.nestedObject.data !== null - ) { - const __D3 = {}; - if (typeof json.nestedObject.data.id === "string") { - __D3.id = json.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/optionalProperties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - if ( - typeof json.nestedObject.data.timestamp === - "object" && - json.nestedObject.data.timestamp instanceof Date - ) { - __D3.timestamp = - json.nestedObject.data.timestamp; - } else if ( - typeof json.nestedObject.data.timestamp === - "string" - ) { - __D3.timestamp = new Date( - json.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/optionalProperties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - if ( - typeof json.nestedObject.data.data === - "object" && - json.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - typeof json.nestedObject.data.data.id === - "string" - ) { - __D4.id = json.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/optionalProperties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - if ( - typeof json.nestedObject.data.data - .timestamp === "object" && - json.nestedObject.data.data - .timestamp instanceof Date - ) { - __D4.timestamp = - json.nestedObject.data.data.timestamp; - } else if ( - typeof json.nestedObject.data.data - .timestamp === "string" - ) { - __D4.timestamp = new Date( - json.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/optionalProperties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - __D3.data = __D4; - } else { - $fallback( - "/nestedObject/data/data", - "/optionalProperties/nestedObject/properties/data/properties/data", - "Expected object", - ); - } - __D2.data = __D3; - } else { - $fallback( - "/nestedObject/data", - "/optionalProperties/nestedObject/properties/data", - "Expected object", - ); - } - __D1.nestedObject = __D2; - } else { - $fallback( - "/nestedObject", - "/optionalProperties/nestedObject", - "Expected object", - ); - } - } - if (typeof json.nestedArray === "undefined") { - // ignore undefined - } else { - if (Array.isArray(json.nestedArray)) { - const __D2 = []; - for (const __D2AItem of json.nestedArray) { - let __D2AItemAResult; - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (typeof __D3AItem.id === "string") { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/optionalProperties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - if ( - typeof __D3AItem.timestamp === - "object" && - __D3AItem.timestamp instanceof Date - ) { - __D4.timestamp = - __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === - "string" - ) { - __D4.timestamp = new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/optionalProperties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", - ); - } - __D3AItemAResult = __D4; - } else { - $fallback( - "/nestedArray/[0]/[0]", - "/optionalProperties/nestedArray/elements/elements", - "Expected object", - ); - } - __D3.push(__D3AItemAResult); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/nestedArray/[0]", - "/optionalProperties/nestedArray/elements", - "Expected Array", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.nestedArray = __D2; - } else { - $fallback( - "/nestedArray", - "/optionalProperties/nestedArray", - "Expected Array", - ); - } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.any === "undefined") { - // ignore undefined - } else { - __D1.any = input.any; - } - if (typeof input.boolean === "undefined") { - // ignore undefined - } else { - if (typeof input.boolean === "boolean") { - __D1.boolean = input.boolean; - } else { - $fallback( - "/boolean", - "/optionalProperties/boolean/type", - "Expected boolean for /boolean", - ); - } - } - if (typeof input.string === "undefined") { - // ignore undefined - } else { - if (typeof input.string === "string") { - __D1.string = input.string; - } else { - $fallback( - "/string", - "/optionalProperties/string/type", - "Expected string at /string", - ); - } - } - if (typeof input.timestamp === "undefined") { - // ignore undefined - } else { - if ( - typeof input.timestamp === "object" && - input.timestamp instanceof Date - ) { - __D1.timestamp = input.timestamp; - } else if (typeof input.timestamp === "string") { - __D1.timestamp = new Date(input.timestamp); - } else { - $fallback( - "/timestamp", - "/optionalProperties/timestamp", - "Expected instanceof Date or ISO Date string at /timestamp", - ); - } - } - if (typeof input.float32 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.float32 === "number" && - !Number.isNaN(input.float32) - ) { - __D1.float32 = input.float32; - } else { - $fallback( - "/float32", - "/optionalProperties/float32/type", - "Expected number at /float32", - ); - } - } - if (typeof input.float64 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.float64 === "number" && - !Number.isNaN(input.float64) - ) { - __D1.float64 = input.float64; - } else { - $fallback( - "/float64", - "/optionalProperties/float64/type", - "Expected number at /float64", - ); - } - } - if (typeof input.int8 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.int8 === "number" && - Number.isInteger(input.int8) && - input.int8 >= -128 && - input.int8 <= 127 - ) { - __D1.int8 = input.int8; - } else { - $fallback( - "/int8", - "/optionalProperties/int8", - "Expected valid integer between -128 and 127", - ); - } - } - if (typeof input.uint8 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.uint8 === "number" && - Number.isInteger(input.uint8) && - input.uint8 >= 0 && - input.uint8 <= 255 - ) { - __D1.uint8 = input.uint8; - } else { - $fallback( - "/uint8", - "/optionalProperties/uint8", - "Expected valid integer between 0 and 255", - ); - } - } - if (typeof input.int16 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.int16 === "number" && - Number.isInteger(input.int16) && - input.int16 >= -32768 && - input.int16 <= 32767 - ) { - __D1.int16 = input.int16; - } else { - $fallback( - "/int16", - "/optionalProperties/int16", - "Expected valid integer between -32768 and 32767", - ); - } - } - if (typeof input.uint16 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.uint16 === "number" && - Number.isInteger(input.uint16) && - input.uint16 >= 0 && - input.uint16 <= 65535 - ) { - __D1.uint16 = input.uint16; - } else { - $fallback( - "/uint16", - "/optionalProperties/uint16", - "Expected valid integer between 0 and 65535", - ); - } - } - if (typeof input.int32 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.int32 === "number" && - Number.isInteger(input.int32) && - input.int32 >= -2147483648 && - input.int32 <= 2147483647 - ) { - __D1.int32 = input.int32; - } else { - $fallback( - "/int32", - "/optionalProperties/int32", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - } - if (typeof input.uint32 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.uint32 === "number" && - Number.isInteger(input.uint32) && - input.uint32 >= 0 && - input.uint32 <= 4294967295 - ) { - __D1.uint32 = input.uint32; - } else { - $fallback( - "/uint32", - "/optionalProperties/uint32", - "Expected valid integer between 0 and 4294967295", - ); - } - } - if (typeof input.int64 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.int64 === "string" || - typeof input.int64 === "number" - ) { - try { - const val = BigInt(input.int64); - __D1.int64 = val; - } catch (err) { - $fallback( - "/int64", - "/optionalProperties/int64", - "Unable to parse BigInt from input.int64.", - ); - } - } else if (typeof input.int64 === "bigint") { - __D1.int64 = input.int64; - } else { - $fallback( - "/int64", - "/optionalProperties/int64", - "Expected BigInt or Integer string. Got ${input.int64}", - ); - } - } - if (typeof input.uint64 === "undefined") { - // ignore undefined - } else { - if ( - typeof input.uint64 === "string" || - typeof input.uint64 === "number" - ) { - try { - const val = BigInt(input.uint64); - if (val >= BigInt("0")) { - __D1.uint64 = val; - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unable to parse BigInt from input.uint64.", - ); - } - } else if (typeof input.uint64 === "bigint") { - if (input.uint64 >= BigInt("0")) { - __D1.uint64 = input.uint64; - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else { - $fallback( - "/uint64", - "/optionalProperties/uint64", - "Expected BigInt or Integer string. Got ${input.uint64}", - ); - } - } - if (typeof input.enumerator === "undefined") { - // ignore undefined - } else { - if (typeof input.enumerator === "string") { - if ( - input.enumerator === "A" || - input.enumerator === "B" || - input.enumerator === "C" - ) { - __D1.enumerator = input.enumerator; - } else { - $fallback( - "/enumerator", - "/optionalProperties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } else { - $fallback( - "/enumerator", - "/optionalProperties/enumerator", - "Expected one of the following values: [A, B, C] at /enumerator.", - ); - } - } - if (typeof input.array === "undefined") { - // ignore undefined - } else { - if (Array.isArray(input.array)) { - const __D2 = []; - for (const __D2AItem of input.array) { - let __D2AItemAResult; - if (typeof __D2AItem === "boolean") { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/array/[0]", - "/optionalProperties/array/elements/type", - "Expected boolean for /array/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.array = __D2; - } else { - $fallback( - "/array", - "/optionalProperties/array", - "Expected Array", - ); - } - } - if (typeof input.object === "undefined") { - // ignore undefined - } else { - if (typeof input.object === "object" && input.object !== null) { - const __D2 = {}; - if (typeof input.object.string === "string") { - __D2.string = input.object.string; - } else { - $fallback( - "/object/string", - "/optionalProperties/object/properties/string/type", - "Expected string at /object/string", - ); - } - if (typeof input.object.boolean === "boolean") { - __D2.boolean = input.object.boolean; - } else { - $fallback( - "/object/boolean", - "/optionalProperties/object/properties/boolean/type", - "Expected boolean for /object/boolean", - ); - } - if ( - typeof input.object.timestamp === "object" && - input.object.timestamp instanceof Date - ) { - __D2.timestamp = input.object.timestamp; - } else if (typeof input.object.timestamp === "string") { - __D2.timestamp = new Date(input.object.timestamp); - } else { - $fallback( - "/object/timestamp", - "/optionalProperties/object/properties/timestamp", - "Expected instanceof Date or ISO Date string at /object/timestamp", - ); - } - __D1.object = __D2; - } else { - $fallback( - "/object", - "/optionalProperties/object", - "Expected object", - ); - } - } - if (typeof input.record === "undefined") { - // ignore undefined - } else { - if (typeof input.record === "object" && input.record !== null) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(input.record)) { - let __D2RKeyRVal; - if (typeof input.record[__D2RKey] === "boolean") { - __D2RKeyRVal = input.record[__D2RKey]; - } else { - $fallback( - "/record/[key]", - "/optionalProperties/record/values/type", - "Expected boolean for /record/[key]", - ); - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.record = __D2RResult; - } else { - $fallback( - "/record", - "/optionalProperties/record", - "Expected object.", - ); - } - } - if (typeof input.discriminator === "undefined") { - // ignore undefined - } else { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - switch (input.discriminator.type) { - case "A": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "A"; - if ( - typeof input.discriminator.title === - "string" - ) { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/optionalProperties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "Expected object", - ); - } - break; - } - case "B": { - if ( - typeof input.discriminator === "object" && - input.discriminator !== null - ) { - const __D2 = {}; - __D2.type = "B"; - if ( - typeof input.discriminator.title === - "string" - ) { - __D2.title = input.discriminator.title; - } else { - $fallback( - "/discriminator/title", - "/optionalProperties/discriminator/mapping/properties/title/type", - "Expected string at /discriminator/title", - ); - } - if ( - typeof input.discriminator.description === - "string" - ) { - __D2.description = - input.discriminator.description; - } else { - $fallback( - "/discriminator/description", - "/optionalProperties/discriminator/mapping/properties/description/type", - "Expected string at /discriminator/description", - ); - } - __D1.discriminator = __D2; - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/discriminator", - "/optionalProperties/discriminator/mapping", - "input.discriminator.type did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/discriminator", - "/optionalProperties/discriminator", - "Expected Object.", - ); - } - } - if (typeof input.nestedObject === "undefined") { - // ignore undefined - } else { - if ( - typeof input.nestedObject === "object" && - input.nestedObject !== null - ) { - const __D2 = {}; - if (typeof input.nestedObject.id === "string") { - __D2.id = input.nestedObject.id; - } else { - $fallback( - "/nestedObject/id", - "/optionalProperties/nestedObject/properties/id/type", - "Expected string at /nestedObject/id", - ); - } - if ( - typeof input.nestedObject.timestamp === "object" && - input.nestedObject.timestamp instanceof Date - ) { - __D2.timestamp = input.nestedObject.timestamp; - } else if ( - typeof input.nestedObject.timestamp === "string" - ) { - __D2.timestamp = new Date(input.nestedObject.timestamp); - } else { - $fallback( - "/nestedObject/timestamp", - "/optionalProperties/nestedObject/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/timestamp", - ); - } - if ( - typeof input.nestedObject.data === "object" && - input.nestedObject.data !== null - ) { - const __D3 = {}; - if (typeof input.nestedObject.data.id === "string") { - __D3.id = input.nestedObject.data.id; - } else { - $fallback( - "/nestedObject/data/id", - "/optionalProperties/nestedObject/properties/data/properties/id/type", - "Expected string at /nestedObject/data/id", - ); - } - if ( - typeof input.nestedObject.data.timestamp === - "object" && - input.nestedObject.data.timestamp instanceof Date - ) { - __D3.timestamp = input.nestedObject.data.timestamp; - } else if ( - typeof input.nestedObject.data.timestamp === - "string" - ) { - __D3.timestamp = new Date( - input.nestedObject.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/timestamp", - "/optionalProperties/nestedObject/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/timestamp", - ); - } - if ( - typeof input.nestedObject.data.data === "object" && - input.nestedObject.data.data !== null - ) { - const __D4 = {}; - if ( - typeof input.nestedObject.data.data.id === - "string" - ) { - __D4.id = input.nestedObject.data.data.id; - } else { - $fallback( - "/nestedObject/data/data/id", - "/optionalProperties/nestedObject/properties/data/properties/data/properties/id/type", - "Expected string at /nestedObject/data/data/id", - ); - } - if ( - typeof input.nestedObject.data.data - .timestamp === "object" && - input.nestedObject.data.data - .timestamp instanceof Date - ) { - __D4.timestamp = - input.nestedObject.data.data.timestamp; - } else if ( - typeof input.nestedObject.data.data - .timestamp === "string" - ) { - __D4.timestamp = new Date( - input.nestedObject.data.data.timestamp, - ); - } else { - $fallback( - "/nestedObject/data/data/timestamp", - "/optionalProperties/nestedObject/properties/data/properties/data/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedObject/data/data/timestamp", - ); - } - __D3.data = __D4; - } else { - $fallback( - "/nestedObject/data/data", - "/optionalProperties/nestedObject/properties/data/properties/data", - "Expected object", - ); - } - __D2.data = __D3; - } else { - $fallback( - "/nestedObject/data", - "/optionalProperties/nestedObject/properties/data", - "Expected object", - ); - } - __D1.nestedObject = __D2; - } else { - $fallback( - "/nestedObject", - "/optionalProperties/nestedObject", - "Expected object", - ); - } - } - if (typeof input.nestedArray === "undefined") { - // ignore undefined - } else { - if (Array.isArray(input.nestedArray)) { - const __D2 = []; - for (const __D2AItem of input.nestedArray) { - let __D2AItemAResult; - if (Array.isArray(__D2AItem)) { - const __D3 = []; - for (const __D3AItem of __D2AItem) { - let __D3AItemAResult; - if ( - typeof __D3AItem === "object" && - __D3AItem !== null - ) { - const __D4 = {}; - if (typeof __D3AItem.id === "string") { - __D4.id = __D3AItem.id; - } else { - $fallback( - "/nestedArray/[0]/[0]/id", - "/optionalProperties/nestedArray/elements/elements/properties/id/type", - "Expected string at /nestedArray/[0]/[0]/id", - ); - } - if ( - typeof __D3AItem.timestamp === - "object" && - __D3AItem.timestamp instanceof Date - ) { - __D4.timestamp = __D3AItem.timestamp; - } else if ( - typeof __D3AItem.timestamp === "string" - ) { - __D4.timestamp = new Date( - __D3AItem.timestamp, - ); - } else { - $fallback( - "/nestedArray/[0]/[0]/timestamp", - "/optionalProperties/nestedArray/elements/elements/properties/timestamp", - "Expected instanceof Date or ISO Date string at /nestedArray/[0]/[0]/timestamp", - ); - } - __D3AItemAResult = __D4; - } else { - $fallback( - "/nestedArray/[0]/[0]", - "/optionalProperties/nestedArray/elements/elements", - "Expected object", - ); - } - __D3.push(__D3AItemAResult); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/nestedArray/[0]", - "/optionalProperties/nestedArray/elements", - "Expected Array", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.nestedArray = __D2; - } else { - $fallback( - "/nestedArray", - "/optionalProperties/nestedArray", - "Expected Array", - ); - } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: ObjectWithEveryOptionalType): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - let inputHasFields = false; - if (typeof input.any !== "undefined") { - if (inputHasFields) { - if (typeof input.any !== "undefined") { - json += ',"any":' + JSON.stringify(input.any); - } - } else { - if (typeof input.any !== "undefined") { - json += '"any":' + JSON.stringify(input.any); - } - inputHasFields = true; - } - } - if (typeof input.boolean !== "undefined") { - if (inputHasFields) { - json += `,"boolean":${input.boolean}`; - } else { - json += `"boolean":${input.boolean}`; - inputHasFields = true; - } - } - if (typeof input.string !== "undefined") { - if (inputHasFields) { - json += `,"string":`; - if (input.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.string.length; i++) { - __point__ = input.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.string}"`; - } else { - json += `"${__result__}${input.string.slice(__last__)}"`; - } - } - } else if ( - input.string.length < 5000 && - !STR_ESCAPE.test(input.string) - ) { - json += `"${input.string}"`; - } else { - json += JSON.stringify(input.string); - } - } else { - json += `"string":`; - if (input.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.string.length; i++) { - __point__ = input.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.string}"`; - } else { - json += `"${__result__}${input.string.slice(__last__)}"`; - } - } - } else if ( - input.string.length < 5000 && - !STR_ESCAPE.test(input.string) - ) { - json += `"${input.string}"`; - } else { - json += JSON.stringify(input.string); - } - inputHasFields = true; - } - } - if (typeof input.timestamp !== "undefined") { - if (inputHasFields) { - json += `,"timestamp":"${input.timestamp.toISOString()}"`; - } else { - json += `"timestamp":"${input.timestamp.toISOString()}"`; - inputHasFields = true; - } - } - if (typeof input.float32 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.float32)) { - throw new Error("Expected number at /float32 got NaN"); - } - json += `,"float32":${input.float32}`; - } else { - if (Number.isNaN(input.float32)) { - throw new Error("Expected number at /float32 got NaN"); - } - json += `"float32":${input.float32}`; - inputHasFields = true; - } - } - if (typeof input.float64 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.float64)) { - throw new Error("Expected number at /float64 got NaN"); - } - json += `,"float64":${input.float64}`; - } else { - if (Number.isNaN(input.float64)) { - throw new Error("Expected number at /float64 got NaN"); - } - json += `"float64":${input.float64}`; - inputHasFields = true; - } - } - if (typeof input.int8 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.int8)) { - throw new Error("Expected number at /int8 got NaN"); - } - json += `,"int8":${input.int8}`; - } else { - if (Number.isNaN(input.int8)) { - throw new Error("Expected number at /int8 got NaN"); - } - json += `"int8":${input.int8}`; - inputHasFields = true; - } - } - if (typeof input.uint8 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.uint8)) { - throw new Error("Expected number at /uint8 got NaN"); - } - json += `,"uint8":${input.uint8}`; - } else { - if (Number.isNaN(input.uint8)) { - throw new Error("Expected number at /uint8 got NaN"); - } - json += `"uint8":${input.uint8}`; - inputHasFields = true; - } - } - if (typeof input.int16 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.int16)) { - throw new Error("Expected number at /int16 got NaN"); - } - json += `,"int16":${input.int16}`; - } else { - if (Number.isNaN(input.int16)) { - throw new Error("Expected number at /int16 got NaN"); - } - json += `"int16":${input.int16}`; - inputHasFields = true; - } - } - if (typeof input.uint16 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.uint16)) { - throw new Error("Expected number at /uint16 got NaN"); - } - json += `,"uint16":${input.uint16}`; - } else { - if (Number.isNaN(input.uint16)) { - throw new Error("Expected number at /uint16 got NaN"); - } - json += `"uint16":${input.uint16}`; - inputHasFields = true; - } - } - if (typeof input.int32 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.int32)) { - throw new Error("Expected number at /int32 got NaN"); - } - json += `,"int32":${input.int32}`; - } else { - if (Number.isNaN(input.int32)) { - throw new Error("Expected number at /int32 got NaN"); - } - json += `"int32":${input.int32}`; - inputHasFields = true; - } - } - if (typeof input.uint32 !== "undefined") { - if (inputHasFields) { - if (Number.isNaN(input.uint32)) { - throw new Error("Expected number at /uint32 got NaN"); - } - json += `,"uint32":${input.uint32}`; - } else { - if (Number.isNaN(input.uint32)) { - throw new Error("Expected number at /uint32 got NaN"); - } - json += `"uint32":${input.uint32}`; - inputHasFields = true; - } - } - if (typeof input.int64 !== "undefined") { - if (inputHasFields) { - json += `,"int64":"${input.int64.toString()}"`; - } else { - json += `"int64":"${input.int64.toString()}"`; - inputHasFields = true; - } - } - if (typeof input.uint64 !== "undefined") { - if (inputHasFields) { - json += `,"uint64":"${input.uint64.toString()}"`; - } else { - json += `"uint64":"${input.uint64.toString()}"`; - inputHasFields = true; - } - } - if (typeof input.enumerator !== "undefined") { - if (inputHasFields) { - json += `,"enumerator":"${input.enumerator}"`; - } else { - json += `"enumerator":"${input.enumerator}"`; - inputHasFields = true; - } - } - if (typeof input.array !== "undefined") { - if (inputHasFields) { - json += ',"array":['; - for (let i = 0; i < input.array.length; i++) { - const valArrayItem = input.array[i]; - if (i !== 0) { - json += ","; - } - json += `${valArrayItem}`; - } - json += "]"; - } else { - json += '"array":['; - for (let i = 0; i < input.array.length; i++) { - const valArrayItem = input.array[i]; - if (i !== 0) { - json += ","; - } - json += `${valArrayItem}`; - } - json += "]"; - inputHasFields = true; - } - } - if (typeof input.object !== "undefined") { - if (inputHasFields) { - json += ',"object":'; - json += "{"; - json += `"string":`; - if (input.object.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.object.string.length; i++) { - __point__ = input.object.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.object.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.object.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.object.string}"`; - } else { - json += `"${__result__}${input.object.string.slice(__last__)}"`; - } - } - } else if ( - input.object.string.length < 5000 && - !STR_ESCAPE.test(input.object.string) - ) { - json += `"${input.object.string}"`; - } else { - json += JSON.stringify(input.object.string); - } - json += `,"boolean":${input.object.boolean}`; - json += `,"timestamp":"${input.object.timestamp.toISOString()}"`; - json += "}"; - } else { - json += '"object":'; - json += "{"; - json += `"string":`; - if (input.object.string.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.object.string.length; i++) { - __point__ = input.object.string.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.object.string); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.object.string.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.object.string}"`; - } else { - json += `"${__result__}${input.object.string.slice(__last__)}"`; - } - } - } else if ( - input.object.string.length < 5000 && - !STR_ESCAPE.test(input.object.string) - ) { - json += `"${input.object.string}"`; - } else { - json += JSON.stringify(input.object.string); - } - json += `,"boolean":${input.object.boolean}`; - json += `,"timestamp":"${input.object.timestamp.toISOString()}"`; - json += "}"; - inputHasFields = true; - } - } - if (typeof input.record !== "undefined") { - if (inputHasFields) { - const recordKeys = Object.keys(input.record); - json += ',"record":{'; - for (let i = 0; i < recordKeys.length; i++) { - const key = recordKeys[i]; - const innerVal = input.record[key]; - if (i !== 0) { - json += `,"${key}":`; - } else { - json += `"${key}":`; - } - json += `${innerVal}`; - } - json += "}"; - } else { - const recordKeys = Object.keys(input.record); - json += '"record":{'; - for (let i = 0; i < recordKeys.length; i++) { - const key = recordKeys[i]; - const innerVal = input.record[key]; - if (i !== 0) { - json += `,"${key}":`; - } else { - json += `"${key}":`; - } - json += `${innerVal}`; - } - json += "}"; - inputHasFields = true; - } - } - if (typeof input.discriminator !== "undefined") { - if (inputHasFields) { - switch (input.discriminator.type) { - case "A": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"A"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += "}"; - break; - } - case "B": { - json += ',"discriminator":'; - json += "{"; - json += `"type":"B"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += `,"description":`; - if (input.discriminator.description.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.description.length; - i++ - ) { - __point__ = - input.discriminator.description.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.description, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.description.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.description}"`; - } else { - json += `"${__result__}${input.discriminator.description.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.description.length < 5000 && - !STR_ESCAPE.test(input.discriminator.description) - ) { - json += `"${input.discriminator.description}"`; - } else { - json += JSON.stringify( - input.discriminator.description, - ); - } - json += "}"; - break; - } - } - } else { - switch (input.discriminator.type) { - case "A": { - json += '"discriminator":'; - json += "{"; - json += `"type":"A"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += "}"; - break; - } - case "B": { - json += '"discriminator":'; - json += "{"; - json += `"type":"B"`; - json += `,"title":`; - if (input.discriminator.title.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.title.length; - i++ - ) { - __point__ = - input.discriminator.title.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.title, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.title.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.title}"`; - } else { - json += `"${__result__}${input.discriminator.title.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.title.length < 5000 && - !STR_ESCAPE.test(input.discriminator.title) - ) { - json += `"${input.discriminator.title}"`; - } else { - json += JSON.stringify(input.discriminator.title); - } - json += `,"description":`; - if (input.discriminator.description.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.discriminator.description.length; - i++ - ) { - __point__ = - input.discriminator.description.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.discriminator.description, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.discriminator.description.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.discriminator.description}"`; - } else { - json += `"${__result__}${input.discriminator.description.slice(__last__)}"`; - } - } - } else if ( - input.discriminator.description.length < 5000 && - !STR_ESCAPE.test(input.discriminator.description) - ) { - json += `"${input.discriminator.description}"`; - } else { - json += JSON.stringify( - input.discriminator.description, - ); - } - json += "}"; - break; - } - } - inputHasFields = true; - } - } - if (typeof input.nestedObject !== "undefined") { - if (inputHasFields) { - json += ',"nestedObject":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.id.length; i++) { - __point__ = input.nestedObject.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.id}"`; - } else { - json += `"${__result__}${input.nestedObject.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.id) - ) { - json += `"${input.nestedObject.id}"`; - } else { - json += JSON.stringify(input.nestedObject.id); - } - json += `,"timestamp":"${input.nestedObject.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.id.length; - i++ - ) { - __point__ = input.nestedObject.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.data.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.id.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.id) - ) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.data.id.length; - i++ - ) { - __point__ = - input.nestedObject.data.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.nestedObject.data.data.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.data.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.data.id) - ) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.data.timestamp.toISOString()}"`; - json += "}"; - json += "}"; - json += "}"; - } else { - json += '"nestedObject":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.nestedObject.id.length; i++) { - __point__ = input.nestedObject.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.id}"`; - } else { - json += `"${__result__}${input.nestedObject.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.id) - ) { - json += `"${input.nestedObject.id}"`; - } else { - json += JSON.stringify(input.nestedObject.id); - } - json += `,"timestamp":"${input.nestedObject.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.id.length; - i++ - ) { - __point__ = input.nestedObject.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.nestedObject.data.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.id.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.id) - ) { - json += `"${input.nestedObject.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.timestamp.toISOString()}"`; - - json += ',"data":'; - json += "{"; - json += `"id":`; - if (input.nestedObject.data.data.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < input.nestedObject.data.data.id.length; - i++ - ) { - __point__ = - input.nestedObject.data.data.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - input.nestedObject.data.data.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.nestedObject.data.data.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += `"${__result__}${input.nestedObject.data.data.id.slice(__last__)}"`; - } - } - } else if ( - input.nestedObject.data.data.id.length < 5000 && - !STR_ESCAPE.test(input.nestedObject.data.data.id) - ) { - json += `"${input.nestedObject.data.data.id}"`; - } else { - json += JSON.stringify(input.nestedObject.data.data.id); - } - json += `,"timestamp":"${input.nestedObject.data.data.timestamp.toISOString()}"`; - json += "}"; - json += "}"; - json += "}"; - inputHasFields = true; - } - } - if (typeof input.nestedArray !== "undefined") { - if (inputHasFields) { - json += ',"nestedArray":['; - for (let i = 0; i < input.nestedArray.length; i++) { - const valNestedArrayItem = input.nestedArray[i]; - if (i !== 0) { - json += ","; - } - json += "["; - for (let i = 0; i < valNestedArrayItem.length; i++) { - const valNestedArrayItemItem = valNestedArrayItem[i]; - if (i !== 0) { - json += ","; - } - - json += ""; - json += "{"; - json += `"id":`; - if (valNestedArrayItemItem.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valNestedArrayItemItem.id.length; - i++ - ) { - __point__ = - valNestedArrayItemItem.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valNestedArrayItemItem.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valNestedArrayItemItem.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += `"${__result__}${valNestedArrayItemItem.id.slice(__last__)}"`; - } - } - } else if ( - valNestedArrayItemItem.id.length < 5000 && - !STR_ESCAPE.test(valNestedArrayItemItem.id) - ) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += JSON.stringify(valNestedArrayItemItem.id); - } - json += `,"timestamp":"${valNestedArrayItemItem.timestamp.toISOString()}"`; - json += "}"; - } - json += "]"; - } - json += "]"; - } else { - json += '"nestedArray":['; - for (let i = 0; i < input.nestedArray.length; i++) { - const valNestedArrayItem = input.nestedArray[i]; - if (i !== 0) { - json += ","; - } - json += "["; - for (let i = 0; i < valNestedArrayItem.length; i++) { - const valNestedArrayItemItem = valNestedArrayItem[i]; - if (i !== 0) { - json += ","; - } - - json += ""; - json += "{"; - json += `"id":`; - if (valNestedArrayItemItem.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valNestedArrayItemItem.id.length; - i++ - ) { - __point__ = - valNestedArrayItemItem.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valNestedArrayItemItem.id, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valNestedArrayItemItem.id.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += `"${__result__}${valNestedArrayItemItem.id.slice(__last__)}"`; - } - } - } else if ( - valNestedArrayItemItem.id.length < 5000 && - !STR_ESCAPE.test(valNestedArrayItemItem.id) - ) { - json += `"${valNestedArrayItemItem.id}"`; - } else { - json += JSON.stringify(valNestedArrayItemItem.id); - } - json += `,"timestamp":"${valNestedArrayItemItem.timestamp.toISOString()}"`; - json += "}"; - } - json += "]"; - } - json += "]"; - inputHasFields = true; - } - } - json += "}"; - return json; - }, -}; -export type ObjectWithEveryOptionalTypeEnumerator = "A" | "B" | "C"; -export interface ObjectWithEveryOptionalTypeObject { - string: string; - boolean: boolean; - timestamp: Date; -} - -export type ObjectWithEveryOptionalTypeRecord = Record; - -export type ObjectWithEveryOptionalTypeDiscriminator = - | ObjectWithEveryOptionalTypeDiscriminatorA - | ObjectWithEveryOptionalTypeDiscriminatorB; - -export interface ObjectWithEveryOptionalTypeDiscriminatorA { - type: "A"; - title: string; -} + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=A"); + queryParts.push(`title=${input.title}`); + return queryParts.join("&"); + }, + }; export interface ObjectWithEveryOptionalTypeDiscriminatorB { type: "B"; title: string; description: string; } +const $$ObjectWithEveryOptionalTypeDiscriminatorB: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeDiscriminatorB { + return { + type: "B", + title: "", + description: "", + }; + }, + validate(input): input is ObjectWithEveryOptionalTypeDiscriminatorB { + return ( + isObject(input) && + input.type === "B" && + typeof input.title === "string" && + typeof input.description === "string" + ); + }, + fromJson(input): ObjectWithEveryOptionalTypeDiscriminatorB { + const _type = "B"; + let _title: string; + if (typeof input.title === "string") { + _title = input.title; + } else { + _title = ""; + } + let _description: string; + if (typeof input.description === "string") { + _description = input.description; + } else { + _description = ""; + } + return { + type: _type, + title: _title, + description: _description, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeDiscriminatorB { + return $$ObjectWithEveryOptionalTypeDiscriminatorB.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"B"'; + json += ',"title":'; + json += serializeString(input.title); + json += ',"description":'; + json += serializeString(input.description); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=B"); + queryParts.push(`title=${input.title}`); + queryParts.push(`description=${input.description}`); + return queryParts.join("&"); + }, + }; export interface ObjectWithEveryOptionalTypeNestedObject { id: string; timestamp: Date; data: ObjectWithEveryOptionalTypeNestedObjectData; } - -export interface ObjectWithEveryOptionalTypeNestedObjectData { - id: string; - timestamp: Date; - data: ObjectWithEveryOptionalTypeNestedObjectDataData; -} - -export interface ObjectWithEveryOptionalTypeNestedObjectDataData { - id: string; - timestamp: Date; -} - -export interface ObjectWithEveryOptionalTypeNestedArrayItemItem { - id: string; - timestamp: Date; -} - -export interface RecursiveObject { - left: RecursiveObject | null; - right: RecursiveObject | null; - value: string; -} -export const $$RecursiveObject = { - parse(input: Record): RecursiveObject { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - function __parse_RecursiveObject(_fnVal) { - let _fnTarget; - if (typeof _fnVal === "object" && _fnVal !== null) { - const __D1 = {}; - if (_fnVal.left === null) { - __D1.left = null; - } else { - __D1.left = __parse_RecursiveObject(_fnVal.left); - } - if (_fnVal.right === null) { - __D1.right = null; - } else { - __D1.right = __parse_RecursiveObject(_fnVal.right); - } - if (typeof _fnVal.value === "string") { - __D1.value = _fnVal.value; - } else { - $fallback( - "/value", - "/properties/value/type", - "Expected string at /value", - ); - } - _fnTarget = __D1; - } else { - $fallback("", "", "Expected object"); - } - return _fnTarget; - } - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - result = __parse_RecursiveObject(json); - return result; - } - let result = {}; - result = __parse_RecursiveObject(input); - return result; - }, - serialize(input: RecursiveObject): string { - let json = ""; - function __serialize_RecursiveObject(__inputVal__) { - json += "{"; - if (__inputVal__.left === null) { - json += '"left":null'; - } else { - json += '"left":'; - __serialize_RecursiveObject(__inputVal__.left); - } - if (__inputVal__.right === null) { - json += ',"right":null'; - } else { - json += ',"right":'; - __serialize_RecursiveObject(__inputVal__.right); - } - json += `,"value":`; - if (__inputVal__.value.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < __inputVal__.value.length; i++) { - __point__ = __inputVal__.value.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(__inputVal__.value); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - __inputVal__.value.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${__inputVal__.value}"`; - } else { - json += `"${__result__}${__inputVal__.value.slice(__last__)}"`; - } - } - } else if ( - __inputVal__.value.length < 5000 && - !STR_ESCAPE.test(__inputVal__.value) - ) { - json += `"${__inputVal__.value}"`; - } else { - json += JSON.stringify(__inputVal__.value); - } - json += "}"; - } - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - __serialize_RecursiveObject(input); - return json; - }, -}; - -export type RecursiveUnion = - | RecursiveUnionChild - | RecursiveUnionChildren - | RecursiveUnionText - | RecursiveUnionShape; -export const $$RecursiveUnion = { - parse(input: Record): RecursiveUnion { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - function __parse_RecursiveUnion(_fnVal) { - let _fnTarget; - if (typeof _fnVal === "object" && _fnVal !== null) { - switch (_fnVal.type) { - case "CHILD": { - if (typeof _fnVal === "object" && _fnVal !== null) { - const __D1 = {}; - __D1.type = "CHILD"; - __D1.data = __parse_RecursiveUnion(_fnVal.data); - _fnTarget = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "CHILDREN": { - if (typeof _fnVal === "object" && _fnVal !== null) { - const __D1 = {}; - __D1.type = "CHILDREN"; - if (Array.isArray(_fnVal.data)) { - const __D2 = []; - for (const __D2AItem of _fnVal.data) { - let __D2AItemAResult; - __D2AItemAResult = - __parse_RecursiveUnion(__D2AItem); - __D2.push(__D2AItemAResult); - } - __D1.data = __D2; - } else { - $fallback( - "/data", - "/mapping/properties/data", - "Expected Array", - ); - } - _fnTarget = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "TEXT": { - if (typeof _fnVal === "object" && _fnVal !== null) { - const __D1 = {}; - __D1.type = "TEXT"; - if (typeof _fnVal.data === "string") { - __D1.data = _fnVal.data; - } else { - $fallback( - "/data", - "/mapping/properties/data/type", - "Expected string at /data", - ); - } - _fnTarget = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "SHAPE": { - if (typeof _fnVal === "object" && _fnVal !== null) { - const __D1 = {}; - __D1.type = "SHAPE"; - if ( - typeof _fnVal.data === "object" && - _fnVal.data !== null - ) { - const __D2 = {}; - if ( - typeof _fnVal.data.width === "number" && - !Number.isNaN(_fnVal.data.width) - ) { - __D2.width = _fnVal.data.width; - } else { - $fallback( - "/data/width", - "/mapping/properties/data/properties/width/type", - "Expected number at /data/width", - ); - } - if ( - typeof _fnVal.data.height === "number" && - !Number.isNaN(_fnVal.data.height) - ) { - __D2.height = _fnVal.data.height; - } else { - $fallback( - "/data/height", - "/mapping/properties/data/properties/height/type", - "Expected number at /data/height", - ); - } - if (typeof _fnVal.data.color === "string") { - __D2.color = _fnVal.data.color; - } else { - $fallback( - "/data/color", - "/mapping/properties/data/properties/color/type", - "Expected string at /data/color", - ); - } - __D1.data = __D2; - } else { - $fallback( - "/data", - "/mapping/properties/data", - "Expected object", - ); - } - _fnTarget = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "input.type did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); - } - return _fnTarget; - } - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - result = __parse_RecursiveUnion(json); - return result; - } - let result = {}; - result = __parse_RecursiveUnion(input); - return result; - }, - serialize(input: RecursiveUnion): string { - let json = ""; - function __serialize_RecursiveUnion(__fnInput__) { - switch (__fnInput__.type) { - case "CHILD": { - json += ""; - json += "{"; - json += `"type":"CHILD"`; - json += ',"data":'; - __serialize_RecursiveUnion(__fnInput__.data); - json += "}"; - break; - } - case "CHILDREN": { - json += ""; - json += "{"; - json += `"type":"CHILDREN"`; - json += ',"data":['; - for (let i = 0; i < __fnInput__.data.length; i++) { - const valDataItem = __fnInput__.data[i]; - if (i !== 0) { - json += ","; - } - json += ""; - __serialize_RecursiveUnion(valDataItem); - } - json += "]"; - json += "}"; - break; - } - case "TEXT": { - json += ""; - json += "{"; - json += `"type":"TEXT"`; - json += `,"data":`; - if (__fnInput__.data.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < __fnInput__.data.length; i++) { - __point__ = __fnInput__.data.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(__fnInput__.data); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - __fnInput__.data.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${__fnInput__.data}"`; - } else { - json += `"${__result__}${__fnInput__.data.slice(__last__)}"`; - } - } - } else if ( - __fnInput__.data.length < 5000 && - !STR_ESCAPE.test(__fnInput__.data) - ) { - json += `"${__fnInput__.data}"`; - } else { - json += JSON.stringify(__fnInput__.data); - } - json += "}"; - break; - } - case "SHAPE": { - json += ""; - json += "{"; - json += `"type":"SHAPE"`; - - json += ',"data":'; - json += "{"; - - if (Number.isNaN(__fnInput__.data.width)) { - throw new Error( - "Expected number at /data/width got NaN", - ); - } - json += `"width":${__fnInput__.data.width}`; - - if (Number.isNaN(__fnInput__.data.height)) { - throw new Error( - "Expected number at /data/height got NaN", - ); - } - json += `,"height":${__fnInput__.data.height}`; - json += `,"color":`; - if (__fnInput__.data.color.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < __fnInput__.data.color.length; - i++ - ) { - __point__ = __fnInput__.data.color.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(__fnInput__.data.color); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - __fnInput__.data.color.slice(__last__, i) + - "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${__fnInput__.data.color}"`; - } else { - json += `"${__result__}${__fnInput__.data.color.slice(__last__)}"`; - } - } - } else if ( - __fnInput__.data.color.length < 5000 && - !STR_ESCAPE.test(__fnInput__.data.color) - ) { - json += `"${__fnInput__.data.color}"`; - } else { - json += JSON.stringify(__fnInput__.data.color); - } - json += "}"; - json += "}"; - break; - } - } - } - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - __serialize_RecursiveUnion(input); - return json; - }, -}; -/** - * Child node - */ -export interface RecursiveUnionChild { - type: "CHILD"; - data: RecursiveUnion; -} - -/** - * List of children node - */ -export interface RecursiveUnionChildren { - type: "CHILDREN"; - data: Array; -} - -/** - * Text node - */ -export interface RecursiveUnionText { - type: "TEXT"; - data: string; -} - -/** - * Shape node - */ -export interface RecursiveUnionShape { - type: "SHAPE"; - data: RecursiveUnionShapeData; -} - -export interface RecursiveUnionShapeData { - width: number; - height: number; - color: string; -} - -export interface AutoReconnectParams { - messageCount: number; -} -export const $$AutoReconnectParams = { - parse(input: Record): AutoReconnectParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if ( - typeof json.messageCount === "number" && - Number.isInteger(json.messageCount) && - json.messageCount >= 0 && - json.messageCount <= 255 - ) { - __D1.messageCount = json.messageCount; - } else { - $fallback( - "/messageCount", - "/properties/messageCount", - "Expected valid integer between 0 and 255", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if ( - typeof input.messageCount === "number" && - Number.isInteger(input.messageCount) && - input.messageCount >= 0 && - input.messageCount <= 255 - ) { - __D1.messageCount = input.messageCount; - } else { - $fallback( - "/messageCount", - "/properties/messageCount", - "Expected valid integer between 0 and 255", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: AutoReconnectParams): string { - let json = ""; - - json += ""; - json += "{"; - - if (Number.isNaN(input.messageCount)) { - throw new Error("Expected number at /messageCount got NaN"); - } - json += `"messageCount":${input.messageCount}`; - json += "}"; - return json; - }, -}; - -export interface AutoReconnectResponse { - count: number; - message: string; -} -export const $$AutoReconnectResponse = { - parse(input: Record): AutoReconnectResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, +export const $$ObjectWithEveryOptionalTypeNestedObject: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeNestedObject { + return { + id: "", + timestamp: new Date(), + data: $$ObjectWithEveryOptionalTypeNestedObjectData.new(), + }; + }, + validate(input): input is ObjectWithEveryOptionalTypeNestedObject { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date && + $$ObjectWithEveryOptionalTypeNestedObjectData.validate( + input.data, + ) ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if ( - typeof json.count === "number" && - Number.isInteger(json.count) && - json.count >= 0 && - json.count <= 255 - ) { - __D1.count = json.count; - } else { - $fallback( - "/count", - "/properties/count", - "Expected valid integer between 0 and 255", - ); - } - if (typeof json.message === "string") { - __D1.message = json.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if ( - typeof input.count === "number" && - Number.isInteger(input.count) && - input.count >= 0 && - input.count <= 255 - ) { - __D1.count = input.count; - } else { - $fallback( - "/count", - "/properties/count", - "Expected valid integer between 0 and 255", - ); - } - if (typeof input.message === "string") { - __D1.message = input.message; + }, + fromJson(input): ObjectWithEveryOptionalTypeNestedObject { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: AutoReconnectResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - - if (Number.isNaN(input.count)) { - throw new Error("Expected number at /count got NaN"); - } - json += `"count":${input.count}`; - json += `,"message":`; - if (input.message.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.message.length; i++) { - __point__ = input.message.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.message); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.message.slice(__last__, i) + "\\"; - __last__ = i; - } + _id = ""; } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.message}"`; - } else { - json += `"${__result__}${input.message.slice(__last__)}"`; - } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); } - } else if ( - input.message.length < 5000 && - !STR_ESCAPE.test(input.message) - ) { - json += `"${input.message}"`; - } else { - json += JSON.stringify(input.message); - } - json += "}"; - return json; - }, -}; + let _data: ObjectWithEveryOptionalTypeNestedObjectData; + if (isObject(input.data)) { + _data = $$ObjectWithEveryOptionalTypeNestedObjectData.fromJson( + input.data, + ); + } else { + _data = $$ObjectWithEveryOptionalTypeNestedObjectData.new(); + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeNestedObject { + return $$ObjectWithEveryOptionalTypeNestedObject.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"data":'; + json += $$ObjectWithEveryOptionalTypeNestedObjectData.toJsonString( + input.data, + ); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalTypeNestedObject/data.", + ); + return queryParts.join("&"); + }, + }; -export interface StreamConnectionErrorTestParams { - statusCode: number; - statusMessage: string; +export interface ObjectWithEveryOptionalTypeNestedObjectData { + id: string; + timestamp: Date; + data: ObjectWithEveryOptionalTypeNestedObjectDataData; } -export const $$StreamConnectionErrorTestParams = { - parse(input: Record): StreamConnectionErrorTestParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, +export const $$ObjectWithEveryOptionalTypeNestedObjectData: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeNestedObjectData { + return { + id: "", + timestamp: new Date(), + data: $$ObjectWithEveryOptionalTypeNestedObjectDataData.new(), + }; + }, + validate(input): input is ObjectWithEveryOptionalTypeNestedObjectData { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date && + $$ObjectWithEveryOptionalTypeNestedObjectDataData.validate( + input.data, + ) ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if ( - typeof json.statusCode === "number" && - Number.isInteger(json.statusCode) && - json.statusCode >= -2147483648 && - json.statusCode <= 2147483647 - ) { - __D1.statusCode = json.statusCode; - } else { - $fallback( - "/statusCode", - "/properties/statusCode", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - if (typeof json.statusMessage === "string") { - __D1.statusMessage = json.statusMessage; - } else { - $fallback( - "/statusMessage", - "/properties/statusMessage/type", - "Expected string at /statusMessage", - ); - } - result = __D1; + }, + fromJson(input): ObjectWithEveryOptionalTypeNestedObjectData { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; } else { - $fallback("", "", "Expected object"); + _id = ""; } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if ( - typeof input.statusCode === "number" && - Number.isInteger(input.statusCode) && - input.statusCode >= -2147483648 && - input.statusCode <= 2147483647 - ) { - __D1.statusCode = input.statusCode; + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; } else { - $fallback( - "/statusCode", - "/properties/statusCode", - "Expected valid integer between -2147483648 and 2147483647", - ); + _timestamp = new Date(); } - if (typeof input.statusMessage === "string") { - __D1.statusMessage = input.statusMessage; + let _data: ObjectWithEveryOptionalTypeNestedObjectDataData; + if (isObject(input.data)) { + _data = + $$ObjectWithEveryOptionalTypeNestedObjectDataData.fromJson( + input.data, + ); } else { - $fallback( - "/statusMessage", - "/properties/statusMessage/type", - "Expected string at /statusMessage", + _data = $$ObjectWithEveryOptionalTypeNestedObjectDataData.new(); + } + return { + id: _id, + timestamp: _timestamp, + data: _data, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeNestedObjectData { + return $$ObjectWithEveryOptionalTypeNestedObjectData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += ',"data":'; + json += + $$ObjectWithEveryOptionalTypeNestedObjectDataData.toJsonString( + input.data, ); - } - result = __D1; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /ObjectWithEveryOptionalTypeNestedObjectData/data.", + ); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryOptionalTypeNestedObjectDataData { + id: string; + timestamp: Date; +} +export const $$ObjectWithEveryOptionalTypeNestedObjectDataData: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeNestedObjectDataData { + return { + id: "", + timestamp: new Date(), + }; + }, + validate( + input, + ): input is ObjectWithEveryOptionalTypeNestedObjectDataData { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryOptionalTypeNestedObjectDataData { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString(input): ObjectWithEveryOptionalTypeNestedObjectDataData { + return $$ObjectWithEveryOptionalTypeNestedObjectDataData.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export interface ObjectWithEveryOptionalTypeNestedArrayelementelement { + id: string; + timestamp: Date; +} +export const $$ObjectWithEveryOptionalTypeNestedArrayelementelement: ArriModelValidator = + { + new(): ObjectWithEveryOptionalTypeNestedArrayelementelement { + return { + id: "", + timestamp: new Date(), + }; + }, + validate( + input, + ): input is ObjectWithEveryOptionalTypeNestedArrayelementelement { + return ( + isObject(input) && + typeof input.id === "string" && + input.timestamp instanceof Date + ); + }, + fromJson(input): ObjectWithEveryOptionalTypeNestedArrayelementelement { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _timestamp: Date; + if (typeof input.timestamp === "string") { + _timestamp = new Date(input.timestamp); + } else if (input.timestamp instanceof Date) { + _timestamp = input.timestamp; + } else { + _timestamp = new Date(); + } + return { + id: _id, + timestamp: _timestamp, + }; + }, + fromJsonString( + input, + ): ObjectWithEveryOptionalTypeNestedArrayelementelement { + return $$ObjectWithEveryOptionalTypeNestedArrayelementelement.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"timestamp":'; + json += `"${input.timestamp.toISOString()}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`timestamp=${input.timestamp.toISOString()}`); + return queryParts.join("&"); + }, + }; + +export interface RecursiveObject { + left: RecursiveObject | null; + right: RecursiveObject | null; + value: string; +} +export const $$RecursiveObject: ArriModelValidator = { + new(): RecursiveObject { + return { + left: null, + right: null, + value: "", + }; + }, + validate(input): input is RecursiveObject { + return ( + isObject(input) && + ($$RecursiveObject.validate(input.left) || input.left === null) && + ($$RecursiveObject.validate(input.right) || input.right === null) && + typeof input.value === "string" + ); + }, + fromJson(input): RecursiveObject { + let _left: RecursiveObject | null; + if (isObject(input.left)) { + _left = $$RecursiveObject.fromJson(input.left); } else { - $fallback("", "", "Expected object"); + _left = null; } - return result; + let _right: RecursiveObject | null; + if (isObject(input.right)) { + _right = $$RecursiveObject.fromJson(input.right); + } else { + _right = null; + } + let _value: string; + if (typeof input.value === "string") { + _value = input.value; + } else { + _value = ""; + } + return { + left: _left, + right: _right, + value: _value, + }; }, - serialize(input: StreamConnectionErrorTestParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - - if (Number.isNaN(input.statusCode)) { - throw new Error("Expected number at /statusCode got NaN"); + fromJsonString(input): RecursiveObject { + return $$RecursiveObject.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"left":'; + if (input.left !== null) { + json += $$RecursiveObject.toJsonString(input.left); + } else { + json += "null"; } - json += `"statusCode":${input.statusCode}`; - json += `,"statusMessage":`; - if (input.statusMessage.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.statusMessage.length; i++) { - __point__ = input.statusMessage.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.statusMessage); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.statusMessage.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.statusMessage}"`; - } else { - json += `"${__result__}${input.statusMessage.slice(__last__)}"`; - } - } - } else if ( - input.statusMessage.length < 5000 && - !STR_ESCAPE.test(input.statusMessage) - ) { - json += `"${input.statusMessage}"`; + json += ',"right":'; + if (input.right !== null) { + json += $$RecursiveObject.toJsonString(input.right); } else { - json += JSON.stringify(input.statusMessage); + json += "null"; } + json += ',"value":'; + json += serializeString(input.value); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + console.warn( + "[WARNING] Nested objects cannot be serialized to query string. Ignoring property at /RecursiveObject/left.", + ); + console.warn( + "[WARNING] Nested objects cannot be serialized to query string. Ignoring property at /RecursiveObject/right.", + ); + queryParts.push(`value=${input.value}`); + return queryParts.join("&"); + }, }; -export interface StreamConnectionErrorTestResponse { - message: string; -} -export const $$StreamConnectionErrorTestResponse = { - parse(input: Record): StreamConnectionErrorTestResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); +export type RecursiveUnion = + | RecursiveUnionChild + | RecursiveUnionChildren + | RecursiveUnionText + | RecursiveUnionShape; +export const $$RecursiveUnion: ArriModelValidator = { + new(): RecursiveUnion { + return $$RecursiveUnionChild.new(); + }, + validate(input): input is RecursiveUnion { + if (!isObject(input)) { + return false; } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.message === "string") { - __D1.message = json.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; + if (typeof input.type !== "string") { + return false; } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.message === "string") { - __D1.message = input.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); + switch (input.type) { + case "CHILD": + return $$RecursiveUnionChild.validate(input); + case "CHILDREN": + return $$RecursiveUnionChildren.validate(input); + case "TEXT": + return $$RecursiveUnionText.validate(input); + case "SHAPE": + return $$RecursiveUnionShape.validate(input); + default: + return false; } - return result; }, - serialize(input: StreamConnectionErrorTestResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"message":`; - if (input.message.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.message.length; i++) { - __point__ = input.message.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.message); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.message.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.message}"`; - } else { - json += `"${__result__}${input.message.slice(__last__)}"`; - } - } - } else if ( - input.message.length < 5000 && - !STR_ESCAPE.test(input.message) - ) { - json += `"${input.message}"`; + fromJson(input): RecursiveUnion { + switch (input.type) { + case "CHILD": + return $$RecursiveUnionChild.fromJson(input); + case "CHILDREN": + return $$RecursiveUnionChildren.fromJson(input); + case "TEXT": + return $$RecursiveUnionText.fromJson(input); + case "SHAPE": + return $$RecursiveUnionShape.fromJson(input); + default: + return $$RecursiveUnionChild.new(); + } + }, + fromJsonString(input): RecursiveUnion { + return $$RecursiveUnion.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + switch (input.type) { + case "CHILD": + return $$RecursiveUnionChild.toJsonString(input); + case "CHILDREN": + return $$RecursiveUnionChildren.toJsonString(input); + case "TEXT": + return $$RecursiveUnionText.toJsonString(input); + case "SHAPE": + return $$RecursiveUnionShape.toJsonString(input); + default: + throw new Error(`Unhandled case "${(input as any).type}"`); + } + }, + toUrlQueryString(input): string { + switch (input.type) { + case "CHILD": + return $$RecursiveUnionChild.toUrlQueryString(input); + case "CHILDREN": + return $$RecursiveUnionChildren.toUrlQueryString(input); + case "TEXT": + return $$RecursiveUnionText.toUrlQueryString(input); + case "SHAPE": + return $$RecursiveUnionShape.toUrlQueryString(input); + default: + throw new Error("Unhandled case"); + } + }, +}; +/** + * Child node + */ +export interface RecursiveUnionChild { + type: "CHILD"; + data: RecursiveUnion; +} +const $$RecursiveUnionChild: ArriModelValidator = { + new(): RecursiveUnionChild { + return { + type: "CHILD", + data: RecursiveUnion.new(), + }; + }, + validate(input): input is RecursiveUnionChild { + return ( + isObject(input) && + input.type === "CHILD" && + $$RecursiveUnion.validate(input.data) + ); + }, + fromJson(input): RecursiveUnionChild { + const _type = "CHILD"; + let _data: RecursiveUnion; + if (isObject(input.data)) { + _data = $$RecursiveUnion.fromJson(input.data); } else { - json += JSON.stringify(input.message); + _data = RecursiveUnion.new(); } + return { + type: _type, + data: _data, + }; + }, + fromJsonString(input): RecursiveUnionChild { + return $$RecursiveUnionChild.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"CHILD"'; + json += ',"data":'; + json += $$RecursiveUnion.toJsonString(input.data); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=CHILD"); + console.warn( + "[WARNING] Nested objects cannot be serialized to query string. Ignoring property at /RecursiveUnionChild/data.", + ); + return queryParts.join("&"); + }, }; -export interface StreamLargeObjectsResponse { - numbers: Array; - objects: Array; +/** + * List of children node + */ +export interface RecursiveUnionChildren { + type: "CHILDREN"; + data: RecursiveUnion[]; } -export const $$StreamLargeObjectsResponse = { - parse(input: Record): StreamLargeObjectsResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (Array.isArray(json.numbers)) { - const __D2 = []; - for (const __D2AItem of json.numbers) { - let __D2AItemAResult; - if ( - typeof __D2AItem === "number" && - !Number.isNaN(__D2AItem) - ) { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/numbers/[0]", - "/properties/numbers/elements/type", - "Expected number at /numbers/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.numbers = __D2; - } else { - $fallback( - "/numbers", - "/properties/numbers", - "Expected Array", - ); - } - if (Array.isArray(json.objects)) { - const __D2 = []; - for (const __D2AItem of json.objects) { - let __D2AItemAResult; - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - const __D3 = {}; - if (typeof __D2AItem.id === "string") { - __D3.id = __D2AItem.id; - } else { - $fallback( - "/objects/[0]/id", - "/properties/objects/elements/properties/id/type", - "Expected string at /objects/[0]/id", - ); - } - if (typeof __D2AItem.name === "string") { - __D3.name = __D2AItem.name; - } else { - $fallback( - "/objects/[0]/name", - "/properties/objects/elements/properties/name/type", - "Expected string at /objects/[0]/name", - ); - } - if (typeof __D2AItem.email === "string") { - __D3.email = __D2AItem.email; - } else { - $fallback( - "/objects/[0]/email", - "/properties/objects/elements/properties/email/type", - "Expected string at /objects/[0]/email", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/objects/[0]", - "/properties/objects/elements", - "Expected object", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.objects = __D2; - } else { - $fallback( - "/objects", - "/properties/objects", - "Expected Array", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (Array.isArray(input.numbers)) { - const __D2 = []; - for (const __D2AItem of input.numbers) { - let __D2AItemAResult; - if ( - typeof __D2AItem === "number" && - !Number.isNaN(__D2AItem) - ) { - __D2AItemAResult = __D2AItem; - } else { - $fallback( - "/numbers/[0]", - "/properties/numbers/elements/type", - "Expected number at /numbers/[0]", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.numbers = __D2; - } else { - $fallback("/numbers", "/properties/numbers", "Expected Array"); - } - if (Array.isArray(input.objects)) { - const __D2 = []; - for (const __D2AItem of input.objects) { - let __D2AItemAResult; - if (typeof __D2AItem === "object" && __D2AItem !== null) { - const __D3 = {}; - if (typeof __D2AItem.id === "string") { - __D3.id = __D2AItem.id; - } else { - $fallback( - "/objects/[0]/id", - "/properties/objects/elements/properties/id/type", - "Expected string at /objects/[0]/id", - ); - } - if (typeof __D2AItem.name === "string") { - __D3.name = __D2AItem.name; - } else { - $fallback( - "/objects/[0]/name", - "/properties/objects/elements/properties/name/type", - "Expected string at /objects/[0]/name", - ); - } - if (typeof __D2AItem.email === "string") { - __D3.email = __D2AItem.email; - } else { - $fallback( - "/objects/[0]/email", - "/properties/objects/elements/properties/email/type", - "Expected string at /objects/[0]/email", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/objects/[0]", - "/properties/objects/elements", - "Expected object", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.objects = __D2; - } else { - $fallback("/objects", "/properties/objects", "Expected Array"); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; +const $$RecursiveUnionChildren: ArriModelValidator = { + new(): RecursiveUnionChildren { + return { + type: "CHILDREN", + data: [], + }; }, - serialize(input: StreamLargeObjectsResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += '"numbers":['; - for (let i = 0; i < input.numbers.length; i++) { - const valNumbersItem = input.numbers[i]; - if (i !== 0) { - json += ","; - } - - if (Number.isNaN(valNumbersItem)) { - throw new Error("Expected number at /numbers/i got NaN"); - } - json += `${valNumbersItem}`; - } - json += "]"; - json += ',"objects":['; - for (let i = 0; i < input.objects.length; i++) { - const valObjectsItem = input.objects[i]; - if (i !== 0) { - json += ","; - } - - json += ""; - json += "{"; - json += `"id":`; - if (valObjectsItem.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < valObjectsItem.id.length; i++) { - __point__ = valObjectsItem.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(valObjectsItem.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valObjectsItem.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valObjectsItem.id}"`; - } else { - json += `"${__result__}${valObjectsItem.id.slice(__last__)}"`; - } - } - } else if ( - valObjectsItem.id.length < 5000 && - !STR_ESCAPE.test(valObjectsItem.id) - ) { - json += `"${valObjectsItem.id}"`; - } else { - json += JSON.stringify(valObjectsItem.id); - } - json += `,"name":`; - if (valObjectsItem.name.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < valObjectsItem.name.length; i++) { - __point__ = valObjectsItem.name.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(valObjectsItem.name); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valObjectsItem.name.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valObjectsItem.name}"`; - } else { - json += `"${__result__}${valObjectsItem.name.slice(__last__)}"`; - } - } - } else if ( - valObjectsItem.name.length < 5000 && - !STR_ESCAPE.test(valObjectsItem.name) - ) { - json += `"${valObjectsItem.name}"`; - } else { - json += JSON.stringify(valObjectsItem.name); - } - json += `,"email":`; - if (valObjectsItem.email.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < valObjectsItem.email.length; i++) { - __point__ = valObjectsItem.email.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(valObjectsItem.email); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valObjectsItem.email.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valObjectsItem.email}"`; - } else { - json += `"${__result__}${valObjectsItem.email.slice(__last__)}"`; - } + validate(input): input is RecursiveUnionChildren { + return ( + isObject(input) && + input.type === "CHILDREN" && + Array.isArray(input.data) && + input.data.every((_element) => $$RecursiveUnion.validate(_element)) + ); + }, + fromJson(input): RecursiveUnionChildren { + const _type = "CHILDREN"; + let _data: RecursiveUnion[]; + if (Array.isArray(input.data)) { + _data = []; + for (const _dataEl of input.data) { + let _dataElValue: RecursiveUnion; + if (isObject(_dataEl)) { + _dataElValue = $$RecursiveUnion.fromJson(_dataEl); + } else { + _dataElValue = RecursiveUnion.new(); } - } else if ( - valObjectsItem.email.length < 5000 && - !STR_ESCAPE.test(valObjectsItem.email) - ) { - json += `"${valObjectsItem.email}"`; - } else { - json += JSON.stringify(valObjectsItem.email); + _data.push(_dataElValue); } - json += "}"; + } else { + _data = []; + } + return { + type: _type, + data: _data, + }; + }, + fromJsonString(input): RecursiveUnionChildren { + return $$RecursiveUnionChildren.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"CHILDREN"'; + json += ',"data":'; + json += "["; + for (let i = 0; i < input.data.length; i++) { + if (i !== 0) json += ","; + const _inputDataEl = input.data[i]; + json += $$RecursiveUnion.toJsonString(_inputDataEl); } json += "]"; json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=CHILDREN"); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /RecursiveUnionChildren/data.", + ); + return queryParts.join("&"); + }, }; -export interface StreamLargeObjectsResponseObjectsItem { - id: string; - name: string; - email: string; -} -export interface ChatMessageParams { - channelId: string; +/** + * Text node + */ +export interface RecursiveUnionText { + type: "TEXT"; + data: string; } -export const $$ChatMessageParams = { - parse(input: Record): ChatMessageParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.channelId === "string") { - __D1.channelId = json.channelId; - } else { - $fallback( - "/channelId", - "/properties/channelId/type", - "Expected string at /channelId", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.channelId === "string") { - __D1.channelId = input.channelId; - } else { - $fallback( - "/channelId", - "/properties/channelId/type", - "Expected string at /channelId", - ); - } - result = __D1; +const $$RecursiveUnionText: ArriModelValidator = { + new(): RecursiveUnionText { + return { + type: "TEXT", + data: "", + }; + }, + validate(input): input is RecursiveUnionText { + return ( + isObject(input) && + input.type === "TEXT" && + typeof input.data === "string" + ); + }, + fromJson(input): RecursiveUnionText { + const _type = "TEXT"; + let _data: string; + if (typeof input.data === "string") { + _data = input.data; } else { - $fallback("", "", "Expected object"); + _data = ""; } - return result; + return { + type: _type, + data: _data, + }; }, - serialize(input: ChatMessageParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + fromJsonString(input): RecursiveUnionText { + return $$RecursiveUnionText.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"TEXT"'; + json += ',"data":'; + json += serializeString(input.data); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=TEXT"); + queryParts.push(`data=${input.data}`); + return queryParts.join("&"); + }, +}; - json += ""; - json += "{"; - json += `"channelId":`; - if (input.channelId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.channelId.length; i++) { - __point__ = input.channelId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.channelId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.channelId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.channelId}"`; - } else { - json += `"${__result__}${input.channelId.slice(__last__)}"`; - } - } - } else if ( - input.channelId.length < 5000 && - !STR_ESCAPE.test(input.channelId) - ) { - json += `"${input.channelId}"`; +/** + * Shape node + */ +export interface RecursiveUnionShape { + type: "SHAPE"; + data: RecursiveUnionShapeData; +} +const $$RecursiveUnionShape: ArriModelValidator = { + new(): RecursiveUnionShape { + return { + type: "SHAPE", + data: $$RecursiveUnionShapeData.new(), + }; + }, + validate(input): input is RecursiveUnionShape { + return ( + isObject(input) && + input.type === "SHAPE" && + $$RecursiveUnionShapeData.validate(input.data) + ); + }, + fromJson(input): RecursiveUnionShape { + const _type = "SHAPE"; + let _data: RecursiveUnionShapeData; + if (isObject(input.data)) { + _data = $$RecursiveUnionShapeData.fromJson(input.data); } else { - json += JSON.stringify(input.channelId); + _data = $$RecursiveUnionShapeData.new(); } + return { + type: _type, + data: _data, + }; + }, + fromJsonString(input): RecursiveUnionShape { + return $$RecursiveUnionShape.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"SHAPE"'; + json += ',"data":'; + json += $$RecursiveUnionShapeData.toJsonString(input.data); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=SHAPE"); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /RecursiveUnionShape/data.", + ); + return queryParts.join("&"); + }, }; -export type ChatMessage = ChatMessageText | ChatMessageImage | ChatMessageUrl; -export const $$ChatMessage = { - parse(input: Record): ChatMessage { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, +export interface RecursiveUnionShapeData { + width: number; + height: number; + color: string; +} +export const $$RecursiveUnionShapeData: ArriModelValidator = + { + new(): RecursiveUnionShapeData { + return { + width: 0, + height: 0, + color: "", + }; + }, + validate(input): input is RecursiveUnionShapeData { + return ( + isObject(input) && + typeof input.width === "number" && + typeof input.height === "number" && + typeof input.color === "string" ); - } + }, + fromJson(input): RecursiveUnionShapeData { + let _width: number; + if (typeof input.width === "number") { + _width = input.width; + } else { + _width = 0; + } + let _height: number; + if (typeof input.height === "number") { + _height = input.height; + } else { + _height = 0; + } + let _color: string; + if (typeof input.color === "string") { + _color = input.color; + } else { + _color = ""; + } + return { + width: _width, + height: _height, + color: _color, + }; + }, + fromJsonString(input): RecursiveUnionShapeData { + return $$RecursiveUnionShapeData.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"width":'; + json += `${input.width}`; + json += ',"height":'; + json += `${input.height}`; + json += ',"color":'; + json += serializeString(input.color); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`width=${input.width}`); + queryParts.push(`height=${input.height}`); + queryParts.push(`color=${input.color}`); + return queryParts.join("&"); + }, + }; - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - switch (json.messageType) { - case "TEXT": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.messageType = "TEXT"; - if (typeof json.id === "string") { - __D1.id = json.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof json.channelId === "string") { - __D1.channelId = json.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof json.userId === "string") { - __D1.userId = json.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof json.date === "object" && - json.date instanceof Date - ) { - __D1.date = json.date; - } else if (typeof json.date === "string") { - __D1.date = new Date(json.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof json.text === "string") { - __D1.text = json.text; - } else { - $fallback( - "/text", - "/mapping/properties/text/type", - "Expected string at /text", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "IMAGE": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.messageType = "IMAGE"; - if (typeof json.id === "string") { - __D1.id = json.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof json.channelId === "string") { - __D1.channelId = json.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof json.userId === "string") { - __D1.userId = json.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof json.date === "object" && - json.date instanceof Date - ) { - __D1.date = json.date; - } else if (typeof json.date === "string") { - __D1.date = new Date(json.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof json.image === "string") { - __D1.image = json.image; - } else { - $fallback( - "/image", - "/mapping/properties/image/type", - "Expected string at /image", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "URL": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.messageType = "URL"; - if (typeof json.id === "string") { - __D1.id = json.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof json.channelId === "string") { - __D1.channelId = json.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof json.userId === "string") { - __D1.userId = json.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof json.date === "object" && - json.date instanceof Date - ) { - __D1.date = json.date; - } else if (typeof json.date === "string") { - __D1.date = new Date(json.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof json.url === "string") { - __D1.url = json.url; - } else { - $fallback( - "/url", - "/mapping/properties/url/type", - "Expected string at /url", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "json.messageType did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - switch (input.messageType) { - case "TEXT": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.messageType = "TEXT"; - if (typeof input.id === "string") { - __D1.id = input.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof input.channelId === "string") { - __D1.channelId = input.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof input.userId === "string") { - __D1.userId = input.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof input.date === "object" && - input.date instanceof Date - ) { - __D1.date = input.date; - } else if (typeof input.date === "string") { - __D1.date = new Date(input.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof input.text === "string") { - __D1.text = input.text; - } else { - $fallback( - "/text", - "/mapping/properties/text/type", - "Expected string at /text", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "IMAGE": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.messageType = "IMAGE"; - if (typeof input.id === "string") { - __D1.id = input.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof input.channelId === "string") { - __D1.channelId = input.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof input.userId === "string") { - __D1.userId = input.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof input.date === "object" && - input.date instanceof Date - ) { - __D1.date = input.date; - } else if (typeof input.date === "string") { - __D1.date = new Date(input.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof input.image === "string") { - __D1.image = input.image; - } else { - $fallback( - "/image", - "/mapping/properties/image/type", - "Expected string at /image", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "URL": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.messageType = "URL"; - if (typeof input.id === "string") { - __D1.id = input.id; - } else { - $fallback( - "/id", - "/mapping/properties/id/type", - "Expected string at /id", - ); - } - if (typeof input.channelId === "string") { - __D1.channelId = input.channelId; - } else { - $fallback( - "/channelId", - "/mapping/properties/channelId/type", - "Expected string at /channelId", - ); - } - if (typeof input.userId === "string") { - __D1.userId = input.userId; - } else { - $fallback( - "/userId", - "/mapping/properties/userId/type", - "Expected string at /userId", - ); - } - if ( - typeof input.date === "object" && - input.date instanceof Date - ) { - __D1.date = input.date; - } else if (typeof input.date === "string") { - __D1.date = new Date(input.date); - } else { - $fallback( - "/date", - "/mapping/properties/date", - "Expected instanceof Date or ISO Date string at /date", - ); - } - if (typeof input.url === "string") { - __D1.url = input.url; - } else { - $fallback( - "/url", - "/mapping/properties/url/type", - "Expected string at /url", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "input.messageType did not match one of the specified values", - ); - break; - } +export interface AutoReconnectParams { + messageCount: number; +} +export const $$AutoReconnectParams: ArriModelValidator = { + new(): AutoReconnectParams { + return { + messageCount: 0, + }; + }, + validate(input): input is AutoReconnectParams { + return ( + isObject(input) && + typeof input.messageCount === "number" && + Number.isInteger(input.messageCount) && + input.messageCount >= 0 && + input.messageCount <= UINT8_MAX + ); + }, + fromJson(input): AutoReconnectParams { + let _messageCount: number; + if ( + typeof input.messageCount === "number" && + Number.isInteger(input.messageCount) && + input.messageCount >= 0 && + input.messageCount <= UINT8_MAX + ) { + _messageCount = input.messageCount; } else { - $fallback("", "", "Expected Object."); + _messageCount = 0; } - return result; + return { + messageCount: _messageCount, + }; }, - serialize(input: ChatMessage): string { - let json = ""; + fromJsonString(input): AutoReconnectParams { + return $$AutoReconnectParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"messageCount":'; + json += `${input.messageCount}`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`messageCount=${input.messageCount}`); + return queryParts.join("&"); + }, +}; - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - switch (input.messageType) { - case "TEXT": { - json += ""; - json += "{"; - json += `"messageType":"TEXT"`; - json += `,"id":`; - if (input.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.id.length; i++) { - __point__ = input.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.id}"`; - } else { - json += `"${__result__}${input.id.slice(__last__)}"`; - } - } - } else if ( - input.id.length < 5000 && - !STR_ESCAPE.test(input.id) - ) { - json += `"${input.id}"`; - } else { - json += JSON.stringify(input.id); - } - json += `,"channelId":`; - if (input.channelId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.channelId.length; i++) { - __point__ = input.channelId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.channelId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.channelId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.channelId}"`; - } else { - json += `"${__result__}${input.channelId.slice(__last__)}"`; - } - } - } else if ( - input.channelId.length < 5000 && - !STR_ESCAPE.test(input.channelId) - ) { - json += `"${input.channelId}"`; - } else { - json += JSON.stringify(input.channelId); - } - json += `,"userId":`; - if (input.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.userId.length; i++) { - __point__ = input.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.userId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.userId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.userId}"`; - } else { - json += `"${__result__}${input.userId.slice(__last__)}"`; - } - } - } else if ( - input.userId.length < 5000 && - !STR_ESCAPE.test(input.userId) - ) { - json += `"${input.userId}"`; - } else { - json += JSON.stringify(input.userId); - } - json += `,"date":"${input.date.toISOString()}"`; - json += `,"text":`; - if (input.text.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.text.length; i++) { - __point__ = input.text.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.text); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.text.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.text}"`; - } else { - json += `"${__result__}${input.text.slice(__last__)}"`; - } - } - } else if ( - input.text.length < 5000 && - !STR_ESCAPE.test(input.text) - ) { - json += `"${input.text}"`; - } else { - json += JSON.stringify(input.text); - } - json += "}"; - break; +export interface AutoReconnectResponse { + count: number; + message: string; +} +export const $$AutoReconnectResponse: ArriModelValidator = + { + new(): AutoReconnectResponse { + return { + count: 0, + message: "", + }; + }, + validate(input): input is AutoReconnectResponse { + return ( + isObject(input) && + typeof input.count === "number" && + Number.isInteger(input.count) && + input.count >= 0 && + input.count <= UINT8_MAX && + typeof input.message === "string" + ); + }, + fromJson(input): AutoReconnectResponse { + let _count: number; + if ( + typeof input.count === "number" && + Number.isInteger(input.count) && + input.count >= 0 && + input.count <= UINT8_MAX + ) { + _count = input.count; + } else { + _count = 0; } - case "IMAGE": { - json += ""; - json += "{"; - json += `"messageType":"IMAGE"`; - json += `,"id":`; - if (input.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.id.length; i++) { - __point__ = input.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.id}"`; - } else { - json += `"${__result__}${input.id.slice(__last__)}"`; - } - } - } else if ( - input.id.length < 5000 && - !STR_ESCAPE.test(input.id) - ) { - json += `"${input.id}"`; - } else { - json += JSON.stringify(input.id); - } - json += `,"channelId":`; - if (input.channelId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.channelId.length; i++) { - __point__ = input.channelId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.channelId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.channelId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.channelId}"`; - } else { - json += `"${__result__}${input.channelId.slice(__last__)}"`; - } - } - } else if ( - input.channelId.length < 5000 && - !STR_ESCAPE.test(input.channelId) - ) { - json += `"${input.channelId}"`; - } else { - json += JSON.stringify(input.channelId); - } - json += `,"userId":`; - if (input.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.userId.length; i++) { - __point__ = input.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.userId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.userId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.userId}"`; - } else { - json += `"${__result__}${input.userId.slice(__last__)}"`; - } - } - } else if ( - input.userId.length < 5000 && - !STR_ESCAPE.test(input.userId) - ) { - json += `"${input.userId}"`; - } else { - json += JSON.stringify(input.userId); - } - json += `,"date":"${input.date.toISOString()}"`; - json += `,"image":`; - if (input.image.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.image.length; i++) { - __point__ = input.image.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.image); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.image.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.image}"`; - } else { - json += `"${__result__}${input.image.slice(__last__)}"`; - } - } - } else if ( - input.image.length < 5000 && - !STR_ESCAPE.test(input.image) - ) { - json += `"${input.image}"`; - } else { - json += JSON.stringify(input.image); - } - json += "}"; - break; + let _message: string; + if (typeof input.message === "string") { + _message = input.message; + } else { + _message = ""; + } + return { + count: _count, + message: _message, + }; + }, + fromJsonString(input): AutoReconnectResponse { + return $$AutoReconnectResponse.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"count":'; + json += `${input.count}`; + json += ',"message":'; + json += serializeString(input.message); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`count=${input.count}`); + queryParts.push(`message=${input.message}`); + return queryParts.join("&"); + }, + }; + +export interface StreamConnectionErrorTestParams { + statusCode: number; + statusMessage: string; +} +export const $$StreamConnectionErrorTestParams: ArriModelValidator = + { + new(): StreamConnectionErrorTestParams { + return { + statusCode: 0, + statusMessage: "", + }; + }, + validate(input): input is StreamConnectionErrorTestParams { + return ( + isObject(input) && + typeof input.statusCode === "number" && + Number.isInteger(input.statusCode) && + input.statusCode >= INT32_MIN && + input.statusCode <= INT32_MAX && + typeof input.statusMessage === "string" + ); + }, + fromJson(input): StreamConnectionErrorTestParams { + let _statusCode: number; + if ( + typeof input.statusCode === "number" && + Number.isInteger(input.statusCode) && + input.statusCode >= INT32_MIN && + input.statusCode <= INT32_MAX + ) { + _statusCode = input.statusCode; + } else { + _statusCode = 0; } - case "URL": { - json += ""; - json += "{"; - json += `"messageType":"URL"`; - json += `,"id":`; - if (input.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.id.length; i++) { - __point__ = input.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.id.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.id}"`; - } else { - json += `"${__result__}${input.id.slice(__last__)}"`; - } - } - } else if ( - input.id.length < 5000 && - !STR_ESCAPE.test(input.id) - ) { - json += `"${input.id}"`; - } else { - json += JSON.stringify(input.id); - } - json += `,"channelId":`; - if (input.channelId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.channelId.length; i++) { - __point__ = input.channelId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.channelId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.channelId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.channelId}"`; - } else { - json += `"${__result__}${input.channelId.slice(__last__)}"`; - } - } - } else if ( - input.channelId.length < 5000 && - !STR_ESCAPE.test(input.channelId) - ) { - json += `"${input.channelId}"`; - } else { - json += JSON.stringify(input.channelId); - } - json += `,"userId":`; - if (input.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.userId.length; i++) { - __point__ = input.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.userId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.userId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.userId}"`; - } else { - json += `"${__result__}${input.userId.slice(__last__)}"`; - } + let _statusMessage: string; + if (typeof input.statusMessage === "string") { + _statusMessage = input.statusMessage; + } else { + _statusMessage = ""; + } + return { + statusCode: _statusCode, + statusMessage: _statusMessage, + }; + }, + fromJsonString(input): StreamConnectionErrorTestParams { + return $$StreamConnectionErrorTestParams.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"statusCode":'; + json += `${input.statusCode}`; + json += ',"statusMessage":'; + json += serializeString(input.statusMessage); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`statusCode=${input.statusCode}`); + queryParts.push(`statusMessage=${input.statusMessage}`); + return queryParts.join("&"); + }, + }; + +export interface StreamConnectionErrorTestResponse { + message: string; +} +export const $$StreamConnectionErrorTestResponse: ArriModelValidator = + { + new(): StreamConnectionErrorTestResponse { + return { + message: "", + }; + }, + validate(input): input is StreamConnectionErrorTestResponse { + return isObject(input) && typeof input.message === "string"; + }, + fromJson(input): StreamConnectionErrorTestResponse { + let _message: string; + if (typeof input.message === "string") { + _message = input.message; + } else { + _message = ""; + } + return { + message: _message, + }; + }, + fromJsonString(input): StreamConnectionErrorTestResponse { + return $$StreamConnectionErrorTestResponse.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"message":'; + json += serializeString(input.message); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`message=${input.message}`); + return queryParts.join("&"); + }, + }; + +export interface StreamLargeObjectsResponse { + numbers: number[]; + objects: StreamLargeObjectsResponseObjectselement[]; +} +export const $$StreamLargeObjectsResponse: ArriModelValidator = + { + new(): StreamLargeObjectsResponse { + return { + numbers: [], + objects: [], + }; + }, + validate(input): input is StreamLargeObjectsResponse { + return ( + isObject(input) && + Array.isArray(input.numbers) && + input.numbers.every( + (_element) => typeof _element === "number", + ) && + Array.isArray(input.objects) && + input.objects.every((_element) => + $$StreamLargeObjectsResponseObjectselement.validate( + _element, + ), + ) + ); + }, + fromJson(input): StreamLargeObjectsResponse { + let _numbers: number[]; + if (Array.isArray(input.numbers)) { + _numbers = []; + for (const _numbersEl of input.numbers) { + let _numbersElValue: number; + if (typeof _numbersEl === "number") { + _numbersElValue = _numbersEl; + } else { + _numbersElValue = 0; } - } else if ( - input.userId.length < 5000 && - !STR_ESCAPE.test(input.userId) - ) { - json += `"${input.userId}"`; - } else { - json += JSON.stringify(input.userId); + _numbers.push(_numbersElValue); } - json += `,"date":"${input.date.toISOString()}"`; - json += `,"url":`; - if (input.url.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.url.length; i++) { - __point__ = input.url.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.url); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.url.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.url}"`; - } else { - json += `"${__result__}${input.url.slice(__last__)}"`; - } + } else { + _numbers = []; + } + let _objects: StreamLargeObjectsResponseObjectselement[]; + if (Array.isArray(input.objects)) { + _objects = []; + for (const _objectsEl of input.objects) { + let _objectsElValue: StreamLargeObjectsResponseObjectselement; + if (isObject(_objectsEl)) { + _objectsElValue = + $$StreamLargeObjectsResponseObjectselement.fromJson( + _objectsEl, + ); + } else { + _objectsElValue = + $$StreamLargeObjectsResponseObjectselement.new(); } - } else if ( - input.url.length < 5000 && - !STR_ESCAPE.test(input.url) - ) { - json += `"${input.url}"`; - } else { - json += JSON.stringify(input.url); + _objects.push(_objectsElValue); } - json += "}"; - break; + } else { + _objects = []; + } + return { + numbers: _numbers, + objects: _objects, + }; + }, + fromJsonString(input): StreamLargeObjectsResponse { + return $$StreamLargeObjectsResponse.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"numbers":'; + json += "["; + for (let i = 0; i < input.numbers.length; i++) { + if (i !== 0) json += ","; + const _inputNumbersEl = input.numbers[i]; + json += `${_inputNumbersEl}`; } + json += "]"; + json += ',"objects":'; + json += "["; + for (let i = 0; i < input.objects.length; i++) { + if (i !== 0) json += ","; + const _inputObjectsEl = input.objects[i]; + json += + $$StreamLargeObjectsResponseObjectselement.toJsonString( + _inputObjectsEl, + ); + } + json += "]"; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /StreamLargeObjectsResponse/numbers.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /StreamLargeObjectsResponse/objects.", + ); + return queryParts.join("&"); + }, + }; + +export interface StreamLargeObjectsResponseObjectselement { + id: string; + name: string; + email: string; +} +export const $$StreamLargeObjectsResponseObjectselement: ArriModelValidator = + { + new(): StreamLargeObjectsResponseObjectselement { + return { + id: "", + name: "", + email: "", + }; + }, + validate(input): input is StreamLargeObjectsResponseObjectselement { + return ( + isObject(input) && + typeof input.id === "string" && + typeof input.name === "string" && + typeof input.email === "string" + ); + }, + fromJson(input): StreamLargeObjectsResponseObjectselement { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _name: string; + if (typeof input.name === "string") { + _name = input.name; + } else { + _name = ""; + } + let _email: string; + if (typeof input.email === "string") { + _email = input.email; + } else { + _email = ""; + } + return { + id: _id, + name: _name, + email: _email, + }; + }, + fromJsonString(input): StreamLargeObjectsResponseObjectselement { + return $$StreamLargeObjectsResponseObjectselement.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"name":'; + json += serializeString(input.name); + json += ',"email":'; + json += serializeString(input.email); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`name=${input.name}`); + queryParts.push(`email=${input.email}`); + return queryParts.join("&"); + }, + }; + +export interface ChatMessageParams { + channelId: string; +} +export const $$ChatMessageParams: ArriModelValidator = { + new(): ChatMessageParams { + return { + channelId: "", + }; + }, + validate(input): input is ChatMessageParams { + return isObject(input) && typeof input.channelId === "string"; + }, + fromJson(input): ChatMessageParams { + let _channelId: string; + if (typeof input.channelId === "string") { + _channelId = input.channelId; + } else { + _channelId = ""; } + return { + channelId: _channelId, + }; + }, + fromJsonString(input): ChatMessageParams { + return $$ChatMessageParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"channelId":'; + json += serializeString(input.channelId); + json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`channelId=${input.channelId}`); + return queryParts.join("&"); + }, +}; + +export type ChatMessage = ChatMessageText | ChatMessageImage | ChatMessageUrl; +export const $$ChatMessage: ArriModelValidator = { + new(): ChatMessage { + return $$ChatMessageText.new(); + }, + validate(input): input is ChatMessage { + if (!isObject(input)) { + return false; + } + if (typeof input.messageType !== "string") { + return false; + } + switch (input.messageType) { + case "TEXT": + return $$ChatMessageText.validate(input); + case "IMAGE": + return $$ChatMessageImage.validate(input); + case "URL": + return $$ChatMessageUrl.validate(input); + default: + return false; + } + }, + fromJson(input): ChatMessage { + switch (input.messageType) { + case "TEXT": + return $$ChatMessageText.fromJson(input); + case "IMAGE": + return $$ChatMessageImage.fromJson(input); + case "URL": + return $$ChatMessageUrl.fromJson(input); + default: + return $$ChatMessageText.new(); + } + }, + fromJsonString(input): ChatMessage { + return $$ChatMessage.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + switch (input.messageType) { + case "TEXT": + return $$ChatMessageText.toJsonString(input); + case "IMAGE": + return $$ChatMessageImage.toJsonString(input); + case "URL": + return $$ChatMessageUrl.toJsonString(input); + default: + throw new Error( + `Unhandled case "${(input as any).messageType}"`, + ); + } + }, + toUrlQueryString(input): string { + switch (input.messageType) { + case "TEXT": + return $$ChatMessageText.toUrlQueryString(input); + case "IMAGE": + return $$ChatMessageImage.toUrlQueryString(input); + case "URL": + return $$ChatMessageUrl.toUrlQueryString(input); + default: + throw new Error("Unhandled case"); + } + }, }; export interface ChatMessageText { messageType: "TEXT"; @@ -10293,6 +5403,101 @@ export interface ChatMessageText { date: Date; text: string; } +const $$ChatMessageText: ArriModelValidator = { + new(): ChatMessageText { + return { + messageType: "TEXT", + id: "", + channelId: "", + userId: "", + date: new Date(), + text: "", + }; + }, + validate(input): input is ChatMessageText { + return ( + isObject(input) && + input.messageType === "TEXT" && + typeof input.id === "string" && + typeof input.channelId === "string" && + typeof input.userId === "string" && + input.date instanceof Date && + typeof input.text === "string" + ); + }, + fromJson(input): ChatMessageText { + const _messageType = "TEXT"; + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _channelId: string; + if (typeof input.channelId === "string") { + _channelId = input.channelId; + } else { + _channelId = ""; + } + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + let _date: Date; + if (typeof input.date === "string") { + _date = new Date(input.date); + } else if (input.date instanceof Date) { + _date = input.date; + } else { + _date = new Date(); + } + let _text: string; + if (typeof input.text === "string") { + _text = input.text; + } else { + _text = ""; + } + return { + messageType: _messageType, + id: _id, + channelId: _channelId, + userId: _userId, + date: _date, + text: _text, + }; + }, + fromJsonString(input): ChatMessageText { + return $$ChatMessageText.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"messageType":"TEXT"'; + json += ',"id":'; + json += serializeString(input.id); + json += ',"channelId":'; + json += serializeString(input.channelId); + json += ',"userId":'; + json += serializeString(input.userId); + json += ',"date":'; + json += `"${input.date.toISOString()}"`; + json += ',"text":'; + json += serializeString(input.text); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("messageType=TEXT"); + queryParts.push(`id=${input.id}`); + queryParts.push(`channelId=${input.channelId}`); + queryParts.push(`userId=${input.userId}`); + queryParts.push(`date=${input.date.toISOString()}`); + queryParts.push(`text=${input.text}`); + return queryParts.join("&"); + }, +}; export interface ChatMessageImage { messageType: "IMAGE"; @@ -10302,534 +5507,313 @@ export interface ChatMessageImage { date: Date; image: string; } - -export interface ChatMessageUrl { - messageType: "URL"; - id: string; - channelId: string; - userId: string; - date: Date; - url: string; -} - -export interface TestsStreamRetryWithNewCredentialsResponse { - message: string; -} -export const $$TestsStreamRetryWithNewCredentialsResponse = { - parse(input: Record): TestsStreamRetryWithNewCredentialsResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); +const $$ChatMessageImage: ArriModelValidator = { + new(): ChatMessageImage { + return { + messageType: "IMAGE", + id: "", + channelId: "", + userId: "", + date: new Date(), + image: "", + }; + }, + validate(input): input is ChatMessageImage { + return ( + isObject(input) && + input.messageType === "IMAGE" && + typeof input.id === "string" && + typeof input.channelId === "string" && + typeof input.userId === "string" && + input.date instanceof Date && + typeof input.image === "string" + ); + }, + fromJson(input): ChatMessageImage { + const _messageType = "IMAGE"; + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.message === "string") { - __D1.message = json.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; + let _channelId: string; + if (typeof input.channelId === "string") { + _channelId = input.channelId; + } else { + _channelId = ""; } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.message === "string") { - __D1.message = input.message; - } else { - $fallback( - "/message", - "/properties/message/type", - "Expected string at /message", - ); - } - result = __D1; + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + let _date: Date; + if (typeof input.date === "string") { + _date = new Date(input.date); + } else if (input.date instanceof Date) { + _date = input.date; } else { - $fallback("", "", "Expected object"); + _date = new Date(); } - return result; + let _image: string; + if (typeof input.image === "string") { + _image = input.image; + } else { + _image = ""; + } + return { + messageType: _messageType, + id: _id, + channelId: _channelId, + userId: _userId, + date: _date, + image: _image, + }; }, - serialize(input: TestsStreamRetryWithNewCredentialsResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + fromJsonString(input): ChatMessageImage { + return $$ChatMessageImage.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"messageType":"IMAGE"'; + json += ',"id":'; + json += serializeString(input.id); + json += ',"channelId":'; + json += serializeString(input.channelId); + json += ',"userId":'; + json += serializeString(input.userId); + json += ',"date":'; + json += `"${input.date.toISOString()}"`; + json += ',"image":'; + json += serializeString(input.image); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("messageType=IMAGE"); + queryParts.push(`id=${input.id}`); + queryParts.push(`channelId=${input.channelId}`); + queryParts.push(`userId=${input.userId}`); + queryParts.push(`date=${input.date.toISOString()}`); + queryParts.push(`image=${input.image}`); + return queryParts.join("&"); + }, +}; - json += ""; - json += "{"; - json += `"message":`; - if (input.message.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.message.length; i++) { - __point__ = input.message.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.message); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.message.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.message}"`; - } else { - json += `"${__result__}${input.message.slice(__last__)}"`; - } - } - } else if ( - input.message.length < 5000 && - !STR_ESCAPE.test(input.message) - ) { - json += `"${input.message}"`; +export interface ChatMessageUrl { + messageType: "URL"; + id: string; + channelId: string; + userId: string; + date: Date; + url: string; +} +const $$ChatMessageUrl: ArriModelValidator = { + new(): ChatMessageUrl { + return { + messageType: "URL", + id: "", + channelId: "", + userId: "", + date: new Date(), + url: "", + }; + }, + validate(input): input is ChatMessageUrl { + return ( + isObject(input) && + input.messageType === "URL" && + typeof input.id === "string" && + typeof input.channelId === "string" && + typeof input.userId === "string" && + input.date instanceof Date && + typeof input.url === "string" + ); + }, + fromJson(input): ChatMessageUrl { + const _messageType = "URL"; + let _id: string; + if (typeof input.id === "string") { + _id = input.id; + } else { + _id = ""; + } + let _channelId: string; + if (typeof input.channelId === "string") { + _channelId = input.channelId; } else { - json += JSON.stringify(input.message); + _channelId = ""; } + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + let _date: Date; + if (typeof input.date === "string") { + _date = new Date(input.date); + } else if (input.date instanceof Date) { + _date = input.date; + } else { + _date = new Date(); + } + let _url: string; + if (typeof input.url === "string") { + _url = input.url; + } else { + _url = ""; + } + return { + messageType: _messageType, + id: _id, + channelId: _channelId, + userId: _userId, + date: _date, + url: _url, + }; + }, + fromJsonString(input): ChatMessageUrl { + return $$ChatMessageUrl.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"messageType":"URL"'; + json += ',"id":'; + json += serializeString(input.id); + json += ',"channelId":'; + json += serializeString(input.channelId); + json += ',"userId":'; + json += serializeString(input.userId); + json += ',"date":'; + json += `"${input.date.toISOString()}"`; + json += ',"url":'; + json += serializeString(input.url); json += "}"; return json; }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("messageType=URL"); + queryParts.push(`id=${input.id}`); + queryParts.push(`channelId=${input.channelId}`); + queryParts.push(`userId=${input.userId}`); + queryParts.push(`date=${input.date.toISOString()}`); + queryParts.push(`url=${input.url}`); + return queryParts.join("&"); + }, }; +export interface TestsStreamRetryWithNewCredentialsResponse { + message: string; +} +export const $$TestsStreamRetryWithNewCredentialsResponse: ArriModelValidator = + { + new(): TestsStreamRetryWithNewCredentialsResponse { + return { + message: "", + }; + }, + validate(input): input is TestsStreamRetryWithNewCredentialsResponse { + return isObject(input) && typeof input.message === "string"; + }, + fromJson(input): TestsStreamRetryWithNewCredentialsResponse { + let _message: string; + if (typeof input.message === "string") { + _message = input.message; + } else { + _message = ""; + } + return { + message: _message, + }; + }, + fromJsonString(input): TestsStreamRetryWithNewCredentialsResponse { + return $$TestsStreamRetryWithNewCredentialsResponse.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"message":'; + json += serializeString(input.message); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`message=${input.message}`); + return queryParts.join("&"); + }, + }; + export type WsMessageParams = | WsMessageParamsCreateEntity | WsMessageParamsUpdateEntity | WsMessageParamsDisconnect; -export const $$WsMessageParams = { - parse(input: Record): WsMessageParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); +export const $$WsMessageParams: ArriModelValidator = { + new(): WsMessageParams { + return $$WsMessageParamsCreateEntity.new(); + }, + validate(input): input is WsMessageParams { + if (!isObject(input)) { + return false; } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - switch (json.type) { - case "CREATE_ENTITY": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.type = "CREATE_ENTITY"; - if (typeof json.entityId === "string") { - __D1.entityId = json.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof json.x === "number" && - !Number.isNaN(json.x) - ) { - __D1.x = json.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof json.y === "number" && - !Number.isNaN(json.y) - ) { - __D1.y = json.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "UPDATE_ENTITY": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.type = "UPDATE_ENTITY"; - if (typeof json.entityId === "string") { - __D1.entityId = json.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof json.x === "number" && - !Number.isNaN(json.x) - ) { - __D1.x = json.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof json.y === "number" && - !Number.isNaN(json.y) - ) { - __D1.y = json.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "DISCONNECT": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.type = "DISCONNECT"; - if (typeof json.reason === "string") { - __D1.reason = json.reason; - } else { - $fallback( - "/reason", - "/mapping/properties/reason/type", - "Expected string at /reason", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "json.type did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); - } - return result; + if (typeof input.type !== "string") { + return false; } - let result = {}; - if (typeof input === "object" && input !== null) { - switch (input.type) { - case "CREATE_ENTITY": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.type = "CREATE_ENTITY"; - if (typeof input.entityId === "string") { - __D1.entityId = input.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof input.x === "number" && - !Number.isNaN(input.x) - ) { - __D1.x = input.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof input.y === "number" && - !Number.isNaN(input.y) - ) { - __D1.y = input.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "UPDATE_ENTITY": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.type = "UPDATE_ENTITY"; - if (typeof input.entityId === "string") { - __D1.entityId = input.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof input.x === "number" && - !Number.isNaN(input.x) - ) { - __D1.x = input.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof input.y === "number" && - !Number.isNaN(input.y) - ) { - __D1.y = input.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "DISCONNECT": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.type = "DISCONNECT"; - if (typeof input.reason === "string") { - __D1.reason = input.reason; - } else { - $fallback( - "/reason", - "/mapping/properties/reason/type", - "Expected string at /reason", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "input.type did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); + switch (input.type) { + case "CREATE_ENTITY": + return $$WsMessageParamsCreateEntity.validate(input); + case "UPDATE_ENTITY": + return $$WsMessageParamsUpdateEntity.validate(input); + case "DISCONNECT": + return $$WsMessageParamsDisconnect.validate(input); + default: + return false; } - return result; }, - serialize(input: WsMessageParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + fromJson(input): WsMessageParams { switch (input.type) { - case "CREATE_ENTITY": { - json += ""; - json += "{"; - json += `"type":"CREATE_ENTITY"`; - json += `,"entityId":`; - if (input.entityId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.entityId.length; i++) { - __point__ = input.entityId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.entityId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.entityId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.entityId}"`; - } else { - json += `"${__result__}${input.entityId.slice(__last__)}"`; - } - } - } else if ( - input.entityId.length < 5000 && - !STR_ESCAPE.test(input.entityId) - ) { - json += `"${input.entityId}"`; - } else { - json += JSON.stringify(input.entityId); - } - - if (Number.isNaN(input.x)) { - throw new Error("Expected number at /x got NaN"); - } - json += `,"x":${input.x}`; - - if (Number.isNaN(input.y)) { - throw new Error("Expected number at /y got NaN"); - } - json += `,"y":${input.y}`; - json += "}"; - break; - } - case "UPDATE_ENTITY": { - json += ""; - json += "{"; - json += `"type":"UPDATE_ENTITY"`; - json += `,"entityId":`; - if (input.entityId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.entityId.length; i++) { - __point__ = input.entityId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.entityId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.entityId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.entityId}"`; - } else { - json += `"${__result__}${input.entityId.slice(__last__)}"`; - } - } - } else if ( - input.entityId.length < 5000 && - !STR_ESCAPE.test(input.entityId) - ) { - json += `"${input.entityId}"`; - } else { - json += JSON.stringify(input.entityId); - } - - if (Number.isNaN(input.x)) { - throw new Error("Expected number at /x got NaN"); - } - json += `,"x":${input.x}`; - - if (Number.isNaN(input.y)) { - throw new Error("Expected number at /y got NaN"); - } - json += `,"y":${input.y}`; - json += "}"; - break; - } - case "DISCONNECT": { - json += ""; - json += "{"; - json += `"type":"DISCONNECT"`; - json += `,"reason":`; - if (input.reason.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.reason.length; i++) { - __point__ = input.reason.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.reason); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.reason.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.reason}"`; - } else { - json += `"${__result__}${input.reason.slice(__last__)}"`; - } - } - } else if ( - input.reason.length < 5000 && - !STR_ESCAPE.test(input.reason) - ) { - json += `"${input.reason}"`; - } else { - json += JSON.stringify(input.reason); - } - json += "}"; - break; - } + case "CREATE_ENTITY": + return $$WsMessageParamsCreateEntity.fromJson(input); + case "UPDATE_ENTITY": + return $$WsMessageParamsUpdateEntity.fromJson(input); + case "DISCONNECT": + return $$WsMessageParamsDisconnect.fromJson(input); + default: + return $$WsMessageParamsCreateEntity.new(); + } + }, + fromJsonString(input): WsMessageParams { + return $$WsMessageParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + switch (input.type) { + case "CREATE_ENTITY": + return $$WsMessageParamsCreateEntity.toJsonString(input); + case "UPDATE_ENTITY": + return $$WsMessageParamsUpdateEntity.toJsonString(input); + case "DISCONNECT": + return $$WsMessageParamsDisconnect.toJsonString(input); + default: + throw new Error(`Unhandled case "${(input as any).type}"`); + } + }, + toUrlQueryString(input): string { + switch (input.type) { + case "CREATE_ENTITY": + return $$WsMessageParamsCreateEntity.toUrlQueryString(input); + case "UPDATE_ENTITY": + return $$WsMessageParamsUpdateEntity.toUrlQueryString(input); + case "DISCONNECT": + return $$WsMessageParamsDisconnect.toUrlQueryString(input); + default: + throw new Error("Unhandled case"); } - return json; }, }; export interface WsMessageParamsCreateEntity { @@ -10838,6 +5822,76 @@ export interface WsMessageParamsCreateEntity { x: number; y: number; } +const $$WsMessageParamsCreateEntity: ArriModelValidator = + { + new(): WsMessageParamsCreateEntity { + return { + type: "CREATE_ENTITY", + entityId: "", + x: 0, + y: 0, + }; + }, + validate(input): input is WsMessageParamsCreateEntity { + return ( + isObject(input) && + input.type === "CREATE_ENTITY" && + typeof input.entityId === "string" && + typeof input.x === "number" && + typeof input.y === "number" + ); + }, + fromJson(input): WsMessageParamsCreateEntity { + const _type = "CREATE_ENTITY"; + let _entityId: string; + if (typeof input.entityId === "string") { + _entityId = input.entityId; + } else { + _entityId = ""; + } + let _x: number; + if (typeof input.x === "number") { + _x = input.x; + } else { + _x = 0; + } + let _y: number; + if (typeof input.y === "number") { + _y = input.y; + } else { + _y = 0; + } + return { + type: _type, + entityId: _entityId, + x: _x, + y: _y, + }; + }, + fromJsonString(input): WsMessageParamsCreateEntity { + return $$WsMessageParamsCreateEntity.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"CREATE_ENTITY"'; + json += ',"entityId":'; + json += serializeString(input.entityId); + json += ',"x":'; + json += `${input.x}`; + json += ',"y":'; + json += `${input.y}`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=CREATE_ENTITY"); + queryParts.push(`entityId=${input.entityId}`); + queryParts.push(`x=${input.x}`); + queryParts.push(`y=${input.y}`); + return queryParts.join("&"); + }, + }; export interface WsMessageParamsUpdateEntity { type: "UPDATE_ENTITY"; @@ -10845,347 +5899,183 @@ export interface WsMessageParamsUpdateEntity { x: number; y: number; } +const $$WsMessageParamsUpdateEntity: ArriModelValidator = + { + new(): WsMessageParamsUpdateEntity { + return { + type: "UPDATE_ENTITY", + entityId: "", + x: 0, + y: 0, + }; + }, + validate(input): input is WsMessageParamsUpdateEntity { + return ( + isObject(input) && + input.type === "UPDATE_ENTITY" && + typeof input.entityId === "string" && + typeof input.x === "number" && + typeof input.y === "number" + ); + }, + fromJson(input): WsMessageParamsUpdateEntity { + const _type = "UPDATE_ENTITY"; + let _entityId: string; + if (typeof input.entityId === "string") { + _entityId = input.entityId; + } else { + _entityId = ""; + } + let _x: number; + if (typeof input.x === "number") { + _x = input.x; + } else { + _x = 0; + } + let _y: number; + if (typeof input.y === "number") { + _y = input.y; + } else { + _y = 0; + } + return { + type: _type, + entityId: _entityId, + x: _x, + y: _y, + }; + }, + fromJsonString(input): WsMessageParamsUpdateEntity { + return $$WsMessageParamsUpdateEntity.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"UPDATE_ENTITY"'; + json += ',"entityId":'; + json += serializeString(input.entityId); + json += ',"x":'; + json += `${input.x}`; + json += ',"y":'; + json += `${input.y}`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=UPDATE_ENTITY"); + queryParts.push(`entityId=${input.entityId}`); + queryParts.push(`x=${input.x}`); + queryParts.push(`y=${input.y}`); + return queryParts.join("&"); + }, + }; export interface WsMessageParamsDisconnect { type: "DISCONNECT"; reason: string; } +const $$WsMessageParamsDisconnect: ArriModelValidator = + { + new(): WsMessageParamsDisconnect { + return { + type: "DISCONNECT", + reason: "", + }; + }, + validate(input): input is WsMessageParamsDisconnect { + return ( + isObject(input) && + input.type === "DISCONNECT" && + typeof input.reason === "string" + ); + }, + fromJson(input): WsMessageParamsDisconnect { + const _type = "DISCONNECT"; + let _reason: string; + if (typeof input.reason === "string") { + _reason = input.reason; + } else { + _reason = ""; + } + return { + type: _type, + reason: _reason, + }; + }, + fromJsonString(input): WsMessageParamsDisconnect { + return $$WsMessageParamsDisconnect.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"DISCONNECT"'; + json += ',"reason":'; + json += serializeString(input.reason); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=DISCONNECT"); + queryParts.push(`reason=${input.reason}`); + return queryParts.join("&"); + }, + }; export type WsMessageResponse = | WsMessageResponseEntityCreated | WsMessageResponseEntityUpdated; -export const $$WsMessageResponse = { - parse(input: Record): WsMessageResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); +export const $$WsMessageResponse: ArriModelValidator = { + new(): WsMessageResponse { + return $$WsMessageResponseEntityCreated.new(); + }, + validate(input): input is WsMessageResponse { + if (!isObject(input)) { + return false; } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - switch (json.type) { - case "ENTITY_CREATED": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.type = "ENTITY_CREATED"; - if (typeof json.entityId === "string") { - __D1.entityId = json.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof json.x === "number" && - !Number.isNaN(json.x) - ) { - __D1.x = json.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof json.y === "number" && - !Number.isNaN(json.y) - ) { - __D1.y = json.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "ENTITY_UPDATED": { - if (typeof json === "object" && json !== null) { - const __D1 = {}; - __D1.type = "ENTITY_UPDATED"; - if (typeof json.entityId === "string") { - __D1.entityId = json.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof json.x === "number" && - !Number.isNaN(json.x) - ) { - __D1.x = json.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof json.y === "number" && - !Number.isNaN(json.y) - ) { - __D1.y = json.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "json.type did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); - } - return result; + if (typeof input.type !== "string") { + return false; } - let result = {}; - if (typeof input === "object" && input !== null) { - switch (input.type) { - case "ENTITY_CREATED": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.type = "ENTITY_CREATED"; - if (typeof input.entityId === "string") { - __D1.entityId = input.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof input.x === "number" && - !Number.isNaN(input.x) - ) { - __D1.x = input.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof input.y === "number" && - !Number.isNaN(input.y) - ) { - __D1.y = input.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - case "ENTITY_UPDATED": { - if (typeof input === "object" && input !== null) { - const __D1 = {}; - __D1.type = "ENTITY_UPDATED"; - if (typeof input.entityId === "string") { - __D1.entityId = input.entityId; - } else { - $fallback( - "/entityId", - "/mapping/properties/entityId/type", - "Expected string at /entityId", - ); - } - if ( - typeof input.x === "number" && - !Number.isNaN(input.x) - ) { - __D1.x = input.x; - } else { - $fallback( - "/x", - "/mapping/properties/x/type", - "Expected number at /x", - ); - } - if ( - typeof input.y === "number" && - !Number.isNaN(input.y) - ) { - __D1.y = input.y; - } else { - $fallback( - "/y", - "/mapping/properties/y/type", - "Expected number at /y", - ); - } - result = __D1; - } else { - $fallback("", "/mapping", "Expected object"); - } - break; - } - default: - $fallback( - "", - "/mapping", - "input.type did not match one of the specified values", - ); - break; - } - } else { - $fallback("", "", "Expected Object."); + switch (input.type) { + case "ENTITY_CREATED": + return $$WsMessageResponseEntityCreated.validate(input); + case "ENTITY_UPDATED": + return $$WsMessageResponseEntityUpdated.validate(input); + default: + return false; } - return result; }, - serialize(input: WsMessageResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; + fromJson(input): WsMessageResponse { switch (input.type) { - case "ENTITY_CREATED": { - json += ""; - json += "{"; - json += `"type":"ENTITY_CREATED"`; - json += `,"entityId":`; - if (input.entityId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.entityId.length; i++) { - __point__ = input.entityId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.entityId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.entityId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.entityId}"`; - } else { - json += `"${__result__}${input.entityId.slice(__last__)}"`; - } - } - } else if ( - input.entityId.length < 5000 && - !STR_ESCAPE.test(input.entityId) - ) { - json += `"${input.entityId}"`; - } else { - json += JSON.stringify(input.entityId); - } - - if (Number.isNaN(input.x)) { - throw new Error("Expected number at /x got NaN"); - } - json += `,"x":${input.x}`; - - if (Number.isNaN(input.y)) { - throw new Error("Expected number at /y got NaN"); - } - json += `,"y":${input.y}`; - json += "}"; - break; - } - case "ENTITY_UPDATED": { - json += ""; - json += "{"; - json += `"type":"ENTITY_UPDATED"`; - json += `,"entityId":`; - if (input.entityId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.entityId.length; i++) { - __point__ = input.entityId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.entityId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - input.entityId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.entityId}"`; - } else { - json += `"${__result__}${input.entityId.slice(__last__)}"`; - } - } - } else if ( - input.entityId.length < 5000 && - !STR_ESCAPE.test(input.entityId) - ) { - json += `"${input.entityId}"`; - } else { - json += JSON.stringify(input.entityId); - } - - if (Number.isNaN(input.x)) { - throw new Error("Expected number at /x got NaN"); - } - json += `,"x":${input.x}`; - - if (Number.isNaN(input.y)) { - throw new Error("Expected number at /y got NaN"); - } - json += `,"y":${input.y}`; - json += "}"; - break; - } + case "ENTITY_CREATED": + return $$WsMessageResponseEntityCreated.fromJson(input); + case "ENTITY_UPDATED": + return $$WsMessageResponseEntityUpdated.fromJson(input); + default: + return $$WsMessageResponseEntityCreated.new(); + } + }, + fromJsonString(input): WsMessageResponse { + return $$WsMessageResponse.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + switch (input.type) { + case "ENTITY_CREATED": + return $$WsMessageResponseEntityCreated.toJsonString(input); + case "ENTITY_UPDATED": + return $$WsMessageResponseEntityUpdated.toJsonString(input); + default: + throw new Error(`Unhandled case "${(input as any).type}"`); + } + }, + toUrlQueryString(input): string { + switch (input.type) { + case "ENTITY_CREATED": + return $$WsMessageResponseEntityCreated.toUrlQueryString(input); + case "ENTITY_UPDATED": + return $$WsMessageResponseEntityUpdated.toUrlQueryString(input); + default: + throw new Error("Unhandled case"); } - return json; }, }; export interface WsMessageResponseEntityCreated { @@ -11194,6 +6084,76 @@ export interface WsMessageResponseEntityCreated { x: number; y: number; } +const $$WsMessageResponseEntityCreated: ArriModelValidator = + { + new(): WsMessageResponseEntityCreated { + return { + type: "ENTITY_CREATED", + entityId: "", + x: 0, + y: 0, + }; + }, + validate(input): input is WsMessageResponseEntityCreated { + return ( + isObject(input) && + input.type === "ENTITY_CREATED" && + typeof input.entityId === "string" && + typeof input.x === "number" && + typeof input.y === "number" + ); + }, + fromJson(input): WsMessageResponseEntityCreated { + const _type = "ENTITY_CREATED"; + let _entityId: string; + if (typeof input.entityId === "string") { + _entityId = input.entityId; + } else { + _entityId = ""; + } + let _x: number; + if (typeof input.x === "number") { + _x = input.x; + } else { + _x = 0; + } + let _y: number; + if (typeof input.y === "number") { + _y = input.y; + } else { + _y = 0; + } + return { + type: _type, + entityId: _entityId, + x: _x, + y: _y, + }; + }, + fromJsonString(input): WsMessageResponseEntityCreated { + return $$WsMessageResponseEntityCreated.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"ENTITY_CREATED"'; + json += ',"entityId":'; + json += serializeString(input.entityId); + json += ',"x":'; + json += `${input.x}`; + json += ',"y":'; + json += `${input.y}`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=ENTITY_CREATED"); + queryParts.push(`entityId=${input.entityId}`); + queryParts.push(`x=${input.x}`); + queryParts.push(`y=${input.y}`); + return queryParts.join("&"); + }, + }; export interface WsMessageResponseEntityUpdated { type: "ENTITY_UPDATED"; @@ -11201,1537 +6161,451 @@ export interface WsMessageResponseEntityUpdated { x: number; y: number; } +const $$WsMessageResponseEntityUpdated: ArriModelValidator = + { + new(): WsMessageResponseEntityUpdated { + return { + type: "ENTITY_UPDATED", + entityId: "", + x: 0, + y: 0, + }; + }, + validate(input): input is WsMessageResponseEntityUpdated { + return ( + isObject(input) && + input.type === "ENTITY_UPDATED" && + typeof input.entityId === "string" && + typeof input.x === "number" && + typeof input.y === "number" + ); + }, + fromJson(input): WsMessageResponseEntityUpdated { + const _type = "ENTITY_UPDATED"; + let _entityId: string; + if (typeof input.entityId === "string") { + _entityId = input.entityId; + } else { + _entityId = ""; + } + let _x: number; + if (typeof input.x === "number") { + _x = input.x; + } else { + _x = 0; + } + let _y: number; + if (typeof input.y === "number") { + _y = input.y; + } else { + _y = 0; + } + return { + type: _type, + entityId: _entityId, + x: _x, + y: _y, + }; + }, + fromJsonString(input): WsMessageResponseEntityUpdated { + return $$WsMessageResponseEntityUpdated.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"type":"ENTITY_UPDATED"'; + json += ',"entityId":'; + json += serializeString(input.entityId); + json += ',"x":'; + json += `${input.x}`; + json += ',"y":'; + json += `${input.y}`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("type=ENTITY_UPDATED"); + queryParts.push(`entityId=${input.entityId}`); + queryParts.push(`x=${input.x}`); + queryParts.push(`y=${input.y}`); + return queryParts.join("&"); + }, + }; export interface UsersWatchUserParams { userId: string; } -export const $$UsersWatchUserParams = { - parse(input: Record): UsersWatchUserParams { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.userId === "string") { - __D1.userId = json.userId; - } else { - $fallback( - "/userId", - "/properties/userId/type", - "Expected string at /userId", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; +export const $$UsersWatchUserParams: ArriModelValidator = + { + new(): UsersWatchUserParams { + return { + userId: "", + }; + }, + validate(input): input is UsersWatchUserParams { + return isObject(input) && typeof input.userId === "string"; + }, + fromJson(input): UsersWatchUserParams { + let _userId: string; if (typeof input.userId === "string") { - __D1.userId = input.userId; - } else { - $fallback( - "/userId", - "/properties/userId/type", - "Expected string at /userId", - ); - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: UsersWatchUserParams): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"userId":`; - if (input.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.userId.length; i++) { - __point__ = input.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.userId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.userId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.userId}"`; - } else { - json += `"${__result__}${input.userId.slice(__last__)}"`; - } - } - } else if ( - input.userId.length < 5000 && - !STR_ESCAPE.test(input.userId) - ) { - json += `"${input.userId}"`; - } else { - json += JSON.stringify(input.userId); - } - json += "}"; - return json; - }, -}; + _userId = input.userId; + } else { + _userId = ""; + } + return { + userId: _userId, + }; + }, + fromJsonString(input): UsersWatchUserParams { + return $$UsersWatchUserParams.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"userId":'; + json += serializeString(input.userId); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`userId=${input.userId}`); + return queryParts.join("&"); + }, + }; export interface UsersWatchUserResponse { id: string; role: UsersWatchUserResponseRole; - /** - * A profile picture - */ photo: UserPhoto | null; createdAt: Date; numFollowers: number; settings: UserSettings; - recentNotifications: Array; - bookmarks: UsersWatchUserResponseBookmarks; - metadata: UsersWatchUserResponseMetadata; - randomList: Array; + recentNotifications: UsersWatchUserResponseRecentNotificationselement[]; + bookmarks: Record; + metadata: Record; + randomList: any[]; bio?: string; } -export const $$UsersWatchUserResponse = { - parse(input: Record): UsersWatchUserResponse { - function $fallback(instancePath, schemaPath) { - throw new Error( - `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`, - ); - } - - if (typeof input === "string") { - const json = JSON.parse(input); - let result = {}; - if (typeof json === "object" && json !== null) { - const __D1 = {}; - if (typeof json.id === "string") { - __D1.id = json.id; - } else { - $fallback( - "/id", - "/properties/id/type", - "Expected string at /id", - ); - } - if (typeof json.role === "string") { - if (json.role === "standard" || json.role === "admin") { - __D1.role = json.role; - } else { - $fallback( - "/role", - "/properties/role", - "Expected one of the following values: [standard, admin] at /role.", - ); - } - } else { - $fallback( - "/role", - "/properties/role", - "Expected one of the following values: [standard, admin] at /role.", - ); - } - if (json.photo === null) { - __D1.photo = null; - } else { - if (typeof json.photo === "object" && json.photo !== null) { - const __D2 = {}; - if (typeof json.photo.url === "string") { - __D2.url = json.photo.url; - } else { - $fallback( - "/photo/url", - "/properties/photo/properties/url/type", - "Expected string at /photo/url", - ); - } - if ( - typeof json.photo.width === "number" && - !Number.isNaN(json.photo.width) - ) { - __D2.width = json.photo.width; - } else { - $fallback( - "/photo/width", - "/properties/photo/properties/width/type", - "Expected number at /photo/width", - ); - } - if ( - typeof json.photo.height === "number" && - !Number.isNaN(json.photo.height) - ) { - __D2.height = json.photo.height; - } else { - $fallback( - "/photo/height", - "/properties/photo/properties/height/type", - "Expected number at /photo/height", - ); - } - if ( - typeof json.photo.bytes === "string" || - typeof json.photo.bytes === "number" - ) { - try { - const val = BigInt(json.photo.bytes); - __D2.bytes = val; - } catch (err) { - $fallback( - "/photo/bytes", - "/properties/photo/properties/bytes", - "Unable to parse BigInt from json.photo.bytes.", - ); - } - } else if (typeof json.photo.bytes === "bigint") { - __D2.bytes = json.photo.bytes; - } else { - $fallback( - "/photo/bytes", - "/properties/photo/properties/bytes", - "Expected BigInt or Integer string. Got ${json.photo.bytes}", - ); - } - if ( - typeof json.photo.nanoseconds === "string" || - typeof json.photo.nanoseconds === "number" - ) { - try { - const val = BigInt(json.photo.nanoseconds); - if (val >= BigInt("0")) { - __D2.nanoseconds = val; - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unable to parse BigInt from json.photo.nanoseconds.", - ); - } - } else if (typeof json.photo.nanoseconds === "bigint") { - if (json.photo.nanoseconds >= BigInt("0")) { - __D2.nanoseconds = json.photo.nanoseconds; - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Expected BigInt or Integer string. Got ${json.photo.nanoseconds}", - ); - } - __D1.photo = __D2; - } else { - $fallback( - "/photo", - "/properties/photo", - "Expected object", - ); - } - } - if ( - typeof json.createdAt === "object" && - json.createdAt instanceof Date - ) { - __D1.createdAt = json.createdAt; - } else if (typeof json.createdAt === "string") { - __D1.createdAt = new Date(json.createdAt); - } else { - $fallback( - "/createdAt", - "/properties/createdAt", - "Expected instanceof Date or ISO Date string at /createdAt", - ); - } - if ( - typeof json.numFollowers === "number" && - Number.isInteger(json.numFollowers) && - json.numFollowers >= -2147483648 && - json.numFollowers <= 2147483647 - ) { - __D1.numFollowers = json.numFollowers; - } else { - $fallback( - "/numFollowers", - "/properties/numFollowers", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - if ( - typeof json.settings === "object" && - json.settings !== null - ) { - const __D2 = {}; - if ( - typeof json.settings.notificationsEnabled === "boolean" - ) { - __D2.notificationsEnabled = - json.settings.notificationsEnabled; - } else { - $fallback( - "/settings/notificationsEnabled", - "/properties/settings/properties/notificationsEnabled/type", - "Expected boolean for /settings/notificationsEnabled", - ); - } - if (typeof json.settings.preferredTheme === "string") { - if ( - json.settings.preferredTheme === "dark-mode" || - json.settings.preferredTheme === "light-mode" || - json.settings.preferredTheme === "system" - ) { - __D2.preferredTheme = json.settings.preferredTheme; - } else { - $fallback( - "/settings/preferredTheme", - "/properties/settings/properties/preferredTheme", - "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.", - ); - } - } else { - $fallback( - "/settings/preferredTheme", - "/properties/settings/properties/preferredTheme", - "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.", - ); - } - __D1.settings = __D2; - } else { - $fallback( - "/settings", - "/properties/settings", - "Expected object", - ); - } - if (Array.isArray(json.recentNotifications)) { - const __D2 = []; - for (const __D2AItem of json.recentNotifications) { - let __D2AItemAResult; - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - switch (__D2AItem.notificationType) { - case "POST_LIKE": { - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - const __D3 = {}; - __D3.notificationType = "POST_LIKE"; - if ( - typeof __D2AItem.postId === "string" - ) { - __D3.postId = __D2AItem.postId; - } else { - $fallback( - "/recentNotifications/[0]/postId", - "/properties/recentNotifications/elements/mapping/properties/postId/type", - "Expected string at /recentNotifications/[0]/postId", - ); - } - if ( - typeof __D2AItem.userId === "string" - ) { - __D3.userId = __D2AItem.userId; - } else { - $fallback( - "/recentNotifications/[0]/userId", - "/properties/recentNotifications/elements/mapping/properties/userId/type", - "Expected string at /recentNotifications/[0]/userId", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "Expected object", - ); - } - break; - } - case "POST_COMMENT": { - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - const __D3 = {}; - __D3.notificationType = "POST_COMMENT"; - if ( - typeof __D2AItem.postId === "string" - ) { - __D3.postId = __D2AItem.postId; - } else { - $fallback( - "/recentNotifications/[0]/postId", - "/properties/recentNotifications/elements/mapping/properties/postId/type", - "Expected string at /recentNotifications/[0]/postId", - ); - } - if ( - typeof __D2AItem.userId === "string" - ) { - __D3.userId = __D2AItem.userId; - } else { - $fallback( - "/recentNotifications/[0]/userId", - "/properties/recentNotifications/elements/mapping/properties/userId/type", - "Expected string at /recentNotifications/[0]/userId", - ); - } - if ( - typeof __D2AItem.commentText === - "string" - ) { - __D3.commentText = - __D2AItem.commentText; - } else { - $fallback( - "/recentNotifications/[0]/commentText", - "/properties/recentNotifications/elements/mapping/properties/commentText/type", - "Expected string at /recentNotifications/[0]/commentText", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "__D2AItem.notificationType did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements", - "Expected Object.", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.recentNotifications = __D2; - } else { - $fallback( - "/recentNotifications", - "/properties/recentNotifications", - "Expected Array", - ); - } - if ( - typeof json.bookmarks === "object" && - json.bookmarks !== null - ) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(json.bookmarks)) { - let __D2RKeyRVal; - if ( - typeof json.bookmarks[__D2RKey] === "object" && - json.bookmarks[__D2RKey] !== null - ) { - const __D3 = {}; - if ( - typeof json.bookmarks[__D2RKey].postId === - "string" - ) { - __D3.postId = json.bookmarks[__D2RKey].postId; - } else { - $fallback( - "/bookmarks/[key]/postId", - "/properties/bookmarks/values/properties/postId/type", - "Expected string at /bookmarks/[key]/postId", - ); - } - if ( - typeof json.bookmarks[__D2RKey].userId === - "string" - ) { - __D3.userId = json.bookmarks[__D2RKey].userId; - } else { - $fallback( - "/bookmarks/[key]/userId", - "/properties/bookmarks/values/properties/userId/type", - "Expected string at /bookmarks/[key]/userId", - ); - } - __D2RKeyRVal = __D3; - } else { - $fallback( - "/bookmarks/[key]", - "/properties/bookmarks/values", - "Expected object", - ); - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.bookmarks = __D2RResult; - } else { - $fallback( - "/bookmarks", - "/properties/bookmarks", - "Expected object.", - ); - } - if ( - typeof json.metadata === "object" && - json.metadata !== null - ) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(json.metadata)) { - let __D2RKeyRVal; - __D2RKeyRVal = json.metadata[__D2RKey]; - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.metadata = __D2RResult; - } else { - $fallback( - "/metadata", - "/properties/metadata", - "Expected object.", - ); - } - if (Array.isArray(json.randomList)) { - const __D2 = []; - for (const __D2AItem of json.randomList) { - let __D2AItemAResult; - __D2AItemAResult = __D2AItem; - __D2.push(__D2AItemAResult); - } - __D1.randomList = __D2; - } else { - $fallback( - "/randomList", - "/properties/randomList", - "Expected Array", - ); - } - if (typeof json.bio === "undefined") { - // ignore undefined - } else { - if (typeof json.bio === "string") { - __D1.bio = json.bio; - } else { - $fallback( - "/bio", - "/optionalProperties/bio/type", - "Expected string at /bio", - ); - } - } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - } - let result = {}; - if (typeof input === "object" && input !== null) { - const __D1 = {}; - if (typeof input.id === "string") { - __D1.id = input.id; - } else { - $fallback( - "/id", - "/properties/id/type", - "Expected string at /id", - ); - } - if (typeof input.role === "string") { - if (input.role === "standard" || input.role === "admin") { - __D1.role = input.role; - } else { - $fallback( - "/role", - "/properties/role", - "Expected one of the following values: [standard, admin] at /role.", - ); - } - } else { - $fallback( - "/role", - "/properties/role", - "Expected one of the following values: [standard, admin] at /role.", - ); - } - if (input.photo === null) { - __D1.photo = null; - } else { - if (typeof input.photo === "object" && input.photo !== null) { - const __D2 = {}; - if (typeof input.photo.url === "string") { - __D2.url = input.photo.url; - } else { - $fallback( - "/photo/url", - "/properties/photo/properties/url/type", - "Expected string at /photo/url", - ); - } - if ( - typeof input.photo.width === "number" && - !Number.isNaN(input.photo.width) - ) { - __D2.width = input.photo.width; - } else { - $fallback( - "/photo/width", - "/properties/photo/properties/width/type", - "Expected number at /photo/width", - ); - } - if ( - typeof input.photo.height === "number" && - !Number.isNaN(input.photo.height) - ) { - __D2.height = input.photo.height; - } else { - $fallback( - "/photo/height", - "/properties/photo/properties/height/type", - "Expected number at /photo/height", - ); - } - if ( - typeof input.photo.bytes === "string" || - typeof input.photo.bytes === "number" - ) { - try { - const val = BigInt(input.photo.bytes); - __D2.bytes = val; - } catch (err) { - $fallback( - "/photo/bytes", - "/properties/photo/properties/bytes", - "Unable to parse BigInt from input.photo.bytes.", - ); - } - } else if (typeof input.photo.bytes === "bigint") { - __D2.bytes = input.photo.bytes; - } else { - $fallback( - "/photo/bytes", - "/properties/photo/properties/bytes", - "Expected BigInt or Integer string. Got ${input.photo.bytes}", - ); - } - if ( - typeof input.photo.nanoseconds === "string" || - typeof input.photo.nanoseconds === "number" - ) { - try { - const val = BigInt(input.photo.nanoseconds); - if (val >= BigInt("0")) { - __D2.nanoseconds = val; - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unsigned int must be greater than or equal to 0.", - ); - } - } catch (err) { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unable to parse BigInt from input.photo.nanoseconds.", - ); - } - } else if (typeof input.photo.nanoseconds === "bigint") { - if (input.photo.nanoseconds >= BigInt("0")) { - __D2.nanoseconds = input.photo.nanoseconds; - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Unsigned int must be greater than or equal to 0.", - ); - } - } else { - $fallback( - "/photo/nanoseconds", - "/properties/photo/properties/nanoseconds", - "Expected BigInt or Integer string. Got ${input.photo.nanoseconds}", - ); - } - __D1.photo = __D2; - } else { - $fallback("/photo", "/properties/photo", "Expected object"); - } - } - if ( - typeof input.createdAt === "object" && - input.createdAt instanceof Date - ) { - __D1.createdAt = input.createdAt; - } else if (typeof input.createdAt === "string") { - __D1.createdAt = new Date(input.createdAt); - } else { - $fallback( - "/createdAt", - "/properties/createdAt", - "Expected instanceof Date or ISO Date string at /createdAt", - ); - } - if ( +export const $$UsersWatchUserResponse: ArriModelValidator = + { + new(): UsersWatchUserResponse { + return { + id: "", + role: $$UsersWatchUserResponseRole.new(), + photo: null, + createdAt: new Date(), + numFollowers: 0, + settings: $$UserSettings.new(), + recentNotifications: [], + bookmarks: {}, + metadata: {}, + randomList: [], + }; + }, + validate(input): input is UsersWatchUserResponse { + return ( + isObject(input) && + typeof input.id === "string" && + $$UsersWatchUserResponseRole.validate(input.role) && + ($$UserPhoto.validate(input.photo) || input.photo === null) && + input.createdAt instanceof Date && typeof input.numFollowers === "number" && - Number.isInteger(input.numFollowers) && - input.numFollowers >= -2147483648 && - input.numFollowers <= 2147483647 - ) { - __D1.numFollowers = input.numFollowers; - } else { - $fallback( - "/numFollowers", - "/properties/numFollowers", - "Expected valid integer between -2147483648 and 2147483647", - ); - } - if (typeof input.settings === "object" && input.settings !== null) { - const __D2 = {}; - if (typeof input.settings.notificationsEnabled === "boolean") { - __D2.notificationsEnabled = - input.settings.notificationsEnabled; - } else { - $fallback( - "/settings/notificationsEnabled", - "/properties/settings/properties/notificationsEnabled/type", - "Expected boolean for /settings/notificationsEnabled", - ); - } - if (typeof input.settings.preferredTheme === "string") { - if ( - input.settings.preferredTheme === "dark-mode" || - input.settings.preferredTheme === "light-mode" || - input.settings.preferredTheme === "system" - ) { - __D2.preferredTheme = input.settings.preferredTheme; - } else { - $fallback( - "/settings/preferredTheme", - "/properties/settings/properties/preferredTheme", - "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.", - ); - } - } else { - $fallback( - "/settings/preferredTheme", - "/properties/settings/properties/preferredTheme", - "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.", - ); - } - __D1.settings = __D2; - } else { - $fallback( - "/settings", - "/properties/settings", - "Expected object", - ); - } - if (Array.isArray(input.recentNotifications)) { - const __D2 = []; - for (const __D2AItem of input.recentNotifications) { - let __D2AItemAResult; - if (typeof __D2AItem === "object" && __D2AItem !== null) { - switch (__D2AItem.notificationType) { - case "POST_LIKE": { - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - const __D3 = {}; - __D3.notificationType = "POST_LIKE"; - if (typeof __D2AItem.postId === "string") { - __D3.postId = __D2AItem.postId; - } else { - $fallback( - "/recentNotifications/[0]/postId", - "/properties/recentNotifications/elements/mapping/properties/postId/type", - "Expected string at /recentNotifications/[0]/postId", - ); - } - if (typeof __D2AItem.userId === "string") { - __D3.userId = __D2AItem.userId; - } else { - $fallback( - "/recentNotifications/[0]/userId", - "/properties/recentNotifications/elements/mapping/properties/userId/type", - "Expected string at /recentNotifications/[0]/userId", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "Expected object", - ); - } - break; - } - case "POST_COMMENT": { - if ( - typeof __D2AItem === "object" && - __D2AItem !== null - ) { - const __D3 = {}; - __D3.notificationType = "POST_COMMENT"; - if (typeof __D2AItem.postId === "string") { - __D3.postId = __D2AItem.postId; - } else { - $fallback( - "/recentNotifications/[0]/postId", - "/properties/recentNotifications/elements/mapping/properties/postId/type", - "Expected string at /recentNotifications/[0]/postId", - ); - } - if (typeof __D2AItem.userId === "string") { - __D3.userId = __D2AItem.userId; - } else { - $fallback( - "/recentNotifications/[0]/userId", - "/properties/recentNotifications/elements/mapping/properties/userId/type", - "Expected string at /recentNotifications/[0]/userId", - ); - } - if ( - typeof __D2AItem.commentText === - "string" - ) { - __D3.commentText = - __D2AItem.commentText; - } else { - $fallback( - "/recentNotifications/[0]/commentText", - "/properties/recentNotifications/elements/mapping/properties/commentText/type", - "Expected string at /recentNotifications/[0]/commentText", - ); - } - __D2AItemAResult = __D3; - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "Expected object", - ); - } - break; - } - default: - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements/mapping", - "__D2AItem.notificationType did not match one of the specified values", - ); - break; - } - } else { - $fallback( - "/recentNotifications/[0]", - "/properties/recentNotifications/elements", - "Expected Object.", - ); - } - __D2.push(__D2AItemAResult); - } - __D1.recentNotifications = __D2; - } else { - $fallback( - "/recentNotifications", - "/properties/recentNotifications", - "Expected Array", - ); - } - if ( - typeof input.bookmarks === "object" && - input.bookmarks !== null - ) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(input.bookmarks)) { - let __D2RKeyRVal; - if ( - typeof input.bookmarks[__D2RKey] === "object" && - input.bookmarks[__D2RKey] !== null - ) { - const __D3 = {}; - if ( - typeof input.bookmarks[__D2RKey].postId === "string" - ) { - __D3.postId = input.bookmarks[__D2RKey].postId; - } else { - $fallback( - "/bookmarks/[key]/postId", - "/properties/bookmarks/values/properties/postId/type", - "Expected string at /bookmarks/[key]/postId", - ); - } - if ( - typeof input.bookmarks[__D2RKey].userId === "string" - ) { - __D3.userId = input.bookmarks[__D2RKey].userId; - } else { - $fallback( - "/bookmarks/[key]/userId", - "/properties/bookmarks/values/properties/userId/type", - "Expected string at /bookmarks/[key]/userId", - ); - } - __D2RKeyRVal = __D3; - } else { - $fallback( - "/bookmarks/[key]", - "/properties/bookmarks/values", - "Expected object", - ); - } - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.bookmarks = __D2RResult; + Number.isInteger(input.numFollowers) && + input.numFollowers >= INT32_MIN && + input.numFollowers <= INT32_MAX && + $$UserSettings.validate(input.settings) && + Array.isArray(input.recentNotifications) && + input.recentNotifications.every((_element) => + $$UsersWatchUserResponseRecentNotificationselement.validate( + _element, + ), + ) && + isObject(input.bookmarks) && + Object.values(input.bookmarks).every((_value) => + $$UsersWatchUserResponseBookmarksvalue.validate(_value), + ) && + isObject(input.metadata) && + Object.values(input.metadata).every((_value) => true) && + Array.isArray(input.randomList) && + input.randomList.every((_element) => true) && + (typeof input.bio === "string" || + typeof input.bio === "undefined") + ); + }, + fromJson(input): UsersWatchUserResponse { + let _id: string; + if (typeof input.id === "string") { + _id = input.id; } else { - $fallback( - "/bookmarks", - "/properties/bookmarks", - "Expected object.", - ); + _id = ""; } - if (typeof input.metadata === "object" && input.metadata !== null) { - const __D2RResult = {}; - for (const __D2RKey of Object.keys(input.metadata)) { - let __D2RKeyRVal; - __D2RKeyRVal = input.metadata[__D2RKey]; - __D2RResult[__D2RKey] = __D2RKeyRVal; - } - __D1.metadata = __D2RResult; - } else { - $fallback( - "/metadata", - "/properties/metadata", - "Expected object.", + let _role: UsersWatchUserResponseRole; + if (typeof input.role === "string") { + _role = $$UsersWatchUserResponseRole.fromSerialValue( + input.role, ); + } else { + _role = $$UsersWatchUserResponseRole.new(); } - if (Array.isArray(input.randomList)) { - const __D2 = []; - for (const __D2AItem of input.randomList) { - let __D2AItemAResult; - __D2AItemAResult = __D2AItem; - __D2.push(__D2AItemAResult); - } - __D1.randomList = __D2; + let _photo: UserPhoto | null; + if (isObject(input.photo)) { + _photo = $$UserPhoto.fromJson(input.photo); } else { - $fallback( - "/randomList", - "/properties/randomList", - "Expected Array", - ); + _photo = null; } - if (typeof input.bio === "undefined") { - // ignore undefined + let _createdAt: Date; + if (typeof input.createdAt === "string") { + _createdAt = new Date(input.createdAt); + } else if (input.createdAt instanceof Date) { + _createdAt = input.createdAt; } else { - if (typeof input.bio === "string") { - __D1.bio = input.bio; - } else { - $fallback( - "/bio", - "/optionalProperties/bio/type", - "Expected string at /bio", - ); - } + _createdAt = new Date(); } - result = __D1; - } else { - $fallback("", "", "Expected object"); - } - return result; - }, - serialize(input: UsersWatchUserResponse): string { - let json = ""; - - const STR_ESCAPE = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; - - json += ""; - json += "{"; - json += `"id":`; - if (input.id.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.id.length; i++) { - __point__ = input.id.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.id); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.id.slice(__last__, i) + "\\"; - __last__ = i; - } + let _numFollowers: number; + if ( + typeof input.numFollowers === "number" && + Number.isInteger(input.numFollowers) && + input.numFollowers >= INT32_MIN && + input.numFollowers <= INT32_MAX + ) { + _numFollowers = input.numFollowers; + } else { + _numFollowers = 0; } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.id}"`; - } else { - json += `"${__result__}${input.id.slice(__last__)}"`; - } + let _settings: UserSettings; + if (isObject(input.settings)) { + _settings = $$UserSettings.fromJson(input.settings); + } else { + _settings = $$UserSettings.new(); } - } else if (input.id.length < 5000 && !STR_ESCAPE.test(input.id)) { - json += `"${input.id}"`; - } else { - json += JSON.stringify(input.id); - } - json += `,"role":"${input.role}"`; - if (typeof input.photo === "object" && input.photo !== null) { - json += ',"photo":'; - json += "{"; - json += `"url":`; - if (input.photo.url.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.photo.url.length; i++) { - __point__ = input.photo.url.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.photo.url); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.photo.url.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.photo.url}"`; + let _recentNotifications: UsersWatchUserResponseRecentNotificationselement[]; + if (Array.isArray(input.recentNotifications)) { + _recentNotifications = []; + for (const _recentNotificationsEl of input.recentNotifications) { + let _recentNotificationsElValue: UsersWatchUserResponseRecentNotificationselement; + if (isObject(_recentNotificationsEl)) { + _recentNotificationsElValue = + $$UsersWatchUserResponseRecentNotificationselement.fromJson( + _recentNotificationsEl, + ); } else { - json += `"${__result__}${input.photo.url.slice(__last__)}"`; + _recentNotificationsElValue = + $$UsersWatchUserResponseRecentNotificationselement.new(); } + _recentNotifications.push(_recentNotificationsElValue); } - } else if ( - input.photo.url.length < 5000 && - !STR_ESCAPE.test(input.photo.url) - ) { - json += `"${input.photo.url}"`; } else { - json += JSON.stringify(input.photo.url); - } - - if (Number.isNaN(input.photo.width)) { - throw new Error("Expected number at /photo/width got NaN"); - } - json += `,"width":${input.photo.width}`; - - if (Number.isNaN(input.photo.height)) { - throw new Error("Expected number at /photo/height got NaN"); + _recentNotifications = []; } - json += `,"height":${input.photo.height}`; - json += `,"bytes":"${input.photo.bytes.toString()}"`; - json += `,"nanoseconds":"${input.photo.nanoseconds.toString()}"`; - json += "}"; - } else { - json += ',"photo":null'; - } - json += `,"createdAt":"${input.createdAt.toISOString()}"`; - - if (Number.isNaN(input.numFollowers)) { - throw new Error("Expected number at /numFollowers got NaN"); - } - json += `,"numFollowers":${input.numFollowers}`; - - json += ',"settings":'; - json += "{"; - json += `"notificationsEnabled":${input.settings.notificationsEnabled}`; - json += `,"preferredTheme":"${input.settings.preferredTheme}"`; - json += "}"; - json += ',"recentNotifications":['; - for (let i = 0; i < input.recentNotifications.length; i++) { - const valRecentNotificationsItem = input.recentNotifications[i]; - if (i !== 0) { - json += ","; - } - switch (valRecentNotificationsItem.notificationType) { - case "POST_LIKE": { - json += ""; - json += "{"; - json += `"notificationType":"POST_LIKE"`; - json += `,"postId":`; - if (valRecentNotificationsItem.postId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valRecentNotificationsItem.postId.length; - i++ - ) { - __point__ = - valRecentNotificationsItem.postId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valRecentNotificationsItem.postId, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valRecentNotificationsItem.postId.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valRecentNotificationsItem.postId}"`; - } else { - json += `"${__result__}${valRecentNotificationsItem.postId.slice(__last__)}"`; - } - } - } else if ( - valRecentNotificationsItem.postId.length < 5000 && - !STR_ESCAPE.test(valRecentNotificationsItem.postId) - ) { - json += `"${valRecentNotificationsItem.postId}"`; - } else { - json += JSON.stringify( - valRecentNotificationsItem.postId, - ); - } - json += `,"userId":`; - if (valRecentNotificationsItem.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valRecentNotificationsItem.userId.length; - i++ - ) { - __point__ = - valRecentNotificationsItem.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valRecentNotificationsItem.userId, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valRecentNotificationsItem.userId.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valRecentNotificationsItem.userId}"`; - } else { - json += `"${__result__}${valRecentNotificationsItem.userId.slice(__last__)}"`; - } - } - } else if ( - valRecentNotificationsItem.userId.length < 5000 && - !STR_ESCAPE.test(valRecentNotificationsItem.userId) - ) { - json += `"${valRecentNotificationsItem.userId}"`; + let _bookmarks: Record< + string, + UsersWatchUserResponseBookmarksvalue + >; + if (isObject(input.bookmarks)) { + _bookmarks = {}; + for (const [_key, _value] of Object.entries(input.bookmarks)) { + let _bookmarksValue: UsersWatchUserResponseBookmarksvalue; + if (typeof _value === "boolean") { + _bookmarksValue = _value; } else { - json += JSON.stringify( - valRecentNotificationsItem.userId, - ); + _bookmarksValue = false; } - json += "}"; - break; + _bookmarks[_key] = _bookmarksValue; } - case "POST_COMMENT": { - json += ""; - json += "{"; - json += `"notificationType":"POST_COMMENT"`; - json += `,"postId":`; - if (valRecentNotificationsItem.postId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valRecentNotificationsItem.postId.length; - i++ - ) { - __point__ = - valRecentNotificationsItem.postId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valRecentNotificationsItem.postId, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valRecentNotificationsItem.postId.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valRecentNotificationsItem.postId}"`; - } else { - json += `"${__result__}${valRecentNotificationsItem.postId.slice(__last__)}"`; - } - } - } else if ( - valRecentNotificationsItem.postId.length < 5000 && - !STR_ESCAPE.test(valRecentNotificationsItem.postId) - ) { - json += `"${valRecentNotificationsItem.postId}"`; - } else { - json += JSON.stringify( - valRecentNotificationsItem.postId, - ); - } - json += `,"userId":`; - if (valRecentNotificationsItem.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valRecentNotificationsItem.userId.length; - i++ - ) { - __point__ = - valRecentNotificationsItem.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valRecentNotificationsItem.userId, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valRecentNotificationsItem.userId.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valRecentNotificationsItem.userId}"`; - } else { - json += `"${__result__}${valRecentNotificationsItem.userId.slice(__last__)}"`; - } - } - } else if ( - valRecentNotificationsItem.userId.length < 5000 && - !STR_ESCAPE.test(valRecentNotificationsItem.userId) - ) { - json += `"${valRecentNotificationsItem.userId}"`; - } else { - json += JSON.stringify( - valRecentNotificationsItem.userId, - ); - } - json += `,"commentText":`; - if (valRecentNotificationsItem.commentText.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for ( - let i = 0; - i < valRecentNotificationsItem.commentText.length; - i++ - ) { - __point__ = - valRecentNotificationsItem.commentText.charCodeAt( - i, - ); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify( - valRecentNotificationsItem.commentText, - ); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += - valRecentNotificationsItem.commentText.slice( - __last__, - i, - ) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${valRecentNotificationsItem.commentText}"`; - } else { - json += `"${__result__}${valRecentNotificationsItem.commentText.slice(__last__)}"`; - } - } - } else if ( - valRecentNotificationsItem.commentText.length < 5000 && - !STR_ESCAPE.test(valRecentNotificationsItem.commentText) - ) { - json += `"${valRecentNotificationsItem.commentText}"`; + } else { + _bookmarks = {}; + } + let _metadata: Record; + if (isObject(input.metadata)) { + _metadata = {}; + for (const [_key, _value] of Object.entries(input.metadata)) { + let _metadataValue: any; + if (typeof _value === "boolean") { + _metadataValue = _value; } else { - json += JSON.stringify( - valRecentNotificationsItem.commentText, - ); + _metadataValue = false; } - json += "}"; - break; + _metadata[_key] = _metadataValue; } + } else { + _metadata = {}; } - } - json += "]"; - const bookmarksKeys = Object.keys(input.bookmarks); - json += ',"bookmarks":{'; - for (let i = 0; i < bookmarksKeys.length; i++) { - const key = bookmarksKeys[i]; - const innerVal = input.bookmarks[key]; - if (i !== 0) { - json += `,"${key}":`; + let _randomList: any[]; + if (Array.isArray(input.randomList)) { + _randomList = []; + for (const _randomListEl of input.randomList) { + let _randomListElValue: any; + _randomListElValue = _randomListEl; + _randomList.push(_randomListElValue); + } } else { - json += `"${key}":`; + _randomList = []; } - - json += ""; + let _bio: string | undefined; + if (typeof input.bio !== "undefined") { + if (typeof input.bio === "string") { + _bio = input.bio; + } else { + _bio = ""; + } + } + return { + id: _id, + role: _role, + photo: _photo, + createdAt: _createdAt, + numFollowers: _numFollowers, + settings: _settings, + recentNotifications: _recentNotifications, + bookmarks: _bookmarks, + metadata: _metadata, + randomList: _randomList, + bio: _bio, + }; + }, + fromJsonString(input): UsersWatchUserResponse { + return $$UsersWatchUserResponse.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"id":'; + json += serializeString(input.id); + json += ',"role":'; + json += `"${input.role}"`; + json += ',"photo":'; + if (input.photo !== null) { + json += $$UserPhoto.toJsonString(input.photo); + } else { + json += "null"; + } + json += ',"createdAt":'; + json += `"${input.createdAt.toISOString()}"`; + json += ',"numFollowers":'; + json += `${input.numFollowers}`; + json += ',"settings":'; + json += $$UserSettings.toJsonString(input.settings); + json += ',"recentNotifications":'; + json += "["; + for (let i = 0; i < input.recentNotifications.length; i++) { + if (i !== 0) json += ","; + const _inputRecentNotificationsEl = + input.recentNotifications[i]; + json += + $$UsersWatchUserResponseRecentNotificationselement.toJsonString( + _inputRecentNotificationsEl, + ); + } + json += "]"; + json += ',"bookmarks":'; json += "{"; - json += `"postId":`; - if (innerVal.postId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < innerVal.postId.length; i++) { - __point__ = innerVal.postId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(innerVal.postId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += innerVal.postId.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${innerVal.postId}"`; - } else { - json += `"${__result__}${innerVal.postId.slice(__last__)}"`; - } - } - } else if ( - innerVal.postId.length < 5000 && - !STR_ESCAPE.test(innerVal.postId) - ) { - json += `"${innerVal.postId}"`; - } else { - json += JSON.stringify(innerVal.postId); - } - json += `,"userId":`; - if (innerVal.userId.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < innerVal.userId.length; i++) { - __point__ = innerVal.userId.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(innerVal.userId); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += innerVal.userId.slice(__last__, i) + "\\"; - __last__ = i; - } + let _bookmarksPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.bookmarks)) { + if (_bookmarksPropertyCount !== 0) { + json += ","; } - if (!__finished__) { - if (__last__ === -1) { - json += `"${innerVal.userId}"`; - } else { - json += `"${__result__}${innerVal.userId.slice(__last__)}"`; - } + json += `"${_key}":`; + json += + $$UsersWatchUserResponseBookmarksvalue.toJsonString(_value); + _bookmarksPropertyCount++; + } + json += "}"; + + json += ',"metadata":'; + json += "{"; + let _metadataPropertyCount = 0; + for (const [_key, _value] of Object.entries(input.metadata)) { + if (_metadataPropertyCount !== 0) { + json += ","; } - } else if ( - innerVal.userId.length < 5000 && - !STR_ESCAPE.test(innerVal.userId) - ) { - json += `"${innerVal.userId}"`; - } else { - json += JSON.stringify(innerVal.userId); + json += `"${_key}":`; + json += JSON.stringify(_value); + _metadataPropertyCount++; } json += "}"; - } - json += "}"; - const metadataKeys = Object.keys(input.metadata); - json += ',"metadata":{'; - for (let i = 0; i < metadataKeys.length; i++) { - const key = metadataKeys[i]; - const innerVal = input.metadata[key]; - if (i !== 0) { - json += `,"${key}":`; - } else { - json += `"${key}":`; + + json += ',"randomList":'; + json += "["; + for (let i = 0; i < input.randomList.length; i++) { + if (i !== 0) json += ","; + const _inputRandomListEl = input.randomList[i]; + json += JSON.stringify(_inputRandomListEl); } - if (typeof innerVal !== "undefined") { - json += JSON.stringify(innerVal); + json += "]"; + if (typeof input.bio !== "undefined") { + json += `,"bio":`; + json += serializeString(input.bio); } - } - json += "}"; - json += ',"randomList":['; - for (let i = 0; i < input.randomList.length; i++) { - const valRandomListItem = input.randomList[i]; - if (i !== 0) { - json += ","; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`id=${input.id}`); + queryParts.push(`role=${input.role}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /UsersWatchUserResponse/photo.", + ); + queryParts.push(`createdAt=${input.createdAt.toISOString()}`); + queryParts.push(`numFollowers=${input.numFollowers}`); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /UsersWatchUserResponse/settings.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /UsersWatchUserResponse/recentNotifications.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /UsersWatchUserResponse/bookmarks.", + ); + console.warn( + "[WARNING] Cannot serialize nested objects to query string. Skipping property at /UsersWatchUserResponse/metadata.", + ); + console.warn( + "[WARNING] Cannot serialize arrays to query string. Skipping property at /UsersWatchUserResponse/randomList.", + ); + if (typeof input.bio !== "undefined") { + queryParts.push(`bio=${input.bio}`); + } + return queryParts.join("&"); + }, + }; + +export type UsersWatchUserResponseRole = + (typeof $$UsersWatchUserResponseRoleValues)[number]; +const $$UsersWatchUserResponseRoleValues = ["standard", "admin"] as const; +export const $$UsersWatchUserResponseRole: ArriEnumValidator = + { + new(): UsersWatchUserResponseRole { + return $$UsersWatchUserResponseRoleValues[0]; + }, + validate(input): input is UsersWatchUserResponseRole { + return ( + typeof input === "string" && + $$UsersWatchUserResponseRoleValues.includes(input as any) + ); + }, + values: $$UsersWatchUserResponseRoleValues, + fromSerialValue(input): UsersWatchUserResponseRole { + if ($$UsersWatchUserResponseRoleValues.includes(input as any)) { + return input as UsersWatchUserResponseRole; } - if (typeof valRandomListItem !== "undefined") { - json += JSON.stringify(valRandomListItem); + if ( + $$UsersWatchUserResponseRoleValues.includes( + input.toLowerCase() as any, + ) + ) { + return input.toLowerCase() as UsersWatchUserResponseRole; } - } - json += "]"; - if (typeof input.bio !== "undefined") { - json += `,"bio":`; - if (input.bio.length < 42) { - let __result__ = ""; - let __last__ = -1; - let __point__ = 255; - let __finished__ = false; - for (let i = 0; i < input.bio.length; i++) { - __point__ = input.bio.charCodeAt(i); - if ( - __point__ < 32 || - (__point__ >= 0xd800 && __point__ <= 0xdfff) - ) { - json += JSON.stringify(input.bio); - __finished__ = true; - break; - } - if (__point__ === 0x22 || __point__ === 0x5c) { - __last__ === -1 && (__last__ = 0); - __result__ += input.bio.slice(__last__, i) + "\\"; - __last__ = i; - } - } - if (!__finished__) { - if (__last__ === -1) { - json += `"${input.bio}"`; - } else { - json += `"${__result__}${input.bio.slice(__last__)}"`; - } - } - } else if (input.bio.length < 5000 && !STR_ESCAPE.test(input.bio)) { - json += `"${input.bio}"`; - } else { - json += JSON.stringify(input.bio); + if ( + $$UsersWatchUserResponseRoleValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as UsersWatchUserResponseRole; } - } - json += "}"; - return json; - }, -}; -export type UsersWatchUserResponseRole = "standard" | "admin"; + return "standard"; + }, + }; + /** * A profile picture */ @@ -12740,46 +6614,503 @@ export interface UserPhoto { width: number; height: number; bytes: bigint; - /** - * When the photo was last updated in nanoseconds - */ nanoseconds: bigint; } +export const $$UserPhoto: ArriModelValidator = { + new(): UserPhoto { + return { + url: "", + width: 0, + height: 0, + bytes: BigInt(0), + nanoseconds: BigInt(0), + }; + }, + validate(input): input is UserPhoto { + return ( + isObject(input) && + typeof input.url === "string" && + typeof input.width === "number" && + typeof input.height === "number" && + typeof input.bytes === "bigint" && + input.bytes >= INT64_MIN && + input.bytes <= INT64_MAX && + typeof input.nanoseconds === "bigint" && + input.nanoseconds >= BigInt(0) && + input.nanoseconds <= UINT64_MAX + ); + }, + fromJson(input): UserPhoto { + let _url: string; + if (typeof input.url === "string") { + _url = input.url; + } else { + _url = ""; + } + let _width: number; + if (typeof input.width === "number") { + _width = input.width; + } else { + _width = 0; + } + let _height: number; + if (typeof input.height === "number") { + _height = input.height; + } else { + _height = 0; + } + let _bytes: bigint; + if (typeof input.bytes === "string") { + _bytes = BigInt(input.bytes); + } else if (typeof input.bytes === "bigint") { + _bytes = input.bytes; + } else { + _bytes = BigInt(0); + } + let _nanoseconds: bigint; + if ( + typeof input.nanoseconds === "string" && + BigInt(input.nanoseconds) >= BigInt(0) + ) { + _nanoseconds = BigInt(input.nanoseconds); + } else if ( + typeof input.nanoseconds === "bigint" && + input.nanoseconds >= BigInt(0) + ) { + _nanoseconds = input.nanoseconds; + } else { + _nanoseconds = BigInt(0); + } + return { + url: _url, + width: _width, + height: _height, + bytes: _bytes, + nanoseconds: _nanoseconds, + }; + }, + fromJsonString(input): UserPhoto { + return $$UserPhoto.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"url":'; + json += serializeString(input.url); + json += ',"width":'; + json += `${input.width}`; + json += ',"height":'; + json += `${input.height}`; + json += ',"bytes":'; + json += `"${input.bytes}"`; + json += ',"nanoseconds":'; + json += `"${input.nanoseconds}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`url=${input.url}`); + queryParts.push(`width=${input.width}`); + queryParts.push(`height=${input.height}`); + queryParts.push(`bytes=${input.bytes}`); + queryParts.push(`nanoseconds=${input.nanoseconds}`); + return queryParts.join("&"); + }, +}; export interface UserSettings { notificationsEnabled: boolean; - preferredTheme: UsersWatchUserResponseSettingsPreferredTheme; + preferredTheme: UserSettingsPreferredTheme; } +export const $$UserSettings: ArriModelValidator = { + new(): UserSettings { + return { + notificationsEnabled: false, + preferredTheme: $$UserSettingsPreferredTheme.new(), + }; + }, + validate(input): input is UserSettings { + return ( + isObject(input) && + typeof input.notificationsEnabled === "boolean" && + $$UserSettingsPreferredTheme.validate(input.preferredTheme) + ); + }, + fromJson(input): UserSettings { + let _notificationsEnabled: boolean; + if (typeof input.notificationsEnabled === "boolean") { + _notificationsEnabled = input.notificationsEnabled; + } else { + _notificationsEnabled = false; + } + let _preferredTheme: UserSettingsPreferredTheme; + if (typeof input.preferredTheme === "string") { + _preferredTheme = $$UserSettingsPreferredTheme.fromSerialValue( + input.preferredTheme, + ); + } else { + _preferredTheme = $$UserSettingsPreferredTheme.new(); + } + return { + notificationsEnabled: _notificationsEnabled, + preferredTheme: _preferredTheme, + }; + }, + fromJsonString(input): UserSettings { + return $$UserSettings.fromJson(JSON.parse(input)); + }, + toJsonString(input): string { + let json = "{"; + json += '"notificationsEnabled":'; + json += `${input.notificationsEnabled}`; + json += ',"preferredTheme":'; + json += `"${input.preferredTheme}"`; + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`notificationsEnabled=${input.notificationsEnabled}`); + queryParts.push(`preferredTheme=${input.preferredTheme}`); + return queryParts.join("&"); + }, +}; -export type UsersWatchUserResponseSettingsPreferredTheme = - | "dark-mode" - | "light-mode" - | "system"; -export type UsersWatchUserResponseRecentNotificationsItem = - | UsersWatchUserResponseRecentNotificationsItemPostLike - | UsersWatchUserResponseRecentNotificationsItemPostComment; - -export interface UsersWatchUserResponseRecentNotificationsItemPostLike { +export type UserSettingsPreferredTheme = + (typeof $$UserSettingsPreferredThemeValues)[number]; +const $$UserSettingsPreferredThemeValues = [ + "dark-mode", + "light-mode", + "system", +] as const; +export const $$UserSettingsPreferredTheme: ArriEnumValidator = + { + new(): UserSettingsPreferredTheme { + return $$UserSettingsPreferredThemeValues[0]; + }, + validate(input): input is UserSettingsPreferredTheme { + return ( + typeof input === "string" && + $$UserSettingsPreferredThemeValues.includes(input as any) + ); + }, + values: $$UserSettingsPreferredThemeValues, + fromSerialValue(input): UserSettingsPreferredTheme { + if ($$UserSettingsPreferredThemeValues.includes(input as any)) { + return input as UserSettingsPreferredTheme; + } + if ( + $$UserSettingsPreferredThemeValues.includes( + input.toLowerCase() as any, + ) + ) { + return input.toLowerCase() as UserSettingsPreferredTheme; + } + if ( + $$UserSettingsPreferredThemeValues.includes( + input.toUpperCase() as any, + ) + ) { + return input.toUpperCase() as UserSettingsPreferredTheme; + } + return "dark-mode"; + }, + }; + +export type UsersWatchUserResponseRecentNotificationselement = + | UsersWatchUserResponseRecentNotificationselementPostLike + | UsersWatchUserResponseRecentNotificationselementPostComment; +export const $$UsersWatchUserResponseRecentNotificationselement: ArriModelValidator = + { + new(): UsersWatchUserResponseRecentNotificationselement { + return $$UsersWatchUserResponseRecentNotificationselementPostLike.new(); + }, + validate( + input, + ): input is UsersWatchUserResponseRecentNotificationselement { + if (!isObject(input)) { + return false; + } + if (typeof input.notificationType !== "string") { + return false; + } + switch (input.notificationType) { + case "POST_LIKE": + return $$UsersWatchUserResponseRecentNotificationselementPostLike.validate( + input, + ); + case "POST_COMMENT": + return $$UsersWatchUserResponseRecentNotificationselementPostComment.validate( + input, + ); + default: + return false; + } + }, + fromJson(input): UsersWatchUserResponseRecentNotificationselement { + switch (input.notificationType) { + case "POST_LIKE": + return $$UsersWatchUserResponseRecentNotificationselementPostLike.fromJson( + input, + ); + case "POST_COMMENT": + return $$UsersWatchUserResponseRecentNotificationselementPostComment.fromJson( + input, + ); + default: + return $$UsersWatchUserResponseRecentNotificationselementPostLike.new(); + } + }, + fromJsonString( + input, + ): UsersWatchUserResponseRecentNotificationselement { + return $$UsersWatchUserResponseRecentNotificationselement.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + switch (input.notificationType) { + case "POST_LIKE": + return $$UsersWatchUserResponseRecentNotificationselementPostLike.toJsonString( + input, + ); + case "POST_COMMENT": + return $$UsersWatchUserResponseRecentNotificationselementPostComment.toJsonString( + input, + ); + default: + throw new Error( + `Unhandled case "${(input as any).notificationType}"`, + ); + } + }, + toUrlQueryString(input): string { + switch (input.notificationType) { + case "POST_LIKE": + return $$UsersWatchUserResponseRecentNotificationselementPostLike.toUrlQueryString( + input, + ); + case "POST_COMMENT": + return $$UsersWatchUserResponseRecentNotificationselementPostComment.toUrlQueryString( + input, + ); + default: + throw new Error("Unhandled case"); + } + }, + }; +export interface UsersWatchUserResponseRecentNotificationselementPostLike { notificationType: "POST_LIKE"; postId: string; userId: string; } - -export interface UsersWatchUserResponseRecentNotificationsItemPostComment { +const $$UsersWatchUserResponseRecentNotificationselementPostLike: ArriModelValidator = + { + new(): UsersWatchUserResponseRecentNotificationselementPostLike { + return { + notificationType: "POST_LIKE", + postId: "", + userId: "", + }; + }, + validate( + input, + ): input is UsersWatchUserResponseRecentNotificationselementPostLike { + return ( + isObject(input) && + input.notificationType === "POST_LIKE" && + typeof input.postId === "string" && + typeof input.userId === "string" + ); + }, + fromJson( + input, + ): UsersWatchUserResponseRecentNotificationselementPostLike { + const _notificationType = "POST_LIKE"; + let _postId: string; + if (typeof input.postId === "string") { + _postId = input.postId; + } else { + _postId = ""; + } + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + return { + notificationType: _notificationType, + postId: _postId, + userId: _userId, + }; + }, + fromJsonString( + input, + ): UsersWatchUserResponseRecentNotificationselementPostLike { + return $$UsersWatchUserResponseRecentNotificationselementPostLike.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"notificationType":"POST_LIKE"'; + json += ',"postId":'; + json += serializeString(input.postId); + json += ',"userId":'; + json += serializeString(input.userId); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("notificationType=POST_LIKE"); + queryParts.push(`postId=${input.postId}`); + queryParts.push(`userId=${input.userId}`); + return queryParts.join("&"); + }, + }; + +export interface UsersWatchUserResponseRecentNotificationselementPostComment { notificationType: "POST_COMMENT"; postId: string; userId: string; commentText: string; } - -export type UsersWatchUserResponseBookmarks = Record< - string, - UsersWatchUserResponseBookmarksValue ->; - -export interface UsersWatchUserResponseBookmarksValue { +const $$UsersWatchUserResponseRecentNotificationselementPostComment: ArriModelValidator = + { + new(): UsersWatchUserResponseRecentNotificationselementPostComment { + return { + notificationType: "POST_COMMENT", + postId: "", + userId: "", + commentText: "", + }; + }, + validate( + input, + ): input is UsersWatchUserResponseRecentNotificationselementPostComment { + return ( + isObject(input) && + input.notificationType === "POST_COMMENT" && + typeof input.postId === "string" && + typeof input.userId === "string" && + typeof input.commentText === "string" + ); + }, + fromJson( + input, + ): UsersWatchUserResponseRecentNotificationselementPostComment { + const _notificationType = "POST_COMMENT"; + let _postId: string; + if (typeof input.postId === "string") { + _postId = input.postId; + } else { + _postId = ""; + } + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + let _commentText: string; + if (typeof input.commentText === "string") { + _commentText = input.commentText; + } else { + _commentText = ""; + } + return { + notificationType: _notificationType, + postId: _postId, + userId: _userId, + commentText: _commentText, + }; + }, + fromJsonString( + input, + ): UsersWatchUserResponseRecentNotificationselementPostComment { + return $$UsersWatchUserResponseRecentNotificationselementPostComment.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"notificationType":"POST_COMMENT"'; + json += ',"postId":'; + json += serializeString(input.postId); + json += ',"userId":'; + json += serializeString(input.userId); + json += ',"commentText":'; + json += serializeString(input.commentText); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push("notificationType=POST_COMMENT"); + queryParts.push(`postId=${input.postId}`); + queryParts.push(`userId=${input.userId}`); + queryParts.push(`commentText=${input.commentText}`); + return queryParts.join("&"); + }, + }; + +export interface UsersWatchUserResponseBookmarksvalue { postId: string; userId: string; } - -export type UsersWatchUserResponseMetadata = Record; +export const $$UsersWatchUserResponseBookmarksvalue: ArriModelValidator = + { + new(): UsersWatchUserResponseBookmarksvalue { + return { + postId: "", + userId: "", + }; + }, + validate(input): input is UsersWatchUserResponseBookmarksvalue { + return ( + isObject(input) && + typeof input.postId === "string" && + typeof input.userId === "string" + ); + }, + fromJson(input): UsersWatchUserResponseBookmarksvalue { + let _postId: string; + if (typeof input.postId === "string") { + _postId = input.postId; + } else { + _postId = ""; + } + let _userId: string; + if (typeof input.userId === "string") { + _userId = input.userId; + } else { + _userId = ""; + } + return { + postId: _postId, + userId: _userId, + }; + }, + fromJsonString(input): UsersWatchUserResponseBookmarksvalue { + return $$UsersWatchUserResponseBookmarksvalue.fromJson( + JSON.parse(input), + ); + }, + toJsonString(input): string { + let json = "{"; + json += '"postId":'; + json += serializeString(input.postId); + json += ',"userId":'; + json += serializeString(input.userId); + json += "}"; + return json; + }, + toUrlQueryString(input): string { + const queryParts: string[] = []; + queryParts.push(`postId=${input.postId}`); + queryParts.push(`userId=${input.userId}`); + return queryParts.join("&"); + }, + }; diff --git a/tests/clients/ts/testClient.test.ts b/tests/clients/ts/testClient.test.ts index bee9db88..5df6f3e2 100644 --- a/tests/clients/ts/testClient.test.ts +++ b/tests/clients/ts/testClient.test.ts @@ -160,8 +160,26 @@ test("can send/receive partial objects", async () => { expect(fullObjectResult).toStrictEqual(input); const partialInput: ObjectWithEveryOptionalType = { string: "", + boolean: undefined, + timestamp: undefined, + float32: undefined, + float64: undefined, + int8: undefined, + uint8: undefined, int16: 0, + uint16: undefined, + int32: undefined, + uint32: undefined, int64: 0n, + uint64: undefined, + enumerator: undefined, + array: undefined, + object: undefined, + record: undefined, + discriminator: undefined, + nestedObject: undefined, + nestedArray: undefined, + any: undefined, }; const partialObjectResult = await client.tests.sendPartialObject(partialInput); @@ -270,7 +288,7 @@ test("can send/receive recursive unions", async () => { test("[SSE] supports server sent events", async () => { let wasConnected = false; let receivedMessageCount = 0; - const controller = client.tests.streamMessages( + const controller = await client.tests.streamMessages( { channelId: "1" }, { onMessage(msg) { @@ -306,7 +324,7 @@ test("[SSE] closes connection when receiving 'done' event", async () => { let timesConnected = 0; let messageCount = 0; let errorReceived: ArriErrorInstance | undefined; - const controller = client.tests.streamTenEventsThenEnd({ + const controller = await client.tests.streamTenEventsThenEnd({ onMessage(_) { messageCount++; }, @@ -484,6 +502,7 @@ describe("arri adapters", () => { test("typebox adapter", async () => { const input: TypeBoxObject = { string: "hello world", + optionalString: undefined, boolean: false, integer: 100, number: 10.5, From 7fdae83d8882f97e11f3b47b058a279c28cff31f Mon Sep 17 00:00:00 2001 From: Joshua Sosso Date: Tue, 23 Jul 2024 11:17:07 -0500 Subject: [PATCH 18/18] remove unused file --- .gitignore | 1 + .../ts/ts-codegen/references/wsExample.ts | 61 ------------------- 2 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 languages/ts/ts-codegen/references/wsExample.ts diff --git a/.gitignore b/.gitignore index 765a30aa..aa370285 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ node_modules /.sass-cache /connect.lock /coverage +**/coverage /libpeerconnection.log npm-debug.log yarn-error.log diff --git a/languages/ts/ts-codegen/references/wsExample.ts b/languages/ts/ts-codegen/references/wsExample.ts deleted file mode 100644 index 04dd1515..00000000 --- a/languages/ts/ts-codegen/references/wsExample.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { arriWsRequest, type WsOptions } from "@arrirpc/client"; - -export class UserService { - private readonly baseUrl: string; - private readonly headers: Record; - - constructor(opts: { baseUrl?: string; headers?: Record }) { - this.baseUrl = opts.baseUrl ?? ""; - this.headers = opts.headers ?? {}; - } - - createConnection(opts: WsOptions) { - return arriWsRequest({ - url: `${this.baseUrl}/users/create-connection`, - headers: this.headers, - parser: $$ClientMessage.parse, - serializer: $$ClientMessage.serialize, - onOpen: opts.onOpen, - onClose: opts.onClose, - onError: opts.onError, - onConnectionError: opts.onConnectionError, - onMessage: opts.onMessage, - clientVersion: "1", - }); - } -} - -export interface ServerMessage { - id: string; - content: string; -} -export const $$ServerMessage = { - parse(input: unknown): ServerMessage { - return { - id: "", - content: "", - }; - }, - serialize(input: ServerMessage): string { - return ""; - }, -}; - -export interface ClientMessage { - id: string; - content: string; -} - -export const $$ClientMessage = { - parse(input: unknown): ClientMessage { - return { - id: "", - content: "", - }; - }, - serialize(input: ClientMessage): string { - return ""; - }, -};