diff --git a/.eslintignore b/.eslintignore index d8cc5275c02..79bba6ab6d0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,6 +7,7 @@ generated bundle.c?js .pnp* packages/ir-sdk/** +packages/cli/api-importers/conjure/conjure-sdk/** packages/docs-config/** packages/cli/openapi-ir-sdk/** packages/cli/configuration/src/docs-yml/schemas/** diff --git a/fern/pages/changelogs/cli/2024-09-30.mdx b/fern/pages/changelogs/cli/2024-09-30.mdx new file mode 100644 index 00000000000..4fba297a7ad --- /dev/null +++ b/fern/pages/changelogs/cli/2024-09-30.mdx @@ -0,0 +1,5 @@ +## 0.43.8 +**`(fix):`** Any markdown files that have custom components are also pushed up to the Fern Docs +platform. + + diff --git a/fern/pages/changelogs/cli/2024-10-02.mdx b/fern/pages/changelogs/cli/2024-10-02.mdx new file mode 100644 index 00000000000..1c4bf0a95f6 --- /dev/null +++ b/fern/pages/changelogs/cli/2024-10-02.mdx @@ -0,0 +1,7 @@ +## 0.44.0-rc0 +**`(feat):`** The Fern CLI now supports parsing [Conjure](https://github.com/palantir/conjure), Palantir's +home-grown API Definition format. + +If you know a company that is using Conjure that wants API Docs + SDKs, send them our way! + + diff --git a/fern/pages/changelogs/go-sdk/2024-09-29.mdx b/fern/pages/changelogs/go-sdk/2024-09-29.mdx new file mode 100644 index 00000000000..55f4b4282b6 --- /dev/null +++ b/fern/pages/changelogs/go-sdk/2024-09-29.mdx @@ -0,0 +1,3 @@ +## 0.27.0 +**`(feat):`** Add support for SSE (Server-Sent Events) streaming responses. The user-facing interface for streaming responses remains the same between standard HTTP streaming and SSE. + diff --git a/package.json b/package.json index 753a9195809..a8d88610679 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "seed:local": "pnpm --filter @fern-api/seed-cli dist:cli && node packages/seed/dist/bundle.cjs", "ir:generate": "pnpm --filter @fern-api/ir-sdk generate", "openapi-ir:generate": "pnpm --filter @fern-api/openapi-ir-sdk generate", + "conjure-sdk:generate": "pnpm --filter @fern-api/conjure-sdk generate", "seed-config:generate": "pnpm --filter @fern-api/seed-cli generate", "docs-config:generate": "pnpm --filter @fern-api/configuration generate", "prepare": "husky" diff --git a/packages/cli/api-importers/commons/.depcheckrc.json b/packages/cli/api-importers/commons/.depcheckrc.json new file mode 100644 index 00000000000..a3a4f43188c --- /dev/null +++ b/packages/cli/api-importers/commons/.depcheckrc.json @@ -0,0 +1,10 @@ +{ + "ignores": [ + "@types/jest", + "globals", + "@types/node" + ], + "ignore-patterns": [ + "lib" + ] +} \ No newline at end of file diff --git a/packages/cli/api-importers/commons/.prettierrc.cjs b/packages/cli/api-importers/commons/.prettierrc.cjs new file mode 100644 index 00000000000..9b6214d5129 --- /dev/null +++ b/packages/cli/api-importers/commons/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("../../../../.prettierrc.json"); diff --git a/packages/cli/api-importers/commons/package.json b/packages/cli/api-importers/commons/package.json new file mode 100644 index 00000000000..c15a57ea15d --- /dev/null +++ b/packages/cli/api-importers/commons/package.json @@ -0,0 +1,47 @@ +{ + "name": "@fern-api/importer-commons", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "https://github.com/fern-api/fern.git", + "directory": "packages/cli/generation/remote-generation/remote-workspace-runner" + }, + "private": true, + "files": [ + "lib" + ], + "type": "module", + "source": "src/index.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "sideEffects": false, + "scripts": { + "clean": "rm -rf ./lib && tsc --build --clean", + "compile": "tsc --build", + "test": "vitest --passWithNoTests --run", + "test:update": "vitest --passWithNoTests --run -u", + "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../../../.eslintignore", + "lint:eslint:fix": "yarn lint:eslint --fix", + "format": "prettier --write --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"", + "format:check": "prettier --check --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"", + "organize-imports": "organize-imports-cli tsconfig.json", + "depcheck": "depcheck" + }, + "dependencies": { + "@fern-api/fern-definition-schema": "workspace:*", + "@fern-api/configuration": "workspace:*", + "@fern-api/task-context": "workspace:*", + "@fern-api/fs-utils": "workspace:*", + "lodash-es": "^4.17.21" + }, + "devDependencies": { + "@types/node": "^18.7.18", + "depcheck": "^1.4.6", + "globals": "link:@types/vitest/globals", + "organize-imports-cli": "^0.10.0", + "prettier": "^2.7.1", + "typescript": "4.6.4", + "vitest": "^2.0.5", + "@types/lodash-es": "^4.17.12" + } +} \ No newline at end of file diff --git a/packages/cli/api-importers/commons/src/APIDefinitionImporter.ts b/packages/cli/api-importers/commons/src/APIDefinitionImporter.ts new file mode 100644 index 00000000000..3f14d91b4a7 --- /dev/null +++ b/packages/cli/api-importers/commons/src/APIDefinitionImporter.ts @@ -0,0 +1,17 @@ +import { DefinitionFileSchema, PackageMarkerFileSchema, RootApiFileSchema } from "@fern-api/fern-definition-schema"; +import { RelativeFilePath } from "@fern-api/fs-utils"; +import { TaskContext } from "@fern-api/task-context"; + +export declare namespace APIDefinitionImporter { + interface Return { + rootApiFile: RootApiFileSchema; + packageMarkerFile: PackageMarkerFileSchema; + definitionFiles: Record; + } +} + +export abstract class APIDefinitionImporter { + public constructor(protected readonly context?: TaskContext) {} + + public abstract import(input: T): Promise; +} diff --git a/packages/cli/openapi-ir-to-fern/src/FernDefnitionBuilder.ts b/packages/cli/api-importers/commons/src/FernDefnitionBuilder.ts similarity index 79% rename from packages/cli/openapi-ir-to-fern/src/FernDefnitionBuilder.ts rename to packages/cli/api-importers/commons/src/FernDefnitionBuilder.ts index 880a181797a..2a7c9db7ecb 100644 --- a/packages/cli/openapi-ir-to-fern/src/FernDefnitionBuilder.ts +++ b/packages/cli/api-importers/commons/src/FernDefnitionBuilder.ts @@ -1,13 +1,13 @@ import { FERN_PACKAGE_MARKER_FILENAME, ROOT_API_FILENAME } from "@fern-api/configuration"; import { AbsoluteFilePath, dirname, relative, RelativeFilePath } from "@fern-api/fs-utils"; -import { OpenApiIntermediateRepresentation, Source } from "@fern-api/openapi-ir-sdk"; import { RawSchemas, RootApiFileSchema, visitRawEnvironmentDeclaration } from "@fern-api/fern-definition-schema"; import { camelCase, isEqual } from "lodash-es"; import path, { basename, extname } from "path"; -import { convertToSourceSchema } from "./utils/convertToSourceSchema"; -import { FernDefinitionDirectory } from "./FernDefinitionDirectory"; +import { FernDefinitionDirectory } from "./utils/FernDefinitionDirectory"; export interface FernDefinitionBuilder { + setDisplayName({ displayName }: { displayName: string }): void; + addNavigation({ navigation }: { navigation: string[] }): void; addAuthScheme({ name, schema }: { name: string; schema: RawSchemas.AuthSchemeDeclarationSchema }): void; @@ -40,8 +40,17 @@ export interface FernDefinitionBuilder { * Adds an import and returns the prefix for the import. Returns undefined if no prefix. * @param file the file to add the import to * @param fileToImport the file to import + * @param alias import the file with this alias */ - addImport({ file, fileToImport }: { file: RelativeFilePath; fileToImport: RelativeFilePath }): string | undefined; + addImport({ + file, + fileToImport, + alias + }: { + file: RelativeFilePath; + fileToImport: RelativeFilePath; + alias?: string; + }): string | undefined; addType(file: RelativeFilePath, { name, schema }: { name: string; schema: RawSchemas.TypeDeclarationSchema }): void; @@ -57,7 +66,11 @@ export interface FernDefinitionBuilder { addEndpoint( file: RelativeFilePath, - { name, schema, source }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: Source | undefined } + { + name, + schema, + source + }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: RawSchemas.SourceSchema | undefined } ): void; addWebhook(file: RelativeFilePath, { name, schema }: { name: string; schema: RawSchemas.WebhookSchema }): void; @@ -92,11 +105,7 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { private packageMarkerFile: RawSchemas.PackageMarkerFileSchema = {}; private basePath: string | undefined = undefined; - public constructor( - ir: OpenApiIntermediateRepresentation, - private readonly modifyBasePaths: boolean, - public readonly enableUniqueErrorsPerEndpoint: boolean - ) { + public constructor(public readonly enableUniqueErrorsPerEndpoint: boolean) { this.root = new FernDefinitionDirectory(); this.rootApiFile = { name: "api", @@ -104,16 +113,17 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { strategy: "status-code" } }; - if (ir.title != null) { - this.rootApiFile["display-name"] = ir.title; - } + } + + public setDisplayName({ displayName }: { displayName: string }): void { + this.rootApiFile["display-name"] = displayName; } public addNavigation({ navigation }: { navigation: string[] }): void { this.packageMarkerFile.navigation = navigation; } - setServiceInfo( + public setServiceInfo( file: RelativeFilePath, { displayName, docs }: { displayName?: string | undefined; docs?: string | undefined } ): void { @@ -223,20 +233,24 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { public addImport({ file, - fileToImport + fileToImport, + alias }: { file: RelativeFilePath; fileToImport: RelativeFilePath; + alias?: string; }): string | undefined { if (file === fileToImport) { return undefined; } - const importPrefix = camelCase( - (dirname(fileToImport) + "/" + basename(fileToImport, extname(fileToImport))).replaceAll( - "__package__", - "root" - ) - ); + const importPrefix = + alias ?? + camelCase( + (dirname(fileToImport) + "/" + basename(fileToImport, extname(fileToImport))).replaceAll( + "__package__", + "root" + ) + ); if (file === RelativeFilePath.of(ROOT_API_FILENAME)) { if (this.rootApiFile.imports == null) { @@ -336,7 +350,11 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { public addEndpoint( file: RelativeFilePath, - { name, schema, source }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: Source | undefined } + { + name, + schema, + source + }: { name: string; schema: RawSchemas.HttpEndpointSchema; source: RawSchemas.SourceSchema | undefined } ): void { const fernFile = this.getOrCreateFile(file); if (fernFile.service == null) { @@ -347,7 +365,7 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { }; } if (source != null) { - fernFile.service.source = convertToSourceSchema(source); + fernFile.service.source = source; } fernFile.service.endpoints[name] = schema; } @@ -412,78 +430,6 @@ export class FernDefinitionBuilderImpl implements FernDefinitionBuilder { public build(): FernDefinition { const definitionFiles = this.root.getAllFiles(); - if (this.modifyBasePaths) { - const basePath = getSharedEnvironmentBasePath(this.rootApiFile); - - // substitute package marker file - if (this.packageMarkerFile.service != null) { - this.packageMarkerFile.service = { - ...this.packageMarkerFile.service, - endpoints: Object.fromEntries( - Object.entries(this.packageMarkerFile.service.endpoints).map(([id, endpoint]) => { - return [ - id, - { - ...endpoint, - path: `${basePath}${endpoint.path}` - } - ]; - }) - ) - }; - } - - // subsitute definition files - for (const file of Object.values(definitionFiles)) { - if (file.service != null) { - file.service = { - ...file.service, - endpoints: Object.fromEntries( - Object.entries(file.service.endpoints).map(([id, endpoint]) => { - return [ - id, - { - ...endpoint, - path: `${basePath}${endpoint.path}` - } - ]; - }) - ) - }; - } - } - - if (this.rootApiFile.environments != null) { - this.rootApiFile.environments = { - ...Object.fromEntries( - Object.entries(this.rootApiFile.environments).map(([env, url]) => { - if (typeof url === "string") { - return [env, url.substring(0, url.length - basePath.length)]; - } else if (isSingleBaseUrl(url)) { - return [ - env, - { - url: url.url.substring(0, url.url.length - basePath.length) - } - ]; - } else { - return [ - env, - { - urls: Object.fromEntries( - Object.entries(url.urls).map(([name, url]) => { - return [name, url.substring(0, url.length - basePath.length)]; - }) - ) - } - ]; - } - }) - ) - }; - } - } - const basePath = this.basePath; if (basePath != null) { // substitute package marker file diff --git a/packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionDirectory.test.ts b/packages/cli/api-importers/commons/src/__test__/FernDefinitionDirectory.test.ts similarity index 96% rename from packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionDirectory.test.ts rename to packages/cli/api-importers/commons/src/__test__/FernDefinitionDirectory.test.ts index a5dbffb84ec..1f4cc46c202 100644 --- a/packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionDirectory.test.ts +++ b/packages/cli/api-importers/commons/src/__test__/FernDefinitionDirectory.test.ts @@ -1,6 +1,6 @@ import { RawSchemas } from "@fern-api/fern-definition-schema"; import { RelativeFilePath } from "@fern-api/fs-utils"; -import { FernDefinitionDirectory } from "../FernDefinitionDirectory"; +import { FernDefinitionDirectory } from "../utils/FernDefinitionDirectory"; interface TestCase { description: string; diff --git a/packages/cli/api-importers/commons/src/index.ts b/packages/cli/api-importers/commons/src/index.ts new file mode 100644 index 00000000000..f442f3acb69 --- /dev/null +++ b/packages/cli/api-importers/commons/src/index.ts @@ -0,0 +1,2 @@ +export { APIDefinitionImporter } from "./APIDefinitionImporter"; +export { type FernDefinitionBuilder, FernDefinitionBuilderImpl, type FernDefinition } from "./FernDefnitionBuilder"; diff --git a/packages/cli/openapi-ir-to-fern/src/FernDefinitionDirectory.ts b/packages/cli/api-importers/commons/src/utils/FernDefinitionDirectory.ts similarity index 100% rename from packages/cli/openapi-ir-to-fern/src/FernDefinitionDirectory.ts rename to packages/cli/api-importers/commons/src/utils/FernDefinitionDirectory.ts diff --git a/packages/cli/api-importers/commons/tsconfig.json b/packages/cli/api-importers/commons/tsconfig.json new file mode 100644 index 00000000000..4fdc4e44eab --- /dev/null +++ b/packages/cli/api-importers/commons/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../../shared/tsconfig.shared.json", + "compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" }, + "include": ["./src/**/*"], + "references": [ + { "path": "../../../cli/fern-definition/schema" }, + { "path": "../../../commons/core-utils" }, + { "path": "../../task-context" }, + { "path": "../../../commons/fs-utils" }, + ] +} diff --git a/packages/cli/api-importers/commons/vitest.config.ts b/packages/cli/api-importers/commons/vitest.config.ts new file mode 100644 index 00000000000..d11017dc676 --- /dev/null +++ b/packages/cli/api-importers/commons/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../../../shared/vitest.config"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/.depcheckrc.json b/packages/cli/api-importers/conjure/conjure-sdk/.depcheckrc.json new file mode 100644 index 00000000000..a3a4f43188c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/.depcheckrc.json @@ -0,0 +1,10 @@ +{ + "ignores": [ + "@types/jest", + "globals", + "@types/node" + ], + "ignore-patterns": [ + "lib" + ] +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-sdk/.fernignore b/packages/cli/api-importers/conjure/conjure-sdk/.fernignore new file mode 100644 index 00000000000..a2e78d7482c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/.fernignore @@ -0,0 +1 @@ +index.ts \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-sdk/.prettierrc.cjs b/packages/cli/api-importers/conjure/conjure-sdk/.prettierrc.cjs new file mode 100644 index 00000000000..38a3889281f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("../../../../../.prettierrc.json"); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/api.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/api.yml new file mode 100644 index 00000000000..d690c18ec85 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/api.yml @@ -0,0 +1,7 @@ +name: conjure +docs: | + This API Definition captures the Conjure API Schema. + This schema is built for Fern's Conjure importer, which + +error-discrimination: + strategy: status-code diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/commons.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/commons.yml new file mode 100644 index 00000000000..9613febb1df --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/commons.yml @@ -0,0 +1,4 @@ +types: + WithDocs: + properties: + docs: optional diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/conjure.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/conjure.yml new file mode 100644 index 00000000000..9825b846c7e --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/conjure.yml @@ -0,0 +1,13 @@ +imports: + types: types.yml + services: services.yml + +types: + ConjureServiceName: + type: string + + DefinitionFile: + properties: + imports: optional> + types: optional + services: optional> diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/services.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/services.yml new file mode 100644 index 00000000000..1cddd89e517 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/services.yml @@ -0,0 +1,43 @@ +imports: + commons: commons.yml + types: types.yml + +types: + ConjureService: + extends: + - commons.WithDocs + properties: + name: optional + package: optional + base-path: optional + endpoints: optional> + + ConjureEndpoint: + extends: + - commons.WithDocs + properties: + http: + type: string + docs: The method and path (e.g. GET /users) + args: + type: optional> + returns: optional + + ConjureArgument: + discriminated: false + union: + - types.ConjureTypeReference + - ConjureArgumentWithParamType + + ConjureArgumentWithParamType: + extends: + - commons.WithDocs + properties: + param-type: ConjureParamType + type: types.ConjureTypeReference + + ConjureParamType: + enum: + - path + - query + - body diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/types.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/types.yml new file mode 100644 index 00000000000..c8a17e5d005 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/definition/types.yml @@ -0,0 +1,62 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +types: + ConjureTypes: + properties: + "conjure-imports": optional> + "definitions": optional + + ConjureDefinitions: + properties: + objects: optional> + + ConjureTypeDeclaration: + discriminated: false + union: + - ConjureAliasDeclaration + - ConjureUnionDeclaration + - ConjureObjectDeclaration + - ConjureEnumDeclaration + + ConjureAliasDeclaration: + properties: + alias: ConjureType + docs: optional + + ConjureUnionDeclaration: + properties: + union: map + + ConjureObjectDeclaration: + properties: + fields: map + + ConjureEnumDeclaration: + properties: + values: list + + ConjureTypeReference: + discriminated: false + union: + - ConjureType + - ConjureTypeWithDocs + + ConjureType: + discriminated: false + union: + - ConjurePrimitive + - string + + ConjureTypeWithDocs: + properties: + type: ConjureType + docs: optional + + ConjurePrimitive: + enum: + - rid + - string + - safelong + - integer + - double + - boolean diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/fern.config.json b/packages/cli/api-importers/conjure/conjure-sdk/fern/fern.config.json new file mode 100644 index 00000000000..cfd312e2d08 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "fern", + "version": "0.37.6" +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-sdk/fern/generators.yml b/packages/cli/api-importers/conjure/conjure-sdk/fern/generators.yml new file mode 100644 index 00000000000..90afb829a5a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/fern/generators.yml @@ -0,0 +1,12 @@ +default-group: local +groups: + local: + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.38.6 + output: + location: local-file-system + path: ../src/sdk + config: + outputSourceFiles: true + noOptionalProperties: true \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-sdk/package.json b/packages/cli/api-importers/conjure/conjure-sdk/package.json new file mode 100644 index 00000000000..e864f4d6f23 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/package.json @@ -0,0 +1,40 @@ +{ + "name": "@fern-api/conjure-sdk", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "https://github.com/fern-api/fern.git", + "directory": "packages/ir-sdk" + }, + "private": true, + "files": [ + "lib" + ], + "type": "module", + "source": "src/index.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "sideEffects": false, + "scripts": { + "clean": "rm -rf ./lib && tsc --build --clean", + "compile": "tsc --build", + "test": "vitest --run --passWithNoTests", + "test:update": "vitest --run --passWithNoTests -u", + "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../.eslintignore", + "lint:eslint:fix": "yarn lint:eslint --fix", + "format": "prettier --write --ignore-unknown --ignore-path ../../shared/.prettierignore \"**\"", + "format:check": "prettier --check --ignore-unknown --ignore-path ../../shared/.prettierignore \"**\"", + "organize-imports": "organize-imports-cli tsconfig.json", + "depcheck": "depcheck", + "generate": "fern generate --local" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "^18.7.18", + "depcheck": "^1.4.6", + "eslint": "^8.56.0", + "organize-imports-cli": "^0.10.0", + "prettier": "^2.7.1", + "typescript": "4.6.4" + } +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/index.ts new file mode 100644 index 00000000000..78e6bf6d5b6 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/index.ts @@ -0,0 +1,3 @@ +export * from "./sdk"; +export * from "./sdk/api"; +export * as serialization from "./sdk/serialization"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/index.ts new file mode 100644 index 00000000000..3e5335fe421 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/index.ts @@ -0,0 +1 @@ +export * from "./resources"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/WithDocs.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/WithDocs.ts new file mode 100644 index 00000000000..307969c10bc --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/WithDocs.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface WithDocs { + docs: string | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/index.ts new file mode 100644 index 00000000000..5408dd522d6 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/commons/types/index.ts @@ -0,0 +1 @@ +export * from "./WithDocs"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/ConjureServiceName.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/ConjureServiceName.ts new file mode 100644 index 00000000000..705b8c52f1b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/ConjureServiceName.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ConjureServiceName = string; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/DefinitionFile.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/DefinitionFile.ts new file mode 100644 index 00000000000..237ab0375de --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/DefinitionFile.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface DefinitionFile { + imports: Record | undefined; + types: FernConjure.ConjureTypes | undefined; + services: Record | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/index.ts new file mode 100644 index 00000000000..e9a7aafde8c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/conjure/types/index.ts @@ -0,0 +1,2 @@ +export * from "./ConjureServiceName"; +export * from "./DefinitionFile"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/index.ts new file mode 100644 index 00000000000..bb56beec27f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/index.ts @@ -0,0 +1,8 @@ +export * as commons from "./commons"; +export * from "./commons/types"; +export * as conjure from "./conjure"; +export * from "./conjure/types"; +export * as services from "./services"; +export * from "./services/types"; +export * as types from "./types"; +export * from "./types/types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgument.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgument.ts new file mode 100644 index 00000000000..9eed615331d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgument.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export type ConjureArgument = FernConjure.ConjureTypeReference | FernConjure.ConjureArgumentWithParamType; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgumentWithParamType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgumentWithParamType.ts new file mode 100644 index 00000000000..c87feca68f0 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureArgumentWithParamType.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureArgumentWithParamType extends FernConjure.WithDocs { + paramType: FernConjure.ConjureParamType; + type: FernConjure.ConjureTypeReference; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureEndpoint.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureEndpoint.ts new file mode 100644 index 00000000000..91f7fa80e65 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureEndpoint.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureEndpoint extends FernConjure.WithDocs { + /** The method and path (e.g. GET /users) */ + http: string; + args: Record | undefined; + returns: FernConjure.ConjureTypeReference | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureParamType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureParamType.ts new file mode 100644 index 00000000000..2e28a4b72b2 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureParamType.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ConjureParamType = "path" | "query" | "body"; + +export const ConjureParamType = { + Path: "path", + Query: "query", + Body: "body", +} as const; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureService.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureService.ts new file mode 100644 index 00000000000..55d65303034 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/ConjureService.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureService extends FernConjure.WithDocs { + name: string | undefined; + package: string | undefined; + basePath: string | undefined; + endpoints: Record | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/index.ts new file mode 100644 index 00000000000..8c1cbd2fcc7 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/services/types/index.ts @@ -0,0 +1,5 @@ +export * from "./ConjureService"; +export * from "./ConjureEndpoint"; +export * from "./ConjureArgument"; +export * from "./ConjureArgumentWithParamType"; +export * from "./ConjureParamType"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureAliasDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureAliasDeclaration.ts new file mode 100644 index 00000000000..3ac7eb64033 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureAliasDeclaration.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureAliasDeclaration { + alias: FernConjure.ConjureType; + docs: string | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureDefinitions.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureDefinitions.ts new file mode 100644 index 00000000000..af80d116cc3 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureDefinitions.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureDefinitions { + objects: Record | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureEnumDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureEnumDeclaration.ts new file mode 100644 index 00000000000..bbc99952fb1 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureEnumDeclaration.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ConjureEnumDeclaration { + values: string[]; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureObjectDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureObjectDeclaration.ts new file mode 100644 index 00000000000..3458b24f726 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureObjectDeclaration.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureObjectDeclaration { + fields: Record; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjurePrimitive.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjurePrimitive.ts new file mode 100644 index 00000000000..e6f2107621b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjurePrimitive.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ConjurePrimitive = "rid" | "string" | "safelong" | "integer" | "double" | "boolean"; + +export const ConjurePrimitive = { + Rid: "rid", + String: "string", + Safelong: "safelong", + Integer: "integer", + Double: "double", + Boolean: "boolean", +} as const; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureType.ts new file mode 100644 index 00000000000..3300a09f050 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureType.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export type ConjureType = FernConjure.ConjurePrimitive | string; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeDeclaration.ts new file mode 100644 index 00000000000..9e8301dae04 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeDeclaration.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export type ConjureTypeDeclaration = + | FernConjure.ConjureAliasDeclaration + | FernConjure.ConjureUnionDeclaration + | FernConjure.ConjureObjectDeclaration + | FernConjure.ConjureEnumDeclaration; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeReference.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeReference.ts new file mode 100644 index 00000000000..b36dcd15367 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeReference.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export type ConjureTypeReference = FernConjure.ConjureType | FernConjure.ConjureTypeWithDocs; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeWithDocs.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeWithDocs.ts new file mode 100644 index 00000000000..573b6d488b7 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypeWithDocs.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureTypeWithDocs { + type: FernConjure.ConjureType; + docs: string | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypes.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypes.ts new file mode 100644 index 00000000000..cc957ae5933 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureTypes.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureTypes { + conjureImports: Record | undefined; + definitions: FernConjure.ConjureDefinitions | undefined; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureUnionDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureUnionDeclaration.ts new file mode 100644 index 00000000000..dce2af4e14a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/ConjureUnionDeclaration.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernConjure from "../../../index"; + +export interface ConjureUnionDeclaration { + union: Record; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/index.ts new file mode 100644 index 00000000000..cba7dfc00f4 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/api/resources/types/types/index.ts @@ -0,0 +1,11 @@ +export * from "./ConjureTypes"; +export * from "./ConjureDefinitions"; +export * from "./ConjureTypeDeclaration"; +export * from "./ConjureAliasDeclaration"; +export * from "./ConjureUnionDeclaration"; +export * from "./ConjureObjectDeclaration"; +export * from "./ConjureEnumDeclaration"; +export * from "./ConjureTypeReference"; +export * from "./ConjureType"; +export * from "./ConjureTypeWithDocs"; +export * from "./ConjurePrimitive"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/index.ts new file mode 100644 index 00000000000..3ae53c06d38 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/index.ts @@ -0,0 +1 @@ +export * as serialization from "./schemas"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/Schema.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/Schema.ts new file mode 100644 index 00000000000..19acc5dc44b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/Schema.ts @@ -0,0 +1,98 @@ +import { SchemaUtils } from "./builders"; + +export type Schema = BaseSchema & SchemaUtils; + +export type inferRaw = S extends Schema ? Raw : never; +export type inferParsed = S extends Schema ? Parsed : never; + +export interface BaseSchema { + parse: (raw: unknown, opts?: SchemaOptions) => MaybeValid; + json: (parsed: unknown, opts?: SchemaOptions) => MaybeValid; + getType: () => SchemaType | SchemaType; +} + +export const SchemaType = { + DATE: "date", + ENUM: "enum", + LIST: "list", + STRING_LITERAL: "stringLiteral", + BOOLEAN_LITERAL: "booleanLiteral", + OBJECT: "object", + ANY: "any", + BOOLEAN: "boolean", + NUMBER: "number", + STRING: "string", + UNKNOWN: "unknown", + RECORD: "record", + SET: "set", + UNION: "union", + UNDISCRIMINATED_UNION: "undiscriminatedUnion", + OPTIONAL: "optional", +} as const; +export type SchemaType = typeof SchemaType[keyof typeof SchemaType]; + +export type MaybeValid = Valid | Invalid; + +export interface Valid { + ok: true; + value: T; +} + +export interface Invalid { + ok: false; + errors: ValidationError[]; +} + +export interface ValidationError { + path: string[]; + message: string; +} + +export interface SchemaOptions { + /** + * how to handle unrecognized keys in objects + * + * @default "fail" + */ + unrecognizedObjectKeys?: "fail" | "passthrough" | "strip"; + + /** + * whether to fail when an unrecognized discriminant value is + * encountered in a union + * + * @default false + */ + allowUnrecognizedUnionMembers?: boolean; + + /** + * whether to fail when an unrecognized enum value is encountered + * + * @default false + */ + allowUnrecognizedEnumValues?: boolean; + + /** + * whether to allow data that doesn't conform to the schema. + * invalid data is passed through without transformation. + * + * when this is enabled, .parse() and .json() will always + * return `ok: true`. `.parseOrThrow()` and `.jsonOrThrow()` + * will never fail. + * + * @default false + */ + skipValidation?: boolean; + + /** + * each validation failure contains a "path" property, which is + * the breadcrumbs to the offending node in the JSON. you can supply + * a prefix that is prepended to all the errors' paths. this can be + * helpful for zurg's internal debug logging. + */ + breadcrumbsPrefix?: string[]; + + /** + * whether to send 'null' for optional properties explicitly set to 'undefined'. + */ + omitUndefined?: boolean; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/date.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/date.ts new file mode 100644 index 00000000000..b70f24b045a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/date.ts @@ -0,0 +1,65 @@ +import { BaseSchema, Schema, SchemaType } from "../../Schema"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { getSchemaUtils } from "../schema-utils"; + +// https://stackoverflow.com/questions/12756159/regex-and-iso8601-formatted-datetime +const ISO_8601_REGEX = + /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/; + +export function date(): Schema { + const baseSchema: BaseSchema = { + parse: (raw, { breadcrumbsPrefix = [] } = {}) => { + if (typeof raw !== "string") { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(raw, "string"), + }, + ], + }; + } + if (!ISO_8601_REGEX.test(raw)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(raw, "ISO 8601 date string"), + }, + ], + }; + } + return { + ok: true, + value: new Date(raw), + }; + }, + json: (date, { breadcrumbsPrefix = [] } = {}) => { + if (date instanceof Date) { + return { + ok: true, + value: date.toISOString(), + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(date, "Date object"), + }, + ], + }; + } + }, + getType: () => SchemaType.DATE, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/index.ts new file mode 100644 index 00000000000..187b29040f6 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/date/index.ts @@ -0,0 +1 @@ +export { date } from "./date"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/enum.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/enum.ts new file mode 100644 index 00000000000..c1e24d69dec --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/enum.ts @@ -0,0 +1,43 @@ +import { Schema, SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export function enum_(values: E): Schema { + const validValues = new Set(values); + + const schemaCreator = createIdentitySchemaCreator( + SchemaType.ENUM, + (value, { allowUnrecognizedEnumValues, breadcrumbsPrefix = [] } = {}) => { + if (typeof value !== "string") { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "string"), + }, + ], + }; + } + + if (!validValues.has(value) && !allowUnrecognizedEnumValues) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "enum"), + }, + ], + }; + } + + return { + ok: true, + value: value as U, + }; + } + ); + + return schemaCreator(); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/index.ts new file mode 100644 index 00000000000..fe6faed93e3 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/enum/index.ts @@ -0,0 +1 @@ +export { enum_ } from "./enum"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/index.ts new file mode 100644 index 00000000000..050cd2c4efb --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/index.ts @@ -0,0 +1,13 @@ +export * from "./date"; +export * from "./enum"; +export * from "./lazy"; +export * from "./list"; +export * from "./literals"; +export * from "./object"; +export * from "./object-like"; +export * from "./primitives"; +export * from "./record"; +export * from "./schema-utils"; +export * from "./set"; +export * from "./undiscriminated-union"; +export * from "./union"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/index.ts new file mode 100644 index 00000000000..77420fb031c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/index.ts @@ -0,0 +1,3 @@ +export { lazy } from "./lazy"; +export type { SchemaGetter } from "./lazy"; +export { lazyObject } from "./lazyObject"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazy.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazy.ts new file mode 100644 index 00000000000..835c61f8a56 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazy.ts @@ -0,0 +1,32 @@ +import { BaseSchema, Schema } from "../../Schema"; +import { getSchemaUtils } from "../schema-utils"; + +export type SchemaGetter> = () => SchemaType; + +export function lazy(getter: SchemaGetter>): Schema { + const baseSchema = constructLazyBaseSchema(getter); + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; +} + +export function constructLazyBaseSchema( + getter: SchemaGetter> +): BaseSchema { + return { + parse: (raw, opts) => getMemoizedSchema(getter).parse(raw, opts), + json: (parsed, opts) => getMemoizedSchema(getter).json(parsed, opts), + getType: () => getMemoizedSchema(getter).getType(), + }; +} + +type MemoizedGetter> = SchemaGetter & { __zurg_memoized?: SchemaType }; + +export function getMemoizedSchema>(getter: SchemaGetter): SchemaType { + const castedGetter = getter as MemoizedGetter; + if (castedGetter.__zurg_memoized == null) { + castedGetter.__zurg_memoized = getter(); + } + return castedGetter.__zurg_memoized; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazyObject.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazyObject.ts new file mode 100644 index 00000000000..38c9e28404b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/lazy/lazyObject.ts @@ -0,0 +1,20 @@ +import { getObjectUtils } from "../object"; +import { getObjectLikeUtils } from "../object-like"; +import { BaseObjectSchema, ObjectSchema } from "../object/types"; +import { getSchemaUtils } from "../schema-utils"; +import { constructLazyBaseSchema, getMemoizedSchema, SchemaGetter } from "./lazy"; + +export function lazyObject(getter: SchemaGetter>): ObjectSchema { + const baseSchema: BaseObjectSchema = { + ...constructLazyBaseSchema(getter), + _getRawProperties: () => getMemoizedSchema(getter)._getRawProperties(), + _getParsedProperties: () => getMemoizedSchema(getter)._getParsedProperties(), + }; + + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/index.ts new file mode 100644 index 00000000000..25f4bcc1737 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/index.ts @@ -0,0 +1 @@ +export { list } from "./list"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/list.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/list.ts new file mode 100644 index 00000000000..e4c5c4a4a99 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/list/list.ts @@ -0,0 +1,73 @@ +import { BaseSchema, MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { getSchemaUtils } from "../schema-utils"; + +export function list(schema: Schema): Schema { + const baseSchema: BaseSchema = { + parse: (raw, opts) => + validateAndTransformArray(raw, (item, index) => + schema.parse(item, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `[${index}]`], + }) + ), + json: (parsed, opts) => + validateAndTransformArray(parsed, (item, index) => + schema.json(item, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `[${index}]`], + }) + ), + getType: () => SchemaType.LIST, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; +} + +function validateAndTransformArray( + value: unknown, + transformItem: (item: Raw, index: number) => MaybeValid +): MaybeValid { + if (!Array.isArray(value)) { + return { + ok: false, + errors: [ + { + message: getErrorMessageForIncorrectType(value, "list"), + path: [], + }, + ], + }; + } + + const maybeValidItems = value.map((item, index) => transformItem(item, index)); + + return maybeValidItems.reduce>( + (acc, item) => { + if (acc.ok && item.ok) { + return { + ok: true, + value: [...acc.value, item.value], + }; + } + + const errors: ValidationError[] = []; + if (!acc.ok) { + errors.push(...acc.errors); + } + if (!item.ok) { + errors.push(...item.errors); + } + + return { + ok: false, + errors, + }; + }, + { ok: true, value: [] } + ); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/booleanLiteral.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/booleanLiteral.ts new file mode 100644 index 00000000000..a83d22cd48a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/booleanLiteral.ts @@ -0,0 +1,29 @@ +import { Schema, SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export function booleanLiteral(literal: V): Schema { + const schemaCreator = createIdentitySchemaCreator( + SchemaType.BOOLEAN_LITERAL, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (value === literal) { + return { + ok: true, + value: literal, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, `${literal.toString()}`), + }, + ], + }; + } + } + ); + + return schemaCreator(); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/index.ts new file mode 100644 index 00000000000..d2bf08fc6ca --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/index.ts @@ -0,0 +1,2 @@ +export { stringLiteral } from "./stringLiteral"; +export { booleanLiteral } from "./booleanLiteral"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/stringLiteral.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/stringLiteral.ts new file mode 100644 index 00000000000..3939b76b48d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/literals/stringLiteral.ts @@ -0,0 +1,29 @@ +import { Schema, SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export function stringLiteral(literal: V): Schema { + const schemaCreator = createIdentitySchemaCreator( + SchemaType.STRING_LITERAL, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (value === literal) { + return { + ok: true, + value: literal, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, `"${literal}"`), + }, + ], + }; + } + } + ); + + return schemaCreator(); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/getObjectLikeUtils.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/getObjectLikeUtils.ts new file mode 100644 index 00000000000..8331d08da89 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/getObjectLikeUtils.ts @@ -0,0 +1,79 @@ +import { BaseSchema } from "../../Schema"; +import { filterObject } from "../../utils/filterObject"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { isPlainObject } from "../../utils/isPlainObject"; +import { getSchemaUtils } from "../schema-utils"; +import { ObjectLikeSchema, ObjectLikeUtils } from "./types"; + +export function getObjectLikeUtils(schema: BaseSchema): ObjectLikeUtils { + return { + withParsedProperties: (properties) => withParsedProperties(schema, properties), + }; +} + +/** + * object-like utils are defined in one file to resolve issues with circular imports + */ + +export function withParsedProperties( + objectLike: BaseSchema, + properties: { [K in keyof Properties]: Properties[K] | ((parsed: ParsedObjectShape) => Properties[K]) } +): ObjectLikeSchema { + const objectSchema: BaseSchema = { + parse: (raw, opts) => { + const parsedObject = objectLike.parse(raw, opts); + if (!parsedObject.ok) { + return parsedObject; + } + + const additionalProperties = Object.entries(properties).reduce>( + (processed, [key, value]) => { + return { + ...processed, + [key]: typeof value === "function" ? value(parsedObject.value) : value, + }; + }, + {} + ); + + return { + ok: true, + value: { + ...parsedObject.value, + ...(additionalProperties as Properties), + }, + }; + }, + + json: (parsed, opts) => { + if (!isPlainObject(parsed)) { + return { + ok: false, + errors: [ + { + path: opts?.breadcrumbsPrefix ?? [], + message: getErrorMessageForIncorrectType(parsed, "object"), + }, + ], + }; + } + + // strip out added properties + const addedPropertyKeys = new Set(Object.keys(properties)); + const parsedWithoutAddedProperties = filterObject( + parsed, + Object.keys(parsed).filter((key) => !addedPropertyKeys.has(key)) + ); + + return objectLike.json(parsedWithoutAddedProperties as ParsedObjectShape, opts); + }, + + getType: () => objectLike.getType(), + }; + + return { + ...objectSchema, + ...getSchemaUtils(objectSchema), + ...getObjectLikeUtils(objectSchema), + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/index.ts new file mode 100644 index 00000000000..c342e72cf9d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/index.ts @@ -0,0 +1,2 @@ +export { getObjectLikeUtils, withParsedProperties } from "./getObjectLikeUtils"; +export type { ObjectLikeSchema, ObjectLikeUtils } from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/types.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/types.ts new file mode 100644 index 00000000000..75b3698729c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object-like/types.ts @@ -0,0 +1,11 @@ +import { BaseSchema, Schema } from "../../Schema"; + +export type ObjectLikeSchema = Schema & + BaseSchema & + ObjectLikeUtils; + +export interface ObjectLikeUtils { + withParsedProperties: >(properties: { + [K in keyof T]: T[K] | ((parsed: Parsed) => T[K]); + }) => ObjectLikeSchema; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/index.ts new file mode 100644 index 00000000000..e3f4388db28 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/index.ts @@ -0,0 +1,22 @@ +export { getObjectUtils, object } from "./object"; +export { objectWithoutOptionalProperties } from "./objectWithoutOptionalProperties"; +export type { + inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas, + inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas, +} from "./objectWithoutOptionalProperties"; +export { isProperty, property } from "./property"; +export type { Property } from "./property"; +export type { + BaseObjectSchema, + inferObjectSchemaFromPropertySchemas, + inferParsedObject, + inferParsedObjectFromPropertySchemas, + inferParsedPropertySchema, + inferRawKey, + inferRawObject, + inferRawObjectFromPropertySchemas, + inferRawPropertySchema, + ObjectSchema, + ObjectUtils, + PropertySchemas, +} from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/object.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/object.ts new file mode 100644 index 00000000000..e00136d72fc --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/object.ts @@ -0,0 +1,324 @@ +import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { entries } from "../../utils/entries"; +import { filterObject } from "../../utils/filterObject"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { isPlainObject } from "../../utils/isPlainObject"; +import { keys } from "../../utils/keys"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { partition } from "../../utils/partition"; +import { getObjectLikeUtils } from "../object-like"; +import { getSchemaUtils } from "../schema-utils"; +import { isProperty } from "./property"; +import { + BaseObjectSchema, + inferObjectSchemaFromPropertySchemas, + inferParsedObjectFromPropertySchemas, + inferRawObjectFromPropertySchemas, + ObjectSchema, + ObjectUtils, + PropertySchemas, +} from "./types"; + +interface ObjectPropertyWithRawKey { + rawKey: string; + parsedKey: string; + valueSchema: Schema; +} + +export function object>( + schemas: T +): inferObjectSchemaFromPropertySchemas { + const baseSchema: BaseObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectFromPropertySchemas + > = { + _getRawProperties: () => + Object.entries(schemas).map(([parsedKey, propertySchema]) => + isProperty(propertySchema) ? propertySchema.rawKey : parsedKey + ) as unknown as (keyof inferRawObjectFromPropertySchemas)[], + _getParsedProperties: () => keys(schemas) as unknown as (keyof inferParsedObjectFromPropertySchemas)[], + + parse: (raw, opts) => { + const rawKeyToProperty: Record = {}; + const requiredKeys: string[] = []; + + for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) { + const rawKey = isProperty(schemaOrObjectProperty) ? schemaOrObjectProperty.rawKey : parsedKey; + const valueSchema: Schema = isProperty(schemaOrObjectProperty) + ? schemaOrObjectProperty.valueSchema + : schemaOrObjectProperty; + + const property: ObjectPropertyWithRawKey = { + rawKey, + parsedKey: parsedKey as string, + valueSchema, + }; + + rawKeyToProperty[rawKey] = property; + + if (isSchemaRequired(valueSchema)) { + requiredKeys.push(rawKey); + } + } + + return validateAndTransformObject({ + value: raw, + requiredKeys, + getProperty: (rawKey) => { + const property = rawKeyToProperty[rawKey]; + if (property == null) { + return undefined; + } + return { + transformedKey: property.parsedKey, + transform: (propertyValue) => + property.valueSchema.parse(propertyValue, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), rawKey], + }), + }; + }, + unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, + skipValidation: opts?.skipValidation, + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + omitUndefined: opts?.omitUndefined, + }); + }, + + json: (parsed, opts) => { + const requiredKeys: string[] = []; + + for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) { + const valueSchema: Schema = isProperty(schemaOrObjectProperty) + ? schemaOrObjectProperty.valueSchema + : schemaOrObjectProperty; + + if (isSchemaRequired(valueSchema)) { + requiredKeys.push(parsedKey as string); + } + } + + return validateAndTransformObject({ + value: parsed, + requiredKeys, + getProperty: ( + parsedKey + ): { transformedKey: string; transform: (propertyValue: unknown) => MaybeValid } | undefined => { + const property = schemas[parsedKey as keyof T]; + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (property == null) { + return undefined; + } + + if (isProperty(property)) { + return { + transformedKey: property.rawKey, + transform: (propertyValue) => + property.valueSchema.json(propertyValue, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedKey], + }), + }; + } else { + return { + transformedKey: parsedKey, + transform: (propertyValue) => + property.json(propertyValue, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedKey], + }), + }; + } + }, + unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, + skipValidation: opts?.skipValidation, + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + omitUndefined: opts?.omitUndefined, + }); + }, + + getType: () => SchemaType.OBJECT, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; +} + +function validateAndTransformObject({ + value, + requiredKeys, + getProperty, + unrecognizedObjectKeys = "fail", + skipValidation = false, + breadcrumbsPrefix = [], +}: { + value: unknown; + requiredKeys: string[]; + getProperty: ( + preTransformedKey: string + ) => { transformedKey: string; transform: (propertyValue: unknown) => MaybeValid } | undefined; + unrecognizedObjectKeys: "fail" | "passthrough" | "strip" | undefined; + skipValidation: boolean | undefined; + breadcrumbsPrefix: string[] | undefined; + omitUndefined: boolean | undefined; +}): MaybeValid { + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } + + const missingRequiredKeys = new Set(requiredKeys); + const errors: ValidationError[] = []; + const transformed: Record = {}; + + for (const [preTransformedKey, preTransformedItemValue] of Object.entries(value)) { + const property = getProperty(preTransformedKey); + + if (property != null) { + missingRequiredKeys.delete(preTransformedKey); + + const value = property.transform(preTransformedItemValue); + if (value.ok) { + transformed[property.transformedKey] = value.value; + } else { + transformed[preTransformedKey] = preTransformedItemValue; + errors.push(...value.errors); + } + } else { + switch (unrecognizedObjectKeys) { + case "fail": + errors.push({ + path: [...breadcrumbsPrefix, preTransformedKey], + message: `Unexpected key "${preTransformedKey}"`, + }); + break; + case "strip": + break; + case "passthrough": + transformed[preTransformedKey] = preTransformedItemValue; + break; + } + } + } + + errors.push( + ...requiredKeys + .filter((key) => missingRequiredKeys.has(key)) + .map((key) => ({ + path: breadcrumbsPrefix, + message: `Missing required key "${key}"`, + })) + ); + + if (errors.length === 0 || skipValidation) { + return { + ok: true, + value: transformed as Transformed, + }; + } else { + return { + ok: false, + errors, + }; + } +} + +export function getObjectUtils(schema: BaseObjectSchema): ObjectUtils { + return { + extend: (extension: ObjectSchema) => { + const baseSchema: BaseObjectSchema = { + _getParsedProperties: () => [...schema._getParsedProperties(), ...extension._getParsedProperties()], + _getRawProperties: () => [...schema._getRawProperties(), ...extension._getRawProperties()], + parse: (raw, opts) => { + return validateAndTransformExtendedObject({ + extensionKeys: extension._getRawProperties(), + value: raw, + transformBase: (rawBase) => schema.parse(rawBase, opts), + transformExtension: (rawExtension) => extension.parse(rawExtension, opts), + }); + }, + json: (parsed, opts) => { + return validateAndTransformExtendedObject({ + extensionKeys: extension._getParsedProperties(), + value: parsed, + transformBase: (parsedBase) => schema.json(parsedBase, opts), + transformExtension: (parsedExtension) => extension.json(parsedExtension, opts), + }); + }, + getType: () => SchemaType.OBJECT, + }; + + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; + }, + }; +} + +function validateAndTransformExtendedObject({ + extensionKeys, + value, + transformBase, + transformExtension, +}: { + extensionKeys: (keyof PreTransformedExtension)[]; + value: unknown; + transformBase: (value: unknown) => MaybeValid; + transformExtension: (value: unknown) => MaybeValid; +}): MaybeValid { + const extensionPropertiesSet = new Set(extensionKeys); + const [extensionProperties, baseProperties] = partition(keys(value), (key) => + extensionPropertiesSet.has(key as keyof PreTransformedExtension) + ); + + const transformedBase = transformBase(filterObject(value, baseProperties)); + const transformedExtension = transformExtension(filterObject(value, extensionProperties)); + + if (transformedBase.ok && transformedExtension.ok) { + return { + ok: true, + value: { + ...transformedBase.value, + ...transformedExtension.value, + }, + }; + } else { + return { + ok: false, + errors: [ + ...(transformedBase.ok ? [] : transformedBase.errors), + ...(transformedExtension.ok ? [] : transformedExtension.errors), + ], + }; + } +} + +function isSchemaRequired(schema: Schema): boolean { + return !isSchemaOptional(schema); +} + +function isSchemaOptional(schema: Schema): boolean { + switch (schema.getType()) { + case SchemaType.ANY: + case SchemaType.UNKNOWN: + case SchemaType.OPTIONAL: + return true; + default: + return false; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/objectWithoutOptionalProperties.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/objectWithoutOptionalProperties.ts new file mode 100644 index 00000000000..a0951f48efc --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/objectWithoutOptionalProperties.ts @@ -0,0 +1,18 @@ +import { object } from "./object"; +import { inferParsedPropertySchema, inferRawObjectFromPropertySchemas, ObjectSchema, PropertySchemas } from "./types"; + +export function objectWithoutOptionalProperties>( + schemas: T +): inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas { + return object(schemas) as unknown as inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas; +} + +export type inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas> = + ObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas + >; + +export type inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas> = { + [K in keyof T]: inferParsedPropertySchema; +}; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/property.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/property.ts new file mode 100644 index 00000000000..d245c4b193a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/property.ts @@ -0,0 +1,23 @@ +import { Schema } from "../../Schema"; + +export function property( + rawKey: RawKey, + valueSchema: Schema +): Property { + return { + rawKey, + valueSchema, + isProperty: true, + }; +} + +export interface Property { + rawKey: RawKey; + valueSchema: Schema; + isProperty: true; +} + +export function isProperty>(maybeProperty: unknown): maybeProperty is O { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + return (maybeProperty as O).isProperty; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/types.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/types.ts new file mode 100644 index 00000000000..de9bb4074e5 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/object/types.ts @@ -0,0 +1,72 @@ +import { BaseSchema, inferParsed, inferRaw, Schema } from "../../Schema"; +import { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties"; +import { ObjectLikeUtils } from "../object-like"; +import { SchemaUtils } from "../schema-utils"; +import { Property } from "./property"; + +export type ObjectSchema = BaseObjectSchema & + ObjectLikeUtils & + ObjectUtils & + SchemaUtils; + +export interface BaseObjectSchema extends BaseSchema { + _getRawProperties: () => (keyof Raw)[]; + _getParsedProperties: () => (keyof Parsed)[]; +} + +export interface ObjectUtils { + extend: ( + schemas: ObjectSchema + ) => ObjectSchema; +} + +export type inferRawObject> = O extends ObjectSchema ? Raw : never; + +export type inferParsedObject> = O extends ObjectSchema + ? Parsed + : never; + +export type inferObjectSchemaFromPropertySchemas> = ObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectFromPropertySchemas +>; + +export type inferRawObjectFromPropertySchemas> = + addQuestionMarksToNullableProperties<{ + [ParsedKey in keyof T as inferRawKey]: inferRawPropertySchema; + }>; + +export type inferParsedObjectFromPropertySchemas> = + addQuestionMarksToNullableProperties<{ + [K in keyof T]: inferParsedPropertySchema; + }>; + +export type PropertySchemas = Record< + ParsedKeys, + Property | Schema +>; + +export type inferRawPropertySchema

| Schema> = P extends Property< + any, + infer Raw, + any +> + ? Raw + : P extends Schema + ? inferRaw

+ : never; + +export type inferParsedPropertySchema

| Schema> = P extends Property< + any, + any, + infer Parsed +> + ? Parsed + : P extends Schema + ? inferParsed

+ : never; + +export type inferRawKey< + ParsedKey extends string | number | symbol, + P extends Property | Schema +> = P extends Property ? Raw : ParsedKey; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/any.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/any.ts new file mode 100644 index 00000000000..fcaeb04255a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/any.ts @@ -0,0 +1,4 @@ +import { SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; + +export const any = createIdentitySchemaCreator(SchemaType.ANY, (value) => ({ ok: true, value })); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/boolean.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/boolean.ts new file mode 100644 index 00000000000..fad60562120 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/boolean.ts @@ -0,0 +1,25 @@ +import { SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export const boolean = createIdentitySchemaCreator( + SchemaType.BOOLEAN, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "boolean") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "boolean"), + }, + ], + }; + } + } +); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/index.ts new file mode 100644 index 00000000000..788f9416bfe --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/index.ts @@ -0,0 +1,5 @@ +export { any } from "./any"; +export { boolean } from "./boolean"; +export { number } from "./number"; +export { string } from "./string"; +export { unknown } from "./unknown"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/number.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/number.ts new file mode 100644 index 00000000000..c2689456936 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/number.ts @@ -0,0 +1,25 @@ +import { SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export const number = createIdentitySchemaCreator( + SchemaType.NUMBER, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "number") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "number"), + }, + ], + }; + } + } +); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/string.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/string.ts new file mode 100644 index 00000000000..949f1f2a630 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/string.ts @@ -0,0 +1,25 @@ +import { SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; + +export const string = createIdentitySchemaCreator( + SchemaType.STRING, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "string") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "string"), + }, + ], + }; + } + } +); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/unknown.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/unknown.ts new file mode 100644 index 00000000000..4d5249571f5 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/primitives/unknown.ts @@ -0,0 +1,4 @@ +import { SchemaType } from "../../Schema"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; + +export const unknown = createIdentitySchemaCreator(SchemaType.UNKNOWN, (value) => ({ ok: true, value })); diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/index.ts new file mode 100644 index 00000000000..82e25c5c2af --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/index.ts @@ -0,0 +1,2 @@ +export { record } from "./record"; +export type { BaseRecordSchema, RecordSchema } from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/record.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/record.ts new file mode 100644 index 00000000000..6683ac3609f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/record.ts @@ -0,0 +1,130 @@ +import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { entries } from "../../utils/entries"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { isPlainObject } from "../../utils/isPlainObject"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { getSchemaUtils } from "../schema-utils"; +import { BaseRecordSchema, RecordSchema } from "./types"; + +export function record( + keySchema: Schema, + valueSchema: Schema +): RecordSchema { + const baseSchema: BaseRecordSchema = { + parse: (raw, opts) => { + return validateAndTransformRecord({ + value: raw, + isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, + transformKey: (key) => + keySchema.parse(key, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key} (key)`], + }), + transformValue: (value, key) => + valueSchema.parse(value, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key}`], + }), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + json: (parsed, opts) => { + return validateAndTransformRecord({ + value: parsed, + isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, + transformKey: (key) => + keySchema.json(key, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key} (key)`], + }), + transformValue: (value, key) => + valueSchema.json(value, { + ...opts, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key}`], + }), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + getType: () => SchemaType.RECORD, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; +} + +function validateAndTransformRecord({ + value, + isKeyNumeric, + transformKey, + transformValue, + breadcrumbsPrefix = [], +}: { + value: unknown; + isKeyNumeric: boolean; + transformKey: (key: string | number) => MaybeValid; + transformValue: (value: unknown, key: string | number) => MaybeValid; + breadcrumbsPrefix: string[] | undefined; +}): MaybeValid> { + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } + + return entries(value).reduce>>( + (accPromise, [stringKey, value]) => { + // skip nullish keys + if (value == null) { + return accPromise; + } + + const acc = accPromise; + + let key: string | number = stringKey; + if (isKeyNumeric) { + const numberKey = stringKey.length > 0 ? Number(stringKey) : NaN; + if (!isNaN(numberKey)) { + key = numberKey; + } + } + const transformedKey = transformKey(key); + + const transformedValue = transformValue(value, key); + + if (acc.ok && transformedKey.ok && transformedValue.ok) { + return { + ok: true, + value: { + ...acc.value, + [transformedKey.value]: transformedValue.value, + }, + }; + } + + const errors: ValidationError[] = []; + if (!acc.ok) { + errors.push(...acc.errors); + } + if (!transformedKey.ok) { + errors.push(...transformedKey.errors); + } + if (!transformedValue.ok) { + errors.push(...transformedValue.errors); + } + + return { + ok: false, + errors, + }; + }, + { ok: true, value: {} as Record } + ); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/types.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/types.ts new file mode 100644 index 00000000000..eb82cc7f65c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/record/types.ts @@ -0,0 +1,17 @@ +import { BaseSchema } from "../../Schema"; +import { SchemaUtils } from "../schema-utils"; + +export type RecordSchema< + RawKey extends string | number, + RawValue, + ParsedKey extends string | number, + ParsedValue +> = BaseRecordSchema & + SchemaUtils, Record>; + +export type BaseRecordSchema< + RawKey extends string | number, + RawValue, + ParsedKey extends string | number, + ParsedValue +> = BaseSchema, Record>; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/JsonError.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/JsonError.ts new file mode 100644 index 00000000000..2b89ca0e7ad --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/JsonError.ts @@ -0,0 +1,9 @@ +import { ValidationError } from "../../Schema"; +import { stringifyValidationError } from "./stringifyValidationErrors"; + +export class JsonError extends Error { + constructor(public readonly errors: ValidationError[]) { + super(errors.map(stringifyValidationError).join("; ")); + Object.setPrototypeOf(this, JsonError.prototype); + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/ParseError.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/ParseError.ts new file mode 100644 index 00000000000..d056eb45cf7 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/ParseError.ts @@ -0,0 +1,9 @@ +import { ValidationError } from "../../Schema"; +import { stringifyValidationError } from "./stringifyValidationErrors"; + +export class ParseError extends Error { + constructor(public readonly errors: ValidationError[]) { + super(errors.map(stringifyValidationError).join("; ")); + Object.setPrototypeOf(this, ParseError.prototype); + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/getSchemaUtils.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/getSchemaUtils.ts new file mode 100644 index 00000000000..79ecad92132 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/getSchemaUtils.ts @@ -0,0 +1,105 @@ +import { BaseSchema, Schema, SchemaOptions, SchemaType } from "../../Schema"; +import { JsonError } from "./JsonError"; +import { ParseError } from "./ParseError"; + +export interface SchemaUtils { + optional: () => Schema; + transform: (transformer: SchemaTransformer) => Schema; + parseOrThrow: (raw: unknown, opts?: SchemaOptions) => Parsed; + jsonOrThrow: (raw: unknown, opts?: SchemaOptions) => Raw; +} + +export interface SchemaTransformer { + transform: (parsed: Parsed) => Transformed; + untransform: (transformed: any) => Parsed; +} + +export function getSchemaUtils(schema: BaseSchema): SchemaUtils { + return { + optional: () => optional(schema), + transform: (transformer) => transform(schema, transformer), + parseOrThrow: (raw, opts) => { + const parsed = schema.parse(raw, opts); + if (parsed.ok) { + return parsed.value; + } + throw new ParseError(parsed.errors); + }, + jsonOrThrow: (parsed, opts) => { + const raw = schema.json(parsed, opts); + if (raw.ok) { + return raw.value; + } + throw new JsonError(raw.errors); + }, + }; +} + +/** + * schema utils are defined in one file to resolve issues with circular imports + */ + +export function optional( + schema: BaseSchema +): Schema { + const baseSchema: BaseSchema = { + parse: (raw, opts) => { + if (raw == null) { + return { + ok: true, + value: undefined, + }; + } + return schema.parse(raw, opts); + }, + json: (parsed, opts) => { + if (opts?.omitUndefined && parsed === undefined) { + return { + ok: true, + value: undefined, + }; + } + if (parsed == null) { + return { + ok: true, + value: null, + }; + } + return schema.json(parsed, opts); + }, + getType: () => SchemaType.OPTIONAL, + }; + + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; +} + +export function transform( + schema: BaseSchema, + transformer: SchemaTransformer +): Schema { + const baseSchema: BaseSchema = { + parse: (raw, opts) => { + const parsed = schema.parse(raw, opts); + if (!parsed.ok) { + return parsed; + } + return { + ok: true, + value: transformer.transform(parsed.value), + }; + }, + json: (transformed, opts) => { + const parsed = transformer.untransform(transformed); + return schema.json(parsed, opts); + }, + getType: () => schema.getType(), + }; + + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/index.ts new file mode 100644 index 00000000000..aa04e051dfa --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/index.ts @@ -0,0 +1,4 @@ +export { getSchemaUtils, optional, transform } from "./getSchemaUtils"; +export type { SchemaUtils } from "./getSchemaUtils"; +export { JsonError } from "./JsonError"; +export { ParseError } from "./ParseError"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/stringifyValidationErrors.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/stringifyValidationErrors.ts new file mode 100644 index 00000000000..4160f0a2617 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/schema-utils/stringifyValidationErrors.ts @@ -0,0 +1,8 @@ +import { ValidationError } from "../../Schema"; + +export function stringifyValidationError(error: ValidationError): string { + if (error.path.length === 0) { + return error.message; + } + return `${error.path.join(" -> ")}: ${error.message}`; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/index.ts new file mode 100644 index 00000000000..f3310e8bdad --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/index.ts @@ -0,0 +1 @@ +export { set } from "./set"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/set.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/set.ts new file mode 100644 index 00000000000..e9e6bb7e539 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/set/set.ts @@ -0,0 +1,43 @@ +import { BaseSchema, Schema, SchemaType } from "../../Schema"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { list } from "../list"; +import { getSchemaUtils } from "../schema-utils"; + +export function set(schema: Schema): Schema> { + const listSchema = list(schema); + const baseSchema: BaseSchema> = { + parse: (raw, opts) => { + const parsedList = listSchema.parse(raw, opts); + if (parsedList.ok) { + return { + ok: true, + value: new Set(parsedList.value), + }; + } else { + return parsedList; + } + }, + json: (parsed, opts) => { + if (!(parsed instanceof Set)) { + return { + ok: false, + errors: [ + { + path: opts?.breadcrumbsPrefix ?? [], + message: getErrorMessageForIncorrectType(parsed, "Set"), + }, + ], + }; + } + const jsonList = listSchema.json([...parsed], opts); + return jsonList; + }, + getType: () => SchemaType.SET, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/index.ts new file mode 100644 index 00000000000..75b71cb3565 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/index.ts @@ -0,0 +1,6 @@ +export type { + inferParsedUnidiscriminatedUnionSchema, + inferRawUnidiscriminatedUnionSchema, + UndiscriminatedUnionSchema, +} from "./types"; +export { undiscriminatedUnion } from "./undiscriminatedUnion"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/types.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/types.ts new file mode 100644 index 00000000000..43e7108a060 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/types.ts @@ -0,0 +1,10 @@ +import { inferParsed, inferRaw, Schema } from "../../Schema"; + +export type UndiscriminatedUnionSchema = Schema< + inferRawUnidiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema +>; + +export type inferRawUnidiscriminatedUnionSchema = inferRaw; + +export type inferParsedUnidiscriminatedUnionSchema = inferParsed; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts new file mode 100644 index 00000000000..21ed3df0f40 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts @@ -0,0 +1,60 @@ +import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType, ValidationError } from "../../Schema"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { getSchemaUtils } from "../schema-utils"; +import { inferParsedUnidiscriminatedUnionSchema, inferRawUnidiscriminatedUnionSchema } from "./types"; + +export function undiscriminatedUnion, ...Schema[]]>( + schemas: Schemas +): Schema, inferParsedUnidiscriminatedUnionSchema> { + const baseSchema: BaseSchema< + inferRawUnidiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema + > = { + parse: (raw, opts) => { + return validateAndTransformUndiscriminatedUnion>( + (schema, opts) => schema.parse(raw, opts), + schemas, + opts + ); + }, + json: (parsed, opts) => { + return validateAndTransformUndiscriminatedUnion>( + (schema, opts) => schema.json(parsed, opts), + schemas, + opts + ); + }, + getType: () => SchemaType.UNDISCRIMINATED_UNION, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; +} + +function validateAndTransformUndiscriminatedUnion( + transform: (schema: Schema, opts: SchemaOptions) => MaybeValid, + schemas: Schema[], + opts: SchemaOptions | undefined +): MaybeValid { + const errors: ValidationError[] = []; + for (const [index, schema] of schemas.entries()) { + const transformed = transform(schema, { ...opts, skipValidation: false }); + if (transformed.ok) { + return transformed; + } else { + for (const error of transformed.errors) { + errors.push({ + path: error.path, + message: `[Variant ${index}] ${error.message}`, + }); + } + } + } + + return { + ok: false, + errors, + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/discriminant.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/discriminant.ts new file mode 100644 index 00000000000..55065bc8946 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/discriminant.ts @@ -0,0 +1,14 @@ +export function discriminant( + parsedDiscriminant: ParsedDiscriminant, + rawDiscriminant: RawDiscriminant +): Discriminant { + return { + parsedDiscriminant, + rawDiscriminant, + }; +} + +export interface Discriminant { + parsedDiscriminant: ParsedDiscriminant; + rawDiscriminant: RawDiscriminant; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/index.ts new file mode 100644 index 00000000000..85fc008a2d8 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/index.ts @@ -0,0 +1,10 @@ +export { discriminant } from "./discriminant"; +export type { Discriminant } from "./discriminant"; +export type { + inferParsedDiscriminant, + inferParsedUnion, + inferRawDiscriminant, + inferRawUnion, + UnionSubtypes, +} from "./types"; +export { union } from "./union"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/types.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/types.ts new file mode 100644 index 00000000000..6f82c868b2d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/types.ts @@ -0,0 +1,26 @@ +import { inferParsedObject, inferRawObject, ObjectSchema } from "../object"; +import { Discriminant } from "./discriminant"; + +export type UnionSubtypes = { + [K in DiscriminantValues]: ObjectSchema; +}; + +export type inferRawUnion, U extends UnionSubtypes> = { + [K in keyof U]: Record, K> & inferRawObject; +}[keyof U]; + +export type inferParsedUnion, U extends UnionSubtypes> = { + [K in keyof U]: Record, K> & inferParsedObject; +}[keyof U]; + +export type inferRawDiscriminant> = D extends string + ? D + : D extends Discriminant + ? Raw + : never; + +export type inferParsedDiscriminant> = D extends string + ? D + : D extends Discriminant + ? Parsed + : never; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/union.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/union.ts new file mode 100644 index 00000000000..ab61475a572 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/builders/union/union.ts @@ -0,0 +1,170 @@ +import { BaseSchema, MaybeValid, SchemaType } from "../../Schema"; +import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; +import { isPlainObject } from "../../utils/isPlainObject"; +import { keys } from "../../utils/keys"; +import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; +import { enum_ } from "../enum"; +import { ObjectSchema } from "../object"; +import { getObjectLikeUtils, ObjectLikeSchema } from "../object-like"; +import { getSchemaUtils } from "../schema-utils"; +import { Discriminant } from "./discriminant"; +import { inferParsedDiscriminant, inferParsedUnion, inferRawDiscriminant, inferRawUnion, UnionSubtypes } from "./types"; + +export function union, U extends UnionSubtypes>( + discriminant: D, + union: U +): ObjectLikeSchema, inferParsedUnion> { + const rawDiscriminant = + typeof discriminant === "string" ? discriminant : (discriminant.rawDiscriminant as inferRawDiscriminant); + const parsedDiscriminant = + typeof discriminant === "string" + ? discriminant + : (discriminant.parsedDiscriminant as inferParsedDiscriminant); + + const discriminantValueSchema = enum_(keys(union) as string[]); + + const baseSchema: BaseSchema, inferParsedUnion> = { + parse: (raw, opts) => { + return transformAndValidateUnion({ + value: raw, + discriminant: rawDiscriminant, + transformedDiscriminant: parsedDiscriminant, + transformDiscriminantValue: (discriminantValue) => + discriminantValueSchema.parse(discriminantValue, { + allowUnrecognizedEnumValues: opts?.allowUnrecognizedUnionMembers, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), rawDiscriminant], + }), + getAdditionalPropertiesSchema: (discriminantValue) => union[discriminantValue], + allowUnrecognizedUnionMembers: opts?.allowUnrecognizedUnionMembers, + transformAdditionalProperties: (additionalProperties, additionalPropertiesSchema) => + additionalPropertiesSchema.parse(additionalProperties, opts), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + json: (parsed, opts) => { + return transformAndValidateUnion({ + value: parsed, + discriminant: parsedDiscriminant, + transformedDiscriminant: rawDiscriminant, + transformDiscriminantValue: (discriminantValue) => + discriminantValueSchema.json(discriminantValue, { + allowUnrecognizedEnumValues: opts?.allowUnrecognizedUnionMembers, + breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedDiscriminant], + }), + getAdditionalPropertiesSchema: (discriminantValue) => union[discriminantValue], + allowUnrecognizedUnionMembers: opts?.allowUnrecognizedUnionMembers, + transformAdditionalProperties: (additionalProperties, additionalPropertiesSchema) => + additionalPropertiesSchema.json(additionalProperties, opts), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + getType: () => SchemaType.UNION, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + }; +} + +function transformAndValidateUnion< + TransformedDiscriminant extends string, + TransformedDiscriminantValue extends string, + TransformedAdditionalProperties +>({ + value, + discriminant, + transformedDiscriminant, + transformDiscriminantValue, + getAdditionalPropertiesSchema, + allowUnrecognizedUnionMembers = false, + transformAdditionalProperties, + breadcrumbsPrefix = [], +}: { + value: unknown; + discriminant: string; + transformedDiscriminant: TransformedDiscriminant; + transformDiscriminantValue: (discriminantValue: unknown) => MaybeValid; + getAdditionalPropertiesSchema: (discriminantValue: string) => ObjectSchema | undefined; + allowUnrecognizedUnionMembers: boolean | undefined; + transformAdditionalProperties: ( + additionalProperties: unknown, + additionalPropertiesSchema: ObjectSchema + ) => MaybeValid; + breadcrumbsPrefix: string[] | undefined; +}): MaybeValid & TransformedAdditionalProperties> { + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } + + const { [discriminant]: discriminantValue, ...additionalProperties } = value; + + if (discriminantValue == null) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: `Missing discriminant ("${discriminant}")`, + }, + ], + }; + } + + const transformedDiscriminantValue = transformDiscriminantValue(discriminantValue); + if (!transformedDiscriminantValue.ok) { + return { + ok: false, + errors: transformedDiscriminantValue.errors, + }; + } + + const additionalPropertiesSchema = getAdditionalPropertiesSchema(transformedDiscriminantValue.value); + + if (additionalPropertiesSchema == null) { + if (allowUnrecognizedUnionMembers) { + return { + ok: true, + value: { + [transformedDiscriminant]: transformedDiscriminantValue.value, + ...additionalProperties, + } as Record & TransformedAdditionalProperties, + }; + } else { + return { + ok: false, + errors: [ + { + path: [...breadcrumbsPrefix, discriminant], + message: "Unexpected discriminant value", + }, + ], + }; + } + } + + const transformedAdditionalProperties = transformAdditionalProperties( + additionalProperties, + additionalPropertiesSchema + ); + if (!transformedAdditionalProperties.ok) { + return transformedAdditionalProperties; + } + + return { + ok: true, + value: { + [transformedDiscriminant]: discriminantValue, + ...transformedAdditionalProperties.value, + } as Record & TransformedAdditionalProperties, + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/index.ts new file mode 100644 index 00000000000..5429d8b43eb --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/index.ts @@ -0,0 +1,2 @@ +export * from "./builders"; +export type { inferParsed, inferRaw, Schema, SchemaOptions } from "./Schema"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/MaybePromise.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/MaybePromise.ts new file mode 100644 index 00000000000..9cd354b3418 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/MaybePromise.ts @@ -0,0 +1 @@ +export type MaybePromise = T | Promise; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/addQuestionMarksToNullableProperties.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/addQuestionMarksToNullableProperties.ts new file mode 100644 index 00000000000..4111d703cd0 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/addQuestionMarksToNullableProperties.ts @@ -0,0 +1,15 @@ +export type addQuestionMarksToNullableProperties = { + [K in OptionalKeys]?: T[K]; +} & Pick>; + +export type OptionalKeys = { + [K in keyof T]-?: undefined extends T[K] + ? K + : null extends T[K] + ? K + : 1 extends (any extends T[K] ? 0 : 1) + ? never + : K; +}[keyof T]; + +export type RequiredKeys = Exclude>; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/createIdentitySchemaCreator.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/createIdentitySchemaCreator.ts new file mode 100644 index 00000000000..de107cf5ee1 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/createIdentitySchemaCreator.ts @@ -0,0 +1,21 @@ +import { getSchemaUtils } from "../builders/schema-utils"; +import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType } from "../Schema"; +import { maybeSkipValidation } from "./maybeSkipValidation"; + +export function createIdentitySchemaCreator( + schemaType: SchemaType, + validate: (value: unknown, opts?: SchemaOptions) => MaybeValid +): () => Schema { + return () => { + const baseSchema: BaseSchema = { + parse: validate, + json: validate, + getType: () => schemaType, + }; + + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/entries.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/entries.ts new file mode 100644 index 00000000000..e122952137d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/entries.ts @@ -0,0 +1,3 @@ +export function entries(object: T): [keyof T, T[keyof T]][] { + return Object.entries(object) as [keyof T, T[keyof T]][]; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/filterObject.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/filterObject.ts new file mode 100644 index 00000000000..2c25a3455bc --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/filterObject.ts @@ -0,0 +1,10 @@ +export function filterObject(obj: T, keysToInclude: K[]): Pick { + const keysToIncludeSet = new Set(keysToInclude); + return Object.entries(obj).reduce((acc, [key, value]) => { + if (keysToIncludeSet.has(key as K)) { + acc[key as K] = value; + } + return acc; + // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter + }, {} as Pick); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/getErrorMessageForIncorrectType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/getErrorMessageForIncorrectType.ts new file mode 100644 index 00000000000..438012df418 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/getErrorMessageForIncorrectType.ts @@ -0,0 +1,21 @@ +export function getErrorMessageForIncorrectType(value: unknown, expectedType: string): string { + return `Expected ${expectedType}. Received ${getTypeAsString(value)}.`; +} + +function getTypeAsString(value: unknown): string { + if (Array.isArray(value)) { + return "list"; + } + if (value === null) { + return "null"; + } + switch (typeof value) { + case "string": + return `"${value}"`; + case "number": + case "boolean": + case "undefined": + return `${value}`; + } + return typeof value; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/isPlainObject.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/isPlainObject.ts new file mode 100644 index 00000000000..db82a722c35 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/isPlainObject.ts @@ -0,0 +1,17 @@ +// borrowed from https://github.com/lodash/lodash/blob/master/isPlainObject.js +export function isPlainObject(value: unknown): value is Record { + if (typeof value !== "object" || value === null) { + return false; + } + + if (Object.getPrototypeOf(value) === null) { + return true; + } + + let proto = value; + while (Object.getPrototypeOf(proto) !== null) { + proto = Object.getPrototypeOf(proto); + } + + return Object.getPrototypeOf(value) === proto; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/keys.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/keys.ts new file mode 100644 index 00000000000..01867098287 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/keys.ts @@ -0,0 +1,3 @@ +export function keys(object: T): (keyof T)[] { + return Object.keys(object) as (keyof T)[]; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/maybeSkipValidation.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/maybeSkipValidation.ts new file mode 100644 index 00000000000..86c07abf2b4 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/maybeSkipValidation.ts @@ -0,0 +1,38 @@ +import { BaseSchema, MaybeValid, SchemaOptions } from "../Schema"; + +export function maybeSkipValidation, Raw, Parsed>(schema: S): S { + return { + ...schema, + json: transformAndMaybeSkipValidation(schema.json), + parse: transformAndMaybeSkipValidation(schema.parse), + }; +} + +function transformAndMaybeSkipValidation( + transform: (value: unknown, opts?: SchemaOptions) => MaybeValid +): (value: unknown, opts?: SchemaOptions) => MaybeValid { + return (value, opts): MaybeValid => { + const transformed = transform(value, opts); + const { skipValidation = false } = opts ?? {}; + if (!transformed.ok && skipValidation) { + // eslint-disable-next-line no-console + console.warn( + [ + "Failed to validate.", + ...transformed.errors.map( + (error) => + " - " + + (error.path.length > 0 ? `${error.path.join(".")}: ${error.message}` : error.message) + ), + ].join("\n") + ); + + return { + ok: true, + value: value as T, + }; + } else { + return transformed; + } + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/partition.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/partition.ts new file mode 100644 index 00000000000..f58d6f3d35f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/core/schemas/utils/partition.ts @@ -0,0 +1,12 @@ +export function partition(items: readonly T[], predicate: (item: T) => boolean): [T[], T[]] { + const trueItems: T[] = [], + falseItems: T[] = []; + for (const item of items) { + if (predicate(item)) { + trueItems.push(item); + } else { + falseItems.push(item); + } + } + return [trueItems, falseItems]; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureError.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureError.ts new file mode 100644 index 00000000000..b1d9d3df172 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureError.ts @@ -0,0 +1,45 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export class FernConjureError extends Error { + readonly statusCode?: number; + readonly body?: unknown; + + constructor({ message, statusCode, body }: { message?: string; statusCode?: number; body?: unknown }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, FernConjureError.prototype); + if (statusCode != null) { + this.statusCode = statusCode; + } + + if (body !== undefined) { + this.body = body; + } + } +} + +function buildMessage({ + message, + statusCode, + body, +}: { + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; +}): string { + let lines: string[] = []; + if (message != null) { + lines.push(message); + } + + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } + + if (body != null) { + lines.push(`Body: ${JSON.stringify(body, undefined, 2)}`); + } + + return lines.join("\n"); +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureTimeoutError.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureTimeoutError.ts new file mode 100644 index 00000000000..09321a2eef8 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/FernConjureTimeoutError.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export class FernConjureTimeoutError extends Error { + constructor() { + super("Timeout"); + Object.setPrototypeOf(this, FernConjureTimeoutError.prototype); + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/index.ts new file mode 100644 index 00000000000..69776fedc5d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/errors/index.ts @@ -0,0 +1,2 @@ +export { FernConjureError } from "./FernConjureError"; +export { FernConjureTimeoutError } from "./FernConjureTimeoutError"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/index.ts new file mode 100644 index 00000000000..c87bb6fedc2 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/index.ts @@ -0,0 +1,2 @@ +export * as FernConjure from "./api"; +export { FernConjureError, FernConjureTimeoutError } from "./errors"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/index.ts new file mode 100644 index 00000000000..3e5335fe421 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/index.ts @@ -0,0 +1 @@ +export * from "./resources"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/WithDocs.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/WithDocs.ts new file mode 100644 index 00000000000..8821adc25b6 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/WithDocs.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; + +export const WithDocs: core.serialization.ObjectSchema = + core.serialization.objectWithoutOptionalProperties({ + docs: core.serialization.string().optional(), + }); + +export declare namespace WithDocs { + interface Raw { + docs?: string | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/index.ts new file mode 100644 index 00000000000..5408dd522d6 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/commons/types/index.ts @@ -0,0 +1 @@ +export * from "./WithDocs"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/ConjureServiceName.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/ConjureServiceName.ts new file mode 100644 index 00000000000..15449b5b777 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/ConjureServiceName.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; + +export const ConjureServiceName: core.serialization.Schema< + serializers.ConjureServiceName.Raw, + FernConjure.ConjureServiceName +> = core.serialization.string(); + +export declare namespace ConjureServiceName { + type Raw = string; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/DefinitionFile.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/DefinitionFile.ts new file mode 100644 index 00000000000..77f785e2ef3 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/DefinitionFile.ts @@ -0,0 +1,27 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureTypes } from "../../types/types/ConjureTypes"; +import { ConjureServiceName } from "./ConjureServiceName"; +import { ConjureService } from "../../services/types/ConjureService"; + +export const DefinitionFile: core.serialization.ObjectSchema< + serializers.DefinitionFile.Raw, + FernConjure.DefinitionFile +> = core.serialization.objectWithoutOptionalProperties({ + imports: core.serialization.record(core.serialization.string(), core.serialization.string()).optional(), + types: ConjureTypes.optional(), + services: core.serialization.record(ConjureServiceName, ConjureService).optional(), +}); + +export declare namespace DefinitionFile { + interface Raw { + imports?: Record | null; + types?: ConjureTypes.Raw | null; + services?: Record | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/index.ts new file mode 100644 index 00000000000..e9a7aafde8c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/conjure/types/index.ts @@ -0,0 +1,2 @@ +export * from "./ConjureServiceName"; +export * from "./DefinitionFile"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/index.ts new file mode 100644 index 00000000000..bb56beec27f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/index.ts @@ -0,0 +1,8 @@ +export * as commons from "./commons"; +export * from "./commons/types"; +export * as conjure from "./conjure"; +export * from "./conjure/types"; +export * as services from "./services"; +export * from "./services/types"; +export * as types from "./types"; +export * from "./types/types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgument.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgument.ts new file mode 100644 index 00000000000..afd5a73e109 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgument.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureTypeReference } from "../../types/types/ConjureTypeReference"; +import { ConjureArgumentWithParamType } from "./ConjureArgumentWithParamType"; + +export const ConjureArgument: core.serialization.Schema = + core.serialization.undiscriminatedUnion([ConjureTypeReference, ConjureArgumentWithParamType]); + +export declare namespace ConjureArgument { + type Raw = ConjureTypeReference.Raw | ConjureArgumentWithParamType.Raw; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgumentWithParamType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgumentWithParamType.ts new file mode 100644 index 00000000000..803c3416831 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureArgumentWithParamType.ts @@ -0,0 +1,27 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureParamType } from "./ConjureParamType"; +import { ConjureTypeReference } from "../../types/types/ConjureTypeReference"; +import { WithDocs } from "../../commons/types/WithDocs"; + +export const ConjureArgumentWithParamType: core.serialization.ObjectSchema< + serializers.ConjureArgumentWithParamType.Raw, + FernConjure.ConjureArgumentWithParamType +> = core.serialization + .objectWithoutOptionalProperties({ + paramType: core.serialization.property("param-type", ConjureParamType), + type: ConjureTypeReference, + }) + .extend(WithDocs); + +export declare namespace ConjureArgumentWithParamType { + interface Raw extends WithDocs.Raw { + "param-type": ConjureParamType.Raw; + type: ConjureTypeReference.Raw; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureEndpoint.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureEndpoint.ts new file mode 100644 index 00000000000..7006d7cde39 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureEndpoint.ts @@ -0,0 +1,29 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureArgument } from "./ConjureArgument"; +import { ConjureTypeReference } from "../../types/types/ConjureTypeReference"; +import { WithDocs } from "../../commons/types/WithDocs"; + +export const ConjureEndpoint: core.serialization.ObjectSchema< + serializers.ConjureEndpoint.Raw, + FernConjure.ConjureEndpoint +> = core.serialization + .objectWithoutOptionalProperties({ + http: core.serialization.string(), + args: core.serialization.record(core.serialization.string(), ConjureArgument).optional(), + returns: ConjureTypeReference.optional(), + }) + .extend(WithDocs); + +export declare namespace ConjureEndpoint { + interface Raw extends WithDocs.Raw { + http: string; + args?: Record | null; + returns?: ConjureTypeReference.Raw | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureParamType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureParamType.ts new file mode 100644 index 00000000000..4f62914fef5 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureParamType.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; + +export const ConjureParamType: core.serialization.Schema< + serializers.ConjureParamType.Raw, + FernConjure.ConjureParamType +> = core.serialization.enum_(["path", "query", "body"]); + +export declare namespace ConjureParamType { + type Raw = "path" | "query" | "body"; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureService.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureService.ts new file mode 100644 index 00000000000..9593b110731 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/ConjureService.ts @@ -0,0 +1,30 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureEndpoint } from "./ConjureEndpoint"; +import { WithDocs } from "../../commons/types/WithDocs"; + +export const ConjureService: core.serialization.ObjectSchema< + serializers.ConjureService.Raw, + FernConjure.ConjureService +> = core.serialization + .objectWithoutOptionalProperties({ + name: core.serialization.string().optional(), + package: core.serialization.string().optional(), + basePath: core.serialization.property("base-path", core.serialization.string().optional()), + endpoints: core.serialization.record(core.serialization.string(), ConjureEndpoint).optional(), + }) + .extend(WithDocs); + +export declare namespace ConjureService { + interface Raw extends WithDocs.Raw { + name?: string | null; + package?: string | null; + "base-path"?: string | null; + endpoints?: Record | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/index.ts new file mode 100644 index 00000000000..8c1cbd2fcc7 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/services/types/index.ts @@ -0,0 +1,5 @@ +export * from "./ConjureService"; +export * from "./ConjureEndpoint"; +export * from "./ConjureArgument"; +export * from "./ConjureArgumentWithParamType"; +export * from "./ConjureParamType"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/index.ts new file mode 100644 index 00000000000..eea524d6557 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureAliasDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureAliasDeclaration.ts new file mode 100644 index 00000000000..e2affbbe1cd --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureAliasDeclaration.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureType } from "./ConjureType"; + +export const ConjureAliasDeclaration: core.serialization.ObjectSchema< + serializers.ConjureAliasDeclaration.Raw, + FernConjure.ConjureAliasDeclaration +> = core.serialization.objectWithoutOptionalProperties({ + alias: ConjureType, + docs: core.serialization.string().optional(), +}); + +export declare namespace ConjureAliasDeclaration { + interface Raw { + alias: ConjureType.Raw; + docs?: string | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureDefinitions.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureDefinitions.ts new file mode 100644 index 00000000000..faae63f3a2a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureDefinitions.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureTypeDeclaration } from "./ConjureTypeDeclaration"; + +export const ConjureDefinitions: core.serialization.ObjectSchema< + serializers.ConjureDefinitions.Raw, + FernConjure.ConjureDefinitions +> = core.serialization.objectWithoutOptionalProperties({ + objects: core.serialization.record(core.serialization.string(), ConjureTypeDeclaration).optional(), +}); + +export declare namespace ConjureDefinitions { + interface Raw { + objects?: Record | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureEnumDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureEnumDeclaration.ts new file mode 100644 index 00000000000..02f99f17e5a --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureEnumDeclaration.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; + +export const ConjureEnumDeclaration: core.serialization.ObjectSchema< + serializers.ConjureEnumDeclaration.Raw, + FernConjure.ConjureEnumDeclaration +> = core.serialization.objectWithoutOptionalProperties({ + values: core.serialization.list(core.serialization.string()), +}); + +export declare namespace ConjureEnumDeclaration { + interface Raw { + values: string[]; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureObjectDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureObjectDeclaration.ts new file mode 100644 index 00000000000..b5a0c9e9b2c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureObjectDeclaration.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureTypeReference } from "./ConjureTypeReference"; + +export const ConjureObjectDeclaration: core.serialization.ObjectSchema< + serializers.ConjureObjectDeclaration.Raw, + FernConjure.ConjureObjectDeclaration +> = core.serialization.objectWithoutOptionalProperties({ + fields: core.serialization.record(core.serialization.string(), ConjureTypeReference), +}); + +export declare namespace ConjureObjectDeclaration { + interface Raw { + fields: Record; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjurePrimitive.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjurePrimitive.ts new file mode 100644 index 00000000000..9e800c38a85 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjurePrimitive.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; + +export const ConjurePrimitive: core.serialization.Schema< + serializers.ConjurePrimitive.Raw, + FernConjure.ConjurePrimitive +> = core.serialization.enum_(["rid", "string", "safelong", "integer", "double", "boolean"]); + +export declare namespace ConjurePrimitive { + type Raw = "rid" | "string" | "safelong" | "integer" | "double" | "boolean"; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureType.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureType.ts new file mode 100644 index 00000000000..158b437cfe8 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureType.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjurePrimitive } from "./ConjurePrimitive"; + +export const ConjureType: core.serialization.Schema = + core.serialization.undiscriminatedUnion([ConjurePrimitive, core.serialization.string()]); + +export declare namespace ConjureType { + type Raw = ConjurePrimitive.Raw | string; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeDeclaration.ts new file mode 100644 index 00000000000..d752c3c210d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeDeclaration.ts @@ -0,0 +1,29 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureAliasDeclaration } from "./ConjureAliasDeclaration"; +import { ConjureUnionDeclaration } from "./ConjureUnionDeclaration"; +import { ConjureObjectDeclaration } from "./ConjureObjectDeclaration"; +import { ConjureEnumDeclaration } from "./ConjureEnumDeclaration"; + +export const ConjureTypeDeclaration: core.serialization.Schema< + serializers.ConjureTypeDeclaration.Raw, + FernConjure.ConjureTypeDeclaration +> = core.serialization.undiscriminatedUnion([ + ConjureAliasDeclaration, + ConjureUnionDeclaration, + ConjureObjectDeclaration, + ConjureEnumDeclaration, +]); + +export declare namespace ConjureTypeDeclaration { + type Raw = + | ConjureAliasDeclaration.Raw + | ConjureUnionDeclaration.Raw + | ConjureObjectDeclaration.Raw + | ConjureEnumDeclaration.Raw; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeReference.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeReference.ts new file mode 100644 index 00000000000..6d8a7ba44da --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeReference.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureType } from "./ConjureType"; +import { ConjureTypeWithDocs } from "./ConjureTypeWithDocs"; + +export const ConjureTypeReference: core.serialization.Schema< + serializers.ConjureTypeReference.Raw, + FernConjure.ConjureTypeReference +> = core.serialization.undiscriminatedUnion([ConjureType, ConjureTypeWithDocs]); + +export declare namespace ConjureTypeReference { + type Raw = ConjureType.Raw | ConjureTypeWithDocs.Raw; +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeWithDocs.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeWithDocs.ts new file mode 100644 index 00000000000..c2c3e904861 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypeWithDocs.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureType } from "./ConjureType"; + +export const ConjureTypeWithDocs: core.serialization.ObjectSchema< + serializers.ConjureTypeWithDocs.Raw, + FernConjure.ConjureTypeWithDocs +> = core.serialization.objectWithoutOptionalProperties({ + type: ConjureType, + docs: core.serialization.string().optional(), +}); + +export declare namespace ConjureTypeWithDocs { + interface Raw { + type: ConjureType.Raw; + docs?: string | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypes.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypes.ts new file mode 100644 index 00000000000..a6cbaba3cf4 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureTypes.ts @@ -0,0 +1,24 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureDefinitions } from "./ConjureDefinitions"; + +export const ConjureTypes: core.serialization.ObjectSchema = + core.serialization.objectWithoutOptionalProperties({ + conjureImports: core.serialization.property( + "conjure-imports", + core.serialization.record(core.serialization.string(), core.serialization.string()).optional() + ), + definitions: ConjureDefinitions.optional(), + }); + +export declare namespace ConjureTypes { + interface Raw { + "conjure-imports"?: Record | null; + definitions?: ConjureDefinitions.Raw | null; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureUnionDeclaration.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureUnionDeclaration.ts new file mode 100644 index 00000000000..ebbaf9b5c4c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/ConjureUnionDeclaration.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as FernConjure from "../../../../api/index"; +import * as core from "../../../../core"; +import { ConjureTypeReference } from "./ConjureTypeReference"; + +export const ConjureUnionDeclaration: core.serialization.ObjectSchema< + serializers.ConjureUnionDeclaration.Raw, + FernConjure.ConjureUnionDeclaration +> = core.serialization.objectWithoutOptionalProperties({ + union: core.serialization.record(core.serialization.string(), ConjureTypeReference), +}); + +export declare namespace ConjureUnionDeclaration { + interface Raw { + union: Record; + } +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/index.ts b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/index.ts new file mode 100644 index 00000000000..cba7dfc00f4 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/src/sdk/serialization/resources/types/types/index.ts @@ -0,0 +1,11 @@ +export * from "./ConjureTypes"; +export * from "./ConjureDefinitions"; +export * from "./ConjureTypeDeclaration"; +export * from "./ConjureAliasDeclaration"; +export * from "./ConjureUnionDeclaration"; +export * from "./ConjureObjectDeclaration"; +export * from "./ConjureEnumDeclaration"; +export * from "./ConjureTypeReference"; +export * from "./ConjureType"; +export * from "./ConjureTypeWithDocs"; +export * from "./ConjurePrimitive"; diff --git a/packages/cli/api-importers/conjure/conjure-sdk/tsconfig.json b/packages/cli/api-importers/conjure/conjure-sdk/tsconfig.json new file mode 100644 index 00000000000..c8682989a37 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../../../shared/tsconfig.shared.json", + "compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" }, + "include": ["./src/**/*"] +} diff --git a/packages/cli/api-importers/conjure/conjure-sdk/vitest.config.ts b/packages/cli/api-importers/conjure/conjure-sdk/vitest.config.ts new file mode 100644 index 00000000000..7be22ca6cd9 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-sdk/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../../../../shared/vitest.config"; diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/.depcheckrc.json b/packages/cli/api-importers/conjure/conjure-to-fern-tests/.depcheckrc.json new file mode 100644 index 00000000000..a3a4f43188c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/.depcheckrc.json @@ -0,0 +1,10 @@ +{ + "ignores": [ + "@types/jest", + "globals", + "@types/node" + ], + "ignore-patterns": [ + "lib" + ] +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/.prettierrc.cjs b/packages/cli/api-importers/conjure/conjure-to-fern-tests/.prettierrc.cjs new file mode 100644 index 00000000000..38a3889281f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("../../../../../.prettierrc.json"); diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/__snapshots__/conjure.test.ts.snap b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/__snapshots__/conjure.test.ts.snap new file mode 100644 index 00000000000..49da00aa10e --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/__snapshots__/conjure.test.ts.snap @@ -0,0 +1,2411 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`ir > {"name":"trace"} 1`] = ` +{ + "absoluteFilePath": "/DUMMY_PATH", + "importedDefinitions": {}, + "namedDefinitionFiles": { + "__package__.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": {}, + "rawContents": "{} +", + }, + "admin.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "sendTestSubmissionUpdate": { + "auth": true, + "method": "/store-test-submission-status-v2/{submissionId}", + "path": "POST", + "response": undefined, + }, + "sendWorkspaceSubmissionUpdate": { + "auth": true, + "method": "/store-workspace-submission-status-v2/{submissionId}", + "path": "POST", + "response": undefined, + }, + "storeTracedTestCase": { + "auth": true, + "method": "/store-test-trace/submission/{submissionId}/testCase/{testCaseId}", + "path": "POST", + "response": undefined, + }, + "storeTracedTestCaseV2": { + "auth": true, + "method": "/store-test-trace-v2/submission/{submissionId}/testCase/{testCaseId}", + "path": "POST", + "response": undefined, + }, + "storeTracedWorkspace": { + "auth": true, + "method": "/store-workspace-trace/submission/{submissionId}", + "path": "POST", + "response": undefined, + }, + "storeTracedWorkspaceV2": { + "auth": true, + "method": "/store-workspace-trace-v2/submission/{submissionId}", + "path": "POST", + "response": undefined, + }, + "updateTestSubmissionStatus": { + "auth": true, + "method": "/store-test-submission-status/{submissionId}", + "path": "POST", + "response": undefined, + }, + "updateWorkspaceSubmissionStatus": { + "auth": true, + "method": "/store-workspace-submission-status/{submissionId}", + "path": "POST", + "response": undefined, + }, + }, + }, + "types": { + "StoreTracedTestCaseRequest": { + "properties": { + "result": "submission.TestCaseResultWithStdout", + "traceResponses": "list", + }, + }, + "StoreTracedWorkspaceRequest": { + "properties": { + "traceResponses": "list", + "workspaceRunDetails": "submission.WorkspaceRunDetails", + }, + }, + }, + }, + "rawContents": "types: + StoreTracedTestCaseRequest: + properties: + result: submission.TestCaseResultWithStdout + traceResponses: list + StoreTracedWorkspaceRequest: + properties: + workspaceRunDetails: submission.WorkspaceRunDetails + traceResponses: list +service: + auth: false + base-path: '' + endpoints: + updateTestSubmissionStatus: + auth: true + path: POST + method: /store-test-submission-status/{submissionId} + sendTestSubmissionUpdate: + auth: true + path: POST + method: /store-test-submission-status-v2/{submissionId} + updateWorkspaceSubmissionStatus: + auth: true + path: POST + method: /store-workspace-submission-status/{submissionId} + sendWorkspaceSubmissionUpdate: + auth: true + path: POST + method: /store-workspace-submission-status-v2/{submissionId} + storeTracedTestCase: + auth: true + path: POST + method: /store-test-trace/submission/{submissionId}/testCase/{testCaseId} + storeTracedTestCaseV2: + auth: true + path: POST + method: /store-test-trace-v2/submission/{submissionId}/testCase/{testCaseId} + storeTracedWorkspace: + auth: true + path: POST + method: /store-workspace-trace/submission/{submissionId} + storeTracedWorkspaceV2: + auth: true + path: POST + method: /store-workspace-trace-v2/submission/{submissionId} +", + }, + "commons.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "types": { + "BinaryTreeNodeAndTreeValue": { + "properties": { + "fullTree": "BinaryTreeValue", + "nodeId": "NodeId", + }, + }, + "BinaryTreeNodeValue": { + "properties": { + "left": "optional", + "nodeId": "NodeId", + "right": "optional", + "val": "double", + }, + }, + "BinaryTreeValue": { + "properties": { + "nodes": "map", + "root": "optional", + }, + }, + "DebugKeyValuePairs": { + "properties": { + "key": "DebugVariableValue", + "value": "DebugVariableValue", + }, + }, + "DebugMapValue": { + "properties": { + "keyValuePairs": "list", + }, + }, + "DoublyLinkedListNodeAndListValue": { + "properties": { + "fullList": "DoublyLinkedListValue", + "nodeId": "NodeId", + }, + }, + "DoublyLinkedListNodeValue": { + "properties": { + "next": "optional", + "nodeId": "NodeId", + "prev": "optional", + "val": "double", + }, + }, + "DoublyLinkedListValue": { + "properties": { + "head": "optional", + "nodes": "map", + }, + }, + "EmptyObject": { + "properties": {}, + }, + "FileInfo": { + "properties": { + "contents": "string", + "filename": "string", + }, + }, + "FrontendBinaryTreeNodeValue": { + "properties": { + "left": "optional", + "nodeId": "NodeId", + "right": "optional", + "val": "optional", + }, + }, + "FrontendBinaryTreeValue": { + "properties": { + "nodes": "map", + "root": "NodeId", + }, + }, + "FrontendDoublyLinkedListNodeValue": { + "properties": { + "next": "optional", + "nodeId": "NodeId", + "prev": "optional", + "val": "optional", + }, + }, + "FrontendDoublyLinkedListValue": { + "properties": { + "head": "NodeId", + "nodes": "map", + }, + }, + "FrontendKeyValuePair": { + "properties": { + "key": "FrontendVariableValue", + "value": "FrontendVariableValue", + }, + }, + "FrontendMapValue": { + "properties": { + "keyValuePairs": "list", + }, + }, + "FrontendSinglyLinkedListNodeValue": { + "properties": { + "next": "optional", + "nodeId": "NodeId", + "val": "optional", + }, + }, + "FrontendSinglyLinkedListValue": { + "properties": { + "head": "NodeId", + "nodes": "map", + }, + }, + "GenericValue": { + "properties": { + "stringifiedType": "optional", + "stringifiedValue": "string", + }, + }, + "KeyValuePair": { + "properties": { + "key": "VariableValue", + "value": "VariableValue", + }, + }, + "Language": { + "enum": [ + "JAVA", + "JAVASCRIPT", + "PYTHON", + ], + }, + "ListType": { + "properties": { + "isFixedLength": { + "docs": "Whether this list is fixed-size (for languages that supports fixed-size lists). Defaults to false.", + "type": "optional", + }, + "valueType": "VariableType", + }, + }, + "MapType": { + "properties": { + "keyType": "VariableType", + "valueType": "VariableType", + }, + }, + "MapValue": { + "properties": { + "keyValuePairs": "list", + }, + }, + "NodeId": { + "docs": undefined, + "type": "string", + }, + "ProblemId": { + "docs": undefined, + "type": "string", + }, + "SinglyLinkedListNodeAndListValue": { + "properties": { + "fullList": "SinglyLinkedListValue", + "nodeId": "NodeId", + }, + }, + "SinglyLinkedListNodeValue": { + "properties": { + "next": "optional", + "nodeId": "NodeId", + "val": "double", + }, + }, + "SinglyLinkedListValue": { + "properties": { + "head": "optional", + "nodes": "map", + }, + }, + "TestCase": { + "properties": { + "id": "string", + "params": "list", + }, + }, + "TestCaseWithExpectedResult": { + "properties": { + "expectedResult": "VariableValue", + "testCase": "TestCase", + }, + }, + "UserId": { + "docs": undefined, + "type": "string", + }, + }, + }, + "rawContents": "types: + EmptyObject: + properties: {} + ProblemId: + type: string + NodeId: + type: string + ListType: + properties: + valueType: VariableType + isFixedLength: + docs: >- + Whether this list is fixed-size (for languages that supports + fixed-size lists). Defaults to false. + type: optional + MapType: + properties: + keyType: VariableType + valueType: VariableType + GenericValue: + properties: + stringifiedType: optional + stringifiedValue: string + MapValue: + properties: + keyValuePairs: list + KeyValuePair: + properties: + key: VariableValue + value: VariableValue + BinaryTreeValue: + properties: + root: optional + nodes: map + BinaryTreeNodeValue: + properties: + nodeId: NodeId + val: double + right: optional + left: optional + BinaryTreeNodeAndTreeValue: + properties: + nodeId: NodeId + fullTree: BinaryTreeValue + SinglyLinkedListValue: + properties: + head: optional + nodes: map + SinglyLinkedListNodeValue: + properties: + nodeId: NodeId + val: double + next: optional + SinglyLinkedListNodeAndListValue: + properties: + nodeId: NodeId + fullList: SinglyLinkedListValue + DoublyLinkedListValue: + properties: + head: optional + nodes: map + DoublyLinkedListNodeValue: + properties: + nodeId: NodeId + val: double + next: optional + prev: optional + DoublyLinkedListNodeAndListValue: + properties: + nodeId: NodeId + fullList: DoublyLinkedListValue + FrontendMapValue: + properties: + keyValuePairs: list + FrontendKeyValuePair: + properties: + key: FrontendVariableValue + value: FrontendVariableValue + FrontendBinaryTreeValue: + properties: + root: NodeId + nodes: map + FrontendBinaryTreeNodeValue: + properties: + nodeId: NodeId + val: optional + right: optional + left: optional + FrontendSinglyLinkedListValue: + properties: + head: NodeId + nodes: map + FrontendSinglyLinkedListNodeValue: + properties: + nodeId: NodeId + val: optional + next: optional + FrontendDoublyLinkedListValue: + properties: + head: NodeId + nodes: map + FrontendDoublyLinkedListNodeValue: + properties: + nodeId: NodeId + val: optional + next: optional + prev: optional + DebugMapValue: + properties: + keyValuePairs: list + DebugKeyValuePairs: + properties: + key: DebugVariableValue + value: DebugVariableValue + TestCase: + properties: + id: string + params: list + TestCaseWithExpectedResult: + properties: + testCase: TestCase + expectedResult: VariableValue + FileInfo: + properties: + filename: string + contents: string + Language: + enum: + - JAVA + - JAVASCRIPT + - PYTHON + UserId: + type: string +", + }, + "langserver.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "types": { + "LangServerRequest": { + "properties": { + "request": "any", + }, + }, + "LangServerResponse": { + "properties": { + "response": "any", + }, + }, + }, + }, + "rawContents": "types: + LangServerRequest: + properties: + request: any + LangServerResponse: + properties: + response: any +", + }, + "migration.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "getAttemptedMigrations": { + "auth": true, + "method": "/all", + "path": "GET", + "response": "list", + }, + }, + }, + "types": { + "Migration": { + "properties": { + "name": "string", + "status": "MigrationStatus", + }, + }, + "MigrationStatus": { + "enum": [ + "RUNNING", + "FAILED", + "FINISHED", + ], + }, + }, + }, + "rawContents": "types: + MigrationStatus: + enum: + - RUNNING + - FAILED + - FINISHED + Migration: + properties: + name: string + status: MigrationStatus +service: + auth: false + base-path: '' + endpoints: + getAttemptedMigrations: + auth: true + path: GET + method: /all + response: list +", + }, + "playlist.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "createPlaylist": { + "auth": true, + "method": "/create", + "path": "POST", + "response": "Playlist", + }, + "deletePlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "DELETE", + "response": undefined, + }, + "getPlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "GET", + "response": "Playlist", + }, + "getPlaylists": { + "auth": true, + "method": "/all", + "path": "GET", + "response": "list", + }, + "updatePlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "PUT", + "response": "Playlist", + }, + }, + }, + "types": { + "CreatePlaylistRequest": { + "properties": { + "name": "string", + "problems": "list", + }, + }, + "Playlist": { + "properties": { + "name": "string", + "ownerId": "commons.UserId", + "playlistId": "PlaylistId", + "problems": "list", + }, + }, + "PlaylistId": { + "docs": undefined, + "type": "string", + }, + "UpdatePlaylistRequest": { + "properties": { + "name": "string", + "problems": "list", + }, + }, + }, + }, + "rawContents": "types: + PlaylistId: + type: string + Playlist: + properties: + playlistId: PlaylistId + name: string + problems: list + ownerId: commons.UserId + CreatePlaylistRequest: + properties: + name: string + problems: list + UpdatePlaylistRequest: + properties: + name: string + problems: list +service: + auth: false + base-path: '' + endpoints: + createPlaylist: + auth: true + path: POST + method: /create + response: Playlist + getPlaylists: + auth: true + path: GET + method: /all + response: list + getPlaylist: + auth: true + path: GET + method: /{playlistId} + response: Playlist + updatePlaylist: + auth: true + path: PUT + method: /{playlistId} + response: Playlist + deletePlaylist: + auth: true + path: DELETE + method: /{playlistId} +", + }, + "playlistV2.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "createPlaylist": { + "auth": true, + "method": "/create", + "path": "POST", + "response": "playlist.Playlist", + }, + "deletePlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "DELETE", + "response": undefined, + }, + "getPlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "GET", + "response": "playlist.Playlist", + }, + "getPlaylists": { + "auth": true, + "method": "/all", + "path": "GET", + "response": "list", + }, + "updatePlaylist": { + "auth": true, + "method": "/{playlistId}", + "path": "PUT", + "response": "playlist.Playlist", + }, + }, + }, + }, + "rawContents": "service: + auth: false + base-path: '' + endpoints: + createPlaylist: + auth: true + path: POST + method: /create + response: playlist.Playlist + getPlaylists: + auth: true + path: GET + method: /all + response: list + getPlaylist: + auth: true + path: GET + method: /{playlistId} + response: playlist.Playlist + updatePlaylist: + auth: true + path: PUT + method: /{playlistId} + response: playlist.Playlist + deletePlaylist: + auth: true + path: DELETE + method: /{playlistId} +", + }, + "problem.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "createProblem": { + "auth": true, + "method": "/create", + "path": "POST", + "response": "CreateProblemResponse", + }, + "deleteProblem": { + "auth": true, + "method": "/delete/{problemId}", + "path": "DELETE", + "response": undefined, + }, + "getDefaultStarterFiles": { + "auth": true, + "method": "/default-starter-files", + "path": "POST", + "response": "GetDefaultStarterFilesResponse", + }, + "getExpectedResult": { + "auth": true, + "method": "/expected-result/{problemId}", + "path": "POST", + "response": "commons.TestCaseWithExpectedResult", + }, + "getLatestProblem": { + "auth": true, + "method": "/problem-info/{problemId}", + "path": "GET", + "response": "ProblemInfo", + }, + "getProblemVersion": { + "auth": true, + "method": "/problem-info/{problemId}/version/{problemVersion}", + "path": "GET", + "response": "ProblemInfo", + }, + "getProblems": { + "auth": true, + "method": "/problem-info", + "path": "GET", + "response": "list", + }, + "updateProblem": { + "auth": true, + "method": "/update/{problemId}", + "path": "POST", + "response": "UpdateProblemResponse", + }, + }, + }, + "types": { + "CreateProblemRequest": { + "properties": { + "files": "map", + "inputParams": "list", + "methodName": "string", + "outputType": "commons.VariableType", + "problemDescription": "ProblemDescription", + "problemName": "string", + "testcases": "list", + }, + }, + "GenericCreateProblemError": { + "properties": { + "message": "string", + "stacktrace": "string", + "type": "string", + }, + }, + "GetDefaultStarterFilesRequest": { + "properties": { + "inputParams": "list", + "methodName": "string", + "outputType": "commons.VariableType", + }, + }, + "GetDefaultStarterFilesResponse": { + "properties": { + "files": "map", + }, + }, + "ProblemDescription": { + "properties": { + "boards": "list", + }, + }, + "ProblemFiles": { + "properties": { + "readOnlyFiles": "list", + "solutionFile": "commons.FileInfo", + }, + }, + "ProblemInfo": { + "properties": { + "files": "map", + "inputParams": "list", + "methodName": "string", + "outputType": "commons.VariableType", + "problemDescription": "ProblemDescription", + "problemId": "commons.ProblemId", + "problemName": "string", + "problemVersion": "integer", + "supportsCustomTestCases": "boolean", + "testcases": "list", + }, + }, + "UpdateProblemResponse": { + "properties": { + "problemVersion": "integer", + }, + }, + "VariableTypeAndName": { + "properties": { + "name": "string", + "variableType": "commons.VariableType", + }, + }, + }, + }, + "rawContents": "types: + ProblemInfo: + properties: + problemId: commons.ProblemId + problemDescription: ProblemDescription + problemName: string + problemVersion: integer + files: map + inputParams: list + outputType: commons.VariableType + testcases: list + methodName: string + supportsCustomTestCases: boolean + ProblemDescription: + properties: + boards: list + ProblemFiles: + properties: + solutionFile: commons.FileInfo + readOnlyFiles: list + VariableTypeAndName: + properties: + variableType: commons.VariableType + name: string + CreateProblemRequest: + properties: + problemName: string + problemDescription: ProblemDescription + files: map + inputParams: list + outputType: commons.VariableType + testcases: list + methodName: string + GenericCreateProblemError: + properties: + message: string + type: string + stacktrace: string + UpdateProblemResponse: + properties: + problemVersion: integer + GetDefaultStarterFilesRequest: + properties: + inputParams: list + outputType: commons.VariableType + methodName: string + GetDefaultStarterFilesResponse: + properties: + files: map +service: + auth: false + base-path: '' + endpoints: + getProblems: + auth: true + path: GET + method: /problem-info + response: list + getLatestProblem: + auth: true + path: GET + method: /problem-info/{problemId} + response: ProblemInfo + getProblemVersion: + auth: true + path: GET + method: /problem-info/{problemId}/version/{problemVersion} + response: ProblemInfo + getExpectedResult: + auth: true + path: POST + method: /expected-result/{problemId} + response: commons.TestCaseWithExpectedResult + createProblem: + auth: true + path: POST + method: /create + response: CreateProblemResponse + updateProblem: + auth: true + path: POST + method: /update/{problemId} + response: UpdateProblemResponse + deleteProblem: + auth: true + path: DELETE + method: /delete/{problemId} + getDefaultStarterFiles: + auth: true + path: POST + method: /default-starter-files + response: GetDefaultStarterFilesResponse +", + }, + "problemV2.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "createProblem": { + "auth": true, + "method": "/create", + "path": "POST", + "response": "problem.CreateProblemResponse", + }, + "deleteProblem": { + "auth": true, + "method": "/delete/{problemId}", + "path": "DELETE", + "response": undefined, + }, + "getBasicSolutionFile": { + "auth": true, + "method": "/basic-solution-file", + "path": "POST", + "response": "GetBasicSolutionFileResponse", + }, + "getDefaultDirectoryForProblemFiles": { + "auth": true, + "method": "/default-problem-files-directory", + "path": "GET", + "response": "map", + }, + "getFunctionSignature": { + "auth": true, + "method": "/function-signature", + "path": "POST", + "response": "GetFunctionSignatureResponse", + }, + "getGeneratedTestCaseFile": { + "auth": true, + "method": "/generated-test-case-file", + "path": "POST", + "response": "map", + }, + "getGeneratedTestCaseTemplateFile": { + "auth": true, + "method": "/generated-test-case-template-file", + "path": "POST", + "response": "map", + }, + "getLatestProblem": { + "auth": true, + "method": "/problem-info/{problemId}", + "path": "GET", + "response": "ProblemInfoV2", + }, + "getLightweightProblems": { + "auth": true, + "method": "/lightweight-problem-info", + "path": "GET", + "response": "list", + }, + "getProblemVersion": { + "auth": true, + "method": "/problem-info/{problemId}/version/{problemVersion}", + "path": "GET", + "response": "ProblemInfoV2", + }, + "getProblems": { + "auth": true, + "method": "/problem-info", + "path": "GET", + "response": "list", + }, + "updateProblem": { + "auth": true, + "method": "/update/{problemId}", + "path": "POST", + "response": "problem.UpdateProblemResponse", + }, + }, + }, + "types": { + "BasicCustomFiles": { + "properties": { + "additionalFiles": "map", + "basicTestCaseTemplate": "BasicTestCaseTemplate", + "methodName": "string", + "signature": "NonVoidFunctionSignature", + }, + }, + "BasicTestCaseTemplate": { + "properties": { + "description": "TestCaseImplementationDescription", + "expectedValueParameterId": "ParameterId", + "name": "string", + "templateId": "TestCaseTemplateId", + }, + }, + "CreateProblemRequestV2": { + "properties": { + "customFiles": "CustomFiles", + "customTestCaseTemplates": "list", + "isPublic": "boolean", + "problemDescription": "problem.ProblemDescription", + "problemName": "string", + "supportedLanguages": "set", + "testcases": "list", + }, + }, + "DeepEqualityCorrectnessCheck": { + "properties": { + "expectedValueParameterId": "ParameterId", + }, + }, + "DefaultProvidedFile": { + "properties": { + "file": "FileInfoV2", + "relatedTypes": "list", + }, + }, + "FileInfoV2": { + "properties": { + "contents": "string", + "directory": "string", + "editable": "boolean", + "filename": "string", + }, + }, + "Files": { + "properties": { + "files": "list", + }, + }, + "FunctionImplementation": { + "properties": { + "impl": "string;", + "imports": "optional;", + }, + }, + "FunctionImplementationForMultipleLanguages": { + "properties": { + "codeByLanguage": "map", + }, + }, + "GeneratedFiles": { + "properties": { + "generatedTemplateFiles": "map", + "generatedTestCaseFiles": "map", + "other": "map", + }, + }, + "GetBasicSolutionFileRequest": { + "properties": { + "methodName": "string", + "signature": "NonVoidFunctionSignature", + }, + }, + "GetBasicSolutionFileResponse": { + "properties": { + "solutionFileByLanguage": "map", + }, + }, + "GetDefaultProvidedFilesResponse": { + "properties": { + "filesByLanguage": "map>", + }, + }, + "GetFunctionSignatureRequest": { + "properties": { + "functionSignature": "FunctionSignature", + }, + }, + "GetFunctionSignatureResponse": { + "properties": { + "functionByLanguage": "map", + }, + }, + "GetGeneratedTestCaseFileRequest": { + "properties": { + "template": "optional", + "testCase": "TestCaseV2", + }, + }, + "GetGeneratedTestCaseTemplateFileRequest": { + "properties": { + "template": "TestCaseTemplate", + }, + }, + "LightweightProblemInfoV2": { + "properties": { + "problemId": "commons.ProblemId", + "problemName": "string", + "problemVersion": "integer", + "variableTypes": "set", + }, + }, + "NonVoidFunctionDefinition": { + "properties": { + "code": "FunctionImplementationForMultipleLanguages", + "signature": "NonVoidFunctionSignature", + }, + }, + "NonVoidFunctionSignature": { + "properties": { + "parameters": "list", + "returnType": "commons.VariableType", + }, + }, + "Parameter": { + "properties": { + "name": "string", + "parameterId": "ParameterId", + "variableType": "commons.VariableType", + }, + }, + "ParameterId": { + "docs": undefined, + "type": "string", + }, + "ProblemInfoV2": { + "properties": { + "customFiles": "CustomFiles", + "customTestCaseTemplates": "list", + "generatedFiles": "GeneratedFiles", + "isPublic": "boolean", + "problemDescription": "problem.ProblemDescription", + "problemId": "commons.ProblemId", + "problemName": "string", + "problemVersion": "integer", + "supportedLanguages": "set", + "testcases": "list", + }, + }, + "TestCaseExpects": { + "properties": { + "expectedStdout": "optional", + }, + }, + "TestCaseId": { + "docs": undefined, + "type": "string", + }, + "TestCaseImplementation": { + "properties": { + "description": "TestCaseImplementationDescription", + "function": "TestCaseFunction", + }, + }, + "TestCaseImplementationDescription": { + "properties": { + "boards": "list", + }, + }, + "TestCaseMetadata": { + "properties": { + "hidden": "boolean", + "id": "TestCaseId", + "name": "string", + }, + }, + "TestCaseTemplate": { + "properties": { + "implementation": "TestCaseImplementation", + "name": "string", + "templateId": "TestCaseTemplateId", + }, + }, + "TestCaseTemplateId": { + "docs": undefined, + "type": "string", + }, + "TestCaseV2": { + "properties": { + "arguments": "map", + "expects": "optional", + "implementation": "TestCaseImplementationReference", + "metadata": "TestCaseMetadata", + }, + }, + "TestCaseWithActualResultImplementation": { + "properties": { + "assertCorrectnessCheck": "AssertCorrectnessCheck", + "getActualResult": "NonVoidFunctionDefinition", + }, + }, + "VoidFunctionDefinition": { + "properties": { + "code": "FunctionImplementationForMultipleLanguages", + "parameters": "list", + }, + }, + "VoidFunctionDefinitionThatTakesActualResult": { + "properties": { + "additionalParameters": "list", + "code": "FunctionImplementationForMultipleLanguages", + }, + }, + "VoidFunctionSignature": { + "properties": { + "parameters": "list", + }, + }, + "VoidFunctionSignatureThatTakesActualResult": { + "properties": { + "actualResultType": "commons.VariableType", + "parameters": "list", + }, + }, + }, + }, + "rawContents": "types: + TestCaseTemplateId: + type: string + TestCaseId: + type: string + ParameterId: + type: string + ProblemInfoV2: + properties: + problemId: commons.ProblemId + problemDescription: problem.ProblemDescription + problemName: string + problemVersion: integer + supportedLanguages: set + customFiles: CustomFiles + generatedFiles: GeneratedFiles + customTestCaseTemplates: list + testcases: list + isPublic: boolean + LightweightProblemInfoV2: + properties: + problemId: commons.ProblemId + problemName: string + problemVersion: integer + variableTypes: set + CreateProblemRequestV2: + properties: + problemName: string + problemDescription: problem.ProblemDescription + customFiles: CustomFiles + customTestCaseTemplates: list + testcases: list + supportedLanguages: set + isPublic: boolean + TestCaseV2: + properties: + metadata: TestCaseMetadata + implementation: TestCaseImplementationReference + arguments: map + expects: optional + TestCaseExpects: + properties: + expectedStdout: optional + BasicTestCaseTemplate: + properties: + templateId: TestCaseTemplateId + name: string + description: TestCaseImplementationDescription + expectedValueParameterId: ParameterId + TestCaseTemplate: + properties: + templateId: TestCaseTemplateId + name: string + implementation: TestCaseImplementation + TestCaseImplementation: + properties: + description: TestCaseImplementationDescription + function: TestCaseFunction + TestCaseWithActualResultImplementation: + properties: + getActualResult: NonVoidFunctionDefinition + assertCorrectnessCheck: AssertCorrectnessCheck + VoidFunctionDefinition: + properties: + parameters: list + code: FunctionImplementationForMultipleLanguages + Parameter: + properties: + parameterId: ParameterId + name: string + variableType: commons.VariableType + NonVoidFunctionDefinition: + properties: + signature: NonVoidFunctionSignature + code: FunctionImplementationForMultipleLanguages + VoidFunctionSignature: + properties: + parameters: list + NonVoidFunctionSignature: + properties: + parameters: list + returnType: commons.VariableType + VoidFunctionSignatureThatTakesActualResult: + properties: + parameters: list + actualResultType: commons.VariableType + DeepEqualityCorrectnessCheck: + properties: + expectedValueParameterId: ParameterId + VoidFunctionDefinitionThatTakesActualResult: + properties: + additionalParameters: list + code: FunctionImplementationForMultipleLanguages + TestCaseImplementationDescription: + properties: + boards: list + TestCaseMetadata: + properties: + id: TestCaseId + name: string + hidden: boolean + FunctionImplementationForMultipleLanguages: + properties: + codeByLanguage: map + FunctionImplementation: + properties: + impl: string; + imports: optional; + GeneratedFiles: + properties: + generatedTestCaseFiles: map + generatedTemplateFiles: map + other: map + BasicCustomFiles: + properties: + methodName: string + signature: NonVoidFunctionSignature + additionalFiles: map + basicTestCaseTemplate: BasicTestCaseTemplate + Files: + properties: + files: list + FileInfoV2: + properties: + filename: string + directory: string + contents: string + editable: boolean + DefaultProvidedFile: + properties: + file: FileInfoV2 + relatedTypes: list + GetBasicSolutionFileRequest: + properties: + methodName: string + signature: NonVoidFunctionSignature + GetBasicSolutionFileResponse: + properties: + solutionFileByLanguage: map + GetFunctionSignatureRequest: + properties: + functionSignature: FunctionSignature + GetFunctionSignatureResponse: + properties: + functionByLanguage: map + GetDefaultProvidedFilesResponse: + properties: + filesByLanguage: map> + GetGeneratedTestCaseFileRequest: + properties: + template: optional + testCase: TestCaseV2 + GetGeneratedTestCaseTemplateFileRequest: + properties: + template: TestCaseTemplate +service: + auth: false + base-path: '' + endpoints: + getLightweightProblems: + auth: true + path: GET + method: /lightweight-problem-info + response: list + getProblems: + auth: true + path: GET + method: /problem-info + response: list + getLatestProblem: + auth: true + path: GET + method: /problem-info/{problemId} + response: ProblemInfoV2 + getProblemVersion: + auth: true + path: GET + method: /problem-info/{problemId}/version/{problemVersion} + response: ProblemInfoV2 + createProblem: + auth: true + path: POST + method: /create + response: problem.CreateProblemResponse + updateProblem: + auth: true + path: POST + method: /update/{problemId} + response: problem.UpdateProblemResponse + deleteProblem: + auth: true + path: DELETE + method: /delete/{problemId} + getFunctionSignature: + auth: true + path: POST + method: /function-signature + response: GetFunctionSignatureResponse + getBasicSolutionFile: + auth: true + path: POST + method: /basic-solution-file + response: GetBasicSolutionFileResponse + getDefaultDirectoryForProblemFiles: + auth: true + path: GET + method: /default-problem-files-directory + response: map + getGeneratedTestCaseFile: + auth: true + path: POST + method: /generated-test-case-file + response: map + getGeneratedTestCaseTemplateFile: + auth: true + path: POST + method: /generated-test-case-template-file + response: map +", + }, + "submission.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "createExecutionSession": { + "auth": true, + "method": "/create-session/{language}", + "path": "POST", + "response": "ExecutionSessionResponse", + }, + "getExecutionSession": { + "auth": true, + "method": "/{sessionId}", + "path": "GET", + "response": "optional", + }, + "getExecutionSessionsState": { + "auth": true, + "method": "/execution-sessions-state", + "path": "GET", + "response": "ExecutionSessionsState", + }, + "getSubmissionState": { + "auth": true, + "method": "/{submissionId}", + "path": "GET", + "response": "SubmissionState", + }, + "getSubmissionStateV2": { + "auth": true, + "method": "/v2/{submissionId}", + "path": "GET", + "response": "SubmissionStateV2", + }, + "getTraceResponsesPage": { + "auth": true, + "method": "/trace-respose/{submissionId}/testCase/{testCaseId}", + "path": "POST", + "response": "TraceResponsesPage", + }, + "getTraceResponsesPageForWorkspace": { + "auth": true, + "method": "/workspace-trace-response/{submissionId}", + "path": "POST", + "response": "TraceResponsesPage", + }, + "getTraceResponsesV2Page": { + "auth": true, + "method": "/trace-response-v2/{submissionId}/testCase/{testCaseId}", + "path": "POST", + "response": "TraceResponsesPageV2", + }, + "getTraceResponsesV2PageForWorkspace": { + "auth": true, + "method": "/workspace-trace-response-v2/{submissionId}", + "path": "POST", + "response": "TraceResponsesPageV2", + }, + "getWorkspaceStarterFiles": { + "auth": true, + "method": "/get-workspace-starter-files", + "path": "GET", + "response": "WorkspaceStarterFilesResponse", + }, + "getWorkspaceStarterFilesV2": { + "auth": true, + "method": "/get-workspace-starter-files-v2", + "path": "GET", + "response": "WorkspaceStarterFilesResponseV2", + }, + "stopExecutionSession": { + "auth": true, + "method": "/stop/{sessionId}", + "path": "DELETE", + "response": undefined, + }, + }, + }, + "types": { + "BuildingExecutorResponse": { + "properties": { + "status": "ExecutionSessionStatus", + "submissionId": "SubmissionId", + }, + }, + "CompileError": { + "properties": { + "message": "string", + }, + }, + "CustomTestCasesUnsupported": { + "properties": { + "problemId": "commons.ProblemId", + "submissionId": "SubmissionId", + }, + }, + "ErroredResponse": { + "properties": { + "errorInfo": "ErrorInfo", + "submissionId": "SubmissionId", + }, + }, + "ExceptionInfo": { + "properties": { + "exceptionMessage": "string", + "exceptionStacktrace": "string", + "exceptionType": "string", + }, + }, + "ExecutionSessionResponse": { + "properties": { + "executionSessionUrl": "optional", + "language": "commons.Language", + "sessionId": "string", + "status": "ExecutionSessionStatus", + }, + }, + "ExecutionSessionState": { + "properties": { + "awsTaskId": "optional", + "isWarmInstance": "boolean", + "language": "commons.Language", + "lastTimeContacted": "optional", + "sessionId": "string", + "status": "ExecutionSessionStatus", + }, + }, + "ExecutionSessionStatus": { + "enum": [ + "CREATING_CONTAINER", + "PROVISIONING_CONTAINER", + "PENDING_CONTAINER", + "RUNNING_CONTAINER", + "LIVE_CONTAINER", + "FAILED_TO_LAUNCH", + ], + }, + "ExecutionSessionsState": { + "properties": { + "numWarmingInstances": "optional", + "states": "map", + "warmingSessionIds": "list", + }, + }, + "ExistingSubmissionExecuting": { + "properties": { + "submissionId": "SubmissionId", + }, + }, + "ExpressionLocation": { + "properties": { + "offset": "integer", + "start": "integer", + }, + }, + "FinishedResponse": { + "properties": { + "submissionId": "SubmissionId", + }, + }, + "GetTraceResponsesPageRequest": { + "properties": { + "offset": { + "type": "optional", + }, + }, + }, + "GradedResponse": { + "properties": { + "submissionId": "SubmissionId", + "testCases": "map", + }, + }, + "GradedResponseV2": { + "properties": { + "submissionId": "SubmissionId", + "testCases": "map", + }, + }, + "GradedTestCaseUpdate": { + "properties": { + "grade": "TestCaseGrade", + "testCaseId": "problemV2.TestCaseId", + }, + }, + "InitializeProblemRequest": { + "properties": { + "problemId": "commons.ProblemId", + "problemVersion": "optional", + }, + }, + "InternalError": { + "properties": { + "exceptionInfo": "ExceptionInfo", + }, + }, + "InvalidRequestResponse": { + "properties": { + "cause": "InvalidRequestCause", + "request": "SubmissionRequest", + }, + }, + "LightweightStackframeInformation": { + "properties": { + "numStackFrames": "integer", + "topStackFrameMethodName": "string", + }, + }, + "RecordedResponseNotification": { + "properties": { + "submissionId": "SubmissionId", + "testCaseId": "optional", + "traceResponsesSize": "integer", + }, + }, + "RecordedTestCaseUpdate": { + "properties": { + "testCaseId": "problemV2.TestCaseId", + "traceResponsesSize": "integer", + }, + }, + "RecordingResponseNotification": { + "properties": { + "lightweightStackInfo": "LightweightStackframeInformation", + "lineNumber": "integer", + "submissionId": "SubmissionId", + "testCaseId": "optional", + "tracedFile": "optional", + }, + }, + "RunningResponse": { + "properties": { + "state": "RunningSubmissionState", + "submissionId": "SubmissionId", + }, + }, + "RunningSubmissionState": { + "enum": [ + "QUEUEING_SUBMISSION", + "KILLING_HISTORICAL_SUBMISSIONS", + "WRITING_SUBMISSION_TO_FILE", + "COMPILING_SUBMISSION", + "RUNNING_SUBMISSION", + ], + }, + "RuntimeError": { + "properties": { + "message": "string", + }, + }, + "Scope": { + "properties": { + "variables": "map", + }, + }, + "ShareId": { + "docs": undefined, + "type": "string", + }, + "StackFrame": { + "properties": { + "lineNumber": "integer", + "methodName": "string", + "scopes": "list", + }, + }, + "StackInformation": { + "properties": { + "numStackFrames": "integer", + "topStackFrame": "optional", + }, + }, + "StderrResponse": { + "properties": { + "stderr": "string", + "submissionId": "SubmissionId", + }, + }, + "StdoutResponse": { + "properties": { + "stdout": "string", + "submissionId": "SubmissionId", + }, + }, + "StopRequest": { + "properties": { + "submissionId": "SubmissionId", + }, + }, + "StoppedResponse": { + "properties": { + "submissionId": "SubmissionId", + }, + }, + "SubmissionFileInfo": { + "properties": { + "contents": "string", + "directory": "string", + "filename": "string", + }, + }, + "SubmissionId": { + "docs": undefined, + "type": "string", + }, + "SubmissionIdNotFound": { + "properties": { + "missingSubmissionId": "SubmissionId", + }, + }, + "SubmissionState": { + "properties": { + "language": "commons.Language", + "submission": "string", + "submissionTypeState": "SubmissionTypeState", + "timeSubmitted": "optional", + }, + }, + "SubmissionStateV2": { + "properties": { + "language": "commons.Language", + "submissionFiles": "list", + "submissionStatus": "SubmissionStatusV2", + "timeSubmitted": "datetime", + }, + }, + "SubmissionTypeEnum": { + "enum": [ + "TEST", + ], + }, + "SubmitRequestV2": { + "properties": { + "language": "commons.Language", + "problemId": "commons.ProblemId", + "problemVersion": "optional", + "submissionFiles": "list", + "submissionId": "SubmissionId", + "userId": "optional", + }, + }, + "TerminatedResponse": { + "properties": {}, + }, + "TestCaseHiddenGrade": { + "properties": { + "passed": "boolean", + }, + }, + "TestCaseNonHiddenGrade": { + "properties": { + "actualResult": "optional", + "exception": "optional", + "passed": "boolean", + "stdout": "string", + }, + }, + "TestCaseResult": { + "properties": { + "actualResult": "ActualResult", + "expectedResult": "commons.VariableValue", + "passed": "boolean", + }, + }, + "TestCaseResultWithStdout": { + "properties": { + "result": "TestCaseResult", + "stdout": "string", + }, + }, + "TestSubmissionState": { + "properties": { + "customTestCases": "list", + "defaultTestCases": "list", + "problemId": "commons.ProblemId", + "status": "TestSubmissionStatus", + }, + }, + "TestSubmissionStatusV2": { + "properties": { + "problemId": "commons.ProblemId", + "problemInfo": "problemV2.ProblemInfoV2", + "problemVersion": "integer", + "updates": "list", + }, + }, + "TestSubmissionUpdate": { + "properties": { + "updateInfo": "TestSubmissionUpdateInfo", + "updateTime": "datetime", + }, + }, + "TraceResponse": { + "properties": { + "expressionLocation": "optional", + "lineNumber": "integer", + "returnValue": "optional", + "stack": "StackInformation", + "stdout": "optional", + "submissionId": "SubmissionId", + }, + }, + "TraceResponseV2": { + "properties": { + "expressionLocation": "optional", + "file": "TracedFile", + "lineNumber": "integer", + "returnValue": "optional", + "stack": "StackInformation", + "stdout": "optional", + "submissionId": "SubmissionId", + }, + }, + "TraceResponsesPage": { + "properties": { + "offset": { + "docs": "If present, use this to load subseqent pages. +The offset is the id of the next trace response to load. +", + "type": "optional", + }, + "traceResponses": "list", + }, + }, + "TraceResponsesPageV2": { + "properties": { + "offset": { + "docs": "If present, use this to load subseqent pages. +The offset is the id of the next trace response to load. +", + "type": "optional", + }, + "traceResponses": "list", + }, + }, + "TracedFile": { + "properties": { + "directory": "string", + "filename": "string", + }, + }, + "TracedTestCase": { + "properties": { + "result": "TestCaseResultWithStdout", + "traceResponsesSize": "integer", + }, + }, + "UnexpectedLanguageError": { + "properties": { + "actualLanguage": "commons.Language", + "expectedLanguage": "commons.Language", + }, + }, + "WorkspaceFiles": { + "properties": { + "mainFile": "commons.FileInfo", + "readOnlyFiles": "list", + }, + }, + "WorkspaceRanResponse": { + "properties": { + "runDetails": "WorkspaceRunDetails", + "submissionId": "SubmissionId", + }, + }, + "WorkspaceRunDetails": { + "properties": { + "exception": "optional", + "exceptionV2": "optional", + "stdout": "string", + }, + }, + "WorkspaceStarterFilesResponse": { + "properties": { + "files": "map", + }, + }, + "WorkspaceStarterFilesResponseV2": { + "properties": { + "filesByLanguage": "map", + }, + }, + "WorkspaceSubmissionState": { + "properties": { + "status": "WorkspaceSubmissionStatus", + }, + }, + "WorkspaceSubmissionStatusV2": { + "properties": { + "updates": "list", + }, + }, + "WorkspaceSubmissionUpdate": { + "properties": { + "updateInfo": "WorkspaceSubmissionUpdateInfo", + "updateTime": "datetime", + }, + }, + "WorkspaceSubmitRequest": { + "properties": { + "language": "commons.Language", + "submissionFiles": "list", + "submissionId": "SubmissionId", + "userId": "optional", + }, + }, + "WorkspaceTracedUpdate": { + "properties": { + "traceResponsesSize": "integer", + }, + }, + }, + }, + "rawContents": "types: + SubmissionId: + type: string + ShareId: + type: string + InitializeProblemRequest: + properties: + problemId: commons.ProblemId + problemVersion: optional + SubmitRequestV2: + properties: + submissionId: SubmissionId + language: commons.Language + submissionFiles: list + problemId: commons.ProblemId + problemVersion: optional + userId: optional + WorkspaceSubmitRequest: + properties: + submissionId: SubmissionId + language: commons.Language + submissionFiles: list + userId: optional + SubmissionFileInfo: + properties: + directory: string + filename: string + contents: string + SubmissionTypeEnum: + enum: + - TEST + StopRequest: + properties: + submissionId: SubmissionId + BuildingExecutorResponse: + properties: + submissionId: SubmissionId + status: ExecutionSessionStatus + RunningResponse: + properties: + submissionId: SubmissionId + state: RunningSubmissionState + RunningSubmissionState: + enum: + - QUEUEING_SUBMISSION + - KILLING_HISTORICAL_SUBMISSIONS + - WRITING_SUBMISSION_TO_FILE + - COMPILING_SUBMISSION + - RUNNING_SUBMISSION + ErroredResponse: + properties: + submissionId: SubmissionId + errorInfo: ErrorInfo + CompileError: + properties: + message: string + RuntimeError: + properties: + message: string + InternalError: + properties: + exceptionInfo: ExceptionInfo + StoppedResponse: + properties: + submissionId: SubmissionId + WorkspaceRanResponse: + properties: + submissionId: SubmissionId + runDetails: WorkspaceRunDetails + WorkspaceRunDetails: + properties: + exceptionV2: optional + exception: optional + stdout: string + GradedResponse: + properties: + submissionId: SubmissionId + testCases: map + GradedResponseV2: + properties: + submissionId: SubmissionId + testCases: map + TestCaseHiddenGrade: + properties: + passed: boolean + TestCaseNonHiddenGrade: + properties: + passed: boolean + actualResult: optional + exception: optional + stdout: string + RecordedResponseNotification: + properties: + submissionId: SubmissionId + traceResponsesSize: integer + testCaseId: optional + RecordingResponseNotification: + properties: + submissionId: SubmissionId + testCaseId: optional + lineNumber: integer + lightweightStackInfo: LightweightStackframeInformation + tracedFile: optional + LightweightStackframeInformation: + properties: + numStackFrames: integer + topStackFrameMethodName: string + TestCaseResultWithStdout: + properties: + result: TestCaseResult + stdout: string + TestCaseResult: + properties: + expectedResult: commons.VariableValue + actualResult: ActualResult + passed: boolean + ExceptionInfo: + properties: + exceptionType: string + exceptionMessage: string + exceptionStacktrace: string + InvalidRequestResponse: + properties: + request: SubmissionRequest + cause: InvalidRequestCause + ExistingSubmissionExecuting: + properties: + submissionId: SubmissionId + SubmissionIdNotFound: + properties: + missingSubmissionId: SubmissionId + CustomTestCasesUnsupported: + properties: + problemId: commons.ProblemId + submissionId: SubmissionId + UnexpectedLanguageError: + properties: + expectedLanguage: commons.Language + actualLanguage: commons.Language + TerminatedResponse: + properties: {} + FinishedResponse: + properties: + submissionId: SubmissionId + StdoutResponse: + properties: + submissionId: SubmissionId + stdout: string + StderrResponse: + properties: + submissionId: SubmissionId + stderr: string + TraceResponse: + properties: + submissionId: SubmissionId + lineNumber: integer + returnValue: optional + expressionLocation: optional + stack: StackInformation + stdout: optional + TraceResponseV2: + properties: + submissionId: SubmissionId + lineNumber: integer + file: TracedFile + returnValue: optional + expressionLocation: optional + stack: StackInformation + stdout: optional + TracedFile: + properties: + filename: string + directory: string + ExpressionLocation: + properties: + start: integer + offset: integer + StackInformation: + properties: + numStackFrames: integer + topStackFrame: optional + StackFrame: + properties: + methodName: string + lineNumber: integer + scopes: list + Scope: + properties: + variables: map + ExecutionSessionResponse: + properties: + sessionId: string + executionSessionUrl: optional + language: commons.Language + status: ExecutionSessionStatus + ExecutionSessionStatus: + enum: + - CREATING_CONTAINER + - PROVISIONING_CONTAINER + - PENDING_CONTAINER + - RUNNING_CONTAINER + - LIVE_CONTAINER + - FAILED_TO_LAUNCH + SubmissionStateV2: + properties: + timeSubmitted: datetime + language: commons.Language + submissionFiles: list + submissionStatus: SubmissionStatusV2 + TestSubmissionStatusV2: + properties: + updates: list + problemId: commons.ProblemId + problemVersion: integer + problemInfo: problemV2.ProblemInfoV2 + WorkspaceSubmissionStatusV2: + properties: + updates: list + TestSubmissionUpdate: + properties: + updateTime: datetime + updateInfo: TestSubmissionUpdateInfo + WorkspaceSubmissionUpdate: + properties: + updateTime: datetime + updateInfo: WorkspaceSubmissionUpdateInfo + GradedTestCaseUpdate: + properties: + testCaseId: problemV2.TestCaseId + grade: TestCaseGrade + RecordedTestCaseUpdate: + properties: + testCaseId: problemV2.TestCaseId + traceResponsesSize: integer + WorkspaceTracedUpdate: + properties: + traceResponsesSize: integer + SubmissionState: + properties: + timeSubmitted: optional + submission: string + language: commons.Language + submissionTypeState: SubmissionTypeState + WorkspaceSubmissionState: + properties: + status: WorkspaceSubmissionStatus + TestSubmissionState: + properties: + problemId: commons.ProblemId + defaultTestCases: list + customTestCases: list + status: TestSubmissionStatus + TracedTestCase: + properties: + result: TestCaseResultWithStdout + traceResponsesSize: integer + TraceResponsesPage: + properties: + offset: + type: optional + docs: | + If present, use this to load subseqent pages. + The offset is the id of the next trace response to load. + traceResponses: list + TraceResponsesPageV2: + properties: + offset: + type: optional + docs: | + If present, use this to load subseqent pages. + The offset is the id of the next trace response to load. + traceResponses: list + GetTraceResponsesPageRequest: + properties: + offset: + type: optional + WorkspaceStarterFilesResponse: + properties: + files: map + WorkspaceStarterFilesResponseV2: + properties: + filesByLanguage: map + WorkspaceFiles: + properties: + mainFile: commons.FileInfo + readOnlyFiles: list + ExecutionSessionsState: + properties: + states: map + numWarmingInstances: optional + warmingSessionIds: list + ExecutionSessionState: + properties: + lastTimeContacted: optional + sessionId: string + isWarmInstance: boolean + awsTaskId: optional + language: commons.Language + status: ExecutionSessionStatus +service: + auth: false + base-path: '' + endpoints: + createExecutionSession: + auth: true + path: POST + method: /create-session/{language} + response: ExecutionSessionResponse + getExecutionSession: + auth: true + path: GET + method: /{sessionId} + response: optional + stopExecutionSession: + auth: true + path: DELETE + method: /stop/{sessionId} + getExecutionSessionsState: + auth: true + path: GET + method: /execution-sessions-state + response: ExecutionSessionsState + getSubmissionState: + auth: true + path: GET + method: /{submissionId} + response: SubmissionState + getSubmissionStateV2: + auth: true + path: GET + method: /v2/{submissionId} + response: SubmissionStateV2 + getTraceResponsesPage: + auth: true + path: POST + method: /trace-respose/{submissionId}/testCase/{testCaseId} + response: TraceResponsesPage + getTraceResponsesV2Page: + auth: true + path: POST + method: /trace-response-v2/{submissionId}/testCase/{testCaseId} + response: TraceResponsesPageV2 + getTraceResponsesPageForWorkspace: + auth: true + path: POST + method: /workspace-trace-response/{submissionId} + response: TraceResponsesPage + getTraceResponsesV2PageForWorkspace: + auth: true + path: POST + method: /workspace-trace-response-v2/{submissionId} + response: TraceResponsesPageV2 + getWorkspaceStarterFiles: + auth: true + path: GET + method: /get-workspace-starter-files + response: WorkspaceStarterFilesResponse + getWorkspaceStarterFilesV2: + auth: true + path: GET + method: /get-workspace-starter-files-v2 + response: WorkspaceStarterFilesResponseV2 +", + }, + "sysprop.yml": { + "absoluteFilepath": "/DUMMY_PATH", + "contents": { + "service": { + "auth": false, + "base-path": "", + "endpoints": { + "getNumWarmInstances": { + "auth": true, + "method": "/num-warm-instances", + "path": "GET", + "response": "map", + }, + "setNumWarmInstances": { + "auth": true, + "method": "/num-warm-instances/{language}/{numWarmInstances}", + "path": "PUT", + "response": undefined, + }, + }, + }, + }, + "rawContents": "service: + auth: false + base-path: '' + endpoints: + setNumWarmInstances: + auth: true + path: PUT + method: /num-warm-instances/{language}/{numWarmInstances} + getNumWarmInstances: + auth: true + path: GET + method: /num-warm-instances + response: map +", + }, + }, + "packageMarkers": {}, + "rootApiFile": { + "contents": { + "error-discrimination": { + "strategy": "status-code", + }, + "name": "api", + }, + "defaultUrl": undefined, + "rawContents": "name: api +error-discrimination: + strategy: status-code +", + }, +} +`; diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/conjure.test.ts b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/conjure.test.ts new file mode 100644 index 00000000000..cf7652e1495 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/conjure.test.ts @@ -0,0 +1,43 @@ +import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils"; +import { createMockTaskContext } from "@fern-api/task-context"; +import { loadAPIWorkspace } from "@fern-api/workspace-loader"; + +const FIXTURES_DIR = join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("fixtures")); + +const FIXTURES: Fixture[] = [ + { + name: "trace" + } +]; + +interface Fixture { + name: string; + only?: boolean; +} + +describe("ir", () => { + for (const fixture of FIXTURES) { + const { only = false } = fixture; + (only ? it.only : it)( + `${JSON.stringify(fixture)}`, + async () => { + const fixturePath = join(FIXTURES_DIR, RelativeFilePath.of(fixture.name), RelativeFilePath.of("fern")); + const context = createMockTaskContext(); + const workspace = await loadAPIWorkspace({ + absolutePathToWorkspace: fixturePath, + context, + cliVersion: "0.0.0", + workspaceName: fixture.name + }); + if (!workspace.didSucceed) { + throw new Error( + `Failed to convert conjure fixture ${fixture.name}\n${JSON.stringify(workspace.failures)}` + ); + } + // eslint-disable-next-line jest/no-standalone-expect + expect(await workspace.workspace.getDefinition({ context })).toMatchSnapshot(); + }, + 90_000 + ); + } +}); diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/admin.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/admin.yml new file mode 100644 index 00000000000..1cf5d74d92d --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/admin.yml @@ -0,0 +1,72 @@ +types: + conjure-imports: + submission: submission.yml + problemV2: problemV2.yml + definitions: + default-package: com.birch.trace.admin + objects: + StoreTracedTestCaseRequest: + fields: + result: submission.TestCaseResultWithStdout + traceResponses: list + StoreTracedWorkspaceRequest: + fields: + workspaceRunDetails: submission.WorkspaceRunDetails + traceResponses: list + +services: + AdminService: + name: Admin Service + package: com.birch.trace.admin + base-path: /admin + endpoints: + + updateTestSubmissionStatus: + http: POST /store-test-submission-status/{submissionId} + args: + submissionId: submission.SubmissionId + request: submission.TestSubmissionStatus + + sendTestSubmissionUpdate: + http: POST /store-test-submission-status-v2/{submissionId} + args: + submissionId: submission.SubmissionId + request: submission.TestSubmissionUpdate + + updateWorkspaceSubmissionStatus: + http: POST /store-workspace-submission-status/{submissionId} + args: + submissionId: submission.SubmissionId + request: submission.WorkspaceSubmissionStatus + + sendWorkspaceSubmissionUpdate: + http: POST /store-workspace-submission-status-v2/{submissionId} + args: + submissionId: submission.SubmissionId + request: submission.WorkspaceSubmissionUpdate + + storeTracedTestCase: + http: POST /store-test-trace/submission/{submissionId}/testCase/{testCaseId} + args: + submissionId: submission.SubmissionId + testCaseId: string + request: StoreTracedTestCaseRequest + + storeTracedTestCaseV2: + http: POST /store-test-trace-v2/submission/{submissionId}/testCase/{testCaseId} + args: + submissionId: submission.SubmissionId + testCaseId: problemV2.TestCaseId + request: list + + storeTracedWorkspace: + http: POST /store-workspace-trace/submission/{submissionId} + args: + submissionId: submission.SubmissionId + request: StoreTracedWorkspaceRequest + + storeTracedWorkspaceV2: + http: POST /store-workspace-trace-v2/submission/{submissionId} + args: + submissionId: submission.SubmissionId + request: list diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/commons.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/commons.yml new file mode 100644 index 00000000000..0ac4e6f4256 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/commons.yml @@ -0,0 +1,188 @@ +types: + definitions: + default-package: com.birch.trace.commons + objects: + EmptyObject: + fields: {} + ProblemId: + alias: string + NodeId: + alias: string + VariableType: + union: + integerType: EmptyObject + doubleType: EmptyObject + booleanType: EmptyObject + stringType: EmptyObject + charType: EmptyObject + listType: ListType + mapType: MapType + binaryTreeType: EmptyObject + singlyLinkedListType: EmptyObject + doublyLinkedListType: EmptyObject + ListType: + fields: + valueType: VariableType + isFixedLength: + docs: Whether this list is fixed-size (for languages that supports fixed-size lists). Defaults to false. + type: optional + MapType: + fields: + keyType: VariableType + valueType: VariableType + VariableValue: + union: + integerValue: integer + booleanValue: boolean + doubleValue: double + stringValue: string + charValue: string + mapValue: MapValue + listValue: list + binaryTreeValue: BinaryTreeValue + singlyLinkedListValue: SinglyLinkedListValue + doublyLinkedListValue: DoublyLinkedListValue + nullValue: EmptyObject + FrontendVariableValue: + union: + integerValue: integer + booleanValue: boolean + doubleValue: double + stringValue: string + charValue: string + mapValue: FrontendMapValue + listValue: list + binaryTreeValue: FrontendBinaryTreeValue + singlyLinkedListValue: FrontendSinglyLinkedListValue + doublyLinkedListValue: FrontendDoublyLinkedListValue + nullValue: EmptyObject + DebugVariableValue: + union: + integerValue: integer + booleanValue: boolean + doubleValue: double + stringValue: string + charValue: string + mapValue: DebugMapValue + listValue: list + binaryTreeNodeValue: BinaryTreeNodeAndTreeValue + singlyLinkedListNodeValue: SinglyLinkedListNodeAndListValue + doublyLinkedListNodeValue: DoublyLinkedListNodeAndListValue + undefinedValue: EmptyObject + nullValue: EmptyObject + genericValue: GenericValue + GenericValue: + fields: + stringifiedType: optional + stringifiedValue: string + MapValue: + fields: + keyValuePairs: list + KeyValuePair: + fields: + key: VariableValue + value: VariableValue + BinaryTreeValue: + fields: + root: optional + nodes: map + BinaryTreeNodeValue: + fields: + nodeId: NodeId + val: double + right: optional + left: optional + BinaryTreeNodeAndTreeValue: + fields: + nodeId: NodeId + fullTree: BinaryTreeValue + SinglyLinkedListValue: + fields: + head: optional + nodes: map + SinglyLinkedListNodeValue: + fields: + nodeId: NodeId + val: double + next: optional + SinglyLinkedListNodeAndListValue: + fields: + nodeId: NodeId + fullList: SinglyLinkedListValue + DoublyLinkedListValue: + fields: + head: optional + nodes: map + DoublyLinkedListNodeValue: + fields: + nodeId: NodeId + val: double + next: optional + prev: optional + DoublyLinkedListNodeAndListValue: + fields: + nodeId: NodeId + fullList: DoublyLinkedListValue + FrontendMapValue: + fields: + keyValuePairs: list + FrontendKeyValuePair: + fields: + key: FrontendVariableValue + value: FrontendVariableValue + FrontendBinaryTreeValue: + fields: + root: NodeId + nodes: map + FrontendBinaryTreeNodeValue: + fields: + nodeId: NodeId + val: optional + right: optional + left: optional + FrontendSinglyLinkedListValue: + fields: + head: NodeId + nodes: map + FrontendSinglyLinkedListNodeValue: + fields: + nodeId: NodeId + val: optional + next: optional + FrontendDoublyLinkedListValue: + fields: + head: NodeId + nodes: map + FrontendDoublyLinkedListNodeValue: + fields: + nodeId: NodeId + val: optional + next: optional + prev: optional + DebugMapValue: + fields: + keyValuePairs: list + DebugKeyValuePairs: + fields: + key: DebugVariableValue + value: DebugVariableValue + TestCase: + fields: + id: string + params: list + TestCaseWithExpectedResult: + fields: + testCase: TestCase + expectedResult: VariableValue + FileInfo: + fields: + filename: string + contents: string + Language: + values: + - JAVA + - JAVASCRIPT + - PYTHON + + UserId: + alias: string diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/langserver.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/langserver.yml new file mode 100644 index 00000000000..73483199975 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/langserver.yml @@ -0,0 +1,16 @@ +types: + definitions: + default-package: com.birch.trace.submission + objects: + LangServerRequest: + fields: + request: any + LangServerResponse: + fields: + response: any + + + + + + diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/migration.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/migration.yml new file mode 100644 index 00000000000..8d4a97d222b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/migration.yml @@ -0,0 +1,25 @@ +types: + definitions: + default-package: com.birch.trace.migration + objects: + MigrationStatus: + values: + - RUNNING + - FAILED + - FINISHED + Migration: + fields: + name: string + status: MigrationStatus + +services: + MigrationInfoService: + name: Migration Info Service + package: com.birch.trace.migration + base-path: /migration-info + endpoints: + + getAttemptedMigrations: + http: GET /all + args: + returns: list diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlist.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlist.yml new file mode 100644 index 00000000000..ac5f2ff339f --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlist.yml @@ -0,0 +1,68 @@ +types: + conjure-imports: + commons: commons.yml + definitions: + default-package: com.birch.trace.playlist + objects: + PlaylistId: + alias: string + Playlist: + fields: + playlistId: PlaylistId + name: string + problems: list + ownerId: commons.UserId + + CreatePlaylistRequest: + fields: + name: string + problems: list + + UpdatePlaylistRequest: + fields: + name: string + problems: list + +services: + PlaylistCrudService: + name: CRUD service for playlists + package: com.birch.trace.playlist + base-path: /playlist + endpoints: + + createPlaylist: + docs: Create a new playlist + http: POST /create + auth: header + args: + request: CreatePlaylistRequest + returns: Playlist + + getPlaylists: + docs: Returns the user's playlists + http: GET /all + auth: header + returns: list + + getPlaylist: + docs: Returns a playlist + http: GET /{playlistId} + args: + playlistId: PlaylistId + returns: Playlist + + updatePlaylist: + docs: Updates a playlist + http: PUT /{playlistId} + auth: header + args: + playlistId: PlaylistId + request: UpdatePlaylistRequest + returns: Playlist + + deletePlaylist: + docs: Deletes a playlist + http: DELETE /{playlistId} + auth: header + args: + playlistId: PlaylistId \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlistV2.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlistV2.yml new file mode 100644 index 00000000000..5637457b9e1 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/playlistV2.yml @@ -0,0 +1,48 @@ +types: + conjure-imports: + commons: commons.yml + playlist: playlist.yml + +services: + PlaylistCrudServiceV2: + name: CRUD service for playlists + package: com.birch.trace.playlist + base-path: /v2/playlist + endpoints: + + createPlaylist: + docs: Create a new playlist + http: POST /create + auth: header + args: + request: playlist.CreatePlaylistRequest + returns: playlist.Playlist + + getPlaylists: + docs: Returns the user's playlists + http: GET /all + auth: header + returns: list + + getPlaylist: + docs: Returns a playlist + http: GET /{playlistId} + args: + playlistId: playlist.PlaylistId + returns: playlist.Playlist + + updatePlaylist: + docs: Updates a playlist + http: PUT /{playlistId} + auth: header + args: + playlistId: playlist.PlaylistId + request: playlist.UpdatePlaylistRequest + returns: playlist.Playlist + + deletePlaylist: + docs: Deletes a playlist + http: DELETE /{playlistId} + auth: header + args: + playlistId: playlist.PlaylistId \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problem.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problem.yml new file mode 100644 index 00000000000..f386d37ad9c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problem.yml @@ -0,0 +1,139 @@ +types: + conjure-imports: + commons: commons.yml + definitions: + default-package: com.birch.trace.problems + objects: + ProblemInfo: + fields: + problemId: commons.ProblemId + problemDescription: ProblemDescription + problemName: string + problemVersion: integer + files: map + inputParams: list + outputType: commons.VariableType + testcases: list + methodName: string + supportsCustomTestCases: boolean + ProblemDescription: + fields: + boards: list + ProblemDescriptionBoard: + union: + html: string + variable: commons.VariableValue + testCaseId: string + ProblemFiles: + fields: + solutionFile: commons.FileInfo + readOnlyFiles: list + VariableTypeAndName: + fields: + variableType: commons.VariableType + name: string + + CreateProblemRequest: + fields: + problemName: string + problemDescription: ProblemDescription + files: map + inputParams: list + outputType: commons.VariableType + testcases: list + methodName: string + CreateProblemResponse: + union: + success: commons.ProblemId + error: CreateProblemError + CreateProblemError: + union: + generic: GenericCreateProblemError + GenericCreateProblemError: + fields: + message: string + type: string + stacktrace: string + + UpdateProblemResponse: + fields: + problemVersion: integer + + GetDefaultStarterFilesRequest: + fields: + inputParams: list + outputType: commons.VariableType + methodName: string + GetDefaultStarterFilesResponse: + fields: + files: map + +services: + ProblemInfoService: + name: Information about different problems + package: com.birch.trace.problems + base-path: /problems + endpoints: + + getProblems: + docs: Returns latest versions of all problems + http: GET /problem-info + args: {} + returns: list + + getLatestProblem: + docs: Returns latest version of a problem + http: GET /problem-info/{problemId} + args: + problemId: commons.ProblemId + returns: ProblemInfo + + getProblemVersion: + docs: Returns requested version of a problem + http: GET /problem-info/{problemId}/version/{problemVersion} + args: + problemId: commons.ProblemId + problemVersion: integer + returns: ProblemInfo + + getExpectedResult: + docs: Returns test case answer + http: POST /expected-result/{problemId} + args: + problemId: commons.ProblemId + testCase: commons.TestCase + returns: commons.TestCaseWithExpectedResult + + ProblemCrudService: + name: Problem Creation Service + package: com.birch.trace.problems + base-path: /problem-crud + endpoints: + + createProblem: + docs: Creates a problem + http: POST /create + args: + request: CreateProblemRequest + returns: CreateProblemResponse + + updateProblem: + docs: Updates a problem + http: POST /update/{problemId} + args: + problemId: commons.ProblemId + request: CreateProblemRequest + returns: UpdateProblemResponse + + deleteProblem: + docs: Soft deletes a problem + http: DELETE /delete/{problemId} + args: + problemId: commons.ProblemId + + getDefaultStarterFiles: + docs: Returns default starter files for problem + http: POST /default-starter-files + args: + request: GetDefaultStarterFilesRequest + returns: GetDefaultStarterFilesResponse diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problemV2.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problemV2.yml new file mode 100644 index 00000000000..70e0d0fcdce --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/problemV2.yml @@ -0,0 +1,287 @@ +types: + conjure-imports: + commons: commons.yml + problem: problem.yml + definitions: + default-package: com.birch.trace.v2problems + objects: + TestCaseTemplateId: + alias: string + TestCaseId: + alias: string + ParameterId: + alias: string + ProblemInfoV2: + fields: + problemId: commons.ProblemId + problemDescription: problem.ProblemDescription + problemName: string + problemVersion: integer + supportedLanguages: set + customFiles: CustomFiles + generatedFiles: GeneratedFiles + customTestCaseTemplates: list + testcases: list + isPublic: boolean + LightweightProblemInfoV2: + fields: + problemId: commons.ProblemId + problemName: string + problemVersion: integer + variableTypes: set + CreateProblemRequestV2: + fields: + problemName: string + problemDescription: problem.ProblemDescription + customFiles: CustomFiles + customTestCaseTemplates: list + testcases: list + supportedLanguages: set + isPublic: boolean + TestCaseV2: + fields: + metadata: TestCaseMetadata + implementation: TestCaseImplementationReference + arguments: map + expects: optional + TestCaseExpects: + fields: + expectedStdout: optional + TestCaseImplementationReference: + union: + templateId: TestCaseTemplateId + implementation: TestCaseImplementation + BasicTestCaseTemplate: + fields: + templateId: TestCaseTemplateId + name: string + description: TestCaseImplementationDescription + expectedValueParameterId: ParameterId + TestCaseTemplate: + fields: + templateId: TestCaseTemplateId + name: string + implementation: TestCaseImplementation + TestCaseImplementation: + fields: + description: TestCaseImplementationDescription + function: TestCaseFunction + TestCaseFunction: + union: + withActualResult: TestCaseWithActualResultImplementation + custom: VoidFunctionDefinition + TestCaseWithActualResultImplementation: + fields: + getActualResult: NonVoidFunctionDefinition + assertCorrectnessCheck: AssertCorrectnessCheck + VoidFunctionDefinition: + fields: + parameters: list + code: FunctionImplementationForMultipleLanguages + Parameter: + fields: + parameterId: ParameterId + name: string + variableType: commons.VariableType + NonVoidFunctionDefinition: + fields: + signature: NonVoidFunctionSignature + code: FunctionImplementationForMultipleLanguages + VoidFunctionSignature: + fields: + parameters: list + NonVoidFunctionSignature: + fields: + parameters: list + returnType: commons.VariableType + VoidFunctionSignatureThatTakesActualResult: + fields: + parameters: list + actualResultType: commons.VariableType + AssertCorrectnessCheck: + union: + deepEquality: DeepEqualityCorrectnessCheck + custom: VoidFunctionDefinitionThatTakesActualResult + DeepEqualityCorrectnessCheck: + fields: + expectedValueParameterId: ParameterId + VoidFunctionDefinitionThatTakesActualResult: + docs: The generated signature will include an additional param, actualResult + fields: + additionalParameters: list + code: FunctionImplementationForMultipleLanguages + TestCaseImplementationDescription: + fields: + boards: list + TestCaseImplementationDescriptionBoard: + union: + html: string + paramId: ParameterId + TestCaseMetadata: + fields: + id: TestCaseId + name: string + hidden: boolean + FunctionImplementationForMultipleLanguages: + fields: + codeByLanguage: map + FunctionImplementation: + fields: + impl: string; + imports: optional; + GeneratedFiles: + fields: + generatedTestCaseFiles: map + generatedTemplateFiles: map + other: map + CustomFiles: + union: + basic: BasicCustomFiles + custom: map + BasicCustomFiles: + fields: + methodName: string + signature: NonVoidFunctionSignature + additionalFiles: map + basicTestCaseTemplate: BasicTestCaseTemplate + Files: + fields: + files: list + FileInfoV2: + fields: + filename: string + directory: string + contents: string + editable: boolean + DefaultProvidedFile: + fields: + file: FileInfoV2 + relatedTypes: list + GetBasicSolutionFileRequest: + fields: + methodName: string + signature: NonVoidFunctionSignature + GetBasicSolutionFileResponse: + fields: + solutionFileByLanguage: map + GetFunctionSignatureRequest: + fields: + functionSignature: FunctionSignature + FunctionSignature: + union: + void: VoidFunctionSignature + nonVoid: NonVoidFunctionSignature + voidThatTakesActualResult: + type: VoidFunctionSignatureThatTakesActualResult + docs: Useful when specifying custom grading for a testcase where actualResult is defined. + GetFunctionSignatureResponse: + fields: + functionByLanguage: map + GetDefaultProvidedFilesResponse: + fields: + filesByLanguage: map> + + GetGeneratedTestCaseFileRequest: + fields: + template: optional + testCase: TestCaseV2 + docs: Supply template if the test case relies on it + + GetGeneratedTestCaseTemplateFileRequest: + fields: + template: TestCaseTemplate + + +services: + ProblemInfoServicV2: + name: Problem Info Service V2 + package: com.birch.trace.problems + base-path: /problems-v2 + endpoints: + + getLightweightProblems: + docs: Returns lightweight versions of all problems + http: GET /lightweight-problem-info + args: {} + returns: list + + getProblems: + docs: Returns latest versions of all problems + http: GET /problem-info + args: { } + returns: list + + getLatestProblem: + docs: Returns latest version of a problem + http: GET /problem-info/{problemId} + args: + problemId: commons.ProblemId + returns: ProblemInfoV2 + + getProblemVersion: + docs: Returns requested version of a problem + http: GET /problem-info/{problemId}/version/{problemVersion} + args: + problemId: commons.ProblemId + problemVersion: integer + returns: ProblemInfoV2 + + ProblemCrudServiceV2: + name: V2 Problem Creation Service + package: com.birch.trace.v2problems + base-path: /problem-crud-v2 + endpoints: + + createProblem: + docs: Creates a problem + http: POST /create + args: + request: CreateProblemRequestV2 + returns: problem.CreateProblemResponse + + updateProblem: + docs: Updates a problem + http: POST /update/{problemId} + args: + problemId: commons.ProblemId + request: CreateProblemRequestV2 + returns: problem.UpdateProblemResponse + + deleteProblem: + docs: Soft deletes a problem + http: DELETE /delete/{problemId} + args: + problemId: commons.ProblemId + + getFunctionSignature: + docs: Get the generated function signature in every language + http: POST /function-signature + args: + request: GetFunctionSignatureRequest + returns: GetFunctionSignatureResponse + + getBasicSolutionFile: + docs: Returns solution file for basic starter files + http: POST /basic-solution-file + args: + request: GetBasicSolutionFileRequest + returns: GetBasicSolutionFileResponse + + getDefaultDirectoryForProblemFiles: + docs: Returns the default directory where a problem's files should live + http: GET /default-problem-files-directory + returns: map + + getGeneratedTestCaseFile: + docs: Returns the default directory where a problem's files should live + http: POST /generated-test-case-file + args: + request: GetGeneratedTestCaseFileRequest + returns: map + + getGeneratedTestCaseTemplateFile: + docs: Returns the default directory where a problem's files should live + http: POST /generated-test-case-template-file + args: + request: GetGeneratedTestCaseTemplateFileRequest + returns: map diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/submission.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/submission.yml new file mode 100644 index 00000000000..373eadfd414 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/submission.yml @@ -0,0 +1,550 @@ +types: + conjure-imports: + commons: commons.yml + problemV2: problemV2.yml + definitions: + default-package: com.birch.trace.submission + objects: + SubmissionId: + alias: string + ShareId: + alias: string + SubmissionRequest: + union: + initializeProblemRequest: InitializeProblemRequest + initializeWorkspaceRequest: commons.EmptyObject + submitV2: SubmitRequestV2 + workspaceSubmit: WorkspaceSubmitRequest + stop: StopRequest + InitializeProblemRequest: + fields: + problemId: commons.ProblemId + problemVersion: optional + SubmitRequestV2: + fields: + submissionId: SubmissionId + language: commons.Language + submissionFiles: list + problemId: commons.ProblemId + problemVersion: optional + userId: optional + WorkspaceSubmitRequest: + fields: + submissionId: SubmissionId + language: commons.Language + submissionFiles: list + userId: optional + SubmissionFileInfo: + fields: + directory: string + filename: string + contents: string + SubmissionTypeEnum: + values: + - TEST + docs: Keep in sync with SubmissionType. + StopRequest: + fields: + submissionId: SubmissionId + SubmissionResponse: + union: + serverInitialized: commons.EmptyObject + problemInitialized: commons.ProblemId + workspaceInitialized: commons.EmptyObject + serverErrored: ExceptionInfo + codeExecutionUpdate: CodeExecutionUpdate + terminated: TerminatedResponse + CodeExecutionUpdate: + union: + buildingExecutor: + type: BuildingExecutorResponse + docs: Statuses if an executor for the session isn't ready (Before RunningResponse). + running: + type: RunningResponse + docs: Sent once a test submission is executing. + errored: + type: ErroredResponse + docs: Sent if a submission cannot be run (i.e. Compile Error). + stopped: + type: StoppedResponse + docs: Sent if a submission is stopped. + graded: + type: GradedResponse + docs: Graded testcases without trace information. + gradedV2: + type: GradedResponseV2 + docs: Graded submission for v2 problems. + workspaceRan: + type: WorkspaceRanResponse + docs: Workspace run without trace information. + recording: + type: RecordingResponseNotification + docs: Gives progress about what is being recorded. + recorded: + type: RecordedResponseNotification + docs: Graded testcases with trace information. + invalidRequest: + type: InvalidRequestResponse + docs: Sent if an invalid request is sent for a submission. + finished: + type: FinishedResponse + docs: Sent once a submission is graded and fully recorded. + BuildingExecutorResponse: + fields: + submissionId: SubmissionId + status: ExecutionSessionStatus + RunningResponse: + fields: + submissionId: SubmissionId + state: RunningSubmissionState + RunningSubmissionState: + values: + - QUEUEING_SUBMISSION + - KILLING_HISTORICAL_SUBMISSIONS + - WRITING_SUBMISSION_TO_FILE + - COMPILING_SUBMISSION + - RUNNING_SUBMISSION + ErroredResponse: + fields: + submissionId: SubmissionId + errorInfo: ErrorInfo + ErrorInfo: + union: + compileError: CompileError + runtimeError: + type: RuntimeError + docs: | + If the submission cannot be executed and throws a runtime error before getting to any of the testcases. + internalError: + type: InternalError + docs: | + If the trace backend encounters an unexpected error. + CompileError: + fields: + message: string + RuntimeError: + fields: + message: string + InternalError: + fields: + exceptionInfo: ExceptionInfo + StoppedResponse: + fields: + submissionId: SubmissionId + WorkspaceRanResponse: + fields: + submissionId: SubmissionId + runDetails: WorkspaceRunDetails + WorkspaceRunDetails: + fields: + exceptionV2: optional + exception: optional + stdout: string + GradedResponse: + fields: + submissionId: SubmissionId + testCases: map + GradedResponseV2: + fields: + submissionId: SubmissionId + testCases: map + TestCaseGrade: + union: + hidden: TestCaseHiddenGrade + nonHidden: TestCaseNonHiddenGrade + TestCaseHiddenGrade: + fields: + passed: boolean + TestCaseNonHiddenGrade: + fields: + passed: boolean + actualResult: optional + exception: optional + stdout: string + RecordedResponseNotification: + fields: + submissionId: SubmissionId + traceResponsesSize: integer + testCaseId: optional + RecordingResponseNotification: + fields: + submissionId: SubmissionId + testCaseId: optional + lineNumber: integer + lightweightStackInfo: LightweightStackframeInformation + tracedFile: optional + LightweightStackframeInformation: + fields: + numStackFrames: integer + topStackFrameMethodName: string + TestCaseResultWithStdout: + fields: + result: TestCaseResult + stdout: string + TestCaseResult: + fields: + expectedResult: commons.VariableValue + actualResult: ActualResult + passed: boolean + ActualResult: + union: + value: commons.VariableValue + exception: ExceptionInfo + exceptionV2: ExceptionV2 + ExceptionV2: + union: + generic: ExceptionInfo + timeout: commons.EmptyObject + ExceptionInfo: + fields: + exceptionType: string + exceptionMessage: string + exceptionStacktrace: string + InvalidRequestResponse: + fields: + request: SubmissionRequest + cause: InvalidRequestCause + InvalidRequestCause: + union: + submissionIdNotFound: + type: SubmissionIdNotFound + docs: The submission request references a submission id that doesn't exist. + customTestCasesUnsupported: + type: CustomTestCasesUnsupported + unexpectedLanguage: + type: UnexpectedLanguageError + docs: The submission request was routed to an incorrect language executor. + ExistingSubmissionExecuting: + fields: + submissionId: SubmissionId + SubmissionIdNotFound: + fields: + missingSubmissionId: SubmissionId + CustomTestCasesUnsupported: + fields: + problemId: commons.ProblemId + submissionId: SubmissionId + UnexpectedLanguageError: + fields: + expectedLanguage: commons.Language + actualLanguage: commons.Language + TerminatedResponse: + fields: {} + FinishedResponse: + fields: + submissionId: SubmissionId + + StdoutResponse: + fields: + submissionId: SubmissionId + stdout: string + StderrResponse: + fields: + submissionId: SubmissionId + stderr: string + TraceResponse: + fields: + submissionId: SubmissionId + lineNumber: integer + returnValue: optional + expressionLocation: optional + stack: StackInformation + stdout: optional + + TraceResponseV2: + fields: + submissionId: SubmissionId + lineNumber: integer + file: TracedFile + returnValue: optional + expressionLocation: optional + stack: StackInformation + stdout: optional + TracedFile: + fields: + filename: string + directory: string + + ExpressionLocation: + fields: + start: integer + offset: integer + StackInformation: + fields: + numStackFrames: integer + topStackFrame: optional + StackFrame: + fields: + methodName: string + lineNumber: integer + scopes: list + Scope: + fields: + variables: map + ExecutionSessionResponse: + fields: + sessionId: string + executionSessionUrl: optional + language: commons.Language + status: ExecutionSessionStatus + ExecutionSessionStatus: + values: + - CREATING_CONTAINER #Requesting resources + - PROVISIONING_CONTAINER #Downloading image + - PENDING_CONTAINER #Setting up container + - RUNNING_CONTAINER #Container running + - LIVE_CONTAINER #Container can be pinged + - FAILED_TO_LAUNCH #Container failed to launch + + SubmissionStateV2: + fields: + timeSubmitted: datetime + language: commons.Language + submissionFiles: list + submissionStatus: SubmissionStatusV2 + SubmissionStatusV2: + union: + test: TestSubmissionStatusV2 + workspace: WorkspaceSubmissionStatusV2 + TestSubmissionStatusV2: + fields: + updates: list + problemId: commons.ProblemId + problemVersion: integer + problemInfo: problemV2.ProblemInfoV2 + WorkspaceSubmissionStatusV2: + fields: + updates: list + TestSubmissionUpdate: + fields: + updateTime: datetime + updateInfo: TestSubmissionUpdateInfo + TestSubmissionUpdateInfo: + union: + running: RunningSubmissionState + stopped: commons.EmptyObject + errored: ErrorInfo + gradedTestCase: GradedTestCaseUpdate + recordedTestCase: RecordedTestCaseUpdate + finished: commons.EmptyObject + WorkspaceSubmissionUpdate: + fields: + updateTime: datetime + updateInfo: WorkspaceSubmissionUpdateInfo + WorkspaceSubmissionUpdateInfo: + union: + running: RunningSubmissionState + ran: WorkspaceRunDetails + stopped: commons.EmptyObject + traced: commons.EmptyObject + tracedV2: WorkspaceTracedUpdate + errored: ErrorInfo + finished: commons.EmptyObject + GradedTestCaseUpdate: + fields: + testCaseId: problemV2.TestCaseId + grade: TestCaseGrade + RecordedTestCaseUpdate: + fields: + testCaseId: problemV2.TestCaseId + traceResponsesSize: integer + WorkspaceTracedUpdate: + fields: + traceResponsesSize: integer + + SubmissionState: + fields: + timeSubmitted: optional + submission: string + language: commons.Language + submissionTypeState: SubmissionTypeState + SubmissionTypeState: + union: + test: TestSubmissionState + workspace: WorkspaceSubmissionState + WorkspaceSubmissionState: + fields: + status: WorkspaceSubmissionStatus + WorkspaceSubmissionStatus: + union: + stopped: commons.EmptyObject + errored: ErrorInfo + running: RunningSubmissionState + ran: WorkspaceRunDetails + traced: WorkspaceRunDetails + TestSubmissionState: + fields: + problemId: commons.ProblemId + defaultTestCases: list + customTestCases: list + status: TestSubmissionStatus + TestSubmissionStatus: + union: + stopped: commons.EmptyObject + errored: ErrorInfo + running: RunningSubmissionState + testCaseIdToState: map + SubmissionStatusForTestCase: + union: + graded: TestCaseResultWithStdout + gradedV2: TestCaseGrade + traced: TracedTestCase + TracedTestCase: + fields: + result: TestCaseResultWithStdout + traceResponsesSize: integer + TraceResponsesPage: + fields: + offset: + type: optional + docs: | + If present, use this to load subseqent pages. + The offset is the id of the next trace response to load. + traceResponses: list + TraceResponsesPageV2: + fields: + offset: + type: optional + docs: | + If present, use this to load subseqent pages. + The offset is the id of the next trace response to load. + traceResponses: list + GetTraceResponsesPageRequest: + fields: + offset: + type: optional + WorkspaceStarterFilesResponse: + fields: + files: map + WorkspaceStarterFilesResponseV2: + fields: + filesByLanguage: map + WorkspaceFiles: + fields: + mainFile: commons.FileInfo + readOnlyFiles: list + + ExecutionSessionsState: + fields: + states: map + numWarmingInstances: optional + warmingSessionIds: list + ExecutionSessionState: + fields: + lastTimeContacted: optional + sessionId: string + isWarmInstance: boolean + awsTaskId: optional + language: commons.Language + status: ExecutionSessionStatus + +services: + ExecutionSesssionManagementService: + name: Responsible for spinning up and spinning down execution. + package: com.birch.trace.session + base-path: /sessions + endpoints: + + createExecutionSession: + docs: Returns sessionId and execution server URL for session. Spins up server. + http: POST /create-session/{language} + args: + language: commons.Language + returns: ExecutionSessionResponse + + getExecutionSession: + docs: Returns execution server URL for session. Returns empty if session isn't registered. + http: GET /{sessionId} + args: + sessionId: string + returns: optional + + stopExecutionSession: + docs: Stops execution session. #TODO: only an admin should be able to trigger this + http: DELETE /stop/{sessionId} + args: + sessionId: string + + getExecutionSessionsState: + http: GET /execution-sessions-state + returns: ExecutionSessionsState + + SubmissionInfoService: + name: Responsible for serving information about submissions + package: com.birch.trace.submission + base-path: /submissions + endpoints: + + getSubmissionState: + docs: Returns information about the submission + http: GET /{submissionId} + args: + submissionId: SubmissionId + returns: SubmissionState + + getSubmissionStateV2: + docs: Returns information about submission for problem V2 + http: GET /v2/{submissionId} + args: + submissionId: SubmissionId + returns: SubmissionStateV2 + + getTraceResponsesPage: + docs: Returns traces for the submission and test case + http: POST /trace-respose/{submissionId}/testCase/{testCaseId} + args: + submissionId: SubmissionId + testCaseId: string + request: GetTraceResponsesPageRequest + returns: TraceResponsesPage + + getTraceResponsesV2Page: + docs: Returns traces for the submission and test case + http: POST /trace-response-v2/{submissionId}/testCase/{testCaseId} + args: + submissionId: SubmissionId + testCaseId: problemV2.TestCaseId + request: GetTraceResponsesPageRequest + returns: TraceResponsesPageV2 + + getTraceResponsesPageForWorkspace: + docs: Returns traces for the workspace + http: POST /workspace-trace-response/{submissionId} + args: + submissionId: SubmissionId + request: GetTraceResponsesPageRequest + returns: TraceResponsesPage + + getTraceResponsesV2PageForWorkspace: + docs: Returns traces for the submission and test case + http: POST /workspace-trace-response-v2/{submissionId} + args: + submissionId: SubmissionId + request: GetTraceResponsesPageRequest + returns: TraceResponsesPageV2 + + WorkspaceInfoService: + name: Workspace Info Service + package: com.birch.trace.workspace + base-path: /workspace + endpoints: + + getWorkspaceStarterFiles: + docs: Returns starter files for workspace + http: GET /get-workspace-starter-files + returns: WorkspaceStarterFilesResponse + + getWorkspaceStarterFilesV2: + docs: Returns starter files for workspace + http: GET /get-workspace-starter-files-v2 + returns: WorkspaceStarterFilesResponseV2 + + + + + + + + + + diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/sysprop.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/sysprop.yml new file mode 100644 index 00000000000..ccebf85afaf --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/conjure/sysprop.yml @@ -0,0 +1,23 @@ +types: + conjure-imports: + commons: commons.yml + definitions: + default-package: com.birch.trace.sysprop + objects: +services: + SysPropCrudService: + name: System Property CRUD Service + package: com.birch.trace.sysprop + base-path: /sysprop + endpoints: + + setNumWarmInstances: + http: PUT /num-warm-instances/{language}/{numWarmInstances} + args: + language: commons.Language + numWarmInstances: integer + + getNumWarmInstances: + http: GET /num-warm-instances + returns: map + diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/fern.config.json b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/fern.config.json new file mode 100644 index 00000000000..7980537f564 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/fern.config.json @@ -0,0 +1,4 @@ +{ + "organization": "fern", + "version": "*" +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/generators.yml b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/generators.yml new file mode 100644 index 00000000000..951dc85eda9 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/__test__/fixtures/trace/fern/generators.yml @@ -0,0 +1,11 @@ +api: + specs: + conjure: ../conjure +groups: + local: + generators: + - name: fernapi/fern-typescript-node-sdk + version: 0.39.3 + output: + location: local-file-system + path: ../sdks/typescript diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/package.json b/packages/cli/api-importers/conjure/conjure-to-fern-tests/package.json new file mode 100644 index 00000000000..7c1ee001f46 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/package.json @@ -0,0 +1,45 @@ +{ + "name": "@fern-api/conjure-to-fern-tests", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "https://github.com/fern-api/fern.git", + "directory": "packages/cli/openapi-ir-to-fern" + }, + "private": true, + "files": [ + "lib" + ], + "type": "module", + "source": "src/index.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "sideEffects": false, + "scripts": { + "clean": "rm -rf ./lib && tsc --build --clean", + "compile": "tsc --build", + "test": "vitest --run", + "test:update": "vitest --run -u", + "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../.eslintignore", + "lint:eslint:fix": "yarn lint:eslint --fix", + "format": "prettier --write --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"", + "format:check": "prettier --check --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"", + "organize-imports": "organize-imports-cli tsconfig.json", + "depcheck": "depcheck" + }, + "dependencies": { + "@fern-api/fs-utils": "workspace:*", + "@fern-api/task-context": "workspace:*", + "@fern-api/workspace-loader": "workspace:*" + }, + "devDependencies": { + "@types/node": "^18.7.18", + "depcheck": "^1.4.6", + "eslint": "^8.56.0", + "globals": "link:@types/vitest/globals", + "organize-imports-cli": "^0.10.0", + "prettier": "^2.7.1", + "typescript": "4.6.4", + "vitest": "^2.0.5" + } +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/tsconfig.json b/packages/cli/api-importers/conjure/conjure-to-fern-tests/tsconfig.json new file mode 100644 index 00000000000..e500e93558e --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../../shared/tsconfig.shared.json", + "compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" }, + "include": ["./src/**/*"], + "exclude": ["./src/**/__test__/**/generated"], + "references": [ + { "path": "../../../../commons/fs-utils" }, + { "path": "../../../configuration" }, + { "path": "../../../logger" }, + { "path": "../../../openapi-parser" }, + { "path": "../../../task-context" }, + { "path": "../../../workspace-commons" }, + { "path": "../../../workspace-loader" }, + { "path": "../../../openapi-ir-to-fern" }, + { "path": "../../../fern-definition/schema" }, + { "path": "../../../fern-definition/validator" } + ] +} diff --git a/packages/cli/api-importers/conjure/conjure-to-fern-tests/vitest.config.ts b/packages/cli/api-importers/conjure/conjure-to-fern-tests/vitest.config.ts new file mode 100644 index 00000000000..7be22ca6cd9 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern-tests/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../../../../shared/vitest.config"; diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/.depcheckrc.json b/packages/cli/api-importers/conjure/conjure-to-fern/.depcheckrc.json new file mode 100644 index 00000000000..a3a4f43188c --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/.depcheckrc.json @@ -0,0 +1,10 @@ +{ + "ignores": [ + "@types/jest", + "globals", + "@types/node" + ], + "ignore-patterns": [ + "lib" + ] +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/.prettierrc.cjs b/packages/cli/api-importers/conjure/conjure-to-fern/.prettierrc.cjs new file mode 100644 index 00000000000..402a8099827 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("../../../../../.prettierrc.json"); \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/package.json b/packages/cli/api-importers/conjure/conjure-to-fern/package.json new file mode 100644 index 00000000000..f0c84987cb8 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/package.json @@ -0,0 +1,46 @@ +{ + "name": "@fern-api/conjure-to-fern", + "version": "0.0.0", + "repository": { + "type": "git", + "url": "https://github.com/fern-api/fern.git", + "directory": "packages/cli/generation/remote-generation/remote-workspace-runner" + }, + "private": true, + "files": [ + "lib" + ], + "type": "module", + "source": "src/index.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "sideEffects": false, + "scripts": { + "clean": "rm -rf ./lib && tsc --build --clean", + "compile": "tsc --build", + "test": "vitest --passWithNoTests --run", + "test:update": "vitest --passWithNoTests --run -u", + "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../../../.eslintignore", + "lint:eslint:fix": "yarn lint:eslint --fix", + "format": "prettier --write --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"", + "format:check": "prettier --check --ignore-unknown --ignore-path ../../../../../shared/.prettierignore \"**\"", + "organize-imports": "organize-imports-cli tsconfig.json", + "depcheck": "depcheck" + }, + "dependencies": { + "@fern-api/conjure-sdk": "workspace:*", + "@fern-api/importer-commons": "workspace:*", + "@fern-api/fs-utils": "workspace:*", + "js-yaml": "^4.1.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.8", + "@types/node": "^18.7.18", + "depcheck": "^1.4.6", + "globals": "link:@types/vitest/globals", + "organize-imports-cli": "^0.10.0", + "prettier": "^2.7.1", + "typescript": "4.6.4", + "vitest": "^2.0.5" + } +} \ No newline at end of file diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/src/ConjureImporter.ts b/packages/cli/api-importers/conjure/conjure-to-fern/src/ConjureImporter.ts new file mode 100644 index 00000000000..617e1542752 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/src/ConjureImporter.ts @@ -0,0 +1,102 @@ +import { AbsoluteFilePath, RelativeFilePath } from "@fern-api/fs-utils"; +import { + ConjureTypeDeclaration, + DefinitionFile, + ConjureAliasDeclaration, + ConjureObjectDeclaration, + ConjureEnumDeclaration +} from "@fern-api/conjure-sdk"; +import { APIDefinitionImporter, FernDefinitionBuilderImpl } from "@fern-api/importer-commons"; +import { listConjureFiles } from "./listConjureFiles"; + +export declare namespace ConjureImporter { + interface Args { + absolutePathToConjureFolder: AbsoluteFilePath; + } +} + +export class ConjureImporter extends APIDefinitionImporter { + private fernDefinitionBuilder = new FernDefinitionBuilderImpl(false); + + public async import({ absolutePathToConjureFolder }: ConjureImporter.Args): Promise { + await visitAllConjureDefinitionFiles(absolutePathToConjureFolder, (filepath, definition) => { + for (const [import_, importedFilepath] of Object.entries(definition.imports ?? {})) { + this.fernDefinitionBuilder.addImport({ + file: filepath, + fileToImport: RelativeFilePath.of(importedFilepath), + alias: import_ + }); + } + + for (const [typeName, typeDeclaration] of Object.entries(definition.types?.definitions?.objects ?? {})) { + if (isAlias(typeDeclaration)) { + this.fernDefinitionBuilder.addType(filepath, { + name: typeName, + schema: { + type: typeDeclaration.alias, + docs: typeDeclaration.docs + } + }); + } else if (isObject(typeDeclaration)) { + this.fernDefinitionBuilder.addType(filepath, { + name: typeName, + schema: { + properties: typeDeclaration.fields + } + }); + } else if (isEnum(typeDeclaration)) { + this.fernDefinitionBuilder.addType(filepath, { + name: typeName, + schema: { + enum: typeDeclaration.values + } + }); + } + } + + for (const [serviceName, serviceDeclaration] of Object.entries(definition.services ?? {})) { + for (const [endpointName, endpointDeclaration] of Object.entries(serviceDeclaration.endpoints ?? {})) { + const splitConjurePath = endpointDeclaration.http.split(" "); + const method = splitConjurePath[1]; + const path = splitConjurePath[0]; + if (method == null || path == null) { + break; + } + this.fernDefinitionBuilder.addEndpoint(filepath, { + name: endpointName, + schema: { + auth: true, + path, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + method: method as any, + response: endpointDeclaration.returns + }, + source: undefined + }); + } + } + }); + return this.fernDefinitionBuilder.build(); + } +} + +export async function visitAllConjureDefinitionFiles( + absolutePathToConjureFolder: AbsoluteFilePath, + visitor: (filepath: RelativeFilePath, definitionFile: DefinitionFile) => void | Promise +): Promise { + for (const conjureFile of await listConjureFiles(absolutePathToConjureFolder, "{yml,yaml}")) { + await visitor(conjureFile.relativeFilepath, conjureFile.fileContents); + } +} + +function isAlias(type: ConjureTypeDeclaration): type is ConjureAliasDeclaration { + return (type as ConjureAliasDeclaration)?.alias != null; +} + +function isEnum(type: ConjureTypeDeclaration): type is ConjureEnumDeclaration { + return (type as ConjureEnumDeclaration)?.values != null; +} + +function isObject(type: ConjureTypeDeclaration): type is ConjureObjectDeclaration { + return (type as ConjureObjectDeclaration)?.fields != null; +} diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/src/index.ts b/packages/cli/api-importers/conjure/conjure-to-fern/src/index.ts new file mode 100644 index 00000000000..b0a04abddf5 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/src/index.ts @@ -0,0 +1 @@ +export { ConjureImporter } from "./ConjureImporter"; diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/src/listConjureFiles.ts b/packages/cli/api-importers/conjure/conjure-to-fern/src/listConjureFiles.ts new file mode 100644 index 00000000000..cae6194000b --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/src/listConjureFiles.ts @@ -0,0 +1,44 @@ +import { DefinitionFile, serialization } from "@fern-api/conjure-sdk"; +import { AbsoluteFilePath, listFiles, relative, RelativeFilePath } from "@fern-api/fs-utils"; +import { readFile } from "fs/promises"; +import yaml from "js-yaml"; + +export interface ConjureFile { + fileContents: DefinitionFile; + absoluteFilepath: AbsoluteFilePath; + relativeFilepath: RelativeFilePath; +} + +export async function listConjureFiles(root: AbsoluteFilePath, extensionGlob: string): Promise { + const files: ConjureFile[] = []; + + for (const absoluteFilepath of await listFiles(root, extensionGlob)) { + files.push( + await createConjureFile({ + relativeFilepath: relative(root, absoluteFilepath), + absoluteFilepath + }) + ); + } + + return files; +} + +async function createConjureFile({ + relativeFilepath, + absoluteFilepath +}: { + relativeFilepath: RelativeFilePath; + absoluteFilepath: AbsoluteFilePath; +}): Promise { + const rawContents = (await readFile(absoluteFilepath)).toString(); + return { + relativeFilepath, + absoluteFilepath, + fileContents: serialization.DefinitionFile.parseOrThrow(yaml.load(rawContents), { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedEnumValues: true, + allowUnrecognizedUnionMembers: true + }) + }; +} diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/tsconfig.json b/packages/cli/api-importers/conjure/conjure-to-fern/tsconfig.json new file mode 100644 index 00000000000..93e5a9e35b3 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../../../shared/tsconfig.shared.json", + "compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" }, + "include": ["./src/**/*"], + "references": [ + { "path": "../conjure-sdk" }, + { "path": "../../commons" }, + ] +} diff --git a/packages/cli/api-importers/conjure/conjure-to-fern/vitest.config.ts b/packages/cli/api-importers/conjure/conjure-to-fern/vitest.config.ts new file mode 100644 index 00000000000..7be22ca6cd9 --- /dev/null +++ b/packages/cli/api-importers/conjure/conjure-to-fern/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../../../../shared/vitest.config"; diff --git a/packages/cli/cli/versions.yml b/packages/cli/cli/versions.yml index 5ee5c3d9f47..0df6772206a 100644 --- a/packages/cli/cli/versions.yml +++ b/packages/cli/cli/versions.yml @@ -1,3 +1,13 @@ +- changelogEntry: + - summary: | + The Fern CLI now supports parsing [Conjure](https://github.com/palantir/conjure), Palantir's + home-grown API Definition format. + + If you know a company that is using Conjure that wants API Docs + SDKs, send them our way! + type: feat + irVersion: 53 + version: 0.44.0-rc0 + - changelogEntry: - summary: | Any markdown files that have custom components are also pushed up to the Fern Docs diff --git a/packages/cli/configuration/src/generators-yml/GeneratorsConfiguration.ts b/packages/cli/configuration/src/generators-yml/GeneratorsConfiguration.ts index 954d46ea6be..1633cc2823c 100644 --- a/packages/cli/configuration/src/generators-yml/GeneratorsConfiguration.ts +++ b/packages/cli/configuration/src/generators-yml/GeneratorsConfiguration.ts @@ -19,7 +19,7 @@ export interface GeneratorsConfiguration { absolutePathToConfiguration: AbsoluteFilePath; } -export type APIDefinition = SingleNamespaceAPIDefinition | MultiNamespaceAPIDefinition; +export type APIDefinition = SingleNamespaceAPIDefinition | MultiNamespaceAPIDefinition | ConjureAPIDefinition; export interface SingleNamespaceAPIDefinition extends RawSchemas.WithEnvironmentsSchema, @@ -38,6 +38,14 @@ export interface MultiNamespaceAPIDefinition definitions: Record; } +export interface ConjureAPIDefinition + extends RawSchemas.WithEnvironmentsSchema, + RawSchemas.WithAuthSchema, + RawSchemas.WithHeadersSchema { + type: "conjure"; + pathToConjureDefinition: string; +} + export interface APIDefinitionSettings { shouldUseTitleAsName: boolean | undefined; shouldUseUndiscriminatedUnionsWithLiterals: boolean | undefined; diff --git a/packages/cli/configuration/src/generators-yml/convertGeneratorsConfiguration.ts b/packages/cli/configuration/src/generators-yml/convertGeneratorsConfiguration.ts index a3cde6cfd63..f884e1c7283 100644 --- a/packages/cli/configuration/src/generators-yml/convertGeneratorsConfiguration.ts +++ b/packages/cli/configuration/src/generators-yml/convertGeneratorsConfiguration.ts @@ -1,4 +1,4 @@ -import { assertNever, isNonNullish, isPlainObject } from "@fern-api/core-utils"; +import { assertNever, isPlainObject } from "@fern-api/core-utils"; import { AbsoluteFilePath, dirname, join, RelativeFilePath, resolve } from "@fern-api/fs-utils"; import { FernFiddle } from "@fern-fern/fiddle-sdk"; import { GithubPullRequestReviewer, OutputMetadata, PublishingMetadata, PypiMetadata } from "@fern-fern/fiddle-sdk/api"; @@ -17,7 +17,7 @@ import { APIConfigurationSchemaInternal, APIConfigurationV2Schema } from "./sche import { GeneratorGroupSchema } from "./schemas/GeneratorGroupSchema"; import { GeneratorInvocationSchema } from "./schemas/GeneratorInvocationSchema"; import { GeneratorOutputSchema } from "./schemas/GeneratorOutputSchema"; -import { isApiConfigurationV2Schema, isOpenAPISchema } from "./schemas/utils"; +import { isApiConfigurationV2Schema, isConjureSchema, isOpenAPISchema } from "./schemas/utils"; import { API_ORIGIN_LOCATION_KEY, API_SETTINGS_KEY, @@ -256,10 +256,17 @@ async function parseApiConfigurationV2Schema({ apiConfiguration: APIConfigurationV2Schema; rawConfiguration: GeneratorsConfigurationSchema; }): Promise { + if (isConjureSchema(apiConfiguration.specs)) { + return { + type: "conjure", + pathToConjureDefinition: apiConfiguration.specs.conjure + }; + } + const rootDefinitions: APIDefinitionLocation[] = []; const namespacedDefinitions: Record = {}; - for (const spec of apiConfiguration.specs) { + for (const spec of apiConfiguration.specs ?? []) { if (isOpenAPISchema(spec)) { const definitionLocation: APIDefinitionLocation = { schema: { diff --git a/packages/cli/configuration/src/generators-yml/schemas/APIConfigurationV2Schema.ts b/packages/cli/configuration/src/generators-yml/schemas/APIConfigurationV2Schema.ts index e165dad89e5..a0a77a47629 100644 --- a/packages/cli/configuration/src/generators-yml/schemas/APIConfigurationV2Schema.ts +++ b/packages/cli/configuration/src/generators-yml/schemas/APIConfigurationV2Schema.ts @@ -37,14 +37,29 @@ export const AsyncAPISchema = z.strictObject({ export type AsyncAPISchema = z.infer; -export const SpecSchema = z.union([OpenAPISpecSchema, AsyncAPISchema]); +/*********** Conjure Spec ***********/ -export type SpecSchema = z.infer; +export const ConjureSettingsSchema = z.strictObject({}); + +export type ConjureSettingsSchema = z.infer; + +export const ConjureSchema = z.strictObject({ + conjure: z.string() +}); + +export type ConjureSchema = z.infer; + +/*********** Global Schemas ***********/ + +export const AsyncAPIOrOpenAPISpecSchema = z.union([OpenAPISpecSchema, AsyncAPISchema]); + +export type AsyncAPIOrOpenAPISpecSchema = z.infer; export const APIConfigurationV2Schema = z .object({ auth: z.optional(RawSchemas.ApiAuthSchema), - specs: z.array(SpecSchema) + // You can't union Conjure specs with OpenAPI and AsyncAPI (drastically inreases complexity) + specs: z.union([z.array(AsyncAPIOrOpenAPISpecSchema), ConjureSchema]) }) .extend(RawSchemas.WithHeadersSchema.shape) .extend(RawSchemas.WithEnvironmentsSchema.shape); diff --git a/packages/cli/configuration/src/generators-yml/schemas/utils/index.ts b/packages/cli/configuration/src/generators-yml/schemas/utils/index.ts index 096bb3e179c..d6bd91dd3fd 100644 --- a/packages/cli/configuration/src/generators-yml/schemas/utils/index.ts +++ b/packages/cli/configuration/src/generators-yml/schemas/utils/index.ts @@ -1,3 +1,4 @@ export { isApiConfigurationV2Schema } from "./isApiConfigurationV2Schema"; export { isAsyncAPISchema } from "./isAsyncAPISpecSchema"; export { isOpenAPISchema } from "./isOpenAPISpecSchema"; +export { isConjureSchema } from "./isConjureSchema"; diff --git a/packages/cli/configuration/src/generators-yml/schemas/utils/isAsyncAPISpecSchema.ts b/packages/cli/configuration/src/generators-yml/schemas/utils/isAsyncAPISpecSchema.ts index 186efb6ba01..ecad0a47174 100644 --- a/packages/cli/configuration/src/generators-yml/schemas/utils/isAsyncAPISpecSchema.ts +++ b/packages/cli/configuration/src/generators-yml/schemas/utils/isAsyncAPISpecSchema.ts @@ -1,5 +1,5 @@ -import { AsyncAPISchema, SpecSchema } from "../APIConfigurationV2Schema"; +import { AsyncAPISchema, AsyncAPIOrOpenAPISpecSchema } from "../APIConfigurationV2Schema"; -export function isAsyncAPISchema(spec: SpecSchema): spec is AsyncAPISchema { +export function isAsyncAPISchema(spec: AsyncAPIOrOpenAPISpecSchema): spec is AsyncAPISchema { return (spec as AsyncAPISchema)?.asyncapi != null; } diff --git a/packages/cli/configuration/src/generators-yml/schemas/utils/isConjureSchema.ts b/packages/cli/configuration/src/generators-yml/schemas/utils/isConjureSchema.ts new file mode 100644 index 00000000000..6345a243aee --- /dev/null +++ b/packages/cli/configuration/src/generators-yml/schemas/utils/isConjureSchema.ts @@ -0,0 +1,5 @@ +import { AsyncAPIOrOpenAPISpecSchema, ConjureSchema } from "../APIConfigurationV2Schema"; + +export function isConjureSchema(specs: AsyncAPIOrOpenAPISpecSchema[] | ConjureSchema): specs is ConjureSchema { + return (specs as ConjureSchema)?.conjure != null; +} diff --git a/packages/cli/configuration/src/generators-yml/schemas/utils/isOpenAPISpecSchema.ts b/packages/cli/configuration/src/generators-yml/schemas/utils/isOpenAPISpecSchema.ts index 38be188f8fb..2ecfd43e05c 100644 --- a/packages/cli/configuration/src/generators-yml/schemas/utils/isOpenAPISpecSchema.ts +++ b/packages/cli/configuration/src/generators-yml/schemas/utils/isOpenAPISpecSchema.ts @@ -1,5 +1,5 @@ -import { OpenAPISpecSchema, SpecSchema } from "../APIConfigurationV2Schema"; +import { OpenAPISpecSchema, AsyncAPIOrOpenAPISpecSchema } from "../APIConfigurationV2Schema"; -export function isOpenAPISchema(spec: SpecSchema): spec is OpenAPISpecSchema { +export function isOpenAPISchema(spec: AsyncAPIOrOpenAPISpecSchema): spec is OpenAPISpecSchema { return (spec as OpenAPISpecSchema)?.openapi != null; } diff --git a/packages/cli/lazy-fern-workspace/package.json b/packages/cli/lazy-fern-workspace/package.json index 0ffbcbd34bf..240be105412 100644 --- a/packages/cli/lazy-fern-workspace/package.json +++ b/packages/cli/lazy-fern-workspace/package.json @@ -40,6 +40,7 @@ "@fern-api/semver-utils": "workspace:*", "@fern-api/task-context": "workspace:*", "@fern-api/fern-definition-schema": "workspace:*", + "@fern-api/conjure-to-fern": "workspace:*", "@fern-fern/fiddle-sdk": "0.0.584", "@types/uuid": "^9.0.8", "axios": "^0.28.0", diff --git a/packages/cli/lazy-fern-workspace/src/ConjureWorkspace.ts b/packages/cli/lazy-fern-workspace/src/ConjureWorkspace.ts new file mode 100644 index 00000000000..2c0b1dea8a8 --- /dev/null +++ b/packages/cli/lazy-fern-workspace/src/ConjureWorkspace.ts @@ -0,0 +1,80 @@ +import { AbstractAPIWorkspace, FernDefinition, FernWorkspace } from "@fern-api/api-workspace-commons"; +import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils"; +import { TaskContext } from "@fern-api/task-context"; +import { ConjureImporter } from "@fern-api/conjure-to-fern"; +import { FERN_PACKAGE_MARKER_FILENAME } from "@fern-api/configuration"; +import yaml from "js-yaml"; +import { mapValues } from "./utils/mapValues"; + +export declare namespace ConjureWorkspace { + export interface Args extends AbstractAPIWorkspace.Args { + context: TaskContext; + relativePathToConjureDirectory: RelativeFilePath; + } + + export interface Settings {} +} + +export class ConjureWorkspace extends AbstractAPIWorkspace { + private absolutePathToConjureFolder: AbsoluteFilePath; + + constructor({ relativePathToConjureDirectory, ...superArgs }: ConjureWorkspace.Args) { + super(superArgs); + this.absolutePathToConjureFolder = join(superArgs.absoluteFilePath, relativePathToConjureDirectory); + } + + public async toFernWorkspace( + { context }: { context: TaskContext }, + settings?: ConjureWorkspace.Settings + ): Promise { + const definition = await this.getDefinition({ context }, settings); + return new FernWorkspace({ + absoluteFilePath: this.absoluteFilePath, + workspaceName: this.workspaceName, + generatorsConfiguration: this.generatorsConfiguration, + dependenciesConfiguration: { + dependencies: {} + }, + definition, + cliVersion: this.cliVersion, + sources: undefined + }); + } + + public async getDefinition( + { context }: { context?: TaskContext | undefined }, + settings?: ConjureWorkspace.Settings + ): Promise { + const conjure = new ConjureImporter(context); + const definition = await conjure.import({ absolutePathToConjureFolder: this.absolutePathToConjureFolder }); + return { + // these files doesn't live on disk, so there's no absolute filepath + absoluteFilePath: AbsoluteFilePath.of("/DUMMY_PATH"), + rootApiFile: { + defaultUrl: definition.rootApiFile["default-url"], + contents: definition.rootApiFile, + rawContents: yaml.dump(definition.rootApiFile) + }, + namedDefinitionFiles: { + ...mapValues(definition.definitionFiles, (definitionFile) => ({ + // these files doesn't live on disk, so there's no absolute filepath + absoluteFilepath: AbsoluteFilePath.of("/DUMMY_PATH"), + rawContents: yaml.dump(definitionFile), + contents: definitionFile + })), + [RelativeFilePath.of(FERN_PACKAGE_MARKER_FILENAME)]: { + // these files doesn't live on disk, so there's no absolute filepath + absoluteFilepath: AbsoluteFilePath.of("/DUMMY_PATH"), + rawContents: yaml.dump(definition.packageMarkerFile), + contents: definition.packageMarkerFile + } + }, + packageMarkers: {}, + importedDefinitions: {} + }; + } + + public getAbsoluteFilePaths(): AbsoluteFilePath[] { + return [this.absolutePathToConjureFolder]; + } +} diff --git a/packages/cli/lazy-fern-workspace/src/OSSWorkspace.ts b/packages/cli/lazy-fern-workspace/src/OSSWorkspace.ts index 24af874d0c2..a3acf0a2a8e 100644 --- a/packages/cli/lazy-fern-workspace/src/OSSWorkspace.ts +++ b/packages/cli/lazy-fern-workspace/src/OSSWorkspace.ts @@ -5,7 +5,6 @@ import { convert } from "@fern-api/openapi-ir-to-fern"; import { parse, ParseOpenAPIOptions } from "@fern-api/openapi-parser"; import { TaskContext } from "@fern-api/task-context"; import yaml from "js-yaml"; -import { mapValues as mapValuesLodash } from "lodash-es"; import { v4 as uuidv4 } from "uuid"; import { getAllOpenAPISpecs } from "./utils/getAllOpenAPISpecs"; import { @@ -14,6 +13,7 @@ import { FernDefinition, IdentifiableSource } from "@fern-api/api-workspace-commons"; +import { mapValues } from "./utils/mapValues"; export type Spec = OpenAPISpec | ProtobufSpec; @@ -255,7 +255,3 @@ function getOptionsOverridesFromSettings(settings?: OSSWorkspace.Settings): Part } return result; } - -function mapValues(items: T, mapper: (item: T[keyof T]) => U): Record { - return mapValuesLodash(items, mapper) as Record; -} diff --git a/packages/cli/lazy-fern-workspace/src/index.ts b/packages/cli/lazy-fern-workspace/src/index.ts index d397c22f4f1..cb539bef780 100644 --- a/packages/cli/lazy-fern-workspace/src/index.ts +++ b/packages/cli/lazy-fern-workspace/src/index.ts @@ -2,3 +2,4 @@ export { type AsyncAPISource, type OpenAPISource, type ProtobufSource, type Sour export * from "./utils"; export * from "./LazyFernWorkspace"; export * from "./OSSWorkspace"; +export * from "./ConjureWorkspace"; diff --git a/packages/cli/lazy-fern-workspace/src/utils/Result.ts b/packages/cli/lazy-fern-workspace/src/utils/Result.ts index 3dec4a1dd5a..4b497c145a6 100644 --- a/packages/cli/lazy-fern-workspace/src/utils/Result.ts +++ b/packages/cli/lazy-fern-workspace/src/utils/Result.ts @@ -2,13 +2,14 @@ import { RelativeFilePath } from "@fern-api/fs-utils"; import { ZodError } from "zod"; import { OSSWorkspace } from "../OSSWorkspace"; import { LazyFernWorkspace } from "../LazyFernWorkspace"; +import { ConjureWorkspace } from "../ConjureWorkspace"; export declare namespace WorkspaceLoader { export type Result = SuccessfulResult | FailedResult; export interface SuccessfulResult { didSucceed: true; - workspace: LazyFernWorkspace | OSSWorkspace; + workspace: LazyFernWorkspace | OSSWorkspace | ConjureWorkspace; } export interface FailedResult { diff --git a/packages/cli/lazy-fern-workspace/src/utils/mapValues.ts b/packages/cli/lazy-fern-workspace/src/utils/mapValues.ts new file mode 100644 index 00000000000..661fdca7cfe --- /dev/null +++ b/packages/cli/lazy-fern-workspace/src/utils/mapValues.ts @@ -0,0 +1,5 @@ +import { mapValues as mapValuesLodash } from "lodash-es"; + +export function mapValues(items: T, mapper: (item: T[keyof T]) => U): Record { + return mapValuesLodash(items, mapper) as Record; +} diff --git a/packages/cli/lazy-fern-workspace/tsconfig.json b/packages/cli/lazy-fern-workspace/tsconfig.json index c15d81b744d..cbca6756b2d 100644 --- a/packages/cli/lazy-fern-workspace/tsconfig.json +++ b/packages/cli/lazy-fern-workspace/tsconfig.json @@ -6,6 +6,7 @@ { "path": "../../commons/core-utils" }, { "path": "../../commons/fs-utils" }, { "path": "../../commons/logging-execa" }, + { "path": "../api-importers/conjure/conjure-to-fern" }, { "path": "../../core" }, { "path": "../configuration" }, { "path": "../logger" }, diff --git a/packages/cli/openapi-ir-to-fern/package.json b/packages/cli/openapi-ir-to-fern/package.json index 32478eb67f0..99344b5f1ba 100644 --- a/packages/cli/openapi-ir-to-fern/package.json +++ b/packages/cli/openapi-ir-to-fern/package.json @@ -18,8 +18,8 @@ "scripts": { "clean": "rm -rf ./lib && tsc --build --clean", "compile": "tsc --build", - "test": "vitest --run", - "test:update": "vitest --run -u", + "test": "vitest --passWithNoTests --run", + "test:update": "vitest --passWithNoTests --run -u", "lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../.eslintignore", "lint:eslint:fix": "yarn lint:eslint --fix", "format": "prettier --write --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"", @@ -36,6 +36,7 @@ "@fern-api/openapi-parser": "workspace:*", "@fern-api/task-context": "workspace:*", "@fern-api/fern-definition-schema": "workspace:*", + "@fern-api/importer-commons": "workspace:*", "lodash-es": "^4.17.21" }, "devDependencies": { diff --git a/packages/cli/openapi-ir-to-fern/src/OpenApiIrConverterContext.ts b/packages/cli/openapi-ir-to-fern/src/OpenApiIrConverterContext.ts index 0f1b71fbfeb..1779a186af5 100644 --- a/packages/cli/openapi-ir-to-fern/src/OpenApiIrConverterContext.ts +++ b/packages/cli/openapi-ir-to-fern/src/OpenApiIrConverterContext.ts @@ -2,7 +2,7 @@ import { RawSchemas } from "@fern-api/fern-definition-schema"; import { Logger } from "@fern-api/logger"; import { OpenApiIntermediateRepresentation, Schema, SchemaId } from "@fern-api/openapi-ir-sdk"; import { TaskContext } from "@fern-api/task-context"; -import { FernDefinitionBuilder, FernDefinitionBuilderImpl } from "./FernDefnitionBuilder"; +import { FernDefinitionBuilder, FernDefinitionBuilderImpl } from "@fern-api/importer-commons"; export interface OpenApiIrConverterContextOpts { taskContext: TaskContext; @@ -50,7 +50,10 @@ export class OpenApiIrConverterContext { this.logger = taskContext.logger; this.taskContext = taskContext; this.ir = ir; - this.builder = new FernDefinitionBuilderImpl(ir, false, enableUniqueErrorsPerEndpoint); + this.builder = new FernDefinitionBuilderImpl(enableUniqueErrorsPerEndpoint); + if (ir.title != null) { + this.builder.setDisplayName({ displayName: ir.title }); + } this.detectGlobalHeaders = detectGlobalHeaders; this.environmentOverrides = environmentOverrides; this.authOverrides = authOverrides; diff --git a/packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionBuilder.test.ts b/packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionBuilder.test.ts deleted file mode 100644 index a2045849c27..00000000000 --- a/packages/cli/openapi-ir-to-fern/src/__test__/FernDefinitionBuilder.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { RelativeFilePath } from "@fern-api/fs-utils"; -import { FernDefinitionBuilderImpl } from "../FernDefnitionBuilder"; - -describe("Fern Definition Builder", () => { - it("removes base path from environment", async () => { - const builder = new FernDefinitionBuilderImpl( - { - apiVersion: undefined, - title: undefined, - description: undefined, - basePath: undefined, - servers: [], - tags: { - tagsById: {}, - orderedTagIds: [] - }, - hasEndpointsMarkedInternal: false, - endpoints: [], - webhooks: [], - groupedSchemas: { - rootSchemas: {}, - namespacedSchemas: {} - }, - variables: {}, - nonRequestReferencedSchemas: new Set(), - securitySchemes: {}, - globalHeaders: [], - idempotencyHeaders: [], - groups: {}, - channel: [] - }, - true, - false - ); - builder.addEnvironment({ - name: "Production", - schema: "https://buildwithfern.com/api/v1" - }); - builder.addEnvironment({ - name: "Staging", - schema: { - url: "https://staging.buildwithfern.com/api/v1" - } - }); - const usersYml = RelativeFilePath.of("users.yml"); - builder.addEndpoint(usersYml, { - name: "get", - schema: { - method: "GET", - path: "/users" - }, - source: undefined - }); - const definition = builder.build(); - expect(definition.rootApiFile.environments != null).toEqual(true); - const stringifiedEnvironments = JSON.stringify(definition.rootApiFile.environments ?? {}); - expect(stringifiedEnvironments).toContain("https://buildwithfern.com"); - expect(stringifiedEnvironments).toContain("https://staging.buildwithfern.com"); - expect(stringifiedEnvironments).not.toContain("https://buildwithfern.com/api/v1"); - expect(stringifiedEnvironments).not.toContain("https://staging.buildwithfern.com/api/v1"); - - // eslint-disable-next-line @typescript-eslint/dot-notation - expect(definition.definitionFiles[usersYml]?.service?.endpoints["get"]?.path).toBe("/api/v1/users"); - }); -}); diff --git a/packages/cli/openapi-ir-to-fern/src/buildFernDefinition.ts b/packages/cli/openapi-ir-to-fern/src/buildFernDefinition.ts index 387e1f2b0f5..3f67b9e7b41 100644 --- a/packages/cli/openapi-ir-to-fern/src/buildFernDefinition.ts +++ b/packages/cli/openapi-ir-to-fern/src/buildFernDefinition.ts @@ -10,7 +10,7 @@ import { buildServices } from "./buildServices"; import { buildTypeDeclaration } from "./buildTypeDeclaration"; import { buildVariables } from "./buildVariables"; import { buildWebhooks } from "./buildWebhooks"; -import { FernDefinition } from "./FernDefnitionBuilder"; +import { FernDefinition } from "@fern-api/importer-commons"; import { OpenApiIrConverterContext } from "./OpenApiIrConverterContext"; import { getDeclarationFileForSchema } from "./utils/getDeclarationFileForSchema"; import { getTypeFromTypeReference } from "./utils/getTypeFromTypeReference"; diff --git a/packages/cli/openapi-ir-to-fern/src/buildServices.ts b/packages/cli/openapi-ir-to-fern/src/buildServices.ts index 8d2c3b7019e..cb342780e49 100644 --- a/packages/cli/openapi-ir-to-fern/src/buildServices.ts +++ b/packages/cli/openapi-ir-to-fern/src/buildServices.ts @@ -1,6 +1,7 @@ import { FernOpenapiIr } from "@fern-api/openapi-ir-sdk"; import { buildEndpoint } from "./buildEndpoint"; import { OpenApiIrConverterContext } from "./OpenApiIrConverterContext"; +import { convertToSourceSchema } from "./utils/convertToSourceSchema"; import { getEndpointLocation } from "./utils/getEndpointLocation"; export function buildServices(context: OpenApiIrConverterContext): { @@ -40,7 +41,7 @@ export function buildServices(context: OpenApiIrConverterContext): { context.builder.addEndpoint(file, { name: endpointId, schema: convertedEndpoint.value, - source: endpoint.source + source: endpoint.source != null ? convertToSourceSchema(endpoint.source) : undefined }); if (irTag?.id != null || irTag?.description != null) { context.builder.setServiceInfo(file, { diff --git a/packages/cli/openapi-ir-to-fern/tsconfig.json b/packages/cli/openapi-ir-to-fern/tsconfig.json index 60b1a683102..5c232156504 100644 --- a/packages/cli/openapi-ir-to-fern/tsconfig.json +++ b/packages/cli/openapi-ir-to-fern/tsconfig.json @@ -12,6 +12,7 @@ { "path": "../openapi-parser" }, { "path": "../task-context" }, { "path": "../workspace-commons" }, + { "path": "../api-importers/commons" }, { "path": "../fern-definition/schema" }, ] } diff --git a/packages/cli/workspace-loader/src/loadAPIWorkspace.ts b/packages/cli/workspace-loader/src/loadAPIWorkspace.ts index 8577563b578..fa7e1d2e224 100644 --- a/packages/cli/workspace-loader/src/loadAPIWorkspace.ts +++ b/packages/cli/workspace-loader/src/loadAPIWorkspace.ts @@ -7,7 +7,8 @@ import { OSSWorkspace, LazyFernWorkspace, WorkspaceLoader, - WorkspaceLoaderFailureType + WorkspaceLoaderFailureType, + ConjureWorkspace } from "@fern-api/lazy-fern-workspace"; export async function loadSingleNamespaceAPIWorkspace({ @@ -142,6 +143,21 @@ export async function loadAPIWorkspace({ changelog = await loadAPIChangelog({ absolutePathToWorkspace }); } catch (err) {} + if (generatorsConfiguration?.api != null && generatorsConfiguration?.api.type === "conjure") { + return { + didSucceed: true, + workspace: new ConjureWorkspace({ + workspaceName, + absoluteFilePath: absolutePathToWorkspace, + generatorsConfiguration, + changelog, + cliVersion, + context, + relativePathToConjureDirectory: RelativeFilePath.of(generatorsConfiguration.api.pathToConjureDefinition) + }) + }; + } + if ( generatorsConfiguration?.api != null && ((generatorsConfiguration.api.type === "singleNamespace" && diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fdae32e9512..cf8bebbb605 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2980,6 +2980,150 @@ importers: specifier: ^2.0.5 version: 2.0.5(@types/node@18.7.18)(jsdom@20.0.3)(sass@1.72.0)(terser@5.31.5) + packages/cli/api-importers/commons: + dependencies: + '@fern-api/configuration': + specifier: workspace:* + version: link:../../configuration + '@fern-api/fern-definition-schema': + specifier: workspace:* + version: link:../../fern-definition/schema + '@fern-api/fs-utils': + specifier: workspace:* + version: link:../../../commons/fs-utils + '@fern-api/task-context': + specifier: workspace:* + version: link:../../task-context + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + devDependencies: + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 + '@types/node': + specifier: ^18.7.18 + version: 18.7.18 + depcheck: + specifier: ^1.4.6 + version: 1.4.6 + globals: + specifier: link:@types/vitest/globals + version: link:@types/vitest/globals + organize-imports-cli: + specifier: ^0.10.0 + version: 0.10.0 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + typescript: + specifier: 4.6.4 + version: 4.6.4 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@18.7.18)(jsdom@20.0.3)(sass@1.72.0)(terser@5.31.5) + + packages/cli/api-importers/conjure/conjure-sdk: + devDependencies: + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@types/node': + specifier: ^18.7.18 + version: 18.7.18 + depcheck: + specifier: ^1.4.6 + version: 1.4.6 + eslint: + specifier: ^8.56.0 + version: 8.56.0 + organize-imports-cli: + specifier: ^0.10.0 + version: 0.10.0 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + typescript: + specifier: 4.6.4 + version: 4.6.4 + + packages/cli/api-importers/conjure/conjure-to-fern: + dependencies: + '@fern-api/conjure-sdk': + specifier: workspace:* + version: link:../conjure-sdk + '@fern-api/fs-utils': + specifier: workspace:* + version: link:../../../../commons/fs-utils + '@fern-api/importer-commons': + specifier: workspace:* + version: link:../../commons + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + devDependencies: + '@types/js-yaml': + specifier: ^4.0.8 + version: 4.0.8 + '@types/node': + specifier: ^18.7.18 + version: 18.7.18 + depcheck: + specifier: ^1.4.6 + version: 1.4.6 + globals: + specifier: link:@types/vitest/globals + version: link:@types/vitest/globals + organize-imports-cli: + specifier: ^0.10.0 + version: 0.10.0 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + typescript: + specifier: 4.6.4 + version: 4.6.4 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@18.7.18)(jsdom@20.0.3)(sass@1.72.0)(terser@5.31.5) + + packages/cli/api-importers/conjure/conjure-to-fern-tests: + dependencies: + '@fern-api/fs-utils': + specifier: workspace:* + version: link:../../../../commons/fs-utils + '@fern-api/task-context': + specifier: workspace:* + version: link:../../../task-context + '@fern-api/workspace-loader': + specifier: workspace:* + version: link:../../../workspace-loader + devDependencies: + '@types/node': + specifier: ^18.7.18 + version: 18.7.18 + depcheck: + specifier: ^1.4.6 + version: 1.4.6 + eslint: + specifier: ^8.56.0 + version: 8.56.0 + globals: + specifier: link:@types/vitest/globals + version: link:@types/vitest/globals + organize-imports-cli: + specifier: ^0.10.0 + version: 0.10.0 + prettier: + specifier: ^2.7.1 + version: 2.7.1 + typescript: + specifier: 4.6.4 + version: 4.6.4 + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@18.7.18)(jsdom@20.0.3)(sass@1.72.0)(terser@5.31.5) + packages/cli/auth: dependencies: '@fern-api/core': @@ -4625,6 +4769,9 @@ importers: '@fern-api/configuration': specifier: workspace:* version: link:../configuration + '@fern-api/conjure-to-fern': + specifier: workspace:* + version: link:../api-importers/conjure/conjure-to-fern '@fern-api/core': specifier: workspace:* version: link:../../core @@ -4929,6 +5076,9 @@ importers: '@fern-api/fs-utils': specifier: workspace:* version: link:../../commons/fs-utils + '@fern-api/importer-commons': + specifier: workspace:* + version: link:../api-importers/commons '@fern-api/logger': specifier: workspace:* version: link:../logger diff --git a/shared/.prettierignore b/shared/.prettierignore index e39fcee8e3f..617d5ce51a9 100644 --- a/shared/.prettierignore +++ b/shared/.prettierignore @@ -1,3 +1,4 @@ +../packages/cli/api-importers/conjure/conjure-sdk/** ../packages/ir-sdk/** ../packages/cli/configuration/src/docs-yml/schemas/** ../packages/cli/openapi-ir-sdk/**