@artil-ai/server 0.1.0 → 0.1.1

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/bin/main.js CHANGED
@@ -22322,7 +22322,7 @@ var channel = {
22322
22322
  create: ({ webhookUrl, secret, fetch: fetch2 }) => new TelegramChannel(createBotApi({ webhook: webhookUrl ? { url: webhookUrl, secret } : undefined, fetch: fetch2 }))
22323
22323
  };
22324
22324
  // package.json
22325
- var version2 = "0.1.0";
22325
+ var version2 = "0.1.1";
22326
22326
 
22327
22327
  // src/app/cli.ts
22328
22328
  import { parseArgs } from "util";
@@ -24560,14 +24560,108 @@ var findTargetHandler = (handler) => {
24560
24560
  return handler["__COMPOSED_HANDLER"] ? findTargetHandler(handler[COMPOSED_HANDLER]) : handler;
24561
24561
  };
24562
24562
 
24563
- // ../../node_modules/.bun/hono-openapi@1.3.3+498ad4f22b3f3380/node_modules/hono-openapi/dist/index.js
24563
+ // ../../node_modules/.bun/hono-openapi@1.5.0+498ad4f22b3f3380/node_modules/hono-openapi/dist/index.js
24564
24564
  init_dist2();
24565
24565
 
24566
24566
  // ../../node_modules/.bun/@standard-community+standard-openapi@0.2.11+eb0485ab6460c735/node_modules/@standard-community/standard-openapi/dist/index.js
24567
24567
  init_index_CKGGDjCx();
24568
24568
 
24569
- // ../../node_modules/.bun/hono-openapi@1.3.3+498ad4f22b3f3380/node_modules/hono-openapi/dist/index.js
24570
- var uniqueSymbol = Symbol("openapi");
24569
+ // ../../node_modules/.bun/hono-openapi@1.5.0+498ad4f22b3f3380/node_modules/hono-openapi/dist/index.js
24570
+ var COMPONENTS_PREFIX = "#/components/";
24571
+ var SCHEMA_REF = `${COMPONENTS_PREFIX}schemas/`;
24572
+ var decodeName = (name) => name.replaceAll("~1", "/").replaceAll("~0", "~");
24573
+ var encodeName = (name) => name.replaceAll("~", "~0").replaceAll("/", "~1");
24574
+ var renameRef = (ref, rename) => {
24575
+ if (!ref.startsWith(SCHEMA_REF)) {
24576
+ return ref;
24577
+ }
24578
+ const renamed = rename(decodeName(ref.slice(SCHEMA_REF.length)));
24579
+ return renamed === undefined ? ref : `${SCHEMA_REF}${encodeName(renamed)}`;
24580
+ };
24581
+ var renameMappingTarget = (target, rename) => {
24582
+ if (target.startsWith(SCHEMA_REF)) {
24583
+ return renameRef(target, rename);
24584
+ }
24585
+ if (target.includes("/") || target.includes("#")) {
24586
+ return target;
24587
+ }
24588
+ return rename(target) ?? target;
24589
+ };
24590
+ var isDiscriminator = (value) => value != null && typeof value === "object" && typeof value.propertyName === "string";
24591
+ var LITERAL_FIELDS = /* @__PURE__ */ new Set([
24592
+ "example",
24593
+ "default",
24594
+ "enum",
24595
+ "const",
24596
+ "value"
24597
+ ]);
24598
+ var REFERENCE_MAPS = /* @__PURE__ */ new Set([
24599
+ "paths",
24600
+ "webhooks",
24601
+ "examples",
24602
+ "schemas",
24603
+ "parameters",
24604
+ "responses",
24605
+ "requestBodies",
24606
+ "headers",
24607
+ "content",
24608
+ "encoding",
24609
+ "links",
24610
+ "callbacks",
24611
+ "pathItems",
24612
+ "properties",
24613
+ "patternProperties",
24614
+ "$defs",
24615
+ "definitions",
24616
+ "dependentSchemas",
24617
+ "dependencies"
24618
+ ]);
24619
+ var mapReferences = (value, reference, isMap = false) => {
24620
+ if (Array.isArray(value)) {
24621
+ return value.map((item) => mapReferences(item, reference));
24622
+ }
24623
+ if (value == null || typeof value !== "object") {
24624
+ return value;
24625
+ }
24626
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => {
24627
+ if (isMap) {
24628
+ return [key, mapReferences(item, reference)];
24629
+ }
24630
+ if (LITERAL_FIELDS.has(key) || key.startsWith("x-") || key === "examples" && Array.isArray(item)) {
24631
+ return [key, item];
24632
+ }
24633
+ if (key === "$ref" && typeof item === "string") {
24634
+ return [key, reference(item, false)];
24635
+ }
24636
+ if (key === "discriminator" && isDiscriminator(item) && item.mapping) {
24637
+ return [
24638
+ key,
24639
+ {
24640
+ ...item,
24641
+ mapping: Object.fromEntries(Object.entries(item.mapping).map(([name, target]) => [
24642
+ name,
24643
+ reference(target, true)
24644
+ ]))
24645
+ }
24646
+ ];
24647
+ }
24648
+ return [key, mapReferences(item, reference, REFERENCE_MAPS.has(key))];
24649
+ }));
24650
+ };
24651
+ var renameSchemaRefs = (value, rename, isMap = false) => mapReferences(value, (target, mapping) => mapping ? renameMappingTarget(target, rename) : renameRef(target, rename), isMap);
24652
+ var componentRefs = (value) => {
24653
+ const refs = [];
24654
+ mapReferences(value, (target, mapping) => {
24655
+ if (target.startsWith(COMPONENTS_PREFIX)) {
24656
+ refs.push(target.slice(COMPONENTS_PREFIX.length));
24657
+ } else if (mapping && !target.includes("/") && !target.includes("#")) {
24658
+ refs.push(`schemas/${encodeName(target)}`);
24659
+ }
24660
+ return target;
24661
+ });
24662
+ return refs;
24663
+ };
24664
+ var uniqueSymbol = Symbol.for("hono-openapi");
24571
24665
  var VALIDATION_MARKER = "__HonoOpenAPIValidator__";
24572
24666
  var ALLOWED_METHODS = [
24573
24667
  "GET",
@@ -24611,6 +24705,40 @@ var generateOperationId = (route) => {
24611
24705
  }
24612
24706
  return operationId;
24613
24707
  };
24708
+ var generatedOperationIds = /* @__PURE__ */ new WeakMap;
24709
+ var derivedOperationIds = /* @__PURE__ */ new WeakMap;
24710
+ var pathParameterNames = (path) => path.split("/").filter((segment) => segment.startsWith(":")).map((segment) => toOpenAPIPathSegment(segment).slice(1, -1));
24711
+ var expandOptionalParameters = (route) => {
24712
+ const paths = checkOptionalParameter(route.path);
24713
+ if (!paths) {
24714
+ return [{ route, omitted: undefined }];
24715
+ }
24716
+ const names = pathParameterNames(route.path);
24717
+ return paths.map((path) => {
24718
+ const kept = pathParameterNames(path);
24719
+ return {
24720
+ route: { ...route, path },
24721
+ omitted: names.filter((name) => !kept.includes(name))
24722
+ };
24723
+ });
24724
+ };
24725
+ var withOmittedParameters = (specs, omitted) => {
24726
+ if (!omitted || !specs) {
24727
+ return specs;
24728
+ }
24729
+ const expanded = {
24730
+ ...specs,
24731
+ ...omitted.length && typeof specs.operationId === "string" ? {
24732
+ operationId: `${specs.operationId}Without${omitted.map(toPascalCase).join("And")}`
24733
+ } : {}
24734
+ };
24735
+ if (omitted.length && typeof expanded.operationId === "string") {
24736
+ derivedOperationIds.set(expanded, expanded.operationId);
24737
+ }
24738
+ setSpecComponents(expanded, getSpecComponents(specs));
24739
+ expandedOperations.add(expanded);
24740
+ return expanded;
24741
+ };
24614
24742
  var paramKey = (param) => ("$ref" in param) ? param.$ref : `${param.in} ${param.name}`;
24615
24743
  function mergeParameters(...params) {
24616
24744
  const merged = params.flatMap((x) => x ?? []).reduce((acc, param) => {
@@ -24619,6 +24747,11 @@ function mergeParameters(...params) {
24619
24747
  }, /* @__PURE__ */ new Map);
24620
24748
  return Array.from(merged.values());
24621
24749
  }
24750
+ var specComponents = /* @__PURE__ */ new WeakMap;
24751
+ var setSpecComponents = (spec, components) => specComponents.set(spec, components);
24752
+ var getSpecComponents = (spec) => spec != null && typeof spec === "object" && specComponents.get(spec) || [];
24753
+ var expandedOperations = /* @__PURE__ */ new WeakSet;
24754
+ var isExpandedOperation = (spec) => spec != null && typeof spec === "object" && expandedOperations.has(spec);
24622
24755
  var specsByPathContext = /* @__PURE__ */ new Map;
24623
24756
  function getPathContext(path, pathContext) {
24624
24757
  const context = [];
@@ -24632,13 +24765,14 @@ function getPathContext(path, pathContext) {
24632
24765
  }
24633
24766
  return context;
24634
24767
  }
24635
- function mergeRequestBodies(previous, current) {
24768
+ function mergeRequestBodies(previous, current, fromValidator = false) {
24636
24769
  if (!previous || !current || "$ref" in previous || "$ref" in current) {
24637
24770
  return current;
24638
24771
  }
24639
24772
  return {
24640
24773
  ...previous,
24641
24774
  ...current,
24775
+ ...fromValidator && previous.required !== undefined ? { required: previous.required } : {},
24642
24776
  content: {
24643
24777
  ...previous.content,
24644
24778
  ...current.content
@@ -24646,12 +24780,17 @@ function mergeRequestBodies(previous, current) {
24646
24780
  };
24647
24781
  }
24648
24782
  function mergeSpecs(route, ...specs) {
24649
- return specs.reduce((prev, spec) => {
24783
+ const generatedOperationId = generateOperationId(route);
24784
+ const operationIdSpec = specs.findLast((spec) => spec?.operationId != null && generatedOperationIds.get(spec) !== spec.operationId);
24785
+ const merged = specs.reduce((prev, spec) => {
24650
24786
  if (!spec || !prev)
24651
24787
  return prev;
24652
24788
  for (const [key, value] of Object.entries(spec)) {
24653
24789
  if (value == null)
24654
24790
  continue;
24791
+ if (key === "operationId" && generatedOperationIds.get(spec) === value) {
24792
+ continue;
24793
+ }
24655
24794
  if (key in prev && (typeof value === "object" || typeof value === "function" && key === "operationId")) {
24656
24795
  if (Array.isArray(value)) {
24657
24796
  const values = [...prev[key] ?? [], ...value];
@@ -24668,7 +24807,7 @@ function mergeSpecs(route, ...specs) {
24668
24807
  if (key === "parameters") {
24669
24808
  prev[key] = mergeParameters(prev[key], value);
24670
24809
  } else if (key === "requestBody") {
24671
- prev.requestBody = mergeRequestBodies(prev.requestBody, value);
24810
+ prev.requestBody = mergeRequestBodies(prev.requestBody, value, spec[VALIDATION_MARKER] === true);
24672
24811
  } else {
24673
24812
  prev[key] = {
24674
24813
  ...prev[key],
@@ -24682,8 +24821,18 @@ function mergeSpecs(route, ...specs) {
24682
24821
  }
24683
24822
  return prev;
24684
24823
  }, {
24685
- operationId: generateOperationId(route)
24824
+ operationId: generatedOperationId
24686
24825
  });
24826
+ if (!operationIdSpec) {
24827
+ generatedOperationIds.set(merged, generatedOperationId);
24828
+ } else if (derivedOperationIds.get(operationIdSpec) === merged.operationId) {
24829
+ derivedOperationIds.set(merged, merged.operationId);
24830
+ }
24831
+ setSpecComponents(merged, specs.flatMap(getSpecComponents));
24832
+ if (specs.some(isExpandedOperation)) {
24833
+ expandedOperations.add(merged);
24834
+ }
24835
+ return merged;
24687
24836
  }
24688
24837
  function registerSchemaPath({ route, specs, paths }, pathContext = specsByPathContext) {
24689
24838
  const path = toOpenAPIPath(route.path);
@@ -24707,6 +24856,42 @@ function registerSchemaPath({ route, specs, paths }, pathContext = specsByPathCo
24707
24856
  }
24708
24857
  }
24709
24858
  }
24859
+ var uniqueOperationIds = (paths) => {
24860
+ const methods = ALLOWED_METHODS.map((method) => method.toLowerCase());
24861
+ const operations = Object.values(paths).flatMap((item) => methods.flatMap((method) => {
24862
+ const operation = item?.[method];
24863
+ return typeof operation?.operationId === "string" ? [operation] : [];
24864
+ }));
24865
+ const isGenerated = (operation) => generatedOperationIds.get(operation) === operation.operationId || derivedOperationIds.get(operation) === operation.operationId;
24866
+ const reserved = new Set(operations.map(({ operationId }) => operationId));
24867
+ const explicit = operations.filter((operation) => !isGenerated(operation));
24868
+ operations.filter(isGenerated).reduce((taken, operation) => {
24869
+ const operationId = operation.operationId;
24870
+ if (taken.has(operationId)) {
24871
+ operation.operationId = withFreeSuffix(operationId, (id) => taken.has(id) || reserved.has(id));
24872
+ }
24873
+ return taken.add(operation.operationId);
24874
+ }, new Set(explicit.map(({ operationId }) => operationId)));
24875
+ };
24876
+ var withFreeSuffix = (operationId, isUsed) => {
24877
+ let suffix = 2;
24878
+ while (isUsed(`${operationId}${suffix}`))
24879
+ suffix++;
24880
+ return `${operationId}${suffix}`;
24881
+ };
24882
+ var parameterComponent = (ref, ctx) => {
24883
+ const prefix = "#/components/parameters/";
24884
+ if (!ref.$ref.startsWith(prefix)) {
24885
+ return;
24886
+ }
24887
+ const name = ref.$ref.slice(prefix.length);
24888
+ const generated = ctx.components.parameters?.[name];
24889
+ if (generated) {
24890
+ return { generated: true, name, parameter: generated };
24891
+ }
24892
+ const documented = ctx.options.documentation?.components?.parameters?.[name];
24893
+ return documented && { generated: false, name, parameter: documented };
24894
+ };
24710
24895
  function removeExcludedPaths(paths, ctx) {
24711
24896
  const { exclude, excludeStaticFile } = ctx.options;
24712
24897
  const newPaths = {};
@@ -24738,6 +24923,29 @@ function removeExcludedPaths(paths, ctx) {
24738
24923
  continue;
24739
24924
  const hasValidation = schema[VALIDATION_MARKER] === true;
24740
24925
  delete schema[VALIDATION_MARKER];
24926
+ if (schema.parameters && isExpandedOperation(schema)) {
24927
+ const names = key.split("/").filter((x) => x.startsWith("{")).map((x) => x.slice(1, -1));
24928
+ schema.parameters = schema.parameters.flatMap((x) => {
24929
+ const component = "$ref" in x ? parameterComponent(x, ctx) : undefined;
24930
+ const parameter = component?.parameter ?? x;
24931
+ if ("$ref" in parameter || parameter.in !== "path") {
24932
+ return [x];
24933
+ }
24934
+ if (!names.includes(parameter.name)) {
24935
+ return [];
24936
+ }
24937
+ if (!component) {
24938
+ return [{ ...parameter, required: true }];
24939
+ }
24940
+ if (component.generated && !parameter.required) {
24941
+ ctx.components.parameters = {
24942
+ ...ctx.components.parameters,
24943
+ [component.name]: { ...parameter, required: true }
24944
+ };
24945
+ }
24946
+ return [x];
24947
+ });
24948
+ }
24741
24949
  if (key.includes("{")) {
24742
24950
  schema.parameters = schema.parameters ? [...schema.parameters] : [];
24743
24951
  const pathParameters = key.split("/").filter((x) => x.startsWith("{") && !schema.parameters.find((params) => params.in === "path" && params.name === x.slice(1, x.length - 1)));
@@ -24745,12 +24953,9 @@ function removeExcludedPaths(paths, ctx) {
24745
24953
  const paramName = param.slice(1, param.length - 1);
24746
24954
  const index = schema.parameters.findIndex((x) => {
24747
24955
  if ("$ref" in x) {
24748
- const pos = x.$ref.split("/").pop();
24749
- if (pos) {
24750
- const param2 = ctx.components.parameters?.[pos];
24751
- if (param2 && !("$ref" in param2)) {
24752
- return param2.in === "path" && param2.name === paramName;
24753
- }
24956
+ const param2 = parameterComponent(x, ctx)?.parameter;
24957
+ if (param2 && !("$ref" in param2)) {
24958
+ return param2.in === "path" && param2.name === paramName;
24754
24959
  }
24755
24960
  return false;
24756
24961
  }
@@ -24766,9 +24971,9 @@ function removeExcludedPaths(paths, ctx) {
24766
24971
  }
24767
24972
  }
24768
24973
  }
24769
- if (!schema.responses) {
24974
+ if (!schema.responses || Object.keys(schema.responses).length === 0) {
24770
24975
  schema.responses = {
24771
- 200: {}
24976
+ 200: { description: "Successful response" }
24772
24977
  };
24773
24978
  }
24774
24979
  if (hasValidation && ctx.options.defaultValidationErrorResponse !== false && !schema.responses["400"]) {
@@ -24792,6 +24997,23 @@ function removeExcludedPaths(paths, ctx) {
24792
24997
  }
24793
24998
  return newPaths;
24794
24999
  }
25000
+ var componentKey = (type, name) => `${type}/${encodeName(name)}`;
25001
+ var reachableRefs = (refs, components, reached) => refs.reduce((seen, ref) => {
25002
+ if (seen.has(ref)) {
25003
+ return seen;
25004
+ }
25005
+ const [type, ...name] = ref.split("/");
25006
+ const component = components[type]?.[decodeName(name.join("/"))];
25007
+ return reachableRefs(componentRefs(component), components, seen.add(ref));
25008
+ }, reached);
25009
+ function documentedComponents(components, paths, documentation) {
25010
+ const contributed = new Set(Object.values(paths).flatMap((item) => item == null ? [] : Object.values(item)).flatMap(getSpecComponents).flatMap((operationComponents) => Object.entries(operationComponents).flatMap(([type, entries]) => Object.keys(entries ?? {}).map((name) => componentKey(type, name)))));
25011
+ const kept = reachableRefs([...componentRefs(paths), ...componentRefs(documentation)], components, contributed);
25012
+ return Object.fromEntries(Object.entries(components).flatMap(([type, entries]) => {
25013
+ const remaining = Object.entries(entries ?? {}).filter(([name]) => kept.has(componentKey(type, name)));
25014
+ return remaining.length > 0 ? [[type, Object.fromEntries(remaining)]] : [];
25015
+ }));
25016
+ }
24795
25017
  var DEFAULT_OPTIONS = {
24796
25018
  documentation: {},
24797
25019
  excludeStaticFile: true,
@@ -24851,7 +25073,9 @@ async function generateSpecs(hono, options = DEFAULT_OPTIONS, c3) {
24851
25073
  if (resolvedDocumentation && documentation.components) {
24852
25074
  documentation.components.responses = resolvedDocumentation.responses;
24853
25075
  }
24854
- const components = mergeComponentsObjects(documentation.components, resolvedDocumentation?.components, ctx.components);
25076
+ const documentedPaths = removeExcludedPaths(paths, ctx);
25077
+ uniqueOperationIds({ ...documentedPaths, ...documentation.paths });
25078
+ const { components, paths: outputPaths } = splitOutputComponents(mergeComponentsObjects(documentation.components, resolvedDocumentation?.components, documentedComponents(ctx.components, documentedPaths, withOutputRefs([documentation, resolvedDocumentation?.components], ctx))), documentedPaths);
24855
25079
  return {
24856
25080
  openapi: "3.1.0",
24857
25081
  ...documentation,
@@ -24863,7 +25087,7 @@ async function generateSpecs(hono, options = DEFAULT_OPTIONS, c3) {
24863
25087
  ...documentation.info
24864
25088
  },
24865
25089
  paths: {
24866
- ...removeExcludedPaths(paths, ctx),
25090
+ ...outputPaths,
24867
25091
  ...documentation.paths
24868
25092
  },
24869
25093
  components
@@ -24872,14 +25096,15 @@ async function generateSpecs(hono, options = DEFAULT_OPTIONS, c3) {
24872
25096
  async function generatePaths(hono, ctx) {
24873
25097
  const paths = {};
24874
25098
  const pathContext = /* @__PURE__ */ new Map;
25099
+ const defaulted = /* @__PURE__ */ new Set;
24875
25100
  for (const route of hono.routes) {
24876
25101
  const middlewareHandler = findTargetHandler(route.handler)[uniqueSymbol];
24877
25102
  if (!middlewareHandler) {
24878
25103
  if (ctx.options.includeEmptyPaths) {
24879
- registerSchemaPath({
24880
- route,
25104
+ expandOptionalParameters(route).forEach((expanded) => registerSchemaPath({
25105
+ route: expanded.route,
24881
25106
  paths
24882
- }, pathContext);
25107
+ }, pathContext));
24883
25108
  }
24884
25109
  continue;
24885
25110
  }
@@ -24892,14 +25117,23 @@ async function generatePaths(hono, ctx) {
24892
25117
  continue;
24893
25118
  }
24894
25119
  }
24895
- const defaultOptionsForThisMethod = ctx.options.defaultOptions?.[routeMethod] && { ...ctx.options.defaultOptions[routeMethod] };
24896
- const { schema: routeSpecs, components = {} } = await getSpec(middlewareHandler, defaultOptionsForThisMethod, ctx.components.parameters);
24897
- ctx.components = mergeComponentsObjects(ctx.components, components);
24898
- registerSchemaPath({
24899
- route,
24900
- specs: routeSpecs,
25120
+ const operation = `${routeMethod} ${route.path}`;
25121
+ const defaultOptionsForThisMethod = !defaulted.has(operation) && ctx.options.defaultOptions?.[routeMethod] && {
25122
+ ...ctx.options.defaultOptions[routeMethod]
25123
+ };
25124
+ defaulted.add(operation);
25125
+ const {
25126
+ schema: routeSpecs,
25127
+ components = {},
25128
+ unreferencedComponents
25129
+ } = await getSpec(middlewareHandler, defaultOptionsForThisMethod, ctx.components.parameters);
25130
+ ctx.components = mergeComponentsObjects(ctx.components, components, unreferencedComponents);
25131
+ setSpecComponents(routeSpecs, [components]);
25132
+ expandOptionalParameters(route).forEach((expanded) => registerSchemaPath({
25133
+ route: expanded.route,
25134
+ specs: withOmittedParameters(routeSpecs, expanded.omitted),
24901
25135
  paths
24902
- }, pathContext);
25136
+ }, pathContext));
24903
25137
  }
24904
25138
  return paths;
24905
25139
  }
@@ -24915,6 +25149,15 @@ function getHiddenValue(options) {
24915
25149
  }
24916
25150
  return false;
24917
25151
  }
25152
+ var COMBINING_KEYWORDS = ["allOf", "anyOf", "oneOf", "not", "if"];
25153
+ var needsBody = (schema, components) => {
25154
+ const resolved = "$ref" in schema ? components?.schemas?.[schema.$ref.split("/").at(-1) ?? ""] : schema;
25155
+ if (!resolved || "$ref" in resolved) {
25156
+ return true;
25157
+ }
25158
+ const types = [resolved.type].flat();
25159
+ return !types.includes("object") || COMBINING_KEYWORDS.some((keyword) => (keyword in resolved)) || (resolved.required?.length ?? 0) > 0 || (resolved.minProperties ?? 0) > 0;
25160
+ };
24918
25161
  async function getSpec(middlewareHandler, defaultOptions, parameterComponents) {
24919
25162
  if ("spec" in middlewareHandler) {
24920
25163
  const tmp = {
@@ -24925,42 +25168,30 @@ async function getSpec(middlewareHandler, defaultOptions, parameterComponents) {
24925
25168
  ...middlewareHandler.spec.responses
24926
25169
  }
24927
25170
  };
24928
- let components = {};
24929
- if (tmp.responses) {
24930
- const resolved = await resolveResponseSchemas(tmp.responses);
24931
- tmp.responses = resolved.responses;
24932
- components = resolved.components;
24933
- }
24934
- if (tmp.requestBody && "content" in tmp.requestBody) {
24935
- const resolved = await resolveContentSchemas(tmp.requestBody.content);
24936
- tmp.requestBody = {
24937
- ...tmp.requestBody,
24938
- content: resolved.content
24939
- };
24940
- components = mergeComponentsObjects(components, resolved.components);
24941
- }
24942
- return { schema: tmp, components };
25171
+ return {
25172
+ ...await resolveSpecSchemas(tmp),
25173
+ unreferencedComponents: undefined
25174
+ };
24943
25175
  }
24944
25176
  const result = await middlewareHandler.toOpenAPISchema();
24945
25177
  liftSchemaDefs(result);
25178
+ let unreferencedComponents;
24946
25179
  const docs = {
24947
25180
  ...defaultOptions,
24948
25181
  [VALIDATION_MARKER]: true
24949
25182
  };
24950
25183
  if (middlewareHandler.target === "form" || middlewareHandler.target === "json") {
24951
- const media = middlewareHandler.options?.media ?? (middlewareHandler.target === "json" ? "application/json" : "multipart/form-data");
25184
+ const mediaTypes = middlewareHandler.options?.media ? [middlewareHandler.options.media] : middlewareHandler.target === "json" ? ["application/json"] : ["application/x-www-form-urlencoded", "multipart/form-data"];
25185
+ const content = Object.fromEntries(mediaTypes.map((media) => [media, { schema: result.schema }]));
24952
25186
  if (!docs.requestBody || !("content" in docs.requestBody) || !docs.requestBody.content) {
24953
25187
  docs.requestBody = {
24954
- required: true,
24955
- content: {
24956
- [media]: {
24957
- schema: result.schema
24958
- }
24959
- }
25188
+ ...needsBody(result.schema, result.components) ? { required: true } : {},
25189
+ content
24960
25190
  };
24961
25191
  } else {
24962
- docs.requestBody.content[media] = {
24963
- schema: result.schema
25192
+ docs.requestBody = {
25193
+ ...docs.requestBody,
25194
+ content: { ...docs.requestBody.content, ...content }
24964
25195
  };
24965
25196
  }
24966
25197
  } else {
@@ -24980,6 +25211,8 @@ async function getSpec(middlewareHandler, defaultOptions, parameterComponents) {
24980
25211
  delete result.components.schemas[pos];
24981
25212
  } else {
24982
25213
  parameters = generatedParameters;
25214
+ unreferencedComponents = { schemas: { [pos]: schema } };
25215
+ delete result.components.schemas[pos];
24983
25216
  }
24984
25217
  }
24985
25218
  } else {
@@ -24987,7 +25220,27 @@ async function getSpec(middlewareHandler, defaultOptions, parameterComponents) {
24987
25220
  }
24988
25221
  docs.parameters = parameters;
24989
25222
  }
24990
- return { schema: docs, components: result.components };
25223
+ const resolved = await resolveSpecSchemas(docs);
25224
+ return {
25225
+ schema: resolved.schema,
25226
+ components: mergeComponentsObjects(result.components, resolved.components),
25227
+ unreferencedComponents
25228
+ };
25229
+ }
25230
+ async function resolveSpecSchemas(spec) {
25231
+ const schema = { ...spec };
25232
+ let components = {};
25233
+ if (schema.responses) {
25234
+ const resolved = await resolveResponseSchemas(schema.responses);
25235
+ schema.responses = resolved.responses;
25236
+ components = resolved.components;
25237
+ }
25238
+ if (schema.requestBody && "content" in schema.requestBody) {
25239
+ const resolved = await resolveContentSchemas(schema.requestBody.content);
25240
+ schema.requestBody = { ...schema.requestBody, content: resolved.content };
25241
+ components = mergeComponentsObjects(components, resolved.components);
25242
+ }
25243
+ return { schema, components };
24991
25244
  }
24992
25245
  function generateParameters(target, schema, schemas4) {
24993
25246
  const parameters = [];
@@ -25004,59 +25257,134 @@ function generateParameters(target, schema, schemas4) {
25004
25257
  def.description = def.schema.description;
25005
25258
  def.schema = { ...def.schema, description: undefined };
25006
25259
  }
25260
+ if (def.schema && "deprecated" in def.schema && def.schema.deprecated) {
25261
+ def.deprecated = true;
25262
+ def.schema = { ...def.schema, deprecated: undefined };
25263
+ }
25264
+ const referenced = def.schema && "$ref" in def.schema ? referencedSchema(def.schema.$ref, schemas4) : undefined;
25265
+ if (referenced?.description && !def.description) {
25266
+ def.description = referenced.description;
25267
+ }
25268
+ if (referenced?.deprecated) {
25269
+ def.deprecated = true;
25270
+ }
25007
25271
  parameters.push(def);
25008
25272
  }
25009
25273
  return parameters;
25010
25274
  }
25011
- function collectParameterProperties(schema, schemas4) {
25275
+ var referencedSchema = ($ref, schemas4) => {
25276
+ const prefix = "#/components/schemas/";
25277
+ if (!$ref.startsWith(prefix)) {
25278
+ return;
25279
+ }
25280
+ const name = $ref.slice(prefix.length).replaceAll("~1", "/").replaceAll("~0", "~");
25281
+ return schemas4?.[name];
25282
+ };
25283
+ var intersect = (entries) => {
25012
25284
  const properties = /* @__PURE__ */ new Map;
25013
- const resolvingRefs = /* @__PURE__ */ new Set;
25014
- const collect = (current) => {
25015
- for (const [key, value] of Object.entries(current.properties ?? {})) {
25016
- const existing = properties.get(key);
25017
- properties.set(key, {
25018
- schema: existing ? { allOf: [existing.schema, value] } : value,
25019
- required: Boolean(current.required?.includes(key)) || existing?.required
25020
- });
25021
- }
25022
- for (const member of current.allOf ?? []) {
25023
- if ("$ref" in member) {
25024
- const prefix = "#/components/schemas/";
25025
- if (!member.$ref.startsWith(prefix))
25026
- continue;
25027
- const name = member.$ref.slice(prefix.length).replaceAll("~1", "/").replaceAll("~0", "~");
25028
- const referencedSchema = schemas4?.[name];
25029
- if (referencedSchema && !resolvingRefs.has(name)) {
25030
- resolvingRefs.add(name);
25031
- collect(referencedSchema);
25032
- resolvingRefs.delete(name);
25033
- }
25034
- } else {
25035
- collect(member);
25285
+ for (const [key, property] of entries) {
25286
+ const existing = properties.get(key);
25287
+ properties.set(key, existing ? {
25288
+ required: existing.required || property.required,
25289
+ schema: { allOf: [existing.schema, property.schema] }
25290
+ } : property);
25291
+ }
25292
+ return properties;
25293
+ };
25294
+ var unite = (variants) => {
25295
+ const keys = new Set(variants.flatMap((variant) => [...variant.keys()]));
25296
+ return new Map([...keys].map((key) => {
25297
+ const found = variants.map((variant) => variant.get(key));
25298
+ const [first, ...others] = new Map(found.filter((property) => property !== undefined).map(({ schema }) => [JSON.stringify(schema), schema])).values();
25299
+ return [
25300
+ key,
25301
+ {
25302
+ required: found.every((property) => property?.required),
25303
+ schema: others.length ? { anyOf: [first, ...others] } : first
25036
25304
  }
25305
+ ];
25306
+ }));
25307
+ };
25308
+ var collectParameterProperties = (schema, schemas4) => {
25309
+ const collectMember = (member, resolving) => {
25310
+ if (!("$ref" in member))
25311
+ return collect(member, resolving);
25312
+ const prefix = "#/components/schemas/";
25313
+ if (!member.$ref.startsWith(prefix))
25314
+ return /* @__PURE__ */ new Map;
25315
+ const name = member.$ref.slice(prefix.length).replaceAll("~1", "/").replaceAll("~0", "~");
25316
+ const referencedSchema2 = schemas4?.[name];
25317
+ if (!referencedSchema2 || resolving.has(name))
25318
+ return /* @__PURE__ */ new Map;
25319
+ return collect(referencedSchema2, new Set(resolving).add(name));
25320
+ };
25321
+ const collect = (current, resolving) => intersect([
25322
+ ...Object.entries(current.properties ?? {}).map(([key, value]) => [
25323
+ key,
25324
+ { required: Boolean(current.required?.includes(key)), schema: value }
25325
+ ]),
25326
+ ...(current.allOf ?? []).flatMap((member) => [
25327
+ ...collectMember(member, resolving)
25328
+ ]),
25329
+ ...[current.anyOf, current.oneOf].filter((variants) => variants?.length).flatMap((variants = []) => [
25330
+ ...unite(variants.map((variant) => collectMember(variant, resolving)))
25331
+ ])
25332
+ ]);
25333
+ return collect(schema, /* @__PURE__ */ new Set);
25334
+ };
25335
+ var resolveHeaders = async (headers, direction) => {
25336
+ const resolved = await Promise.all(Object.entries(headers).map(async ([name, header]) => {
25337
+ if ("$ref" in header || typeof header.schema !== "object" || header.schema === null || !("toOpenAPISchema" in header.schema)) {
25338
+ return { components: undefined, entry: [name, header] };
25037
25339
  }
25340
+ const result = await header.schema.toOpenAPISchema(undefined, direction);
25341
+ liftSchemaDefs(result);
25342
+ return {
25343
+ components: result.components,
25344
+ entry: [name, { ...header, schema: result.schema }]
25345
+ };
25346
+ }));
25347
+ return {
25348
+ components: mergeComponentsObjects({}, ...resolved.map(({ components }) => components)),
25349
+ headers: Object.fromEntries(resolved.map(({ entry }) => entry))
25038
25350
  };
25039
- collect(schema);
25040
- return properties;
25041
- }
25042
- async function resolveContentSchemas(content) {
25351
+ };
25352
+ var resolveEncoding = async (encoding, direction) => {
25353
+ const resolved = await Promise.all(Object.entries(encoding).map(async ([property, entry]) => {
25354
+ if (!entry.headers) {
25355
+ return { components: undefined, entry: [property, entry] };
25356
+ }
25357
+ const { components, headers } = await resolveHeaders(entry.headers, direction);
25358
+ return { components, entry: [property, { ...entry, headers }] };
25359
+ }));
25360
+ return {
25361
+ components: mergeComponentsObjects({}, ...resolved.map(({ components }) => components)),
25362
+ encoding: Object.fromEntries(resolved.map(({ entry }) => entry))
25363
+ };
25364
+ };
25365
+ async function resolveContentSchemas(content, direction) {
25043
25366
  let components = {};
25044
25367
  const resolvedContent = {};
25045
25368
  for (const [contentKey, raw] of Object.entries(content)) {
25046
25369
  if (!raw)
25047
25370
  continue;
25048
- if (raw.schema && "toOpenAPISchema" in raw.schema) {
25049
- const result = await raw.schema.toOpenAPISchema();
25371
+ const encoding = raw.encoding ? await resolveEncoding(raw.encoding, direction) : undefined;
25372
+ const media = encoding ? { ...raw, encoding: encoding.encoding } : raw;
25373
+ if (encoding) {
25374
+ components = mergeComponentsObjects(components, encoding.components);
25375
+ }
25376
+ if (media.schema != null && typeof media.schema === "object" && "toOpenAPISchema" in media.schema) {
25377
+ const result = await media.schema.toOpenAPISchema(undefined, direction);
25050
25378
  liftSchemaDefs(result);
25051
25379
  resolvedContent[contentKey] = {
25052
- ...raw,
25380
+ ...media,
25053
25381
  schema: result.schema
25054
25382
  };
25055
25383
  if (result.components) {
25056
25384
  components = mergeComponentsObjects(components, result.components);
25057
25385
  }
25058
25386
  } else {
25059
- resolvedContent[contentKey] = raw;
25387
+ resolvedContent[contentKey] = media;
25060
25388
  }
25061
25389
  }
25062
25390
  return { content: resolvedContent, components };
@@ -25065,18 +25393,20 @@ async function resolveResponseSchemas(responses) {
25065
25393
  let components = {};
25066
25394
  const resolvedResponses = {};
25067
25395
  for (const [key, response] of Object.entries(responses)) {
25068
- if (!response || !("content" in response) || !response.content) {
25396
+ if (!response || "$ref" in response || !response.content && !response.headers) {
25069
25397
  resolvedResponses[key] = response;
25070
25398
  continue;
25071
25399
  }
25072
- const resolved = await resolveContentSchemas(response.content);
25400
+ const content = response.content ? await resolveContentSchemas(response.content, "output") : undefined;
25401
+ const headers = response.headers ? await resolveHeaders(response.headers, "output") : undefined;
25073
25402
  resolvedResponses[key] = {
25074
25403
  ...response,
25075
- content: resolved.content
25404
+ ...content && { content: content.content },
25405
+ ...headers && { headers: headers.headers }
25076
25406
  };
25077
- components = mergeComponentsObjects(components, resolved.components);
25407
+ components = mergeComponentsObjects(components, content?.components, headers?.components);
25078
25408
  }
25079
- return { responses: resolvedResponses, components };
25409
+ return markAsOutput(resolvedResponses, components);
25080
25410
  }
25081
25411
  function liftSchemaDefs(result) {
25082
25412
  const defs = result.schema.$defs;
@@ -25108,6 +25438,96 @@ function mergeComponentsObjects(...components) {
25108
25438
  return prev;
25109
25439
  }, components[0] ?? {});
25110
25440
  }
25441
+ var OUTPUT_MARK = "\x00output";
25442
+ var isOutput = (name) => name.endsWith(OUTPUT_MARK);
25443
+ var inputName = (output3) => output3.slice(0, -OUTPUT_MARK.length);
25444
+ var markAsOutput = (responses, components) => {
25445
+ const schemas4 = components.schemas ?? {};
25446
+ const mark = (name) => Object.hasOwn(schemas4, name) ? `${name}${OUTPUT_MARK}` : undefined;
25447
+ return {
25448
+ responses: renameSchemaRefs(responses, mark, true),
25449
+ components: {
25450
+ ...components,
25451
+ ...components.schemas && {
25452
+ schemas: Object.fromEntries(Object.entries(schemas4).map(([name, schema]) => [
25453
+ `${name}${OUTPUT_MARK}`,
25454
+ renameSchemaRefs(schema, mark)
25455
+ ]))
25456
+ }
25457
+ }
25458
+ };
25459
+ };
25460
+ var withOutputRefs = (documentation, ctx) => [
25461
+ documentation,
25462
+ componentRefs(documentation).filter((ref) => ref.startsWith("schemas/")).map((ref) => decodeName(ref.slice("schemas/".length))).filter((name) => !Object.hasOwn(ctx.components.schemas ?? {}, name) && Object.hasOwn(ctx.components.schemas ?? {}, `${name}${OUTPUT_MARK}`)).map((name) => ({
25463
+ $ref: `${SCHEMA_REF}${encodeName(`${name}${OUTPUT_MARK}`)}`
25464
+ }))
25465
+ ];
25466
+ var canonical = (value) => JSON.stringify(value, (_key, item) => item && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.entries(item).toSorted(([a2], [b2]) => a2.localeCompare(b2))) : item);
25467
+ var freeName = (name, used) => {
25468
+ let candidate = name;
25469
+ for (let suffix = 2;used.has(candidate); suffix++) {
25470
+ candidate = `${name}${suffix}`;
25471
+ }
25472
+ return candidate;
25473
+ };
25474
+ var assignOutputNames = (outputs, taken) => {
25475
+ const used = new Set(taken);
25476
+ const names = /* @__PURE__ */ new Map;
25477
+ for (const output3 of outputs) {
25478
+ const name = freeName(`${inputName(output3)}Output`, used);
25479
+ used.add(name);
25480
+ names.set(output3, name);
25481
+ }
25482
+ return names;
25483
+ };
25484
+ var splitOutputComponents = (components, paths) => {
25485
+ const { schemas: schemas4 = {}, ...otherComponents } = components;
25486
+ const outputs = Object.keys(schemas4).filter(isOutput);
25487
+ if (outputs.length === 0) {
25488
+ return { components, paths };
25489
+ }
25490
+ const asInput = (name) => isOutput(name) ? inputName(name) : undefined;
25491
+ const shared = new Set(outputs.filter((output3) => Object.hasOwn(schemas4, inputName(output3))));
25492
+ const outputRefs = new Map([...shared].map((output3) => [
25493
+ output3,
25494
+ componentRefs(schemas4[output3]).filter((ref) => ref.startsWith("schemas/")).map((ref) => decodeName(ref.slice("schemas/".length)))
25495
+ ]));
25496
+ const refersTo = (output3, split2) => outputRefs.get(output3)?.some((name) => split2.has(name));
25497
+ const split = new Set([...shared].filter((output3) => canonical(renameSchemaRefs(schemas4[output3], asInput)) !== canonical(schemas4[inputName(output3)])));
25498
+ let previousSize;
25499
+ do {
25500
+ previousSize = split.size;
25501
+ for (const output3 of shared) {
25502
+ if (!split.has(output3) && refersTo(output3, split)) {
25503
+ split.add(output3);
25504
+ }
25505
+ }
25506
+ } while (split.size !== previousSize);
25507
+ const taken = [
25508
+ ...Object.keys(schemas4).filter((name) => !isOutput(name)),
25509
+ ...outputs.filter((output3) => !shared.has(output3)).map(inputName)
25510
+ ];
25511
+ const outputNames = assignOutputNames([...split].toSorted(), taken);
25512
+ const rename = (name) => isOutput(name) ? outputNames.get(name) ?? inputName(name) : undefined;
25513
+ return {
25514
+ components: {
25515
+ ...renameSchemaRefs(otherComponents, rename),
25516
+ schemas: Object.fromEntries(Object.entries(schemas4).flatMap(([name, schema]) => {
25517
+ const renamed = renameSchemaRefs(schema, rename);
25518
+ if (!isOutput(name)) {
25519
+ return [[name, renamed]];
25520
+ }
25521
+ const output3 = outputNames.get(name);
25522
+ if (output3) {
25523
+ return [[output3, renamed]];
25524
+ }
25525
+ return Object.hasOwn(schemas4, inputName(name)) ? [] : [[inputName(name), renamed]];
25526
+ }))
25527
+ },
25528
+ paths: renameSchemaRefs(paths, rename, true)
25529
+ };
25530
+ };
25111
25531
  var arktypeMorphFallback = (ctx) => ctx.base;
25112
25532
  var zodV4DateOverride = (ctx) => {
25113
25533
  if (ctx.zodSchema._zod.def.type === "date") {
@@ -25121,14 +25541,34 @@ function resolver(schema, userDefinedOptions) {
25121
25541
  vendor,
25122
25542
  validate: schema["~standard"].validate,
25123
25543
  toJSONSchema: (customOptions) => toJsonSchema(schema, { ...userDefinedOptions, ...customOptions }),
25124
- toOpenAPISchema: (customOptions) => toOpenAPISchema(schema, {
25125
- ...userDefinedOptions,
25126
- ...customOptions,
25127
- ...vendor === "arktype" ? injectArktypeFallback(userDefinedOptions, customOptions) : undefined,
25128
- ...vendor === "zod" ? injectZodV4DateOverride(schema, userDefinedOptions, customOptions) : undefined
25129
- })
25544
+ toOpenAPISchema: (customOptions, direction) => {
25545
+ const context = {
25546
+ ...userDefinedOptions,
25547
+ ...customOptions,
25548
+ ...vendor === "arktype" ? injectArktypeFallback(userDefinedOptions, customOptions) : undefined,
25549
+ ...vendor === "zod" ? injectZodV4DateOverride(schema, userDefinedOptions, customOptions) : undefined
25550
+ };
25551
+ const directionOptions = direction === "output" ? outputOptions(schema) : undefined;
25552
+ return toOpenAPISchema(schema, directionOptions ? {
25553
+ ...context,
25554
+ options: {
25555
+ ...directionOptions,
25556
+ ...context.options
25557
+ }
25558
+ } : context);
25559
+ }
25130
25560
  };
25131
25561
  }
25562
+ var outputOptions = (schema) => {
25563
+ switch (schema["~standard"].vendor) {
25564
+ case "zod":
25565
+ return "_zod" in schema ? { io: "output" } : { schemaType: "output" };
25566
+ case "valibot":
25567
+ return { typeMode: "output" };
25568
+ default:
25569
+ return;
25570
+ }
25571
+ };
25132
25572
  function injectArktypeFallback(userDefined, custom3) {
25133
25573
  const userNested = userDefined?.options;
25134
25574
  const customNested = custom3?.options;
@@ -28538,12 +28978,12 @@ function createSetOperator(type, isAll) {
28538
28978
  var getSQLiteSetOperators = () => ({
28539
28979
  union: union3,
28540
28980
  unionAll,
28541
- intersect,
28981
+ intersect: intersect2,
28542
28982
  except
28543
28983
  });
28544
28984
  var union3 = createSetOperator("union", false);
28545
28985
  var unionAll = createSetOperator("union", true);
28546
- var intersect = createSetOperator("intersect", false);
28986
+ var intersect2 = createSetOperator("intersect", false);
28547
28987
  var except = createSetOperator("except", false);
28548
28988
 
28549
28989
  // ../../node_modules/.bun/drizzle-orm@0.45.4+6458dd716b2a29fa/node_modules/drizzle-orm/sqlite-core/query-builders/query-builder.js
@@ -32336,8 +32776,12 @@ function setHeaders(ctx, headersToSet) {
32336
32776
  }
32337
32777
 
32338
32778
  // src/platform/http/openapi.ts
32779
+ var openObjects = { options: { io: "input" } };
32339
32780
  function jsonResponse(description, schema) {
32340
- return { description, content: { "application/json": { schema: resolver(schema) } } };
32781
+ return {
32782
+ description,
32783
+ content: { "application/json": { schema: resolver(schema, openObjects) } }
32784
+ };
32341
32785
  }
32342
32786
  var methods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
32343
32787
  var failure2 = {
@@ -52158,5 +52602,5 @@ try {
52158
52602
  process.exitCode = 1;
52159
52603
  }
52160
52604
 
52161
- //# debugId=2F8C02334FD34D1264756E2164756E21
52605
+ //# debugId=F29E635AF65D464664756E2164756E21
52162
52606
  //# sourceMappingURL=main.js.map