@warlock.js/core 5.27.0 → 5.29.0

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.
Files changed (127) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/esm/cli/commands/openapi-generator.action.mjs +1 -1
  3. package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
  4. package/esm/cli/commands/postman-generator.action.mjs +47 -0
  5. package/esm/cli/commands/postman-generator.action.mjs.map +1 -0
  6. package/esm/cli/commands/postman-generator.command.mjs +43 -0
  7. package/esm/cli/commands/postman-generator.command.mjs.map +1 -0
  8. package/esm/cli/framework-cli-commands.mjs +2 -0
  9. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  10. package/esm/container/development-app-modules.d.mts +31 -0
  11. package/esm/container/development-app-modules.d.mts.map +1 -0
  12. package/esm/container/index.d.mts +2 -0
  13. package/esm/container/index.d.mts.map +1 -1
  14. package/esm/container/index.mjs.map +1 -1
  15. package/esm/dev-server/app-module-registry.mjs +52 -0
  16. package/esm/dev-server/app-module-registry.mjs.map +1 -0
  17. package/esm/dev-server/files-orchestrator.mjs +13 -2
  18. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  19. package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
  20. package/esm/http/middleware/inject-request-context.mjs +29 -3
  21. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  22. package/esm/http/request.d.mts +2 -2
  23. package/esm/http/request.d.mts.map +1 -1
  24. package/esm/index.d.mts +7 -2
  25. package/esm/index.mjs +5 -2
  26. package/esm/localization/parse-locale-dictionary.d.mts +6 -1
  27. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  28. package/esm/localization/parse-locale-dictionary.mjs +5 -1
  29. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  30. package/esm/openapi/development-openapi-provider.d.mts +12 -1
  31. package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
  32. package/esm/openapi/development-openapi-provider.mjs +15 -1
  33. package/esm/openapi/development-openapi-provider.mjs.map +1 -1
  34. package/esm/openapi/index.d.mts +5 -2
  35. package/esm/openapi/index.mjs +3 -1
  36. package/esm/openapi/postman/build-request-body.mjs +86 -0
  37. package/esm/openapi/postman/build-request-body.mjs.map +1 -0
  38. package/esm/openapi/postman/build-request-url.mjs +85 -0
  39. package/esm/openapi/postman/build-request-url.mjs.map +1 -0
  40. package/esm/openapi/postman/build-saved-responses.mjs +60 -0
  41. package/esm/openapi/postman/build-saved-responses.mjs.map +1 -0
  42. package/esm/openapi/postman/example-from-schema.d.mts +17 -0
  43. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -0
  44. package/esm/openapi/postman/example-from-schema.mjs +92 -0
  45. package/esm/openapi/postman/example-from-schema.mjs.map +1 -0
  46. package/esm/openapi/postman/http-status-text.mjs +31 -0
  47. package/esm/openapi/postman/http-status-text.mjs.map +1 -0
  48. package/esm/openapi/postman/index.d.mts +3 -0
  49. package/esm/openapi/postman/openapi-to-postman-collection.d.mts +22 -0
  50. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -0
  51. package/esm/openapi/postman/openapi-to-postman-collection.mjs +109 -0
  52. package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -0
  53. package/esm/openapi/postman/postman-types.d.mts +119 -0
  54. package/esm/openapi/postman/postman-types.d.mts.map +1 -0
  55. package/esm/openapi/postman/resolve-operation-auth.mjs +51 -0
  56. package/esm/openapi/postman/resolve-operation-auth.mjs.map +1 -0
  57. package/esm/openapi/postman/schema-refs.d.mts +7 -0
  58. package/esm/openapi/postman/schema-refs.d.mts.map +1 -0
  59. package/esm/openapi/postman/schema-refs.mjs +41 -0
  60. package/esm/openapi/postman/schema-refs.mjs.map +1 -0
  61. package/esm/openapi/postman/uuid-v5.mjs +29 -0
  62. package/esm/openapi/postman/uuid-v5.mjs.map +1 -0
  63. package/esm/openapi/response-schemas.mjs +4 -1
  64. package/esm/openapi/response-schemas.mjs.map +1 -1
  65. package/esm/openapi/schema-registry.mjs +6 -0
  66. package/esm/openapi/schema-registry.mjs.map +1 -1
  67. package/esm/resource/index.d.mts +1 -0
  68. package/esm/resource/index.mjs +1 -0
  69. package/esm/resource/nullable-resource.d.mts +44 -0
  70. package/esm/resource/nullable-resource.d.mts.map +1 -0
  71. package/esm/resource/nullable-resource.mjs +38 -0
  72. package/esm/resource/nullable-resource.mjs.map +1 -0
  73. package/esm/resource/resource.d.mts.map +1 -1
  74. package/esm/resource/resource.mjs +24 -7
  75. package/esm/resource/resource.mjs.map +1 -1
  76. package/esm/resource/types.d.mts +10 -5
  77. package/esm/resource/types.d.mts.map +1 -1
  78. package/esm/restful/restful.d.mts +5 -5
  79. package/esm/restful/restful.d.mts.map +1 -1
  80. package/esm/router/response-schema-types.mjs +2 -0
  81. package/esm/router/response-schema-types.mjs.map +1 -1
  82. package/llms-full.txt +269 -241
  83. package/llms.txt +42 -42
  84. package/package.json +12 -12
  85. package/skills/README.md +39 -39
  86. package/skills/add-connector/SKILL.md +4 -4
  87. package/skills/benchmark-code/SKILL.md +3 -3
  88. package/skills/build-restful/SKILL.md +5 -5
  89. package/skills/build-url/SKILL.md +7 -7
  90. package/skills/configure-app/SKILL.md +7 -7
  91. package/skills/create-controller/SKILL.md +8 -8
  92. package/skills/create-module/SKILL.md +9 -9
  93. package/skills/define-resource/SKILL.md +4 -4
  94. package/skills/encrypt-data/SKILL.md +7 -7
  95. package/skills/generate-openapi/SKILL.md +33 -5
  96. package/skills/hash-password/SKILL.md +8 -8
  97. package/skills/health-checks/SKILL.md +6 -6
  98. package/skills/lower-stage3-decorators/SKILL.md +4 -4
  99. package/skills/process-image/SKILL.md +5 -5
  100. package/skills/register-route/SKILL.md +6 -6
  101. package/skills/request-memo/SKILL.md +4 -4
  102. package/skills/request-tracing/SKILL.md +6 -6
  103. package/skills/resolve-path/SKILL.md +6 -6
  104. package/skills/retry-operation/SKILL.md +4 -4
  105. package/skills/run-app/SKILL.md +11 -11
  106. package/skills/send-mail/SKILL.md +3 -3
  107. package/skills/send-response/SKILL.md +6 -6
  108. package/skills/store-file/SKILL.md +4 -4
  109. package/skills/test-http/SKILL.md +5 -5
  110. package/skills/test-service/SKILL.md +5 -5
  111. package/skills/update-packages/SKILL.md +6 -6
  112. package/skills/upload-file/SKILL.md +7 -7
  113. package/skills/use-app-context/SKILL.md +7 -7
  114. package/skills/use-localization/SKILL.md +6 -6
  115. package/skills/use-middleware/SKILL.md +6 -6
  116. package/skills/use-model-transformers/SKILL.md +6 -6
  117. package/skills/use-repository/SKILL.md +7 -7
  118. package/skills/use-request-locals/SKILL.md +4 -4
  119. package/skills/validate-input/SKILL.md +7 -7
  120. package/skills/warlock-conventions/SKILL.md +6 -6
  121. package/skills/warlock-doctor/SKILL.md +5 -5
  122. package/skills/warlock-routes/SKILL.md +6 -6
  123. package/skills/wire-socket/SKILL.md +4 -4
  124. package/skills/write-cli-command/SKILL.md +6 -6
  125. package/skills/write-middleware/SKILL.md +8 -8
  126. package/skills/write-seeder/SKILL.md +5 -5
  127. package/skills/write-use-case/SKILL.md +3 -3
@@ -0,0 +1,60 @@
1
+ import { exampleFromSchema } from "./example-from-schema.mjs";
2
+ import { httpStatusText } from "./http-status-text.mjs";
3
+
4
+ //#region ../core/src/openapi/postman/build-saved-responses.ts
5
+ function previewLanguage(contentType) {
6
+ if (contentType === "application/json" || contentType.endsWith("+json")) return "json";
7
+ return contentType === "text/html" ? "html" : "text";
8
+ }
9
+ function stringExample(example) {
10
+ return typeof example === "string" ? example : "";
11
+ }
12
+ function responseBody(content, components) {
13
+ const contentTypes = Object.keys(content);
14
+ const contentType = contentTypes.find((type) => previewLanguage(type) === "json") ?? contentTypes[0];
15
+ const schema = contentType !== void 0 ? content[contentType]?.schema : void 0;
16
+ if (contentType === void 0 || schema === void 0) return {
17
+ body: "",
18
+ header: [],
19
+ language: "text"
20
+ };
21
+ const language = previewLanguage(contentType);
22
+ const example = exampleFromSchema(schema, components);
23
+ return {
24
+ body: language === "json" ? JSON.stringify(example, null, 2) : stringExample(example),
25
+ header: [{
26
+ key: "Content-Type",
27
+ value: contentType,
28
+ type: "text"
29
+ }],
30
+ language
31
+ };
32
+ }
33
+ /**
34
+ * One saved Postman response per declared numeric status, with an example body from the
35
+ * response schema. `default` and range keys (`2XX`) have no single status code and are skipped.
36
+ */
37
+ function buildSavedResponses(responses, originalRequest, components) {
38
+ return Object.entries(responses).flatMap(([status, response]) => {
39
+ if (!/^\d{3}$/.test(status)) return [];
40
+ const code = Number(status);
41
+ const { body, header, language } = response.content ? responseBody(response.content, components) : {
42
+ body: "",
43
+ header: [],
44
+ language: "text"
45
+ };
46
+ return [{
47
+ name: `${status} ${response.description}`,
48
+ originalRequest,
49
+ status: httpStatusText(code, response.description),
50
+ code,
51
+ _postman_previewlanguage: language,
52
+ header,
53
+ body
54
+ }];
55
+ });
56
+ }
57
+
58
+ //#endregion
59
+ export { buildSavedResponses };
60
+ //# sourceMappingURL=build-saved-responses.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-saved-responses.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/build-saved-responses.ts"],"sourcesContent":["import type { OpenApiOperation } from \"../types\";\nimport { exampleFromSchema } from \"./example-from-schema\";\nimport { httpStatusText } from \"./http-status-text\";\nimport type { PostmanHeader, PostmanOriginalRequest, PostmanResponse } from \"./postman-types\";\nimport type { SchemaComponents } from \"./schema-refs\";\n\ntype PreviewLanguage = PostmanResponse[\"_postman_previewlanguage\"];\n\nfunction previewLanguage(contentType: string): PreviewLanguage {\n if (contentType === \"application/json\" || contentType.endsWith(\"+json\")) {\n return \"json\";\n }\n\n return contentType === \"text/html\" ? \"html\" : \"text\";\n}\n\nfunction stringExample(example: unknown): string {\n return typeof example === \"string\" ? example : \"\";\n}\n\nfunction responseBody(\n content: NonNullable<OpenApiOperation[\"responses\"][string][\"content\"]>,\n components: SchemaComponents,\n): { body: string; header: PostmanHeader[]; language: PreviewLanguage } {\n const contentTypes = Object.keys(content);\n const contentType = contentTypes.find((type) => previewLanguage(type) === \"json\") ?? contentTypes[0];\n const schema = contentType !== undefined ? content[contentType]?.schema : undefined;\n\n if (contentType === undefined || schema === undefined) {\n return { body: \"\", header: [], language: \"text\" };\n }\n\n const language = previewLanguage(contentType);\n const example = exampleFromSchema(schema, components);\n const body = language === \"json\" ? JSON.stringify(example, null, 2) : stringExample(example);\n\n return { body, header: [{ key: \"Content-Type\", value: contentType, type: \"text\" }], language };\n}\n\n/**\n * One saved Postman response per declared numeric status, with an example body from the\n * response schema. `default` and range keys (`2XX`) have no single status code and are skipped.\n */\nexport function buildSavedResponses(\n responses: OpenApiOperation[\"responses\"],\n originalRequest: PostmanOriginalRequest,\n components: SchemaComponents,\n): PostmanResponse[] {\n return Object.entries(responses).flatMap(([status, response]): PostmanResponse[] => {\n if (!/^\\d{3}$/.test(status)) {\n return [];\n }\n\n const code = Number(status);\n const { body, header, language } = response.content\n ? responseBody(response.content, components)\n : { body: \"\", header: [], language: \"text\" as const };\n\n return [\n {\n name: `${status} ${response.description}`,\n originalRequest,\n status: httpStatusText(code, response.description),\n code,\n _postman_previewlanguage: language,\n header,\n body,\n },\n ];\n });\n}\n"],"mappings":";;;;AAQA,SAAS,gBAAgB,aAAsC;CAC7D,IAAI,gBAAgB,sBAAsB,YAAY,SAAS,OAAO,GACpE,OAAO;CAGT,OAAO,gBAAgB,cAAc,SAAS;AAChD;AAEA,SAAS,cAAc,SAA0B;CAC/C,OAAO,OAAO,YAAY,WAAW,UAAU;AACjD;AAEA,SAAS,aACP,SACA,YACsE;CACtE,MAAM,eAAe,OAAO,KAAK,OAAO;CACxC,MAAM,cAAc,aAAa,MAAM,SAAS,gBAAgB,IAAI,MAAM,MAAM,KAAK,aAAa;CAClG,MAAM,SAAS,gBAAgB,SAAY,QAAQ,YAAY,EAAE,SAAS;CAE1E,IAAI,gBAAgB,UAAa,WAAW,QAC1C,OAAO;EAAE,MAAM;EAAI,QAAQ,CAAC;EAAG,UAAU;CAAO;CAGlD,MAAM,WAAW,gBAAgB,WAAW;CAC5C,MAAM,UAAU,kBAAkB,QAAQ,UAAU;CAGpD,OAAO;EAAE,MAFI,aAAa,SAAS,KAAK,UAAU,SAAS,MAAM,CAAC,IAAI,cAAc,OAAO;EAE5E,QAAQ,CAAC;GAAE,KAAK;GAAgB,OAAO;GAAa,MAAM;EAAO,CAAC;EAAG;CAAS;AAC/F;;;;;AAMA,SAAgB,oBACd,WACA,iBACA,YACmB;CACnB,OAAO,OAAO,QAAQ,SAAS,CAAC,CAAC,SAAS,CAAC,QAAQ,cAAiC;EAClF,IAAI,CAAC,UAAU,KAAK,MAAM,GACxB,OAAO,CAAC;EAGV,MAAM,OAAO,OAAO,MAAM;EAC1B,MAAM,EAAE,MAAM,QAAQ,aAAa,SAAS,UACxC,aAAa,SAAS,SAAS,UAAU,IACzC;GAAE,MAAM;GAAI,QAAQ,CAAC;GAAG,UAAU;EAAgB;EAEtD,OAAO,CACL;GACE,MAAM,GAAG,OAAO,GAAG,SAAS;GAC5B;GACA,QAAQ,eAAe,MAAM,SAAS,WAAW;GACjD;GACA,0BAA0B;GAC1B;GACA;EACF,CACF;CACF,CAAC;AACH"}
@@ -0,0 +1,17 @@
1
+ import { OpenApiSchema } from "../types.mjs";
2
+ import { SchemaComponents } from "./schema-refs.mjs";
3
+
4
+ //#region ../core/src/openapi/postman/example-from-schema.d.ts
5
+ /**
6
+ * A deterministic example value for a JSON Schema.
7
+ *
8
+ * Explicit `example`, `const`, `default`, `enum[0]` and `examples[0]` win, in that order;
9
+ * otherwise a type sample is produced (format-aware strings, `0`, `false`, one array item,
10
+ * every object property). `$ref`s resolve against `components`; a cyclic reference is cut
11
+ * (the property is omitted, an array of it is empty). A nullable union yields its non-null
12
+ * branch. A schema with no usable type is `null`.
13
+ */
14
+ declare function exampleFromSchema(schema: OpenApiSchema, components?: SchemaComponents): unknown;
15
+ //#endregion
16
+ export { exampleFromSchema };
17
+ //# sourceMappingURL=example-from-schema.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example-from-schema.d.mts","names":[],"sources":["../../../../../../../../core/src/openapi/postman/example-from-schema.ts"],"mappings":";;;;;;AAgJA;;;;;;;iBAAgB,iBAAA,CAAkB,MAAA,EAAQ,aAAA,EAAe,UAAA,GAAa,gBAAgB"}
@@ -0,0 +1,92 @@
1
+ import { isRecord, primaryType, refName, resolveSchema } from "./schema-refs.mjs";
2
+
3
+ //#region ../core/src/openapi/postman/example-from-schema.ts
4
+ const STRING_FORMAT_EXAMPLES = {
5
+ email: "user@example.com",
6
+ "date-time": "2024-01-01T00:00:00.000Z",
7
+ date: "2024-01-01",
8
+ time: "00:00:00",
9
+ uri: "https://example.com",
10
+ url: "https://example.com",
11
+ iri: "https://example.com",
12
+ uuid: "00000000-0000-4000-8000-000000000000",
13
+ hostname: "example.com",
14
+ ipv4: "127.0.0.1",
15
+ ipv6: "::1"
16
+ };
17
+ function numberExample(schema) {
18
+ if (typeof schema.minimum === "number" && schema.minimum > 0) return schema.minimum;
19
+ if (typeof schema.maximum === "number" && schema.maximum < 0) return schema.maximum;
20
+ return 0;
21
+ }
22
+ function stringExample(schema) {
23
+ const format = typeof schema.format === "string" ? schema.format : void 0;
24
+ return (format !== void 0 ? STRING_FORMAT_EXAMPLES[format] : void 0) ?? "string";
25
+ }
26
+ function isNullBranch(branch, components) {
27
+ return isRecord(branch) && primaryType(resolveSchema(branch, components)) === "null";
28
+ }
29
+ function mergeExamples(parts) {
30
+ const objects = parts.filter(isRecord);
31
+ if (objects.length === parts.length) return Object.assign({}, ...objects);
32
+ return parts[parts.length - 1] ?? null;
33
+ }
34
+ /**
35
+ * `undefined` marks a `$ref` cycle: the caller omits the property, or yields an empty array.
36
+ */
37
+ function generate(schema, components, stack) {
38
+ if (!isRecord(schema)) return null;
39
+ const name = refName(schema);
40
+ if (name !== void 0) {
41
+ const target = components?.[name];
42
+ if (stack.includes(name)) return;
43
+ return target ? generate(target, components, [...stack, name]) : null;
44
+ }
45
+ if ("example" in schema) return schema.example;
46
+ if ("const" in schema) return schema.const;
47
+ if ("default" in schema) return schema.default;
48
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
49
+ if (Array.isArray(schema.examples) && schema.examples.length > 0) return schema.examples[0];
50
+ for (const key of ["oneOf", "anyOf"]) {
51
+ const branches = schema[key];
52
+ if (Array.isArray(branches) && branches.length > 0) return generate(branches.find((candidate) => !isNullBranch(candidate, components)) ?? branches[0], components, stack);
53
+ }
54
+ if (Array.isArray(schema.allOf) && schema.allOf.length > 0) return mergeExamples(schema.allOf.map((part) => generate(part, components, stack)));
55
+ switch (primaryType(schema)) {
56
+ case "string": return stringExample(schema);
57
+ case "number":
58
+ case "integer": return numberExample(schema);
59
+ case "boolean": return false;
60
+ case "array": {
61
+ const item = generate(schema.items, components, stack);
62
+ return item === void 0 ? [] : [item];
63
+ }
64
+ case "object": {
65
+ const result = {};
66
+ const properties = isRecord(schema.properties) ? schema.properties : {};
67
+ for (const [key, property] of Object.entries(properties)) {
68
+ const value = generate(property, components, stack);
69
+ if (value !== void 0) result[key] = value;
70
+ }
71
+ return result;
72
+ }
73
+ default: return null;
74
+ }
75
+ }
76
+ /**
77
+ * A deterministic example value for a JSON Schema.
78
+ *
79
+ * Explicit `example`, `const`, `default`, `enum[0]` and `examples[0]` win, in that order;
80
+ * otherwise a type sample is produced (format-aware strings, `0`, `false`, one array item,
81
+ * every object property). `$ref`s resolve against `components`; a cyclic reference is cut
82
+ * (the property is omitted, an array of it is empty). A nullable union yields its non-null
83
+ * branch. A schema with no usable type is `null`.
84
+ */
85
+ function exampleFromSchema(schema, components) {
86
+ const value = generate(schema, components, []);
87
+ return value === void 0 ? null : value;
88
+ }
89
+
90
+ //#endregion
91
+ export { exampleFromSchema };
92
+ //# sourceMappingURL=example-from-schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example-from-schema.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/example-from-schema.ts"],"sourcesContent":["import type { OpenApiSchema } from \"../types\";\nimport { isRecord, primaryType, refName, resolveSchema, type SchemaComponents } from \"./schema-refs\";\n\nconst STRING_FORMAT_EXAMPLES: Record<string, string> = {\n email: \"user@example.com\",\n \"date-time\": \"2024-01-01T00:00:00.000Z\",\n date: \"2024-01-01\",\n time: \"00:00:00\",\n uri: \"https://example.com\",\n url: \"https://example.com\",\n iri: \"https://example.com\",\n uuid: \"00000000-0000-4000-8000-000000000000\",\n hostname: \"example.com\",\n ipv4: \"127.0.0.1\",\n ipv6: \"::1\",\n};\n\nfunction numberExample(schema: OpenApiSchema): number {\n if (typeof schema.minimum === \"number\" && schema.minimum > 0) {\n return schema.minimum;\n }\n\n if (typeof schema.maximum === \"number\" && schema.maximum < 0) {\n return schema.maximum;\n }\n\n return 0;\n}\n\nfunction stringExample(schema: OpenApiSchema): string {\n const format = typeof schema.format === \"string\" ? schema.format : undefined;\n\n return (format !== undefined ? STRING_FORMAT_EXAMPLES[format] : undefined) ?? \"string\";\n}\n\nfunction isNullBranch(branch: unknown, components: SchemaComponents): boolean {\n return isRecord(branch) && primaryType(resolveSchema(branch, components)) === \"null\";\n}\n\nfunction mergeExamples(parts: unknown[]): unknown {\n const objects = parts.filter(isRecord);\n\n if (objects.length === parts.length) {\n return Object.assign({}, ...objects);\n }\n\n return parts[parts.length - 1] ?? null;\n}\n\n/**\n * `undefined` marks a `$ref` cycle: the caller omits the property, or yields an empty array.\n */\nfunction generate(schema: unknown, components: SchemaComponents, stack: readonly string[]): unknown {\n if (!isRecord(schema)) {\n return null;\n }\n\n const name = refName(schema);\n\n if (name !== undefined) {\n const target = components?.[name];\n\n if (stack.includes(name)) {\n return undefined;\n }\n\n return target ? generate(target, components, [...stack, name]) : null;\n }\n\n if (\"example\" in schema) {\n return schema.example;\n }\n\n if (\"const\" in schema) {\n return schema.const;\n }\n\n if (\"default\" in schema) {\n return schema.default;\n }\n\n if (Array.isArray(schema.enum) && schema.enum.length > 0) {\n return schema.enum[0];\n }\n\n if (Array.isArray(schema.examples) && schema.examples.length > 0) {\n return schema.examples[0];\n }\n\n for (const key of [\"oneOf\", \"anyOf\"] as const) {\n const branches = schema[key];\n\n if (Array.isArray(branches) && branches.length > 0) {\n const branch = branches.find((candidate) => !isNullBranch(candidate, components)) ?? branches[0];\n\n return generate(branch, components, stack);\n }\n }\n\n if (Array.isArray(schema.allOf) && schema.allOf.length > 0) {\n return mergeExamples(schema.allOf.map((part) => generate(part, components, stack)));\n }\n\n switch (primaryType(schema)) {\n case \"string\":\n return stringExample(schema);\n case \"number\":\n case \"integer\":\n return numberExample(schema);\n case \"boolean\":\n return false;\n case \"array\": {\n const item = generate(schema.items, components, stack);\n\n return item === undefined ? [] : [item];\n }\n case \"object\": {\n const result: Record<string, unknown> = {};\n const properties = isRecord(schema.properties) ? schema.properties : {};\n\n for (const [key, property] of Object.entries(properties)) {\n const value = generate(property, components, stack);\n\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n }\n default:\n return null;\n }\n}\n\n/**\n * A deterministic example value for a JSON Schema.\n *\n * Explicit `example`, `const`, `default`, `enum[0]` and `examples[0]` win, in that order;\n * otherwise a type sample is produced (format-aware strings, `0`, `false`, one array item,\n * every object property). `$ref`s resolve against `components`; a cyclic reference is cut\n * (the property is omitted, an array of it is empty). A nullable union yields its non-null\n * branch. A schema with no usable type is `null`.\n */\nexport function exampleFromSchema(schema: OpenApiSchema, components?: SchemaComponents): unknown {\n const value = generate(schema, components, []);\n\n return value === undefined ? null : value;\n}\n"],"mappings":";;;AAGA,MAAM,yBAAiD;CACrD,OAAO;CACP,aAAa;CACb,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,UAAU;CACV,MAAM;CACN,MAAM;AACR;AAEA,SAAS,cAAc,QAA+B;CACpD,IAAI,OAAO,OAAO,YAAY,YAAY,OAAO,UAAU,GACzD,OAAO,OAAO;CAGhB,IAAI,OAAO,OAAO,YAAY,YAAY,OAAO,UAAU,GACzD,OAAO,OAAO;CAGhB,OAAO;AACT;AAEA,SAAS,cAAc,QAA+B;CACpD,MAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;CAEnE,QAAQ,WAAW,SAAY,uBAAuB,UAAU,WAAc;AAChF;AAEA,SAAS,aAAa,QAAiB,YAAuC;CAC5E,OAAO,SAAS,MAAM,KAAK,YAAY,cAAc,QAAQ,UAAU,CAAC,MAAM;AAChF;AAEA,SAAS,cAAc,OAA2B;CAChD,MAAM,UAAU,MAAM,OAAO,QAAQ;CAErC,IAAI,QAAQ,WAAW,MAAM,QAC3B,OAAO,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO;CAGrC,OAAO,MAAM,MAAM,SAAS,MAAM;AACpC;;;;AAKA,SAAS,SAAS,QAAiB,YAA8B,OAAmC;CAClG,IAAI,CAAC,SAAS,MAAM,GAClB,OAAO;CAGT,MAAM,OAAO,QAAQ,MAAM;CAE3B,IAAI,SAAS,QAAW;EACtB,MAAM,SAAS,aAAa;EAE5B,IAAI,MAAM,SAAS,IAAI,GACrB;EAGF,OAAO,SAAS,SAAS,QAAQ,YAAY,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI;CACnE;CAEA,IAAI,aAAa,QACf,OAAO,OAAO;CAGhB,IAAI,WAAW,QACb,OAAO,OAAO;CAGhB,IAAI,aAAa,QACf,OAAO,OAAO;CAGhB,IAAI,MAAM,QAAQ,OAAO,IAAI,KAAK,OAAO,KAAK,SAAS,GACrD,OAAO,OAAO,KAAK;CAGrB,IAAI,MAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,SAAS,SAAS,GAC7D,OAAO,OAAO,SAAS;CAGzB,KAAK,MAAM,OAAO,CAAC,SAAS,OAAO,GAAY;EAC7C,MAAM,WAAW,OAAO;EAExB,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAG/C,OAAO,SAFQ,SAAS,MAAM,cAAc,CAAC,aAAa,WAAW,UAAU,CAAC,KAAK,SAAS,IAEtE,YAAY,KAAK;CAE7C;CAEA,IAAI,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,SAAS,GACvD,OAAO,cAAc,OAAO,MAAM,KAAK,SAAS,SAAS,MAAM,YAAY,KAAK,CAAC,CAAC;CAGpF,QAAQ,YAAY,MAAM,GAA1B;EACE,KAAK,UACH,OAAO,cAAc,MAAM;EAC7B,KAAK;EACL,KAAK,WACH,OAAO,cAAc,MAAM;EAC7B,KAAK,WACH,OAAO;EACT,KAAK,SAAS;GACZ,MAAM,OAAO,SAAS,OAAO,OAAO,YAAY,KAAK;GAErD,OAAO,SAAS,SAAY,CAAC,IAAI,CAAC,IAAI;EACxC;EACA,KAAK,UAAU;GACb,MAAM,SAAkC,CAAC;GACzC,MAAM,aAAa,SAAS,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;GAEtE,KAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,UAAU,GAAG;IACxD,MAAM,QAAQ,SAAS,UAAU,YAAY,KAAK;IAElD,IAAI,UAAU,QACZ,OAAO,OAAO;GAElB;GAEA,OAAO;EACT;EACA,SACE,OAAO;CACX;AACF;;;;;;;;;;AAWA,SAAgB,kBAAkB,QAAuB,YAAwC;CAC/F,MAAM,QAAQ,SAAS,QAAQ,YAAY,CAAC,CAAC;CAE7C,OAAO,UAAU,SAAY,OAAO;AACtC"}
@@ -0,0 +1,31 @@
1
+ //#region ../core/src/openapi/postman/http-status-text.ts
2
+ const STATUS_TEXT = {
3
+ 200: "OK",
4
+ 201: "Created",
5
+ 202: "Accepted",
6
+ 204: "No Content",
7
+ 301: "Moved Permanently",
8
+ 302: "Found",
9
+ 304: "Not Modified",
10
+ 400: "Bad Request",
11
+ 401: "Unauthorized",
12
+ 403: "Forbidden",
13
+ 404: "Not Found",
14
+ 405: "Method Not Allowed",
15
+ 409: "Conflict",
16
+ 410: "Gone",
17
+ 422: "Unprocessable Entity",
18
+ 429: "Too Many Requests",
19
+ 500: "Internal Server Error",
20
+ 503: "Service Unavailable"
21
+ };
22
+ /**
23
+ * The HTTP reason phrase of a status code, or `fallback` for one that is not listed.
24
+ */
25
+ function httpStatusText(code, fallback) {
26
+ return STATUS_TEXT[code] ?? fallback;
27
+ }
28
+
29
+ //#endregion
30
+ export { httpStatusText };
31
+ //# sourceMappingURL=http-status-text.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-status-text.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/http-status-text.ts"],"sourcesContent":["const STATUS_TEXT: Record<number, string> = {\n 200: \"OK\",\n 201: \"Created\",\n 202: \"Accepted\",\n 204: \"No Content\",\n 301: \"Moved Permanently\",\n 302: \"Found\",\n 304: \"Not Modified\",\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 405: \"Method Not Allowed\",\n 409: \"Conflict\",\n 410: \"Gone\",\n 422: \"Unprocessable Entity\",\n 429: \"Too Many Requests\",\n 500: \"Internal Server Error\",\n 503: \"Service Unavailable\",\n};\n\n/**\n * The HTTP reason phrase of a status code, or `fallback` for one that is not listed.\n */\nexport function httpStatusText(code: number, fallback: string): string {\n return STATUS_TEXT[code] ?? fallback;\n}\n"],"mappings":";AAAA,MAAM,cAAsC;CAC1C,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;;;;AAKA,SAAgB,eAAe,MAAc,UAA0B;CACrE,OAAO,YAAY,SAAS;AAC9B"}
@@ -0,0 +1,3 @@
1
+ import { PostmanAuth, PostmanAuthEntry, PostmanBody, PostmanCollection, PostmanCollectionOptions, PostmanFolder, PostmanFormParam, PostmanHeader, PostmanItem, PostmanOriginalRequest, PostmanQueryParam, PostmanRequest, PostmanRequestItem, PostmanResponse, PostmanUrl, PostmanVariable } from "./postman-types.mjs";
2
+ import { exampleFromSchema } from "./example-from-schema.mjs";
3
+ import { DEFAULT_POSTMAN_BASE_URL, POSTMAN_COLLECTION_SCHEMA, openApiToPostmanCollection } from "./openapi-to-postman-collection.mjs";
@@ -0,0 +1,22 @@
1
+ import { PostmanCollection, PostmanCollectionOptions } from "./postman-types.mjs";
2
+ import { OpenApiDocument } from "../types.mjs";
3
+
4
+ //#region ../core/src/openapi/postman/openapi-to-postman-collection.d.ts
5
+ /** `info.schema` of every collection this converter produces. */
6
+ declare const POSTMAN_COLLECTION_SCHEMA = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json";
7
+ /** `{{baseUrl}}` when neither the options nor the document name a server. */
8
+ declare const DEFAULT_POSTMAN_BASE_URL = "http://localhost:3000";
9
+ /**
10
+ * Convert an OpenAPI document into a Postman Collection v2.1.0 object.
11
+ *
12
+ * Pure and deterministic (the collection id is a UUIDv5 of the title), derived only from the
13
+ * document so the collection can never disagree with the OpenAPI output. Each tag becomes a
14
+ * folder in order of first appearance and untagged operations stay at the root; each
15
+ * operation becomes a request with example bodies generated from its schemas and a saved
16
+ * response per declared status. `{{baseUrl}}` and `{{token}}` are collection variables; a
17
+ * bearer scheme becomes collection-level bearer auth and public operations opt out of it.
18
+ */
19
+ declare function openApiToPostmanCollection(document: OpenApiDocument, options?: PostmanCollectionOptions): PostmanCollection;
20
+ //#endregion
21
+ export { DEFAULT_POSTMAN_BASE_URL, POSTMAN_COLLECTION_SCHEMA, openApiToPostmanCollection };
22
+ //# sourceMappingURL=openapi-to-postman-collection.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-to-postman-collection.d.mts","names":[],"sources":["../../../../../../../../core/src/openapi/postman/openapi-to-postman-collection.ts"],"mappings":";;;;;cAgBa,yBAAA;AAAb;AAAA,cAGa,wBAAA;;;AAHyB;AAGtC;;;;AAAqC;AAqDrC;;iBAAgB,0BAAA,CACd,QAAA,EAAU,eAAA,EACV,OAAA,GAAS,wBAAA,GACR,iBAAA"}
@@ -0,0 +1,109 @@
1
+ import { buildRequestBody } from "./build-request-body.mjs";
2
+ import { buildHeaderParameters, buildRequestUrl } from "./build-request-url.mjs";
3
+ import { buildSavedResponses } from "./build-saved-responses.mjs";
4
+ import { collectionBearerAuth, hasBearerScheme, resolveOperationAuth } from "./resolve-operation-auth.mjs";
5
+ import { uuidV5 } from "./uuid-v5.mjs";
6
+
7
+ //#region ../core/src/openapi/postman/openapi-to-postman-collection.ts
8
+ /** `info.schema` of every collection this converter produces. */
9
+ const POSTMAN_COLLECTION_SCHEMA = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json";
10
+ /** `{{baseUrl}}` when neither the options nor the document name a server. */
11
+ const DEFAULT_POSTMAN_BASE_URL = "http://localhost:3000";
12
+ const OPERATION_METHODS = [
13
+ "get",
14
+ "put",
15
+ "post",
16
+ "delete",
17
+ "options",
18
+ "head",
19
+ "patch",
20
+ "trace"
21
+ ];
22
+ function buildRequestItem(path, method, operation, document) {
23
+ const components = document.components?.schemas;
24
+ const parameters = operation.parameters ?? [];
25
+ const body = buildRequestBody(operation.requestBody, components);
26
+ const { auth, note } = resolveOperationAuth(operation, document.components);
27
+ const description = [operation.description, note].filter((line) => Boolean(line)).join("\n\n");
28
+ const header = [...body?.contentType ? [{
29
+ key: "Content-Type",
30
+ value: body.contentType,
31
+ type: "text"
32
+ }] : [], ...buildHeaderParameters(parameters, components)];
33
+ const originalRequest = {
34
+ method: method.toUpperCase(),
35
+ header,
36
+ ...body ? { body: body.body } : {},
37
+ url: buildRequestUrl(path, parameters, components)
38
+ };
39
+ return {
40
+ name: operation.summary ?? operation.operationId,
41
+ request: {
42
+ ...originalRequest,
43
+ ...auth ? { auth } : {},
44
+ ...description ? { description } : {}
45
+ },
46
+ response: buildSavedResponses(operation.responses, originalRequest, components)
47
+ };
48
+ }
49
+ function normalizeBaseUrl(baseUrl) {
50
+ return baseUrl.replace(/\/+$/, "");
51
+ }
52
+ /**
53
+ * Convert an OpenAPI document into a Postman Collection v2.1.0 object.
54
+ *
55
+ * Pure and deterministic (the collection id is a UUIDv5 of the title), derived only from the
56
+ * document so the collection can never disagree with the OpenAPI output. Each tag becomes a
57
+ * folder in order of first appearance and untagged operations stay at the root; each
58
+ * operation becomes a request with example bodies generated from its schemas and a saved
59
+ * response per declared status. `{{baseUrl}}` and `{{token}}` are collection variables; a
60
+ * bearer scheme becomes collection-level bearer auth and public operations opt out of it.
61
+ */
62
+ function openApiToPostmanCollection(document, options = {}) {
63
+ const name = options.title ?? document.info.title;
64
+ const baseUrl = normalizeBaseUrl(options.baseUrl ?? document.servers?.[0]?.url ?? "http://localhost:3000");
65
+ const root = [];
66
+ const folders = /* @__PURE__ */ new Map();
67
+ for (const [path, pathItem] of Object.entries(document.paths)) for (const [method, operation] of Object.entries(pathItem)) {
68
+ if (!OPERATION_METHODS.includes(method)) continue;
69
+ const item = buildRequestItem(path, method, operation, document);
70
+ const tag = operation.tags?.[0];
71
+ if (tag === void 0) {
72
+ root.push(item);
73
+ continue;
74
+ }
75
+ let folder = folders.get(tag);
76
+ if (!folder) {
77
+ folder = {
78
+ name: tag,
79
+ item: []
80
+ };
81
+ folders.set(tag, folder);
82
+ root.push(folder);
83
+ }
84
+ folder.item.push(item);
85
+ }
86
+ return {
87
+ info: {
88
+ _postman_id: uuidV5(name),
89
+ name,
90
+ ...document.info.description ? { description: document.info.description } : {},
91
+ schema: POSTMAN_COLLECTION_SCHEMA
92
+ },
93
+ item: root,
94
+ ...hasBearerScheme(document.components) ? { auth: collectionBearerAuth() } : {},
95
+ variable: [{
96
+ key: "baseUrl",
97
+ value: baseUrl,
98
+ type: "string"
99
+ }, {
100
+ key: "token",
101
+ value: "",
102
+ type: "string"
103
+ }]
104
+ };
105
+ }
106
+
107
+ //#endregion
108
+ export { DEFAULT_POSTMAN_BASE_URL, POSTMAN_COLLECTION_SCHEMA, openApiToPostmanCollection };
109
+ //# sourceMappingURL=openapi-to-postman-collection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-to-postman-collection.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/openapi-to-postman-collection.ts"],"sourcesContent":["import type { OpenApiDocument, OpenApiOperation } from \"../types\";\nimport { buildRequestBody } from \"./build-request-body\";\nimport { buildHeaderParameters, buildRequestUrl } from \"./build-request-url\";\nimport { buildSavedResponses } from \"./build-saved-responses\";\nimport type {\n PostmanCollection,\n PostmanCollectionOptions,\n PostmanFolder,\n PostmanHeader,\n PostmanItem,\n PostmanRequestItem,\n} from \"./postman-types\";\nimport { collectionBearerAuth, hasBearerScheme, resolveOperationAuth } from \"./resolve-operation-auth\";\nimport { uuidV5 } from \"./uuid-v5\";\n\n/** `info.schema` of every collection this converter produces. */\nexport const POSTMAN_COLLECTION_SCHEMA = \"https://schema.getpostman.com/json/collection/v2.1.0/collection.json\";\n\n/** `{{baseUrl}}` when neither the options nor the document name a server. */\nexport const DEFAULT_POSTMAN_BASE_URL = \"http://localhost:3000\";\n\nconst OPERATION_METHODS = [\"get\", \"put\", \"post\", \"delete\", \"options\", \"head\", \"patch\", \"trace\"];\n\nfunction buildRequestItem(\n path: string,\n method: string,\n operation: OpenApiOperation,\n document: OpenApiDocument,\n): PostmanRequestItem {\n const components = document.components?.schemas;\n const parameters = operation.parameters ?? [];\n const body = buildRequestBody(operation.requestBody, components);\n const { auth, note } = resolveOperationAuth(operation, document.components);\n const description = [operation.description, note].filter((line): line is string => Boolean(line)).join(\"\\n\\n\");\n\n const header: PostmanHeader[] = [\n ...(body?.contentType ? [{ key: \"Content-Type\", value: body.contentType, type: \"text\" as const }] : []),\n ...buildHeaderParameters(parameters, components),\n ];\n\n const originalRequest = {\n method: method.toUpperCase(),\n header,\n ...(body ? { body: body.body } : {}),\n url: buildRequestUrl(path, parameters, components),\n };\n\n return {\n name: operation.summary ?? operation.operationId,\n request: {\n ...originalRequest,\n ...(auth ? { auth } : {}),\n ...(description ? { description } : {}),\n },\n response: buildSavedResponses(operation.responses, originalRequest, components),\n };\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, \"\");\n}\n\n/**\n * Convert an OpenAPI document into a Postman Collection v2.1.0 object.\n *\n * Pure and deterministic (the collection id is a UUIDv5 of the title), derived only from the\n * document so the collection can never disagree with the OpenAPI output. Each tag becomes a\n * folder in order of first appearance and untagged operations stay at the root; each\n * operation becomes a request with example bodies generated from its schemas and a saved\n * response per declared status. `{{baseUrl}}` and `{{token}}` are collection variables; a\n * bearer scheme becomes collection-level bearer auth and public operations opt out of it.\n */\nexport function openApiToPostmanCollection(\n document: OpenApiDocument,\n options: PostmanCollectionOptions = {},\n): PostmanCollection {\n const name = options.title ?? document.info.title;\n const baseUrl = normalizeBaseUrl(options.baseUrl ?? document.servers?.[0]?.url ?? DEFAULT_POSTMAN_BASE_URL);\n const root: PostmanItem[] = [];\n const folders = new Map<string, PostmanFolder>();\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const [method, operation] of Object.entries(pathItem)) {\n if (!OPERATION_METHODS.includes(method)) {\n continue;\n }\n\n const item = buildRequestItem(path, method, operation, document);\n const tag = operation.tags?.[0];\n\n if (tag === undefined) {\n root.push(item);\n\n continue;\n }\n\n let folder = folders.get(tag);\n\n if (!folder) {\n folder = { name: tag, item: [] };\n folders.set(tag, folder);\n root.push(folder);\n }\n\n folder.item.push(item);\n }\n }\n\n return {\n info: {\n _postman_id: uuidV5(name),\n name,\n ...(document.info.description ? { description: document.info.description } : {}),\n schema: POSTMAN_COLLECTION_SCHEMA,\n },\n item: root,\n ...(hasBearerScheme(document.components) ? { auth: collectionBearerAuth() } : {}),\n variable: [\n { key: \"baseUrl\", value: baseUrl, type: \"string\" },\n { key: \"token\", value: \"\", type: \"string\" },\n ],\n };\n}\n"],"mappings":";;;;;;;;AAgBA,MAAa,4BAA4B;;AAGzC,MAAa,2BAA2B;AAExC,MAAM,oBAAoB;CAAC;CAAO;CAAO;CAAQ;CAAU;CAAW;CAAQ;CAAS;AAAO;AAE9F,SAAS,iBACP,MACA,QACA,WACA,UACoB;CACpB,MAAM,aAAa,SAAS,YAAY;CACxC,MAAM,aAAa,UAAU,cAAc,CAAC;CAC5C,MAAM,OAAO,iBAAiB,UAAU,aAAa,UAAU;CAC/D,MAAM,EAAE,MAAM,SAAS,qBAAqB,WAAW,SAAS,UAAU;CAC1E,MAAM,cAAc,CAAC,UAAU,aAAa,IAAI,CAAC,CAAC,QAAQ,SAAyB,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM;CAE7G,MAAM,SAA0B,CAC9B,GAAI,MAAM,cAAc,CAAC;EAAE,KAAK;EAAgB,OAAO,KAAK;EAAa,MAAM;CAAgB,CAAC,IAAI,CAAC,GACrG,GAAG,sBAAsB,YAAY,UAAU,CACjD;CAEA,MAAM,kBAAkB;EACtB,QAAQ,OAAO,YAAY;EAC3B;EACA,GAAI,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;EAClC,KAAK,gBAAgB,MAAM,YAAY,UAAU;CACnD;CAEA,OAAO;EACL,MAAM,UAAU,WAAW,UAAU;EACrC,SAAS;GACP,GAAG;GACH,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;GACvB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;EACvC;EACA,UAAU,oBAAoB,UAAU,WAAW,iBAAiB,UAAU;CAChF;AACF;AAEA,SAAS,iBAAiB,SAAyB;CACjD,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACnC;;;;;;;;;;;AAYA,SAAgB,2BACd,UACA,UAAoC,CAAC,GAClB;CACnB,MAAM,OAAO,QAAQ,SAAS,SAAS,KAAK;CAC5C,MAAM,UAAU,iBAAiB,QAAQ,WAAW,SAAS,UAAU,EAAE,EAAE,8BAA+B;CAC1G,MAAM,OAAsB,CAAC;CAC7B,MAAM,0BAAU,IAAI,IAA2B;CAE/C,KAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,GAC1D,KAAK,MAAM,CAAC,QAAQ,cAAc,OAAO,QAAQ,QAAQ,GAAG;EAC1D,IAAI,CAAC,kBAAkB,SAAS,MAAM,GACpC;EAGF,MAAM,OAAO,iBAAiB,MAAM,QAAQ,WAAW,QAAQ;EAC/D,MAAM,MAAM,UAAU,OAAO;EAE7B,IAAI,QAAQ,QAAW;GACrB,KAAK,KAAK,IAAI;GAEd;EACF;EAEA,IAAI,SAAS,QAAQ,IAAI,GAAG;EAE5B,IAAI,CAAC,QAAQ;GACX,SAAS;IAAE,MAAM;IAAK,MAAM,CAAC;GAAE;GAC/B,QAAQ,IAAI,KAAK,MAAM;GACvB,KAAK,KAAK,MAAM;EAClB;EAEA,OAAO,KAAK,KAAK,IAAI;CACvB;CAGF,OAAO;EACL,MAAM;GACJ,aAAa,OAAO,IAAI;GACxB;GACA,GAAI,SAAS,KAAK,cAAc,EAAE,aAAa,SAAS,KAAK,YAAY,IAAI,CAAC;GAC9E,QAAQ;EACV;EACA,MAAM;EACN,GAAI,gBAAgB,SAAS,UAAU,IAAI,EAAE,MAAM,qBAAqB,EAAE,IAAI,CAAC;EAC/E,UAAU,CACR;GAAE,KAAK;GAAW,OAAO;GAAS,MAAM;EAAS,GACjD;GAAE,KAAK;GAAS,OAAO;GAAI,MAAM;EAAS,CAC5C;CACF;AACF"}
@@ -0,0 +1,119 @@
1
+ //#region ../core/src/openapi/postman/postman-types.d.ts
2
+ /**
3
+ * The slice of the Postman Collection Format v2.1.0 the converter emits.
4
+ * Schema: https://schema.getpostman.com/json/collection/v2.1.0/collection.json
5
+ */
6
+ type PostmanVariable = {
7
+ key: string;
8
+ value: string;
9
+ type?: "string";
10
+ description?: string;
11
+ };
12
+ type PostmanAuthEntry = {
13
+ key: string;
14
+ value: string;
15
+ type: "string";
16
+ };
17
+ type PostmanAuth = {
18
+ type: "noauth";
19
+ } | {
20
+ type: "bearer";
21
+ bearer: PostmanAuthEntry[];
22
+ };
23
+ type PostmanHeader = {
24
+ key: string;
25
+ value: string;
26
+ type?: "text";
27
+ description?: string;
28
+ disabled?: boolean;
29
+ };
30
+ type PostmanQueryParam = {
31
+ key: string;
32
+ value: string;
33
+ description?: string;
34
+ disabled?: boolean;
35
+ };
36
+ type PostmanUrl = {
37
+ raw: string;
38
+ host: string[];
39
+ path: string[];
40
+ variable?: PostmanVariable[];
41
+ query?: PostmanQueryParam[];
42
+ };
43
+ type PostmanFormParam = {
44
+ key: string;
45
+ value: string;
46
+ type: "text";
47
+ description?: string;
48
+ } | {
49
+ key: string;
50
+ type: "file";
51
+ src: string[];
52
+ description?: string;
53
+ };
54
+ type PostmanBody = {
55
+ mode: "raw";
56
+ raw: string;
57
+ options: {
58
+ raw: {
59
+ language: "json" | "text";
60
+ };
61
+ };
62
+ } | {
63
+ mode: "formdata";
64
+ formdata: PostmanFormParam[];
65
+ } | {
66
+ mode: "urlencoded";
67
+ urlencoded: {
68
+ key: string;
69
+ value: string;
70
+ type: "text";
71
+ }[];
72
+ };
73
+ type PostmanOriginalRequest = {
74
+ method: string;
75
+ header: PostmanHeader[];
76
+ body?: PostmanBody;
77
+ url: PostmanUrl;
78
+ };
79
+ type PostmanRequest = PostmanOriginalRequest & {
80
+ auth?: PostmanAuth;
81
+ description?: string;
82
+ };
83
+ type PostmanResponse = {
84
+ name: string;
85
+ originalRequest: PostmanOriginalRequest;
86
+ status: string;
87
+ code: number;
88
+ _postman_previewlanguage: "json" | "html" | "text";
89
+ header: PostmanHeader[];
90
+ body: string;
91
+ };
92
+ type PostmanRequestItem = {
93
+ name: string;
94
+ request: PostmanRequest;
95
+ response: PostmanResponse[];
96
+ };
97
+ type PostmanFolder = {
98
+ name: string;
99
+ item: PostmanItem[];
100
+ };
101
+ type PostmanItem = PostmanFolder | PostmanRequestItem;
102
+ type PostmanCollection = {
103
+ info: {
104
+ _postman_id: string;
105
+ name: string;
106
+ description?: string;
107
+ schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json";
108
+ };
109
+ item: PostmanItem[];
110
+ auth?: PostmanAuth;
111
+ variable: PostmanVariable[];
112
+ };
113
+ type PostmanCollectionOptions = {
114
+ /** Collection name. Defaults to `info.title` of the document. */title?: string; /** Value of the `{{baseUrl}}` variable. Defaults to `servers[0].url`, else `http://localhost:3000`. */
115
+ baseUrl?: string;
116
+ };
117
+ //#endregion
118
+ export { PostmanAuth, PostmanAuthEntry, PostmanBody, PostmanCollection, PostmanCollectionOptions, PostmanFolder, PostmanFormParam, PostmanHeader, PostmanItem, PostmanOriginalRequest, PostmanQueryParam, PostmanRequest, PostmanRequestItem, PostmanResponse, PostmanUrl, PostmanVariable };
119
+ //# sourceMappingURL=postman-types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postman-types.d.mts","names":[],"sources":["../../../../../../../../core/src/openapi/postman/postman-types.ts"],"mappings":";;AAKA;;;KAAY,eAAA;EACV,GAAA;EACA,KAAA;EACA,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EAAqB,GAAA;EAAa,KAAA;EAAe,IAAA;AAAA;AAAA,KAEjD,WAAA;EAAgB,IAAA;AAAA;EAAqB,IAAA;EAAgB,MAAA,EAAQ,gBAAgB;AAAA;AAAA,KAE7E,aAAA;EACV,GAAA;EACA,KAAA;EACA,IAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,KAGU,iBAAA;EACV,GAAA;EACA,KAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,KAGU,UAAA;EACV,GAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA,GAAW,eAAA;EACX,KAAA,GAAQ,iBAAiB;AAAA;AAAA,KAGf,gBAAA;EACN,GAAA;EAAa,KAAA;EAAe,IAAA;EAAc,WAAA;AAAA;EAC1C,GAAA;EAAa,IAAA;EAAc,GAAA;EAAe,WAAA;AAAA;AAAA,KAEpC,WAAA;EACN,IAAA;EAAa,GAAA;EAAa,OAAA;IAAW,GAAA;MAAO,QAAA;IAAA;EAAA;AAAA;EAC5C,IAAA;EAAkB,QAAA,EAAU,gBAAgB;AAAA;EAC5C,IAAA;EAAoB,UAAA;IAAc,GAAA;IAAa,KAAA;IAAe,IAAA;EAAA;AAAA;AAAA,KAExD,sBAAA;EACV,MAAA;EACA,MAAA,EAAQ,aAAA;EACR,IAAA,GAAO,WAAA;EACP,GAAA,EAAK,UAAA;AAAA;AAAA,KAGK,cAAA,GAAiB,sBAAA;EAC3B,IAAA,GAAO,WAAW;EAClB,WAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,eAAA,EAAiB,sBAAA;EACjB,MAAA;EACA,IAAA;EACA,wBAAA;EACA,MAAA,EAAQ,aAAa;EACrB,IAAA;AAAA;AAAA,KAGU,kBAAA;EACV,IAAA;EACA,OAAA,EAAS,cAAA;EACT,QAAA,EAAU,eAAe;AAAA;AAAA,KAGf,aAAA;EACV,IAAA;EACA,IAAA,EAAM,WAAW;AAAA;AAAA,KAGP,WAAA,GAAc,aAAA,GAAgB,kBAAkB;AAAA,KAEhD,iBAAA;EACV,IAAA;IACE,WAAA;IACA,IAAA;IACA,WAAA;IACA,MAAA;EAAA;EAEF,IAAA,EAAM,WAAA;EACN,IAAA,GAAO,WAAA;EACP,QAAA,EAAU,eAAA;AAAA;AAAA,KAGA,wBAAA;EA3CK,iEA6Cf,KAAA,WA1CU;EA4CV,OAAO;AAAA"}
@@ -0,0 +1,51 @@
1
+ //#region ../core/src/openapi/postman/resolve-operation-auth.ts
2
+ /** The collection-level auth: a bearer token read from the `{{token}}` variable. */
3
+ function collectionBearerAuth() {
4
+ return {
5
+ type: "bearer",
6
+ bearer: [{
7
+ key: "token",
8
+ value: "{{token}}",
9
+ type: "string"
10
+ }]
11
+ };
12
+ }
13
+ function isBearer(scheme) {
14
+ return scheme?.type === "http" && scheme.scheme.toLowerCase() === "bearer";
15
+ }
16
+ /**
17
+ * Whether the document declares an HTTP bearer scheme, which is what the collection-level
18
+ * auth stands for.
19
+ */
20
+ function hasBearerScheme(components) {
21
+ return Object.values(components?.securitySchemes ?? {}).some(isBearer);
22
+ }
23
+ /**
24
+ * How one operation relates to the collection-level bearer auth.
25
+ *
26
+ * - No `security` (a public route): `noauth`, so the token is not sent.
27
+ * - A bearer requirement: inherits the collection auth.
28
+ * - Cookie-only: `noauth` plus a note, because Postman keeps cookies per domain instead of
29
+ * in collection auth.
30
+ */
31
+ function resolveOperationAuth(operation, components) {
32
+ const bearerDocument = hasBearerScheme(components);
33
+ const schemes = components?.securitySchemes ?? {};
34
+ const names = (operation.security ?? []).flatMap((requirement) => Object.keys(requirement));
35
+ if (names.some((name) => isBearer(schemes[name]))) return {};
36
+ const cookies = names.flatMap((name) => {
37
+ const scheme = schemes[name];
38
+ return scheme?.type === "apiKey" && scheme.in === "cookie" ? [scheme.name] : [];
39
+ });
40
+ const auth = bearerDocument ? { auth: { type: "noauth" } } : {};
41
+ if (cookies.length === 0) return auth;
42
+ const cookieList = cookies.map((cookie) => `"${cookie}"`).join(", ");
43
+ return {
44
+ ...auth,
45
+ note: `Authenticates with the ${cookieList} cookie. Postman keeps cookies per domain, so sign in against {{baseUrl}} first or add the cookie in the Cookies manager.`
46
+ };
47
+ }
48
+
49
+ //#endregion
50
+ export { collectionBearerAuth, hasBearerScheme, resolveOperationAuth };
51
+ //# sourceMappingURL=resolve-operation-auth.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-operation-auth.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/resolve-operation-auth.ts"],"sourcesContent":["import type { OpenApiComponents, OpenApiOperation, OpenApiSecurityScheme } from \"../types\";\nimport type { PostmanAuth } from \"./postman-types\";\n\nexport type OperationAuth = {\n /** Set only when the operation must not inherit the collection auth. */\n auth?: PostmanAuth;\n /** Text appended to the request description. */\n note?: string;\n};\n\n/** The collection-level auth: a bearer token read from the `{{token}}` variable. */\nexport function collectionBearerAuth(): PostmanAuth {\n return { type: \"bearer\", bearer: [{ key: \"token\", value: \"{{token}}\", type: \"string\" }] };\n}\n\nfunction isBearer(scheme: OpenApiSecurityScheme | undefined): boolean {\n return scheme?.type === \"http\" && scheme.scheme.toLowerCase() === \"bearer\";\n}\n\n/**\n * Whether the document declares an HTTP bearer scheme, which is what the collection-level\n * auth stands for.\n */\nexport function hasBearerScheme(components: OpenApiComponents | undefined): boolean {\n return Object.values(components?.securitySchemes ?? {}).some(isBearer);\n}\n\n/**\n * How one operation relates to the collection-level bearer auth.\n *\n * - No `security` (a public route): `noauth`, so the token is not sent.\n * - A bearer requirement: inherits the collection auth.\n * - Cookie-only: `noauth` plus a note, because Postman keeps cookies per domain instead of\n * in collection auth.\n */\nexport function resolveOperationAuth(\n operation: OpenApiOperation,\n components: OpenApiComponents | undefined,\n): OperationAuth {\n const bearerDocument = hasBearerScheme(components);\n const schemes = components?.securitySchemes ?? {};\n const names = (operation.security ?? []).flatMap((requirement) => Object.keys(requirement));\n\n if (names.some((name) => isBearer(schemes[name]))) {\n return {};\n }\n\n const cookies = names.flatMap((name) => {\n const scheme = schemes[name];\n\n return scheme?.type === \"apiKey\" && scheme.in === \"cookie\" ? [scheme.name] : [];\n });\n\n const auth = bearerDocument ? { auth: { type: \"noauth\" } as const } : {};\n\n if (cookies.length === 0) {\n return auth;\n }\n\n const cookieList = cookies.map((cookie) => `\"${cookie}\"`).join(\", \");\n\n return {\n ...auth,\n note: `Authenticates with the ${cookieList} cookie. Postman keeps cookies per domain, so sign in against {{baseUrl}} first or add the cookie in the Cookies manager.`,\n };\n}\n"],"mappings":";;AAWA,SAAgB,uBAAoC;CAClD,OAAO;EAAE,MAAM;EAAU,QAAQ,CAAC;GAAE,KAAK;GAAS,OAAO;GAAa,MAAM;EAAS,CAAC;CAAE;AAC1F;AAEA,SAAS,SAAS,QAAoD;CACpE,OAAO,QAAQ,SAAS,UAAU,OAAO,OAAO,YAAY,MAAM;AACpE;;;;;AAMA,SAAgB,gBAAgB,YAAoD;CAClF,OAAO,OAAO,OAAO,YAAY,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ;AACvE;;;;;;;;;AAUA,SAAgB,qBACd,WACA,YACe;CACf,MAAM,iBAAiB,gBAAgB,UAAU;CACjD,MAAM,UAAU,YAAY,mBAAmB,CAAC;CAChD,MAAM,SAAS,UAAU,YAAY,CAAC,EAAC,CAAE,SAAS,gBAAgB,OAAO,KAAK,WAAW,CAAC;CAE1F,IAAI,MAAM,MAAM,SAAS,SAAS,QAAQ,KAAK,CAAC,GAC9C,OAAO,CAAC;CAGV,MAAM,UAAU,MAAM,SAAS,SAAS;EACtC,MAAM,SAAS,QAAQ;EAEvB,OAAO,QAAQ,SAAS,YAAY,OAAO,OAAO,WAAW,CAAC,OAAO,IAAI,IAAI,CAAC;CAChF,CAAC;CAED,MAAM,OAAO,iBAAiB,EAAE,MAAM,EAAE,MAAM,SAAS,EAAW,IAAI,CAAC;CAEvE,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,MAAM,aAAa,QAAQ,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,IAAI;CAEnE,OAAO;EACL,GAAG;EACH,MAAM,0BAA0B,WAAW;CAC7C;AACF"}
@@ -0,0 +1,7 @@
1
+ import { OpenApiSchema } from "../types.mjs";
2
+
3
+ //#region ../core/src/openapi/postman/schema-refs.d.ts
4
+ type SchemaComponents = Record<string, OpenApiSchema> | undefined;
5
+ //#endregion
6
+ export { SchemaComponents };
7
+ //# sourceMappingURL=schema-refs.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-refs.d.mts","names":[],"sources":["../../../../../../../../core/src/openapi/postman/schema-refs.ts"],"mappings":";;;KAEY,gBAAA,GAAmB,MAAM,SAAS,aAAA"}
@@ -0,0 +1,41 @@
1
+ //#region ../core/src/openapi/postman/schema-refs.ts
2
+ const REF_PREFIX = "#/components/schemas/";
3
+ function isRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ /**
7
+ * Component name a `$ref` schema points at, or `undefined` for a schema that is not a local
8
+ * component reference.
9
+ */
10
+ function refName(schema) {
11
+ const ref = schema.$ref;
12
+ return typeof ref === "string" && ref.startsWith(REF_PREFIX) ? ref.slice(21) : void 0;
13
+ }
14
+ /**
15
+ * Follow `$ref`s (with a hop limit, so a ref loop cannot hang) to the schema they name.
16
+ * An unknown component resolves to `{}`.
17
+ */
18
+ function resolveSchema(schema, components) {
19
+ let current = schema;
20
+ for (let hop = 0; hop < 32; hop++) {
21
+ const name = refName(current);
22
+ if (name === void 0) return current;
23
+ current = components?.[name] ?? {};
24
+ }
25
+ return {};
26
+ }
27
+ /**
28
+ * The effective JSON Schema type: `type`, or the first non-null member of a `type` array
29
+ * (the 3.1 nullable form), or one inferred from `properties` / `items`.
30
+ */
31
+ function primaryType(schema) {
32
+ const { type } = schema;
33
+ if (typeof type === "string") return type;
34
+ if (Array.isArray(type)) return type.find((member) => typeof member === "string" && member !== "null") ?? (type.includes("null") ? "null" : void 0);
35
+ if (isRecord(schema.properties)) return "object";
36
+ if (isRecord(schema.items)) return "array";
37
+ }
38
+
39
+ //#endregion
40
+ export { isRecord, primaryType, refName, resolveSchema };
41
+ //# sourceMappingURL=schema-refs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-refs.mjs","names":[],"sources":["../../../../../../../../core/src/openapi/postman/schema-refs.ts"],"sourcesContent":["import type { OpenApiSchema } from \"../types\";\n\nexport type SchemaComponents = Record<string, OpenApiSchema> | undefined;\n\nconst REF_PREFIX = \"#/components/schemas/\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Component name a `$ref` schema points at, or `undefined` for a schema that is not a local\n * component reference.\n */\nexport function refName(schema: OpenApiSchema): string | undefined {\n const ref = schema.$ref;\n\n return typeof ref === \"string\" && ref.startsWith(REF_PREFIX) ? ref.slice(REF_PREFIX.length) : undefined;\n}\n\n/**\n * Follow `$ref`s (with a hop limit, so a ref loop cannot hang) to the schema they name.\n * An unknown component resolves to `{}`.\n */\nexport function resolveSchema(schema: OpenApiSchema, components: SchemaComponents): OpenApiSchema {\n let current = schema;\n\n for (let hop = 0; hop < 32; hop++) {\n const name = refName(current);\n\n if (name === undefined) {\n return current;\n }\n\n current = components?.[name] ?? {};\n }\n\n return {};\n}\n\n/**\n * The effective JSON Schema type: `type`, or the first non-null member of a `type` array\n * (the 3.1 nullable form), or one inferred from `properties` / `items`.\n */\nexport function primaryType(schema: OpenApiSchema): string | undefined {\n const { type } = schema;\n\n if (typeof type === \"string\") {\n return type;\n }\n\n if (Array.isArray(type)) {\n const concrete = type.find((member): member is string => typeof member === \"string\" && member !== \"null\");\n\n return concrete ?? (type.includes(\"null\") ? \"null\" : undefined);\n }\n\n if (isRecord(schema.properties)) {\n return \"object\";\n }\n\n if (isRecord(schema.items)) {\n return \"array\";\n }\n\n return undefined;\n}\n"],"mappings":";AAIA,MAAM,aAAa;AAEnB,SAAgB,SAAS,OAAkD;CACzE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;;;AAMA,SAAgB,QAAQ,QAA2C;CACjE,MAAM,MAAM,OAAO;CAEnB,OAAO,OAAO,QAAQ,YAAY,IAAI,WAAW,UAAU,IAAI,IAAI,MAAM,EAAiB,IAAI;AAChG;;;;;AAMA,SAAgB,cAAc,QAAuB,YAA6C;CAChG,IAAI,UAAU;CAEd,KAAK,IAAI,MAAM,GAAG,MAAM,IAAI,OAAO;EACjC,MAAM,OAAO,QAAQ,OAAO;EAE5B,IAAI,SAAS,QACX,OAAO;EAGT,UAAU,aAAa,SAAS,CAAC;CACnC;CAEA,OAAO,CAAC;AACV;;;;;AAMA,SAAgB,YAAY,QAA2C;CACrE,MAAM,EAAE,SAAS;CAEjB,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,MAAM,QAAQ,IAAI,GAGpB,OAFiB,KAAK,MAAM,WAA6B,OAAO,WAAW,YAAY,WAAW,MAEpF,MAAM,KAAK,SAAS,MAAM,IAAI,SAAS;CAGvD,IAAI,SAAS,OAAO,UAAU,GAC5B,OAAO;CAGT,IAAI,SAAS,OAAO,KAAK,GACvB,OAAO;AAIX"}