poe-code 3.0.378 → 3.0.379
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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/packages/toolcraft-openapi/dist/generate.d.ts +11 -1
- package/packages/toolcraft-openapi/dist/generate.js +69 -2
- package/packages/toolcraft-openapi/dist/interpreter.js +34 -0
- package/packages/toolcraft-openapi/dist/runtime.js +7 -0
package/package.json
CHANGED
|
@@ -150,6 +150,7 @@ interface GeneratedCommandExample {
|
|
|
150
150
|
params: Record<string, unknown>;
|
|
151
151
|
}
|
|
152
152
|
interface GeneratedParamDefinitionMetadata {
|
|
153
|
+
additionalProperties?: boolean;
|
|
153
154
|
defaultValue?: unknown;
|
|
154
155
|
format?: string;
|
|
155
156
|
jsonType?: "integer";
|
|
@@ -177,7 +178,16 @@ interface GeneratedArrayParamDefinition extends GeneratedParamDefinitionMetadata
|
|
|
177
178
|
interface GeneratedJsonParamDefinition extends GeneratedParamDefinitionMetadata {
|
|
178
179
|
kind: "json";
|
|
179
180
|
}
|
|
180
|
-
|
|
181
|
+
interface GeneratedObjectParamDefinition extends GeneratedParamDefinitionMetadata {
|
|
182
|
+
kind: "object";
|
|
183
|
+
properties: readonly GeneratedObjectPropertyDefinition[];
|
|
184
|
+
}
|
|
185
|
+
interface GeneratedObjectPropertyDefinition {
|
|
186
|
+
name: string;
|
|
187
|
+
optional: boolean;
|
|
188
|
+
definition: GeneratedParamDefinition;
|
|
189
|
+
}
|
|
190
|
+
export type GeneratedParamDefinition = GeneratedScalarParamDefinition | GeneratedEnumParamDefinition | GeneratedArrayParamDefinition | GeneratedObjectParamDefinition | GeneratedJsonParamDefinition;
|
|
181
191
|
type GeneratedParamScope = "cli" | "mcp" | "sdk";
|
|
182
192
|
type GeneratedEnumValue = string | number | boolean;
|
|
183
193
|
export type GeneratedValueReference = {
|
|
@@ -57,6 +57,10 @@ const SCHEMA_OPTION_SOURCES = [
|
|
|
57
57
|
key: "description",
|
|
58
58
|
get: (param) => param.description
|
|
59
59
|
},
|
|
60
|
+
{
|
|
61
|
+
key: "additionalProperties",
|
|
62
|
+
get: (param) => param.definition.additionalProperties
|
|
63
|
+
},
|
|
60
64
|
{
|
|
61
65
|
key: "default",
|
|
62
66
|
get: (param) => param.definition.defaultValue
|
|
@@ -660,7 +664,7 @@ function assertSupportedPathParameterSerialization(parameter, operationId) {
|
|
|
660
664
|
throw new UserError(`Operation ${JSON.stringify(operationId)} path parameter ${JSON.stringify(parameter.name)} uses unsupported serialization. Path parameters must use style "simple" with explode false in v1.`);
|
|
661
665
|
}
|
|
662
666
|
function createBodyField(document, name, schema, optional, operationId) {
|
|
663
|
-
if (
|
|
667
|
+
if (shouldUseJsonBodyField(document, schema, operationId, `request body field ${JSON.stringify(name)}`)) {
|
|
664
668
|
return createJsonBodyField({
|
|
665
669
|
document,
|
|
666
670
|
name,
|
|
@@ -683,6 +687,25 @@ function createBodyField(document, name, schema, optional, operationId) {
|
|
|
683
687
|
location: "body"
|
|
684
688
|
});
|
|
685
689
|
}
|
|
690
|
+
function shouldUseJsonBodyField(document, schema, operationId, context) {
|
|
691
|
+
if (isUnconstrainedJsonSchema(schema)) {
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
if (getCompositionKeyword(schema) !== undefined || Array.isArray(schema.type)) {
|
|
695
|
+
return true;
|
|
696
|
+
}
|
|
697
|
+
if (schema.type === "object") {
|
|
698
|
+
return typeof schema.additionalProperties === "object";
|
|
699
|
+
}
|
|
700
|
+
if (schema.properties !== undefined || schema.additionalProperties !== undefined) {
|
|
701
|
+
return true;
|
|
702
|
+
}
|
|
703
|
+
if (schema.type !== "array" || schema.items === undefined) {
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
const itemSchema = resolveBodySchema(document, schema.items, operationId, `${context} items`);
|
|
707
|
+
return shouldUseJsonBodyField(document, itemSchema, operationId, `${context} items`);
|
|
708
|
+
}
|
|
686
709
|
function isComplexJsonBodySchema(document, schema, operationId, context) {
|
|
687
710
|
if (isUnconstrainedJsonSchema(schema)) {
|
|
688
711
|
return true;
|
|
@@ -896,7 +919,10 @@ const FIELD_ASSEMBLERS = {
|
|
|
896
919
|
...options,
|
|
897
920
|
location: "body"
|
|
898
921
|
}),
|
|
899
|
-
object: (options) =>
|
|
922
|
+
object: (options) => createScalarParam({
|
|
923
|
+
...options,
|
|
924
|
+
location: "body"
|
|
925
|
+
}),
|
|
900
926
|
scalar: (options) => createScalarParam({
|
|
901
927
|
...options,
|
|
902
928
|
location: "body"
|
|
@@ -990,6 +1016,15 @@ function createParamDefinition(document, schema, operationId, context) {
|
|
|
990
1016
|
...(schema.nullable === true ? { nullable: true } : {})
|
|
991
1017
|
};
|
|
992
1018
|
}
|
|
1019
|
+
if (schema.type === "object") {
|
|
1020
|
+
return {
|
|
1021
|
+
kind: "object",
|
|
1022
|
+
properties: createObjectPropertyDefinitions(document, schema, operationId, context),
|
|
1023
|
+
additionalProperties: schema.additionalProperties !== false,
|
|
1024
|
+
...(schema.default === undefined ? {} : { defaultValue: schema.default }),
|
|
1025
|
+
...(schema.nullable === true ? { nullable: true } : {})
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
993
1028
|
const scalarDefinition = isOpenApiScalarType(schema.type)
|
|
994
1029
|
? SCHEMA_TYPE_TO_KIND[schema.type]
|
|
995
1030
|
: undefined;
|
|
@@ -1021,6 +1056,27 @@ function createParamDefinition(document, schema, operationId, context) {
|
|
|
1021
1056
|
}
|
|
1022
1057
|
throw new UserError(`Operation ${JSON.stringify(operationId)} uses unsupported ${context}. Supported shapes in this milestone are string, number, integer, boolean, enum, and arrays of those values.`);
|
|
1023
1058
|
}
|
|
1059
|
+
function createObjectPropertyDefinitions(document, schema, operationId, context) {
|
|
1060
|
+
const required = new Set(schema.required ?? []);
|
|
1061
|
+
const properties = [];
|
|
1062
|
+
for (const [name, property] of Object.entries(schema.properties ?? {})) {
|
|
1063
|
+
const propertySchema = resolveBodySchema(document, property, operationId, `${context}.properties.${name}`);
|
|
1064
|
+
if (propertySchema.readOnly === true) {
|
|
1065
|
+
continue;
|
|
1066
|
+
}
|
|
1067
|
+
properties.push({
|
|
1068
|
+
name,
|
|
1069
|
+
optional: !required.has(name),
|
|
1070
|
+
definition: shouldUseJsonBodyField(document, propertySchema, operationId, `${context}.properties.${name}`)
|
|
1071
|
+
? {
|
|
1072
|
+
kind: "json",
|
|
1073
|
+
...(propertySchema.nullable === true ? { nullable: true } : {})
|
|
1074
|
+
}
|
|
1075
|
+
: createParamDefinition(document, propertySchema, operationId, `${context}.properties.${name}`)
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
return properties;
|
|
1079
|
+
}
|
|
1024
1080
|
function assertPathTemplateParameters(path, parameters, operationId) {
|
|
1025
1081
|
const placeholders = new Set(collectPathPlaceholders(path));
|
|
1026
1082
|
for (const placeholder of placeholders) {
|
|
@@ -1600,6 +1656,7 @@ const DEFINITION_RENDERERS = {
|
|
|
1600
1656
|
enum: (definition, options) => renderSchemaCall("S.Enum", renderConstArray(definition.enumValues), options),
|
|
1601
1657
|
json: (_definition) => renderSchemaCall("S.Json"),
|
|
1602
1658
|
number: (_definition, options) => renderSchemaCall("S.Number", options),
|
|
1659
|
+
object: (definition, options) => renderSchemaCall("S.Object", renderObjectDefinitionShape(definition), options),
|
|
1603
1660
|
string: (_definition, options) => renderSchemaCall("S.String", options)
|
|
1604
1661
|
};
|
|
1605
1662
|
function renderSchemaCall(builder, ...args) {
|
|
@@ -1612,6 +1669,16 @@ function renderSchemaOptions(param) {
|
|
|
1612
1669
|
function renderConstArray(values) {
|
|
1613
1670
|
return `${JSON.stringify(values)} as const`;
|
|
1614
1671
|
}
|
|
1672
|
+
function renderObjectDefinitionShape(definition) {
|
|
1673
|
+
if (definition.properties.length === 0) {
|
|
1674
|
+
return "{}";
|
|
1675
|
+
}
|
|
1676
|
+
return `{ ${definition.properties.map(renderObjectDefinitionProperty).join(", ")} }`;
|
|
1677
|
+
}
|
|
1678
|
+
function renderObjectDefinitionProperty(property) {
|
|
1679
|
+
const schema = renderDefinition(property.definition, undefined, undefined, undefined);
|
|
1680
|
+
return `${renderObjectKey(property.name)}: ${property.optional ? `S.Optional(${schema})` : schema}`;
|
|
1681
|
+
}
|
|
1615
1682
|
function renderObjectKey(name) {
|
|
1616
1683
|
if (name === "__proto__") {
|
|
1617
1684
|
return `[${JSON.stringify(name)}]`;
|
|
@@ -237,6 +237,8 @@ function findDefinitionIssue(value, definition, path) {
|
|
|
237
237
|
return undefined;
|
|
238
238
|
case "number":
|
|
239
239
|
return findNumberDefinitionIssue(value, definition, path);
|
|
240
|
+
case "object":
|
|
241
|
+
return findObjectDefinitionIssue(value, definition, path);
|
|
240
242
|
case "string":
|
|
241
243
|
return findStringDefinitionIssue(value, definition, path);
|
|
242
244
|
}
|
|
@@ -259,6 +261,35 @@ function findArrayDefinitionIssue(value, definition, path) {
|
|
|
259
261
|
}
|
|
260
262
|
return undefined;
|
|
261
263
|
}
|
|
264
|
+
function findObjectDefinitionIssue(value, definition, path) {
|
|
265
|
+
if (!isJsonObject(value)) {
|
|
266
|
+
return `Expected object at ${formatJsonPath(path)}.`;
|
|
267
|
+
}
|
|
268
|
+
const knownProperties = new Set(definition.properties.map((property) => property.name));
|
|
269
|
+
for (const property of definition.properties) {
|
|
270
|
+
if (!Object.prototype.hasOwnProperty.call(value, property.name)) {
|
|
271
|
+
if (property.optional) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
return `Expected required property ${JSON.stringify(property.name)} at ${formatJsonPath(path)}.`;
|
|
275
|
+
}
|
|
276
|
+
const issue = findDefinitionIssue(value[property.name], property.definition, [
|
|
277
|
+
...path,
|
|
278
|
+
property.name
|
|
279
|
+
]);
|
|
280
|
+
if (issue !== undefined) {
|
|
281
|
+
return issue;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (definition.additionalProperties === false) {
|
|
285
|
+
for (const key of Object.keys(value)) {
|
|
286
|
+
if (!knownProperties.has(key)) {
|
|
287
|
+
return `Unexpected property ${JSON.stringify(key)} at ${formatJsonPath(path)}.`;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
262
293
|
function findNumberDefinitionIssue(value, definition, path) {
|
|
263
294
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
264
295
|
return `Expected ${definition.jsonType === "integer" ? "integer" : "number"} at ${formatJsonPath(path)}.`;
|
|
@@ -292,6 +323,9 @@ function findStringDefinitionIssue(value, definition, path) {
|
|
|
292
323
|
}
|
|
293
324
|
return undefined;
|
|
294
325
|
}
|
|
326
|
+
function isJsonObject(value) {
|
|
327
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
328
|
+
}
|
|
295
329
|
function compileDefinitionPattern(pattern) {
|
|
296
330
|
try {
|
|
297
331
|
return new RegExp(pattern, "u");
|
|
@@ -112,6 +112,13 @@ const RUNTIME_DEFINITION_BUILDERS = {
|
|
|
112
112
|
enum: (definition, options) => options === undefined ? S.Enum(definition.enumValues) : S.Enum(definition.enumValues, options),
|
|
113
113
|
json: (_definition) => S.Json(),
|
|
114
114
|
number: (_definition, options) => options === undefined ? S.Number() : S.Number(options),
|
|
115
|
+
object: (definition, options) => {
|
|
116
|
+
const shape = Object.fromEntries(definition.properties.map((property) => {
|
|
117
|
+
const propertySchema = createRuntimeDefinition(property.definition, undefined, undefined, undefined);
|
|
118
|
+
return [property.name, property.optional ? S.Optional(propertySchema) : propertySchema];
|
|
119
|
+
}));
|
|
120
|
+
return options === undefined ? S.Object(shape) : S.Object(shape, options);
|
|
121
|
+
},
|
|
115
122
|
string: (_definition, options) => options === undefined ? S.String() : S.String(options)
|
|
116
123
|
};
|
|
117
124
|
function createRuntimeSchemaOptions(definition, description, shortFlag, scope, global) {
|