@orpc/openapi 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.js +64 -21
- package/dist/index.js.map +1 -1
- package/dist/src/generator.d.ts.map +1 -1
- package/dist/src/zod-to-json-schema.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -11
- package/src/generator.test.ts +186 -8
- package/src/generator.ts +102 -31
- package/src/zod-to-json-schema.test.ts +1 -1
- package/src/zod-to-json-schema.ts +22 -33
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 oRPC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/generator.ts
|
|
2
2
|
import { eachContractRouterLeaf } from "@orpc/contract";
|
|
3
3
|
import { toContractRouter } from "@orpc/server";
|
|
4
|
-
import { findDeepMatches, omit } from "@orpc/shared";
|
|
4
|
+
import { findDeepMatches, isPlainObject, omit } from "@orpc/shared";
|
|
5
5
|
import { preSerialize } from "@orpc/transformer";
|
|
6
6
|
import {
|
|
7
7
|
OpenApiBuilder
|
|
@@ -3949,20 +3949,16 @@ function zodToJsonSchema(schema, options) {
|
|
|
3949
3949
|
return json;
|
|
3950
3950
|
}
|
|
3951
3951
|
case ZodFirstPartyTypeKind.ZodNaN: {
|
|
3952
|
-
const schema_ = schema;
|
|
3953
3952
|
return { const: "NaN" };
|
|
3954
3953
|
}
|
|
3955
3954
|
case ZodFirstPartyTypeKind.ZodBigInt: {
|
|
3956
|
-
const schema_ = schema;
|
|
3957
3955
|
const json = { type: "string", pattern: "^-?[0-9]+$" };
|
|
3958
3956
|
return json;
|
|
3959
3957
|
}
|
|
3960
3958
|
case ZodFirstPartyTypeKind.ZodBoolean: {
|
|
3961
|
-
const schema_ = schema;
|
|
3962
3959
|
return { type: "boolean" };
|
|
3963
3960
|
}
|
|
3964
3961
|
case ZodFirstPartyTypeKind.ZodDate: {
|
|
3965
|
-
const schema_ = schema;
|
|
3966
3962
|
const jsonSchema = { type: "string", format: Format.Date };
|
|
3967
3963
|
return jsonSchema;
|
|
3968
3964
|
}
|
|
@@ -4230,10 +4226,10 @@ function generateOpenAPI(opts, options) {
|
|
|
4230
4226
|
}
|
|
4231
4227
|
const path = internal.path ?? `/${path_.map(encodeURIComponent).join("/")}`;
|
|
4232
4228
|
const method = internal.method ?? "POST";
|
|
4233
|
-
|
|
4229
|
+
let inputSchema = internal.InputSchema ? zodToJsonSchema(internal.InputSchema, { mode: "input" }) : {};
|
|
4234
4230
|
const outputSchema = internal.OutputSchema ? zodToJsonSchema(internal.OutputSchema, { mode: "output" }) : {};
|
|
4235
4231
|
const params = (() => {
|
|
4236
|
-
const names = path.match(
|
|
4232
|
+
const names = path.match(/\{([^}]+)\}/g);
|
|
4237
4233
|
if (!names || !names.length) {
|
|
4238
4234
|
return void 0;
|
|
4239
4235
|
}
|
|
@@ -4243,9 +4239,9 @@ function generateOpenAPI(opts, options) {
|
|
|
4243
4239
|
);
|
|
4244
4240
|
}
|
|
4245
4241
|
return names.map((raw) => raw.slice(1, -1)).map((name) => {
|
|
4246
|
-
|
|
4242
|
+
let schema = inputSchema.properties?.[name];
|
|
4247
4243
|
const required = inputSchema.required?.includes(name);
|
|
4248
|
-
if (
|
|
4244
|
+
if (schema === void 0) {
|
|
4249
4245
|
throw new Error(
|
|
4250
4246
|
`Parameter ${name} is missing in input schema [${path_.join(".")}]`
|
|
4251
4247
|
);
|
|
@@ -4255,6 +4251,41 @@ function generateOpenAPI(opts, options) {
|
|
|
4255
4251
|
`Parameter ${name} must be required in input schema [${path_.join(".")}]`
|
|
4256
4252
|
);
|
|
4257
4253
|
}
|
|
4254
|
+
const examples = inputSchema.examples?.filter((example) => {
|
|
4255
|
+
return isPlainObject(example) && name in example;
|
|
4256
|
+
}).map((example) => {
|
|
4257
|
+
return example[name];
|
|
4258
|
+
});
|
|
4259
|
+
schema = {
|
|
4260
|
+
examples: examples?.length ? examples : void 0,
|
|
4261
|
+
...schema === true ? {} : schema === false ? UNSUPPORTED_JSON_SCHEMA : schema
|
|
4262
|
+
};
|
|
4263
|
+
inputSchema = {
|
|
4264
|
+
...inputSchema,
|
|
4265
|
+
properties: inputSchema.properties ? Object.entries(inputSchema.properties).reduce(
|
|
4266
|
+
(acc, [key, value]) => {
|
|
4267
|
+
if (key !== name) {
|
|
4268
|
+
acc[key] = value;
|
|
4269
|
+
}
|
|
4270
|
+
return acc;
|
|
4271
|
+
},
|
|
4272
|
+
{}
|
|
4273
|
+
) : void 0,
|
|
4274
|
+
required: inputSchema.required?.filter((v) => v !== name),
|
|
4275
|
+
examples: inputSchema.examples?.map((example) => {
|
|
4276
|
+
if (!isPlainObject(example))
|
|
4277
|
+
return example;
|
|
4278
|
+
return Object.entries(example).reduce(
|
|
4279
|
+
(acc, [key, value]) => {
|
|
4280
|
+
if (key !== name) {
|
|
4281
|
+
acc[key] = value;
|
|
4282
|
+
}
|
|
4283
|
+
return acc;
|
|
4284
|
+
},
|
|
4285
|
+
{}
|
|
4286
|
+
);
|
|
4287
|
+
})
|
|
4288
|
+
};
|
|
4258
4289
|
return {
|
|
4259
4290
|
name,
|
|
4260
4291
|
in: "path",
|
|
@@ -4273,16 +4304,27 @@ function generateOpenAPI(opts, options) {
|
|
|
4273
4304
|
`When method is GET, input schema must be an object [${path_.join(".")}]`
|
|
4274
4305
|
);
|
|
4275
4306
|
}
|
|
4276
|
-
return Object.entries(inputSchema.properties ?? {}).
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4307
|
+
return Object.entries(inputSchema.properties ?? {}).map(
|
|
4308
|
+
([name, schema]) => {
|
|
4309
|
+
const examples = inputSchema.examples?.filter((example) => {
|
|
4310
|
+
return isPlainObject(example) && name in example;
|
|
4311
|
+
}).map((example) => {
|
|
4312
|
+
return example[name];
|
|
4313
|
+
});
|
|
4314
|
+
const schema_ = {
|
|
4315
|
+
examples: examples?.length ? examples : void 0,
|
|
4316
|
+
...schema === true ? {} : schema === false ? UNSUPPORTED_JSON_SCHEMA : schema
|
|
4317
|
+
};
|
|
4318
|
+
return {
|
|
4319
|
+
name,
|
|
4320
|
+
in: "query",
|
|
4321
|
+
style: "deepObject",
|
|
4322
|
+
required: inputSchema?.required?.includes(name) ?? false,
|
|
4323
|
+
schema: schema_,
|
|
4324
|
+
example: internal.inputExample?.[name]
|
|
4325
|
+
};
|
|
4326
|
+
}
|
|
4327
|
+
);
|
|
4286
4328
|
})();
|
|
4287
4329
|
const parameters = [...params ?? [], ...query ?? []];
|
|
4288
4330
|
const requestBody = (() => {
|
|
@@ -4360,7 +4402,7 @@ function generateOpenAPI(opts, options) {
|
|
|
4360
4402
|
parameters: parameters.length ? parameters : void 0,
|
|
4361
4403
|
requestBody,
|
|
4362
4404
|
responses: {
|
|
4363
|
-
|
|
4405
|
+
200: successResponse
|
|
4364
4406
|
}
|
|
4365
4407
|
};
|
|
4366
4408
|
builder.addPath(path, {
|
|
@@ -4370,7 +4412,8 @@ function generateOpenAPI(opts, options) {
|
|
|
4370
4412
|
return preSerialize(builder.getSpec());
|
|
4371
4413
|
}
|
|
4372
4414
|
function isFileSchema(schema) {
|
|
4373
|
-
if (typeof schema !== "object" || schema === null)
|
|
4415
|
+
if (typeof schema !== "object" || schema === null)
|
|
4416
|
+
return false;
|
|
4374
4417
|
return "type" in schema && "contentMediaType" in schema && typeof schema.type === "string" && typeof schema.contentMediaType === "string";
|
|
4375
4418
|
}
|
|
4376
4419
|
export {
|