apollo-conn-gen 0.8.3 → 0.9.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/dist/cli/oas.js +2 -0
- package/dist/cli/oas.js.map +1 -1
- package/dist/json/walker/jsonGen.js +2 -1
- package/dist/json/walker/jsonGen.js.map +1 -1
- package/dist/json/walker/naming.js +11 -12
- package/dist/json/walker/naming.js.map +1 -1
- package/dist/oas/generator/typesCollector.js +6 -1
- package/dist/oas/generator/typesCollector.js.map +1 -1
- package/dist/oas/io/operationWriter.d.ts +2 -0
- package/dist/oas/io/operationWriter.js +34 -2
- package/dist/oas/io/operationWriter.js.map +1 -1
- package/dist/oas/io/schemaWriter.d.ts +13 -0
- package/dist/oas/io/schemaWriter.js +121 -4
- package/dist/oas/io/schemaWriter.js.map +1 -1
- package/dist/oas/io/writer.js +9 -0
- package/dist/oas/io/writer.js.map +1 -1
- package/dist/oas/nodes/comp.d.ts +1 -0
- package/dist/oas/nodes/comp.js +28 -8
- package/dist/oas/nodes/comp.js.map +1 -1
- package/dist/oas/nodes/entity.d.ts +45 -0
- package/dist/oas/nodes/entity.js +90 -0
- package/dist/oas/nodes/entity.js.map +1 -0
- package/dist/oas/nodes/factory.d.ts +19 -0
- package/dist/oas/nodes/factory.js +76 -12
- package/dist/oas/nodes/factory.js.map +1 -1
- package/dist/oas/nodes/iType.d.ts +3 -1
- package/dist/oas/nodes/iType.js.map +1 -1
- package/dist/oas/nodes/interfacePromotion.d.ts +33 -0
- package/dist/oas/nodes/interfacePromotion.js +148 -0
- package/dist/oas/nodes/interfacePromotion.js.map +1 -0
- package/dist/oas/nodes/internal.d.ts +1 -0
- package/dist/oas/nodes/internal.js +1 -0
- package/dist/oas/nodes/internal.js.map +1 -1
- package/dist/oas/nodes/obj.d.ts +12 -1
- package/dist/oas/nodes/obj.js +78 -9
- package/dist/oas/nodes/obj.js.map +1 -1
- package/dist/oas/nodes/param.js +12 -6
- package/dist/oas/nodes/param.js.map +1 -1
- package/dist/oas/nodes/propCircRef.d.ts +2 -2
- package/dist/oas/nodes/propCircRef.js +27 -9
- package/dist/oas/nodes/propCircRef.js.map +1 -1
- package/dist/oas/nodes/refCircRef.d.ts +18 -0
- package/dist/oas/nodes/refCircRef.js +24 -0
- package/dist/oas/nodes/refCircRef.js.map +1 -0
- package/dist/oas/nodes/type.d.ts +1 -0
- package/dist/oas/nodes/type.js +26 -1
- package/dist/oas/nodes/type.js.map +1 -1
- package/dist/oas/nodes/union.d.ts +21 -1
- package/dist/oas/nodes/union.js +86 -4
- package/dist/oas/nodes/union.js.map +1 -1
- package/dist/oas/oasContext.d.ts +3 -0
- package/dist/oas/oasContext.js +53 -0
- package/dist/oas/oasContext.js.map +1 -1
- package/dist/oas/oasGen.d.ts +2 -0
- package/dist/oas/oasGen.js +3 -1
- package/dist/oas/oasGen.js.map +1 -1
- package/dist/oas/utils/naming.d.ts +0 -1
- package/dist/oas/utils/naming.js +75 -26
- package/dist/oas/utils/naming.js.map +1 -1
- package/dist/tests/runners.d.ts +7 -1
- package/dist/tests/runners.js +16 -5
- package/dist/tests/runners.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/versions.d.ts +30 -2
- package/dist/versions.js +77 -2
- package/dist/versions.js.map +1 -1
- package/package.json +4 -3
package/dist/cli/oas.js
CHANGED
|
@@ -38,6 +38,7 @@ async function main(sourceFile, opts) {
|
|
|
38
38
|
postName: opts.postName,
|
|
39
39
|
mapper: mapper,
|
|
40
40
|
skipOptionalArgs: opts.skipOptionalArgs,
|
|
41
|
+
inferEntityResolvers: opts.inferEntityResolvers,
|
|
41
42
|
});
|
|
42
43
|
await gen.visit();
|
|
43
44
|
let pathSet = Array.from(gen.paths.values());
|
|
@@ -86,6 +87,7 @@ program
|
|
|
86
87
|
.option('--federation-version <version>', 'Federation version to use', DEFAULT_VERSIONS.federationVersion)
|
|
87
88
|
.option('--connector-spec-version <version>', 'Connector spec version to use', DEFAULT_VERSIONS.connectorSpecVersion)
|
|
88
89
|
.option('--skip-optional-args', 'Skip optional arguments in queries', false)
|
|
90
|
+
.option('--infer-entity-resolvers', 'Infer entity resolvers and emit @key / entity: true', false)
|
|
89
91
|
.parse(process.argv);
|
|
90
92
|
const source = program.args[0];
|
|
91
93
|
main(source, program.opts()).then(() => console.log('done'));
|
package/dist/cli/oas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oas.js","sourceRoot":"","sources":["../../src/cli/oas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAoB,MAAM,wBAAwB,CAAC;AAErF,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CACnC;IACE,GAAG,EAAE,OAAO,CAAC,GAAG;CACjB,EACD,OAAO,CACR,CAAC;AAEF,8DAA8D;AAC9D,SAAS,SAAS,CAAC,IAAS;IAC1B,IAAI,MAAM,CAAC;IACX,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACxD,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;YACzD,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,iDAAiD;QACjD,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,6EAA6E;AAC7E,KAAK,UAAU,IAAI,CAAC,UAAkB,EAAE,IAAS;IAC/C,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAEvB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE/B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE;QAC5C,GAAG,IAAI;QACP,iBAAiB,EAAE,IAAI;QACvB,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;QAC/C,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,MAAM;QACd,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"oas.js","sourceRoot":"","sources":["../../src/cli/oas.ts"],"names":[],"mappings":"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","sourcesContent":["import { Command } from 'commander';\nimport { DEFAULT_VERSIONS } from '../versions.js';\nimport { generateFromSelection, promptForSelection } from './oas-helpers/index.js';\nimport { OasGen } from '../oas/oasGen.js';\nimport { RulesLoader, OpNameMapper, MapRules, Mapper } from '../oas/mapper/index.js';\n\nconst originalConsole = Object.assign(\n {\n log: console.log,\n },\n console,\n);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction loadRules(opts: any): Mapper | undefined {\n let mapper;\n if (opts.transformRules) {\n try {\n const rules = RulesLoader.fromFile(opts.transformRules);\n mapper = OpNameMapper.fromRules(rules);\n } catch (error) {\n console.error(`Error loading transform rules: ${error}`);\n return undefined;\n }\n } else if (opts.postName) {\n // Backward compatibility with legacy --post-name\n mapper = OpNameMapper.fromPattern(opts.postName);\n }\n\n return mapper;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- for options\nasync function main(sourceFile: string, opts: any): Promise<void> {\n console.log = () => {};\n\n const mapper = loadRules(opts);\n\n const gen = await OasGen.fromFile(sourceFile, {\n ...opts,\n consolidateUnions: true,\n showParentInSelections: false,\n federationVersion: opts.federationVersion,\n connectorSpecVersion: opts.connectorSpecVersion,\n postName: opts.postName,\n mapper: mapper,\n skipOptionalArgs: opts.skipOptionalArgs,\n inferEntityResolvers: opts.inferEntityResolvers,\n });\n\n await gen.visit();\n\n let pathSet = Array.from(gen.paths.values());\n if (opts.loadSelections) {\n generateFromSelection(opts, gen);\n return;\n }\n\n if (opts.grep !== '*') {\n const regex = new RegExp(opts.grep, 'ig');\n pathSet = pathSet.filter((p) => regex.test(p.path()));\n }\n\n if (opts.listPaths) {\n pathSet.forEach((path) => console.info(path.path()));\n return;\n }\n\n let paths: string[];\n if (opts.skipSelection) {\n paths = pathSet.map((p) => p.path() + '>**');\n } else {\n paths = await promptForSelection(gen, opts, pathSet);\n }\n\n if (opts.verbose) console = originalConsole;\n\n console.info(gen.generateSchema(paths));\n\n if (opts.printSelections) {\n console.info('# --------------- Selections -----------------');\n console.info(gen.selections);\n console.info('# --------------- Paths -----------------');\n console.info('paths =', JSON.stringify(paths, null, 2));\n }\n}\n\nconst program = new Command();\nprogram\n .version('0.0.1')\n .argument('<source>', 'source spec (yaml or json)')\n .option('-i --skip-validation', 'Skip validation step', false)\n .option('-n --skip-selection', 'Generate all [filtered] paths without prompting for a selection', false)\n .option('-l --list-paths', 'Only list the paths that can be generated', false)\n .option('-g --grep <regex>', 'Filter the list of paths with the passed expression', '*')\n .option('-p --page-size <num>', 'Number of rows to display in selection mode', '10')\n .option('-s --load-selections <file>', 'Load a JSON file with field selections (other options are ignored)')\n .option('-v --verbose', 'Log all messages from generator')\n .option('-m --print-selections', 'Print selections from generator')\n .option('-t --transform-rules <file>', 'Load transform rules from a JSON file to apply multiple name transformations')\n .option('--federation-version <version>', 'Federation version to use', DEFAULT_VERSIONS.federationVersion)\n .option('--connector-spec-version <version>', 'Connector spec version to use', DEFAULT_VERSIONS.connectorSpecVersion)\n .option('--skip-optional-args', 'Skip optional arguments in queries', false)\n .option('--infer-entity-resolvers', 'Infer entity resolvers and emit @key / entity: true', false)\n .parse(process.argv);\n\nconst source = program.args[0];\nmain(source, program.opts()).then(() => console.log('done'));\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
-
import { DEFAULT_VERSIONS } from '../../versions.js';
|
|
3
|
+
import { DEFAULT_VERSIONS, validateVersionOptions } from '../../versions.js';
|
|
4
4
|
import { ConnectorWriter, JsonArray, JsonContext, JsonObj, JsonScalar, StringWriter } from '../index.js';
|
|
5
5
|
import { trace, warn } from './log/trace.js';
|
|
6
6
|
import { sanitiseField } from './naming.js';
|
|
@@ -16,6 +16,7 @@ export class JsonGen {
|
|
|
16
16
|
connectorSpecVersion: DEFAULT_VERSIONS.connectorSpecVersion,
|
|
17
17
|
...options,
|
|
18
18
|
};
|
|
19
|
+
validateVersionOptions(this.options);
|
|
19
20
|
}
|
|
20
21
|
getContext() {
|
|
21
22
|
return this.context;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonGen.js","sourceRoot":"","sources":["../../../src/json/walker/jsonGen.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport _ from 'lodash';\nimport { DEFAULT_VERSIONS } from '../../versions.js';\nimport { ConnectorWriter, JsonArray, JsonContext, JsonObj, JsonScalar, JsonType, StringWriter } from '../index.js';\nimport { trace, warn } from './log/trace.js';\nimport { sanitiseField } from './naming.js';\n\nexport interface JsonGenOptions {\n federationVersion?: string;\n connectorSpecVersion?: string;\n rootType?: string;\n baseURL?: string;\n relativePath?: string;\n queryField?: string;\n verbose?: boolean;\n}\n\nexport class JsonGen {\n private readonly context: JsonContext;\n private readonly options: JsonGenOptions;\n\n // Private constructor\n private constructor(options: JsonGenOptions = {}) {\n this.context = new JsonContext();\n this.context.verbose = options.verbose ?? false;\n this.options = {\n federationVersion: DEFAULT_VERSIONS.federationVersion,\n connectorSpecVersion: DEFAULT_VERSIONS.connectorSpecVersion,\n ...options,\n };\n }\n\n public getContext(): JsonContext {\n return this.context;\n }\n\n public static new(options?: JsonGenOptions): JsonGen {\n return new JsonGen(options);\n }\n\n // Factory method from a JSON string\n public static fromReader(json: string, options?: JsonGenOptions): JsonGen {\n const walker = new JsonGen(options);\n walker.walkJson(json);\n return walker;\n }\n\n public static fromJsons(jsons: string[], options?: JsonGenOptions): JsonGen {\n const walker = new JsonGen(options);\n for (const json of jsons) {\n walker.walkJson(json);\n }\n return walker;\n }\n\n public generateSchema(): string {\n const writer = new StringWriter();\n ConnectorWriter.write(this, writer, this.options);\n return writer.flush();\n }\n\n // Writes selection using a given Writer\n public writeSelection(indent: number = 6): string {\n const writer = new StringWriter();\n this.context.setIndent(indent);\n\n const types = this.context.getTypes();\n const root = types.find((t: JsonType) => t.getParent() === null);\n if (root) {\n root.select(this.context, writer);\n }\n\n return writer.flush();\n }\n\n // Writes all types in order using the provided Writer\n public writeTypes(): string {\n const writer = new StringWriter();\n\n const types = this.context.getTypes();\n const root = types.find((t: JsonType) => t.getParent() === null);\n if (root) {\n const orderedSet = new Set<JsonType>();\n this.writeType(root, orderedSet);\n\n const generatedSet = new Map<string, JsonType>();\n orderedSet.forEach((t) => {\n // Assumes t is an Obj\n const obj = t as unknown as JsonObj;\n let typeName = obj.getType();\n if (generatedSet.has(typeName)) {\n // If same type, skip generation\n if (_.isEqual(obj, generatedSet.get(typeName))) {\n return;\n }\n obj.setType(JsonGen.generateNewObjType(generatedSet, t, typeName));\n typeName = obj.getType();\n }\n t.write(this.context, writer);\n generatedSet.set(typeName, t);\n });\n }\n\n return writer.flush();\n }\n\n // Recursive helper to order types\n private writeType(type: JsonType, orderedSet: Set<JsonType>): void {\n if (type instanceof JsonObj) {\n // Traverse children first\n for (const child of Array.from((type as JsonObj).getFields().values())) {\n this.writeType(child, orderedSet);\n }\n orderedSet.add(type);\n } else if (type instanceof JsonArray) {\n const arrayType = (type as JsonArray).getArrayType();\n if (arrayType) {\n this.writeType(arrayType, orderedSet);\n }\n }\n }\n\n // Walk the JSON provided as a string\n public walkJson(json: string): void {\n const rootElement = JSON.parse(json);\n const rootName = (this.options.rootType ?? 'root').replace(/^\\[|]$/g, '');\n this.walkElement(this.context, null, rootName, rootElement);\n trace(this.context, ' [walkSource]', 'types found: ' + this.context.getTypes().length);\n }\n\n // Walk an element in the JSON tree\n private walkElement(context: JsonContext, parent: JsonType | null, name: string, element: any): JsonType {\n trace(context, '-> [walkElement]', 'in: ' + name);\n let result: JsonType;\n\n if (typeof element === 'object' && !Array.isArray(element) && element !== null) {\n // JSON object\n result = this.walkObject(context, parent, name, element);\n context.store(result);\n } else if (Array.isArray(element)) {\n result = this.walkArray(context, parent, name, element);\n } else if (typeof element === 'string' || typeof element === 'number' || typeof element === 'boolean') {\n result = this.walkPrimitive(context, parent, name, element);\n } else if (element === null) {\n // we'll treat null as a string\n result = this.walkPrimitive(context, parent, name, 'string');\n } else {\n throw new Error(\"Cannot yet handle '\" + name + \"' of type \" + typeof element);\n }\n\n trace(context, '<- [walkElement]', 'out: ' + name);\n return result;\n }\n\n // Walk a JSON object\n private walkObject(context: JsonContext, parent: JsonType | null, name: string, object: any): JsonObj {\n trace(context, '-> [walkObject]', 'in: ' + name);\n const result = new JsonObj(name, parent);\n const fieldSet = Object.keys(object);\n trace(context, ' [walkObject]', 'fieldSet: ' + fieldSet);\n\n for (const field of fieldSet) {\n trace(context, ' [walkObject]', 'field: ' + field);\n const childElement = object[field];\n const type = this.walkElement(context, result, field, childElement);\n result.add(field, type);\n }\n\n trace(context, '<- [walkObject]', 'out: ' + name);\n return result;\n }\n\n // Walk a JSON array\n private walkArray(context: JsonContext, parent: JsonType | null, name: string, array: any[]): JsonArray {\n trace(context, '-> [walkArray]', 'in: ' + name);\n const result = new JsonArray(name, parent);\n if (array.length > 0) {\n const firstElement = array[0];\n const arrayType = this.walkElement(context, parent, name, firstElement);\n result.setArrayType(arrayType);\n } else {\n warn(context, ' [walkArray]', \"Array is empty -- cannot derive type for field '\" + name + \"'\");\n }\n trace(context, '-> [walkArray]', 'in: ' + name);\n return result;\n }\n\n // Walk a primitive JSON value\n private walkPrimitive(_context: JsonContext, parent: JsonType | null, name: string, primitive: any): JsonScalar {\n let result: JsonScalar;\n if (typeof primitive === 'string') {\n result = new JsonScalar(name, parent, 'String');\n } else if (typeof primitive === 'boolean') {\n result = new JsonScalar(name, parent, 'Boolean');\n } else if (typeof primitive === 'number') {\n result = new JsonScalar(name, parent, 'Int');\n } else {\n throw new Error('Cannot yet handle primitive: ' + primitive);\n }\n return result;\n }\n\n // Utility method for naming conflict resolution\n private static generateNewObjType(generatedSet: Map<string, JsonType>, t: JsonType, typeName: string): string {\n let newName: string;\n let type: JsonType | null = t;\n do {\n const parent: JsonType | null = type.getParent();\n const parentName = parent === null ? '' : sanitiseField(parent.getName()).replace(/^\\w/, (c) => c.toUpperCase());\n const thisName = sanitiseField(typeName).replace(/^\\w/, (c) => c.toUpperCase());\n newName = parentName + thisName;\n type = parent;\n } while (type !== null && generatedSet.has(newName));\n return newName;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"jsonGen.js","sourceRoot":"","sources":["../../../src/json/walker/jsonGen.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport _ from 'lodash';\nimport { DEFAULT_VERSIONS, validateVersionOptions } from '../../versions.js';\nimport { ConnectorWriter, JsonArray, JsonContext, JsonObj, JsonScalar, JsonType, StringWriter } from '../index.js';\nimport { trace, warn } from './log/trace.js';\nimport { sanitiseField } from './naming.js';\n\nexport interface JsonGenOptions {\n federationVersion?: string;\n connectorSpecVersion?: string;\n rootType?: string;\n baseURL?: string;\n relativePath?: string;\n queryField?: string;\n verbose?: boolean;\n}\n\nexport class JsonGen {\n private readonly context: JsonContext;\n private readonly options: JsonGenOptions;\n\n // Private constructor\n private constructor(options: JsonGenOptions = {}) {\n this.context = new JsonContext();\n this.context.verbose = options.verbose ?? false;\n this.options = {\n federationVersion: DEFAULT_VERSIONS.federationVersion,\n connectorSpecVersion: DEFAULT_VERSIONS.connectorSpecVersion,\n ...options,\n };\n validateVersionOptions(this.options);\n }\n\n public getContext(): JsonContext {\n return this.context;\n }\n\n public static new(options?: JsonGenOptions): JsonGen {\n return new JsonGen(options);\n }\n\n // Factory method from a JSON string\n public static fromReader(json: string, options?: JsonGenOptions): JsonGen {\n const walker = new JsonGen(options);\n walker.walkJson(json);\n return walker;\n }\n\n public static fromJsons(jsons: string[], options?: JsonGenOptions): JsonGen {\n const walker = new JsonGen(options);\n for (const json of jsons) {\n walker.walkJson(json);\n }\n return walker;\n }\n\n public generateSchema(): string {\n const writer = new StringWriter();\n ConnectorWriter.write(this, writer, this.options);\n return writer.flush();\n }\n\n // Writes selection using a given Writer\n public writeSelection(indent: number = 6): string {\n const writer = new StringWriter();\n this.context.setIndent(indent);\n\n const types = this.context.getTypes();\n const root = types.find((t: JsonType) => t.getParent() === null);\n if (root) {\n root.select(this.context, writer);\n }\n\n return writer.flush();\n }\n\n // Writes all types in order using the provided Writer\n public writeTypes(): string {\n const writer = new StringWriter();\n\n const types = this.context.getTypes();\n const root = types.find((t: JsonType) => t.getParent() === null);\n if (root) {\n const orderedSet = new Set<JsonType>();\n this.writeType(root, orderedSet);\n\n const generatedSet = new Map<string, JsonType>();\n orderedSet.forEach((t) => {\n // Assumes t is an Obj\n const obj = t as unknown as JsonObj;\n let typeName = obj.getType();\n if (generatedSet.has(typeName)) {\n // If same type, skip generation\n if (_.isEqual(obj, generatedSet.get(typeName))) {\n return;\n }\n obj.setType(JsonGen.generateNewObjType(generatedSet, t, typeName));\n typeName = obj.getType();\n }\n t.write(this.context, writer);\n generatedSet.set(typeName, t);\n });\n }\n\n return writer.flush();\n }\n\n // Recursive helper to order types\n private writeType(type: JsonType, orderedSet: Set<JsonType>): void {\n if (type instanceof JsonObj) {\n // Traverse children first\n for (const child of Array.from((type as JsonObj).getFields().values())) {\n this.writeType(child, orderedSet);\n }\n orderedSet.add(type);\n } else if (type instanceof JsonArray) {\n const arrayType = (type as JsonArray).getArrayType();\n if (arrayType) {\n this.writeType(arrayType, orderedSet);\n }\n }\n }\n\n // Walk the JSON provided as a string\n public walkJson(json: string): void {\n const rootElement = JSON.parse(json);\n const rootName = (this.options.rootType ?? 'root').replace(/^\\[|]$/g, '');\n this.walkElement(this.context, null, rootName, rootElement);\n trace(this.context, ' [walkSource]', 'types found: ' + this.context.getTypes().length);\n }\n\n // Walk an element in the JSON tree\n private walkElement(context: JsonContext, parent: JsonType | null, name: string, element: any): JsonType {\n trace(context, '-> [walkElement]', 'in: ' + name);\n let result: JsonType;\n\n if (typeof element === 'object' && !Array.isArray(element) && element !== null) {\n // JSON object\n result = this.walkObject(context, parent, name, element);\n context.store(result);\n } else if (Array.isArray(element)) {\n result = this.walkArray(context, parent, name, element);\n } else if (typeof element === 'string' || typeof element === 'number' || typeof element === 'boolean') {\n result = this.walkPrimitive(context, parent, name, element);\n } else if (element === null) {\n // we'll treat null as a string\n result = this.walkPrimitive(context, parent, name, 'string');\n } else {\n throw new Error(\"Cannot yet handle '\" + name + \"' of type \" + typeof element);\n }\n\n trace(context, '<- [walkElement]', 'out: ' + name);\n return result;\n }\n\n // Walk a JSON object\n private walkObject(context: JsonContext, parent: JsonType | null, name: string, object: any): JsonObj {\n trace(context, '-> [walkObject]', 'in: ' + name);\n const result = new JsonObj(name, parent);\n const fieldSet = Object.keys(object);\n trace(context, ' [walkObject]', 'fieldSet: ' + fieldSet);\n\n for (const field of fieldSet) {\n trace(context, ' [walkObject]', 'field: ' + field);\n const childElement = object[field];\n const type = this.walkElement(context, result, field, childElement);\n result.add(field, type);\n }\n\n trace(context, '<- [walkObject]', 'out: ' + name);\n return result;\n }\n\n // Walk a JSON array\n private walkArray(context: JsonContext, parent: JsonType | null, name: string, array: any[]): JsonArray {\n trace(context, '-> [walkArray]', 'in: ' + name);\n const result = new JsonArray(name, parent);\n if (array.length > 0) {\n const firstElement = array[0];\n const arrayType = this.walkElement(context, parent, name, firstElement);\n result.setArrayType(arrayType);\n } else {\n warn(context, ' [walkArray]', \"Array is empty -- cannot derive type for field '\" + name + \"'\");\n }\n trace(context, '-> [walkArray]', 'in: ' + name);\n return result;\n }\n\n // Walk a primitive JSON value\n private walkPrimitive(_context: JsonContext, parent: JsonType | null, name: string, primitive: any): JsonScalar {\n let result: JsonScalar;\n if (typeof primitive === 'string') {\n result = new JsonScalar(name, parent, 'String');\n } else if (typeof primitive === 'boolean') {\n result = new JsonScalar(name, parent, 'Boolean');\n } else if (typeof primitive === 'number') {\n result = new JsonScalar(name, parent, 'Int');\n } else {\n throw new Error('Cannot yet handle primitive: ' + primitive);\n }\n return result;\n }\n\n // Utility method for naming conflict resolution\n private static generateNewObjType(generatedSet: Map<string, JsonType>, t: JsonType, typeName: string): string {\n let newName: string;\n let type: JsonType | null = t;\n do {\n const parent: JsonType | null = type.getParent();\n const parentName = parent === null ? '' : sanitiseField(parent.getName()).replace(/^\\w/, (c) => c.toUpperCase());\n const thisName = sanitiseField(typeName).replace(/^\\w/, (c) => c.toUpperCase());\n newName = parentName + thisName;\n type = parent;\n } while (type !== null && generatedSet.has(newName));\n return newName;\n }\n}\n"]}
|
|
@@ -21,7 +21,13 @@ function lowerFirst(s) {
|
|
|
21
21
|
return _.lowerFirst(s);
|
|
22
22
|
}
|
|
23
23
|
export function genParamName(param) {
|
|
24
|
-
|
|
24
|
+
// Split on any run of non-alphanumeric characters, camelCase the parts, then guarantee
|
|
25
|
+
// a valid GraphQL identifier: non-empty and not starting with a digit.
|
|
26
|
+
const camel = lowerFirst(capitaliseParts(param || '', '[^A-Za-z0-9]+'));
|
|
27
|
+
if (camel.length === 0) {
|
|
28
|
+
return '_';
|
|
29
|
+
}
|
|
30
|
+
return /^[0-9]/.test(camel) ? '_' + camel : camel;
|
|
25
31
|
}
|
|
26
32
|
// Private helper; not exported.
|
|
27
33
|
function formatPath(path, parameters) {
|
|
@@ -45,17 +51,10 @@ export function sanitiseFieldForSelect(name) {
|
|
|
45
51
|
if (sanitised === name && !isProtected(name)) {
|
|
46
52
|
return sanitised;
|
|
47
53
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
builder += '"' + (name.startsWith('@') ? name : fieldName) + '"';
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
builder += name.startsWith('@') ? name : fieldName;
|
|
56
|
-
}
|
|
57
|
-
return builder;
|
|
58
|
-
}
|
|
54
|
+
// Alias: safe GraphQL field <- original JSON key, always quoted (it is not a bare
|
|
55
|
+
// identifier — covers spaces, `$`, `%`, leading digits, etc.).
|
|
56
|
+
const original = name.startsWith('@') ? name : fieldName;
|
|
57
|
+
return `${sanitised}: "${original}"`;
|
|
59
58
|
}
|
|
60
59
|
export function upperFirst(s) {
|
|
61
60
|
if (!s)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/json/walker/naming.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC;AAE9B,SAAS,eAAe,CAAC,WAAmB,EAAE,SAAiB;IAC7D,kEAAkE;IAClE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,2CAA2C;YAC3C,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/json/walker/naming.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC;AAE9B,SAAS,eAAe,CAAC,WAAmB,EAAE,SAAiB;IAC7D,kEAAkE;IAClE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,2CAA2C;YAC3C,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,uFAAuF;IACvF,uEAAuE;IACvE,MAAM,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACpD,CAAC;AAED,gCAAgC;AAChC,SAAS,UAAU,CAAC,IAAY,EAAE,UAAoB;IACpD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,sCAAsC;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,+CAA+C;IAC/C,MAAM,OAAO,GAAG,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3D,+CAA+C;IAC/C,OAAO,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,SAAS,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,kFAAkF;IAClF,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,OAAO,GAAG,SAAS,MAAM,QAAQ,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC","sourcesContent":["/**\n * Utility functions for name manipulation.\n */\nimport _ from 'lodash';\n\nconst PROTECTED_NAMES = ['$'];\n\nfunction capitaliseParts(cleanedPath: string, splitChar: string): string {\n // Split the string using a regular expression based on splitChar.\n const parts = cleanedPath.split(new RegExp(splitChar));\n let formattedPath = '';\n for (const part of parts) {\n if (part) {\n // Capitalize the first letter of each part\n formattedPath += upperFirst(part);\n }\n }\n return formattedPath;\n}\n\nfunction lowerFirst(s: string): string {\n if (!s) return s;\n return _.lowerFirst(s);\n}\n\nexport function genParamName(param: string): string {\n // Split on any run of non-alphanumeric characters, camelCase the parts, then guarantee\n // a valid GraphQL identifier: non-empty and not starting with a digit.\n const camel = lowerFirst(capitaliseParts(param || '', '[^A-Za-z0-9]+'));\n if (camel.length === 0) {\n return '_';\n }\n return /^[0-9]/.test(camel) ? '_' + camel : camel;\n}\n\n// Private helper; not exported.\nfunction formatPath(path: string, parameters: string[]): string {\n if (!path || path.length === 0) {\n return path;\n }\n // Remove parameters enclosed in `{}`.\n const cleanedPath = path.replace(/\\{[^}]*\\}/g, parameters.join(''));\n // First, capitalize parts split by \"[:\\-\\.]+\".\n const interim = capitaliseParts(cleanedPath, '[:\\\\-\\\\.]+');\n // Then, split by \"/\" and capitalize each part.\n return capitaliseParts(interim, '/');\n}\n\nexport function sanitiseField(name: string): string {\n const fieldName = name.startsWith('@') ? name.substring(1) : name;\n return genParamName(fieldName);\n}\n\nexport function sanitiseFieldForSelect(name: string): string {\n const fieldName = name.startsWith('@') ? name.substring(1) : name;\n const sanitised = genParamName(fieldName);\n if (sanitised === name && !isProtected(name)) {\n return sanitised;\n }\n // Alias: safe GraphQL field <- original JSON key, always quoted (it is not a bare\n // identifier — covers spaces, `$`, `%`, leading digits, etc.).\n const original = name.startsWith('@') ? name : fieldName;\n return `${sanitised}: \"${original}\"`;\n}\n\nexport function upperFirst(s: string): string {\n if (!s) return s;\n return _.upperFirst(s);\n}\n\nexport function genArrayItems(name: string): string {\n return upperFirst(genParamName(name)) + 'Item';\n}\n\nexport function isProtected(name: string): boolean {\n return PROTECTED_NAMES.includes(name);\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import { Composed } from '../nodes/comp.js';
|
|
3
|
-
import { Prop, PropArray, Scalar, T } from '../nodes/internal.js';
|
|
3
|
+
import { Prop, PropArray, PropCircRef, Scalar, T } from '../nodes/internal.js';
|
|
4
4
|
export class TypesCollector {
|
|
5
5
|
gen;
|
|
6
6
|
types = new Map();
|
|
@@ -135,6 +135,11 @@ class PathsCollector {
|
|
|
135
135
|
if (T.isPropScalar(child) || (child instanceof PropArray && child.items instanceof Scalar)) {
|
|
136
136
|
newSelection.add(child.path());
|
|
137
137
|
}
|
|
138
|
+
else if (child instanceof PropCircRef) {
|
|
139
|
+
// a cut cycle is a leaf: include its path so the commented field is emitted (in both the
|
|
140
|
+
// SDL and the selection) instead of silently dropped. see docs/issues.md #10
|
|
141
|
+
newSelection.add(child.path());
|
|
142
|
+
}
|
|
138
143
|
else {
|
|
139
144
|
this.gen.expand(child);
|
|
140
145
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typesCollector.js","sourceRoot":"","sources":["../../../src/oas/generator/typesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { Composed } from '../nodes/comp.js';\nimport { IType, Prop, PropArray, Scalar, T } from '../nodes/internal.js';\nimport { OasGen } from '../oasGen.js';\n\nexport class TypesCollector {\n types: Map<string, IType> = new Map();\n expanded: string[] = [];\n\n constructor(private gen: OasGen) {}\n\n public collect(selection: string[]): void {\n const pendingTypes: Map<string, IType> = new Map();\n let expanded: string[] = new PathsCollector(this.gen).collectExpandedPaths(selection);\n\n for (const path of expanded) {\n let collection = Array.from(this.gen.paths.values());\n let current: IType | undefined;\n let last: IType | undefined;\n\n let i = 0;\n const parts = path.split('>');\n do {\n const part = parts[i].replace(/#\\/c\\/s/g, '#/components/schemas');\n if (part === '*') {\n // remove the current path from the expanded array\n expanded = expanded.filter((s) => s !== path);\n\n if (current && current instanceof Composed) {\n current!.consolidate(expanded);\n }\n\n // add all the props from the current node and exit loop\n current?.props.forEach((child) => {\n if (T.isLeaf(child)) {\n expanded.push(child.path());\n }\n });\n break;\n }\n\n current = collection.find((t) => t.id === part);\n if (!current) {\n const tree = T.print(last!.ancestors()[0]);\n\n // let's collect the possible paths so we don't have to debug\n throw new Error(\n 'Could not find type: ' + part + ' from ' + path + '\\nlast:\\n' + last?.pathToRoot() + '\\ntree: ' + tree,\n );\n }\n\n // make sure we expand it before we move on to the next part\n this.gen.expand(current);\n last = current;\n\n collection = Array.from(current!.children.values()) || Array.from(current!.props.values()) || [];\n i++;\n } while (i < parts.length);\n\n // optional hook -- if the type in question has deps, add them here\n const deps: IType[] = _.invoke(current, 'dependencies', [this.gen.context]);\n if (deps) {\n deps\n .filter((i) => !pendingTypes.has(i.id))\n .forEach((i) => {\n pendingTypes.set(i.id, i);\n });\n }\n\n if (current && !(current instanceof Scalar)) {\n const parentType = T.findNonPropParent(current as IType);\n if (!pendingTypes.has(parentType.id)) {\n pendingTypes.set(parentType.id, parentType);\n }\n\n // add all ancestors (of the parent of the prop) that are containers so they are generated accordingly\n parentType\n .ancestors()\n .filter((t) => !pendingTypes.has(t.id) && T.isContainer(t))\n .forEach((dep) => {\n pendingTypes.set(dep.id, dep);\n });\n }\n }\n\n // first pass is to consolidate all Composed & Union nodes\n const composed: Array<Composed> = Array.from(pendingTypes.values())\n .filter((t) => t instanceof Composed)\n .map((t) => t as Composed);\n\n const context = this.gen.context!;\n for (const comp of composed) {\n if (!comp.visited) comp.visit(context);\n comp.consolidate(expanded).forEach((id) => pendingTypes.delete(id));\n }\n\n this.types = pendingTypes;\n this.expanded = expanded;\n }\n}\n\nclass PathsCollector {\n constructor(private gen: OasGen) {}\n\n public static findNonPropParent(type: IType) {\n let parent = type;\n while (parent instanceof Prop) {\n parent = parent.parent!;\n }\n return parent;\n }\n\n public static progressiveSplits(input: string): string[] {\n const parts = input.split('>');\n const results: string[] = [];\n for (let i = 1; i <= parts.length; i++) {\n results.push(parts.slice(0, i).join('>'));\n }\n return results;\n }\n\n public collectPaths(path: string, collection: IType[]): IType[] {\n const stack: IType[] = [];\n let current: IType | undefined;\n let last: IType | undefined;\n\n let i = 0;\n const parts = path.split('>');\n do {\n const part = parts[i].replace(/#\\/c\\/s/g, '#/components/schemas');\n\n current = collection.find((t) => t.id === part);\n if (!current) {\n throw new Error('Could not find type: ' + part + ' from ' + path + ', last: ' + last?.pathToRoot());\n }\n\n // make sure we expand it before we move on to the next part\n this.gen.expand(current);\n last = current;\n\n collection = Array.from(current!.children.values()) || Array.from(current!.props.values()) || [];\n\n stack.push(current);\n i++;\n } while (i < parts.length);\n\n return stack;\n }\n\n public collectExpandedPaths(selection: string[]) {\n const newSelection = new Set<string>();\n const expands = selection.filter((p) => p.endsWith('>**'));\n const filtered = expands.map((p) => p.replace('>**', ''));\n\n const paths = Array.from(this.gen.paths.values());\n const nodes = filtered.map((p) => this.collectPaths(p, paths));\n\n nodes.forEach((stack) => {\n const root = _.last(stack)!;\n T.traverse(root, (child) => {\n if (T.isPropScalar(child) || (child instanceof PropArray && child.items instanceof Scalar)) {\n newSelection.add(child.path());\n } else {\n this.gen.expand(child);\n }\n });\n });\n\n // finally remove the expanded paths from the selection\n return [...newSelection, ...selection.filter((p) => !expands.includes(p))];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"typesCollector.js","sourceRoot":"","sources":["../../../src/oas/generator/typesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { Composed } from '../nodes/comp.js';\nimport { IType, Prop, PropArray, PropCircRef, Scalar, T } from '../nodes/internal.js';\nimport { OasGen } from '../oasGen.js';\n\nexport class TypesCollector {\n types: Map<string, IType> = new Map();\n expanded: string[] = [];\n\n constructor(private gen: OasGen) {}\n\n public collect(selection: string[]): void {\n const pendingTypes: Map<string, IType> = new Map();\n let expanded: string[] = new PathsCollector(this.gen).collectExpandedPaths(selection);\n\n for (const path of expanded) {\n let collection = Array.from(this.gen.paths.values());\n let current: IType | undefined;\n let last: IType | undefined;\n\n let i = 0;\n const parts = path.split('>');\n do {\n const part = parts[i].replace(/#\\/c\\/s/g, '#/components/schemas');\n if (part === '*') {\n // remove the current path from the expanded array\n expanded = expanded.filter((s) => s !== path);\n\n if (current && current instanceof Composed) {\n current!.consolidate(expanded);\n }\n\n // add all the props from the current node and exit loop\n current?.props.forEach((child) => {\n if (T.isLeaf(child)) {\n expanded.push(child.path());\n }\n });\n break;\n }\n\n current = collection.find((t) => t.id === part);\n if (!current) {\n const tree = T.print(last!.ancestors()[0]);\n\n // let's collect the possible paths so we don't have to debug\n throw new Error(\n 'Could not find type: ' + part + ' from ' + path + '\\nlast:\\n' + last?.pathToRoot() + '\\ntree: ' + tree,\n );\n }\n\n // make sure we expand it before we move on to the next part\n this.gen.expand(current);\n last = current;\n\n collection = Array.from(current!.children.values()) || Array.from(current!.props.values()) || [];\n i++;\n } while (i < parts.length);\n\n // optional hook -- if the type in question has deps, add them here\n const deps: IType[] = _.invoke(current, 'dependencies', [this.gen.context]);\n if (deps) {\n deps\n .filter((i) => !pendingTypes.has(i.id))\n .forEach((i) => {\n pendingTypes.set(i.id, i);\n });\n }\n\n if (current && !(current instanceof Scalar)) {\n const parentType = T.findNonPropParent(current as IType);\n if (!pendingTypes.has(parentType.id)) {\n pendingTypes.set(parentType.id, parentType);\n }\n\n // add all ancestors (of the parent of the prop) that are containers so they are generated accordingly\n parentType\n .ancestors()\n .filter((t) => !pendingTypes.has(t.id) && T.isContainer(t))\n .forEach((dep) => {\n pendingTypes.set(dep.id, dep);\n });\n }\n }\n\n // first pass is to consolidate all Composed & Union nodes\n const composed: Array<Composed> = Array.from(pendingTypes.values())\n .filter((t) => t instanceof Composed)\n .map((t) => t as Composed);\n\n const context = this.gen.context!;\n for (const comp of composed) {\n if (!comp.visited) comp.visit(context);\n comp.consolidate(expanded).forEach((id) => pendingTypes.delete(id));\n }\n\n this.types = pendingTypes;\n this.expanded = expanded;\n }\n}\n\nclass PathsCollector {\n constructor(private gen: OasGen) {}\n\n public static findNonPropParent(type: IType) {\n let parent = type;\n while (parent instanceof Prop) {\n parent = parent.parent!;\n }\n return parent;\n }\n\n public static progressiveSplits(input: string): string[] {\n const parts = input.split('>');\n const results: string[] = [];\n for (let i = 1; i <= parts.length; i++) {\n results.push(parts.slice(0, i).join('>'));\n }\n return results;\n }\n\n public collectPaths(path: string, collection: IType[]): IType[] {\n const stack: IType[] = [];\n let current: IType | undefined;\n let last: IType | undefined;\n\n let i = 0;\n const parts = path.split('>');\n do {\n const part = parts[i].replace(/#\\/c\\/s/g, '#/components/schemas');\n\n current = collection.find((t) => t.id === part);\n if (!current) {\n throw new Error('Could not find type: ' + part + ' from ' + path + ', last: ' + last?.pathToRoot());\n }\n\n // make sure we expand it before we move on to the next part\n this.gen.expand(current);\n last = current;\n\n collection = Array.from(current!.children.values()) || Array.from(current!.props.values()) || [];\n\n stack.push(current);\n i++;\n } while (i < parts.length);\n\n return stack;\n }\n\n public collectExpandedPaths(selection: string[]) {\n const newSelection = new Set<string>();\n const expands = selection.filter((p) => p.endsWith('>**'));\n const filtered = expands.map((p) => p.replace('>**', ''));\n\n const paths = Array.from(this.gen.paths.values());\n const nodes = filtered.map((p) => this.collectPaths(p, paths));\n\n nodes.forEach((stack) => {\n const root = _.last(stack)!;\n T.traverse(root, (child) => {\n if (T.isPropScalar(child) || (child instanceof PropArray && child.items instanceof Scalar)) {\n newSelection.add(child.path());\n } else if (child instanceof PropCircRef) {\n // a cut cycle is a leaf: include its path so the commented field is emitted (in both the\n // SDL and the selection) instead of silently dropped. see docs/issues.md #10\n newSelection.add(child.path());\n } else {\n this.gen.expand(child);\n }\n });\n });\n\n // finally remove the expanded paths from the selection\n return [...newSelection, ...selection.filter((p) => !expands.includes(p))];\n }\n}\n"]}
|
|
@@ -8,6 +8,8 @@ export declare class OperationWriter {
|
|
|
8
8
|
writeQuery(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void;
|
|
9
9
|
writeMutations(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void;
|
|
10
10
|
writeConnector(context: OasContext, writer: Writer, type: IType, selection: string[]): void;
|
|
11
|
+
private writeErrors;
|
|
12
|
+
private hasDocumentedErrors;
|
|
11
13
|
private requestMethod;
|
|
12
14
|
private writeSelection;
|
|
13
15
|
private writeBodySelection;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import { Naming } from '../utils/naming.js';
|
|
3
|
+
import { DEFAULT_VERSIONS, meetsMinimum } from '../../versions.js';
|
|
4
|
+
import { warn } from '../log/trace.js';
|
|
3
5
|
export class OperationWriter {
|
|
4
6
|
gen;
|
|
5
7
|
constructor(gen) {
|
|
@@ -45,13 +47,43 @@ export class OperationWriter {
|
|
|
45
47
|
this.writeSelection(context, writer, _.get(op, 'resultType'), selection);
|
|
46
48
|
}
|
|
47
49
|
writer.write(spacing).write('"""\n');
|
|
50
|
+
this.writeErrors(context, writer, op, indent);
|
|
48
51
|
spacing = ' '.repeat(indent + 4);
|
|
49
52
|
writer.write(spacing).write(')\n');
|
|
50
53
|
}
|
|
54
|
+
// R4 (opt-in): emit `errors: { extensions: """statusCode: $status""" }` to surface the HTTP status
|
|
55
|
+
// in the GraphQL error extensions, for operations that document HTTP error responses. errors is a
|
|
56
|
+
// connect v0.2+ feature; below that we skip with a logged downgrade rather than emit invalid output.
|
|
57
|
+
writeErrors(context, writer, op, indent) {
|
|
58
|
+
if (!context.generateOptions?.emitConnectorErrors || !this.hasDocumentedErrors(op)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const version = this.gen.options.connectorSpecVersion || DEFAULT_VERSIONS.connectorSpecVersion;
|
|
62
|
+
if (!meetsMinimum(version, 'v0.2')) {
|
|
63
|
+
warn(context, '[errors]', `@connect(errors:) requires connect v0.2, but target is ${version} — not emitted for ${op.verb} ${op.operation.path}`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const outer = ' '.repeat(indent + 6);
|
|
67
|
+
const inner = ' '.repeat(indent + 6);
|
|
68
|
+
writer
|
|
69
|
+
.write(outer)
|
|
70
|
+
.write('errors: { extensions: """\n')
|
|
71
|
+
.write(inner)
|
|
72
|
+
.write('statusCode: $status\n')
|
|
73
|
+
.write(outer)
|
|
74
|
+
.write('""" }\n');
|
|
75
|
+
}
|
|
76
|
+
// True when the operation documents an HTTP error response. Accepts both concrete numeric statuses
|
|
77
|
+
// (4xx/5xx) and the OAS range keys `4XX`/`5XX` (case-insensitive). The `default` key is excluded —
|
|
78
|
+
// it also covers 2xx/3xx, so it is not specifically an error indicator.
|
|
79
|
+
hasDocumentedErrors(op) {
|
|
80
|
+
return op.operation.getResponseStatusCodes().some((code) => /^[45](\d\d|XX)$/i.test(code));
|
|
81
|
+
}
|
|
51
82
|
requestMethod(context, writer, op, selection, indent) {
|
|
52
|
-
//
|
|
83
|
+
// template each {elem} as {$args.<sanitised>} (the arg name), not the raw OAS key. see docs/issues.md #2
|
|
53
84
|
const verb = op.verb;
|
|
54
|
-
|
|
85
|
+
const templatedPath = op.operation.path.replace(/\{([^}]+)\}/g, (_m, name) => `{$args.${Naming.genParamName(name)}}`);
|
|
86
|
+
writer.write(`{ ${verb}: `).write('"' + templatedPath + '"');
|
|
55
87
|
if (op.params.length > 0) {
|
|
56
88
|
// we now include all query params, not just required ones. if they are not set,
|
|
57
89
|
// then the connectors will not include them in the request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operationWriter.js","sourceRoot":"","sources":["../../../src/oas/io/operationWriter.ts"],"names":[],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { OasContext } from '../oasContext.js';\nimport { OasGen } from '../oasGen.js';\nimport { Body, IType, Op, Param, Type } from '../nodes/internal.js';\nimport { Naming } from '../utils/naming.js';\nimport { Writer } from './writer.js';\n\nexport class OperationWriter {\n constructor(private gen: OasGen) {}\n\n public writeQuery(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void {\n const selectionSet = new Set<string>(selection.map((s) => s.split('>')[0]));\n\n const paths = Array.from(collected.values()).filter((path) => selectionSet.has(path.id));\n if (_.isEmpty(paths)) return;\n\n writer.write('type Query {\\n');\n\n for (const path of paths) {\n path.generate(context, writer, []);\n this.writeConnector(context, writer, path, selection);\n context.generatedSet.add(path.id);\n }\n\n writer.write('}\\n\\n');\n }\n\n public writeMutations(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void {\n const selectionSet = new Set<string>(selection.map((s) => s.split('>')[0]));\n\n const paths = Array.from(collected.values()).filter((path) => selectionSet.has(path.id));\n if (_.isEmpty(paths)) return;\n\n writer.write('type Mutation {\\n');\n\n for (const path of paths) {\n path.generate(context, writer, []);\n this.writeConnector(context, writer, path, selection);\n context.generatedSet.add(path.id);\n }\n\n writer.write('}\\n\\n');\n }\n\n public writeConnector(context: OasContext, writer: Writer, type: IType, selection: string[]): void {\n const indent = 0;\n const op = type as unknown as Op; // assume type is GetOp\n let spacing = ' '.repeat(indent + 4);\n writer.write(spacing).write('@connect(\\n');\n\n spacing = ' '.repeat(indent + 6);\n writer.write(spacing).write('source: \"api\"\\n').write(spacing).write('http: ');\n\n this.requestMethod(context, writer, op, selection, indent);\n\n writer.write('\\n').write(spacing).write('selection: \"\"\"\\n');\n\n if (_.has(op, 'resultType')) {\n // scalar types don't need to be generated?\n this.writeSelection(context, writer, _.get(op, 'resultType') as Type, selection);\n }\n\n writer.write(spacing).write('\"\"\"\\n');\n spacing = ' '.repeat(indent + 4);\n writer.write(spacing).write(')\\n');\n }\n\n private requestMethod(context: OasContext, writer: Writer, op: Op, selection: string[], indent: number): void {\n // replace every {elem} in the path for {$args.elem}\n const verb = op.verb;\n writer.write(`{ ${verb}: `).write('\"' + op.operation.path.replace(/\\{([a-zA-Z0-9]+)\\}/g, '{$args.$1}') + '\"');\n\n if (op.params.length > 0) {\n // we now include all query params, not just required ones. if they are not set,\n // then the connectors will not include them in the request.\n let queryParams = op.params.filter((p: Param) => {\n return p.parameter.in && p.parameter.in.toLowerCase() === 'query';\n });\n\n // Skip optional params if skipOptionalArgs is true\n if (context.generateOptions?.skipOptionalArgs) {\n queryParams = queryParams.filter((p: Param) => p.required);\n }\n\n if (queryParams.length > 0) {\n writer.write('\\n');\n let spacing = ' '.repeat(6);\n\n writer.write(spacing).write(`queryParams: \"\"\"\\n`);\n spacing = ' '.repeat(8);\n writer.write(spacing).write(`$args {\\n`);\n spacing = ' '.repeat(10);\n for (const p of queryParams) {\n writer.write(spacing).write(`\"${p.name}\": ${Naming.genParamName(p.name)}\\n`);\n }\n spacing = ' '.repeat(8);\n writer.write(spacing).write('}\\n');\n spacing = ' '.repeat(6);\n writer.write(spacing).write('\"\"\"\\n');\n }\n\n const headers = op.operation.getParameters().filter((p) => p.in && p.in.toLowerCase() === 'header');\n\n if (headers.length > 0) {\n let spacing = ' '.repeat(6);\n writer.write(spacing + 'headers: [\\n');\n spacing = ' '.repeat(8);\n\n for (const p of headers) {\n let value: string | null = null;\n\n if (p.example != null) {\n value = p.example.toString();\n }\n\n if (p.examples && Object.keys(p.examples).length > 0) {\n value = Object.keys(p.examples).join(',');\n }\n\n if (value == null) {\n value = '<placeholder>';\n }\n\n writer.write(spacing + `{ name: \"${p.name}\", value: \"${value}\" }\\n`);\n }\n\n spacing = ' '.repeat(6);\n writer.write(spacing + ']');\n }\n }\n\n if (_.has(op, 'body')) {\n const body = op.body as Body;\n this.writeBodySelection(context, writer, body, selection);\n }\n\n writer.write('}');\n }\n\n private writeSelection(context: OasContext, writer: Writer, type: IType, selection: string[]): void {\n context.indent = 6;\n type.select(context, writer, selection);\n }\n\n private writeBodySelection(context: OasContext, writer: Writer, body: Body, selection: string[]): void {\n writer.write(',\\n');\n context.indent = 6;\n if (body) {\n body.select(context, writer, selection);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"operationWriter.js","sourceRoot":"","sources":["../../../src/oas/io/operationWriter.ts"],"names":[],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { OasContext } from '../oasContext.js';\nimport { OasGen } from '../oasGen.js';\nimport { Body, IType, Op, Param, Type } from '../nodes/internal.js';\nimport { Naming } from '../utils/naming.js';\nimport { Writer } from './writer.js';\nimport { DEFAULT_VERSIONS, meetsMinimum } from '../../versions.js';\nimport { warn } from '../log/trace.js';\n\nexport class OperationWriter {\n constructor(private gen: OasGen) {}\n\n public writeQuery(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void {\n const selectionSet = new Set<string>(selection.map((s) => s.split('>')[0]));\n\n const paths = Array.from(collected.values()).filter((path) => selectionSet.has(path.id));\n if (_.isEmpty(paths)) return;\n\n writer.write('type Query {\\n');\n\n for (const path of paths) {\n path.generate(context, writer, []);\n this.writeConnector(context, writer, path, selection);\n context.generatedSet.add(path.id);\n }\n\n writer.write('}\\n\\n');\n }\n\n public writeMutations(context: OasContext, writer: Writer, collected: Map<string, IType>, selection: string[]): void {\n const selectionSet = new Set<string>(selection.map((s) => s.split('>')[0]));\n\n const paths = Array.from(collected.values()).filter((path) => selectionSet.has(path.id));\n if (_.isEmpty(paths)) return;\n\n writer.write('type Mutation {\\n');\n\n for (const path of paths) {\n path.generate(context, writer, []);\n this.writeConnector(context, writer, path, selection);\n context.generatedSet.add(path.id);\n }\n\n writer.write('}\\n\\n');\n }\n\n public writeConnector(context: OasContext, writer: Writer, type: IType, selection: string[]): void {\n const indent = 0;\n const op = type as unknown as Op; // assume type is GetOp\n let spacing = ' '.repeat(indent + 4);\n writer.write(spacing).write('@connect(\\n');\n\n spacing = ' '.repeat(indent + 6);\n writer.write(spacing).write('source: \"api\"\\n').write(spacing).write('http: ');\n\n this.requestMethod(context, writer, op, selection, indent);\n\n writer.write('\\n').write(spacing).write('selection: \"\"\"\\n');\n\n if (_.has(op, 'resultType')) {\n // scalar types don't need to be generated?\n this.writeSelection(context, writer, _.get(op, 'resultType') as Type, selection);\n }\n\n writer.write(spacing).write('\"\"\"\\n');\n\n this.writeErrors(context, writer, op, indent);\n\n spacing = ' '.repeat(indent + 4);\n writer.write(spacing).write(')\\n');\n }\n\n // R4 (opt-in): emit `errors: { extensions: \"\"\"statusCode: $status\"\"\" }` to surface the HTTP status\n // in the GraphQL error extensions, for operations that document HTTP error responses. errors is a\n // connect v0.2+ feature; below that we skip with a logged downgrade rather than emit invalid output.\n private writeErrors(context: OasContext, writer: Writer, op: Op, indent: number): void {\n if (!context.generateOptions?.emitConnectorErrors || !this.hasDocumentedErrors(op)) {\n return;\n }\n\n const version = this.gen.options.connectorSpecVersion || DEFAULT_VERSIONS.connectorSpecVersion;\n if (!meetsMinimum(version, 'v0.2')) {\n warn(\n context,\n '[errors]',\n `@connect(errors:) requires connect v0.2, but target is ${version} — not emitted for ${op.verb} ${op.operation.path}`,\n );\n return;\n }\n\n const outer = ' '.repeat(indent + 6);\n const inner = ' '.repeat(indent + 6);\n writer\n .write(outer)\n .write('errors: { extensions: \"\"\"\\n')\n .write(inner)\n .write('statusCode: $status\\n')\n .write(outer)\n .write('\"\"\" }\\n');\n }\n\n // True when the operation documents an HTTP error response. Accepts both concrete numeric statuses\n // (4xx/5xx) and the OAS range keys `4XX`/`5XX` (case-insensitive). The `default` key is excluded —\n // it also covers 2xx/3xx, so it is not specifically an error indicator.\n private hasDocumentedErrors(op: Op): boolean {\n return op.operation.getResponseStatusCodes().some((code: string) => /^[45](\\d\\d|XX)$/i.test(code));\n }\n\n private requestMethod(context: OasContext, writer: Writer, op: Op, selection: string[], indent: number): void {\n // template each {elem} as {$args.<sanitised>} (the arg name), not the raw OAS key. see docs/issues.md #2\n const verb = op.verb;\n const templatedPath = op.operation.path.replace(\n /\\{([^}]+)\\}/g,\n (_m, name) => `{$args.${Naming.genParamName(name)}}`,\n );\n writer.write(`{ ${verb}: `).write('\"' + templatedPath + '\"');\n\n if (op.params.length > 0) {\n // we now include all query params, not just required ones. if they are not set,\n // then the connectors will not include them in the request.\n let queryParams = op.params.filter((p: Param) => {\n return p.parameter.in && p.parameter.in.toLowerCase() === 'query';\n });\n\n // Skip optional params if skipOptionalArgs is true\n if (context.generateOptions?.skipOptionalArgs) {\n queryParams = queryParams.filter((p: Param) => p.required);\n }\n\n if (queryParams.length > 0) {\n writer.write('\\n');\n let spacing = ' '.repeat(6);\n\n writer.write(spacing).write(`queryParams: \"\"\"\\n`);\n spacing = ' '.repeat(8);\n writer.write(spacing).write(`$args {\\n`);\n spacing = ' '.repeat(10);\n for (const p of queryParams) {\n writer.write(spacing).write(`\"${p.name}\": ${Naming.genParamName(p.name)}\\n`);\n }\n spacing = ' '.repeat(8);\n writer.write(spacing).write('}\\n');\n spacing = ' '.repeat(6);\n writer.write(spacing).write('\"\"\"\\n');\n }\n\n const headers = op.operation.getParameters().filter((p) => p.in && p.in.toLowerCase() === 'header');\n\n if (headers.length > 0) {\n let spacing = ' '.repeat(6);\n writer.write(spacing + 'headers: [\\n');\n spacing = ' '.repeat(8);\n\n for (const p of headers) {\n let value: string | null = null;\n\n if (p.example != null) {\n value = p.example.toString();\n }\n\n if (p.examples && Object.keys(p.examples).length > 0) {\n value = Object.keys(p.examples).join(',');\n }\n\n if (value == null) {\n value = '<placeholder>';\n }\n\n writer.write(spacing + `{ name: \"${p.name}\", value: \"${value}\" }\\n`);\n }\n\n spacing = ' '.repeat(6);\n writer.write(spacing + ']');\n }\n }\n\n if (_.has(op, 'body')) {\n const body = op.body as Body;\n this.writeBodySelection(context, writer, body, selection);\n }\n\n writer.write('}');\n }\n\n private writeSelection(context: OasContext, writer: Writer, type: IType, selection: string[]): void {\n context.indent = 6;\n type.select(context, writer, selection);\n }\n\n private writeBodySelection(context: OasContext, writer: Writer, body: Body, selection: string[]): void {\n writer.write(',\\n');\n context.indent = 6;\n if (body) {\n body.select(context, writer, selection);\n }\n }\n}\n"]}
|
|
@@ -5,5 +5,18 @@ export declare class SchemaWriter {
|
|
|
5
5
|
constructor(gen: OasGen);
|
|
6
6
|
writeJSONScalar(writer: Writer): void;
|
|
7
7
|
writeDirectives(writer: Writer): void;
|
|
8
|
+
/**
|
|
9
|
+
* R5 (slice 1): derive an `@source`-level auth header from the spec's *global*
|
|
10
|
+
* security requirement. Returns the header literal (e.g.
|
|
11
|
+
* `{ name: "Authorization", value: "Bearer {$config.token}" }`) or null when no
|
|
12
|
+
* header should be emitted. Everything deferred is warned about, never silently dropped.
|
|
13
|
+
*/
|
|
14
|
+
private securityHeader;
|
|
15
|
+
/** Map a single security scheme to its `@source` header literal, or null when it produces no header. */
|
|
16
|
+
private mapScheme;
|
|
17
|
+
/** Build a loud warning for a scheme that was not emitted on `@source`. */
|
|
18
|
+
private dropWarning;
|
|
19
|
+
/** Returns "METHOD /path" for every operation that declares its own `security` (including `security: []`). */
|
|
20
|
+
private operationsWithSecurity;
|
|
8
21
|
private getServerUrl;
|
|
9
22
|
}
|
|
@@ -12,16 +12,133 @@ export class SchemaWriter {
|
|
|
12
12
|
const host = this.getServerUrl(api.getDefinition().servers?.[0]);
|
|
13
13
|
const federationVersion = this.gen.options.federationVersion || DEFAULT_VERSIONS.federationVersion;
|
|
14
14
|
const connectorSpecVersion = this.gen.options.connectorSpecVersion || DEFAULT_VERSIONS.connectorSpecVersion;
|
|
15
|
+
const authHeader = this.securityHeader(api);
|
|
15
16
|
writer
|
|
16
17
|
.write('extend schema\n')
|
|
17
18
|
.write(` @link(url: "https://specs.apollo.dev/federation/${federationVersion}", import: ["@key"])\n`)
|
|
18
19
|
.write(' @link(\n')
|
|
19
20
|
.write(` url: "https://specs.apollo.dev/connect/${connectorSpecVersion}"\n`)
|
|
20
21
|
.write(' import: ["@connect", "@source"]\n')
|
|
21
|
-
.write(' )\n')
|
|
22
|
-
|
|
23
|
-
.write(host)
|
|
24
|
-
|
|
22
|
+
.write(' )\n');
|
|
23
|
+
if (authHeader) {
|
|
24
|
+
writer.write(` @source(name: "api", http: { baseURL: "${host}", headers: [${authHeader}] })\n\n`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
writer.write(' @source(name: "api", http: { baseURL: "').write(host).write('" })\n\n');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* R5 (slice 1): derive an `@source`-level auth header from the spec's *global*
|
|
32
|
+
* security requirement. Returns the header literal (e.g.
|
|
33
|
+
* `{ name: "Authorization", value: "Bearer {$config.token}" }`) or null when no
|
|
34
|
+
* header should be emitted. Everything deferred is warned about, never silently dropped.
|
|
35
|
+
*/
|
|
36
|
+
securityHeader(api) {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
const def = api.getDefinition();
|
|
39
|
+
const global = def.security;
|
|
40
|
+
// OAS3 components.securitySchemes, falling back to Swagger 2.0 securityDefinitions
|
|
41
|
+
// (oas-normalize usually up-converts, but keep the fallback for safety).
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
const schemes = (def.components?.securitySchemes ?? def.securityDefinitions ?? {});
|
|
44
|
+
// Concern-2 guard: a per-operation `security` (including anonymous `security: []`)
|
|
45
|
+
// *replaces* the global requirement, so the requirement is not uniform across
|
|
46
|
+
// endpoints. A shared @source header would wrongly attach auth to overriding
|
|
47
|
+
// endpoints — emit nothing and warn per affected operation. Checked before the
|
|
48
|
+
// global guard so per-op-only specs (e.g. petstore) still warn loudly.
|
|
49
|
+
const overriding = this.operationsWithSecurity(api);
|
|
50
|
+
if (overriding.length > 0) {
|
|
51
|
+
for (const op of overriding) {
|
|
52
|
+
console.warn(`[security] operation ${op} declares its own \`security\`; not emitting a global @source auth header (per-operation auth deferred to a future slice).`);
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
// No global requirement → keep the current headerless @source byte-for-byte.
|
|
57
|
+
if (!global || global.length === 0) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
// Flatten the global requirement to referenced scheme names, in order: across
|
|
61
|
+
// requirement objects (logical OR) and within each object (logical AND).
|
|
62
|
+
const names = [];
|
|
63
|
+
for (const req of global) {
|
|
64
|
+
for (const name of Object.keys(req)) {
|
|
65
|
+
names.push(name);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Pick the first scheme that maps to a header; warn about every other scheme.
|
|
69
|
+
let header = null;
|
|
70
|
+
for (const name of names) {
|
|
71
|
+
const scheme = schemes[name];
|
|
72
|
+
const mapped = scheme ? this.mapScheme(scheme) : null;
|
|
73
|
+
if (mapped && !header) {
|
|
74
|
+
header = mapped;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.warn(this.dropWarning(name, scheme));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!header) {
|
|
81
|
+
console.warn(`[security] global security requirement (${names.join(', ')}) maps to no header-producing scheme; no auth header emitted on @source.`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return header;
|
|
85
|
+
}
|
|
86
|
+
/** Map a single security scheme to its `@source` header literal, or null when it produces no header. */
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
+
mapScheme(scheme) {
|
|
89
|
+
switch (scheme.type) {
|
|
90
|
+
case 'apiKey':
|
|
91
|
+
if (scheme.in === 'header' && scheme.name) {
|
|
92
|
+
return `{ name: "${scheme.name}", value: "{$config.apiKey}" }`;
|
|
93
|
+
}
|
|
94
|
+
return null; // query / cookie handled via warnings
|
|
95
|
+
case 'http':
|
|
96
|
+
if (scheme.scheme === 'bearer') {
|
|
97
|
+
return `{ name: "Authorization", value: "Bearer {$config.token}" }`;
|
|
98
|
+
}
|
|
99
|
+
if (scheme.scheme === 'basic') {
|
|
100
|
+
return `{ name: "Authorization", value: "Basic {$config.token}" }`;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
case 'oauth2':
|
|
104
|
+
case 'openIdConnect':
|
|
105
|
+
return `{ name: "Authorization", value: "Bearer {$config.token}" }`;
|
|
106
|
+
default:
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Build a loud warning for a scheme that was not emitted on `@source`. */
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
112
|
+
dropWarning(name, scheme) {
|
|
113
|
+
if (!scheme) {
|
|
114
|
+
return `[security] scheme "${name}" is referenced by global security but not defined; skipped.`;
|
|
115
|
+
}
|
|
116
|
+
if (scheme.type === 'apiKey' && scheme.in === 'query') {
|
|
117
|
+
return `[security] scheme "${name}" is apiKey in query — not emitted as a header (query-param auth deferred).`;
|
|
118
|
+
}
|
|
119
|
+
if (scheme.type === 'apiKey' && scheme.in === 'cookie') {
|
|
120
|
+
return `[security] scheme "${name}" is apiKey in cookie — not emitted as a header (cookie auth deferred).`;
|
|
121
|
+
}
|
|
122
|
+
return `[security] scheme "${name}" (${scheme.type}) not emitted — only the first header-producing scheme of the global requirement is mapped on @source.`;
|
|
123
|
+
}
|
|
124
|
+
/** Returns "METHOD /path" for every operation that declares its own `security` (including `security: []`). */
|
|
125
|
+
operationsWithSecurity(api) {
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
+
const paths = api.getDefinition().paths ?? {};
|
|
128
|
+
const methods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
|
|
129
|
+
const result = [];
|
|
130
|
+
for (const p of Object.keys(paths)) {
|
|
131
|
+
const item = paths[p];
|
|
132
|
+
if (!item)
|
|
133
|
+
continue;
|
|
134
|
+
for (const m of methods) {
|
|
135
|
+
const op = item[m];
|
|
136
|
+
if (op && Object.prototype.hasOwnProperty.call(op, 'security')) {
|
|
137
|
+
result.push(`${m.toUpperCase()} ${p}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
25
142
|
}
|
|
26
143
|
getServerUrl(server) {
|
|
27
144
|
if (!server) {
|