@decohere/scaffold 0.0.1-dev.18 → 0.0.1-dev.81

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 (240) hide show
  1. package/commonjs/src/add-api.action.js +39 -0
  2. package/commonjs/src/add-api.command.js +41 -0
  3. package/commonjs/src/add.command.js +24 -0
  4. package/commonjs/src/add.module.js +26 -0
  5. package/commonjs/src/cli.js +9 -0
  6. package/commonjs/src/create.command.js +24 -0
  7. package/commonjs/src/create.module.js +26 -0
  8. package/commonjs/src/domain/prompt.js +64 -0
  9. package/commonjs/src/index.js +38 -0
  10. package/commonjs/src/models/compose.model.js +150 -0
  11. package/commonjs/src/models/config-yaml.model.js +88 -0
  12. package/commonjs/src/models/const.js +32 -0
  13. package/commonjs/src/models/dev-container.model.js +116 -0
  14. package/commonjs/src/models/docker-image.model.js +259 -0
  15. package/commonjs/src/models/env-file.model.js +50 -0
  16. package/commonjs/src/models/gitignore.model.js +43 -0
  17. package/commonjs/src/models/launch-json.model.js +74 -0
  18. package/commonjs/src/models/package-json.model.js +149 -0
  19. package/commonjs/src/models/project.model.js +134 -0
  20. package/commonjs/src/models/source-file.js +6 -0
  21. package/commonjs/src/models/tsconfig.model.js +34 -0
  22. package/commonjs/src/models/vitest-config.model.js +35 -0
  23. package/commonjs/src/models/vscode-settings.model.js +31 -0
  24. package/commonjs/src/program.js +57 -0
  25. package/commonjs/src/resolve-target-dir.js +19 -0
  26. package/commonjs/src/services/scaffold.service.js +62 -0
  27. package/commonjs/src/version.js +57 -0
  28. package/commonjs/src/webapi/api-name.js +95 -0
  29. package/commonjs/src/webapi/cli-options.js +101 -0
  30. package/commonjs/src/webapi/const.js +50 -0
  31. package/commonjs/src/webapi/create-api.js +237 -0
  32. package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +166 -0
  33. package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
  34. package/commonjs/src/webapi/devcontainer/host-scripts.js +52 -0
  35. package/commonjs/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
  36. package/commonjs/src/webapi/devcontainer/templates/initialize.sh +169 -0
  37. package/commonjs/src/webapi/devcontainer/templates/post-create.sh +35 -0
  38. package/commonjs/src/webapi/devcontainer/templates/post-start.sh +65 -0
  39. package/commonjs/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
  40. package/commonjs/src/webapi/features/auth.feature.js +441 -0
  41. package/commonjs/src/webapi/features/auth0-cli.js +435 -0
  42. package/commonjs/src/webapi/features/biome-format.js +49 -0
  43. package/commonjs/src/webapi/features/database.feature.js +433 -0
  44. package/commonjs/src/webapi/features/finalize.feature.js +95 -0
  45. package/commonjs/src/webapi/features/postman.feature.js +324 -0
  46. package/commonjs/src/webapi/models/api-package-json.model.js +60 -0
  47. package/commonjs/src/webapi/models/auth-config.model.js +26 -0
  48. package/commonjs/src/webapi/models/controller-source-file.model.js +193 -0
  49. package/commonjs/src/webapi/models/github-ci.model.js +193 -0
  50. package/commonjs/src/webapi/models/main-source-file.model.js +167 -0
  51. package/commonjs/src/webapi/models/production-dockerfile.model.js +157 -0
  52. package/commonjs/src/webapi/models/sample-files.model.js +60 -0
  53. package/commonjs/src/webapi/models/webapi-image.model.js +27 -0
  54. package/commonjs/src/webapi/postman/hello-openapi.js +175 -0
  55. package/commonjs/src/webapi/postman/local-view.js +184 -0
  56. package/commonjs/src/webapi/postman/openapi-to-postman.js +202 -0
  57. package/commonjs/src/webapi/workspace-readme.js +110 -0
  58. package/commonjs/src/webapi.action.js +30 -0
  59. package/commonjs/src/webapi.command.js +45 -0
  60. package/es6/src/add-api.action.js +29 -0
  61. package/es6/src/add-api.command.js +31 -0
  62. package/es6/src/add.command.js +14 -0
  63. package/es6/src/add.module.js +16 -0
  64. package/es6/src/cli.js +5 -0
  65. package/es6/src/create.command.js +14 -0
  66. package/es6/src/create.module.js +16 -0
  67. package/es6/src/domain/prompt.js +43 -0
  68. package/es6/src/index.js +8 -0
  69. package/es6/src/models/compose.model.js +144 -0
  70. package/es6/src/models/config-yaml.model.js +76 -0
  71. package/es6/src/models/const.js +22 -0
  72. package/es6/src/models/dev-container.model.js +106 -0
  73. package/es6/src/models/docker-image.model.js +217 -0
  74. package/es6/src/models/env-file.model.js +46 -0
  75. package/es6/src/models/gitignore.model.js +33 -0
  76. package/es6/src/models/launch-json.model.js +64 -0
  77. package/es6/src/models/package-json.model.js +137 -0
  78. package/es6/src/models/project.model.js +119 -0
  79. package/es6/src/models/source-file.js +3 -0
  80. package/es6/src/models/tsconfig.model.js +24 -0
  81. package/es6/src/models/vitest-config.model.js +25 -0
  82. package/es6/src/models/vscode-settings.model.js +21 -0
  83. package/es6/src/program.js +39 -0
  84. package/es6/src/resolve-target-dir.js +9 -0
  85. package/es6/src/services/scaffold.service.js +52 -0
  86. package/es6/src/version.js +36 -0
  87. package/es6/src/webapi/api-name.js +59 -0
  88. package/es6/src/webapi/cli-options.js +36 -0
  89. package/es6/src/webapi/const.js +20 -0
  90. package/es6/src/webapi/create-api.js +217 -0
  91. package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +156 -0
  92. package/es6/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
  93. package/es6/src/webapi/devcontainer/host-scripts.js +31 -0
  94. package/es6/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
  95. package/es6/src/webapi/devcontainer/templates/initialize.sh +169 -0
  96. package/es6/src/webapi/devcontainer/templates/post-create.sh +35 -0
  97. package/es6/src/webapi/devcontainer/templates/post-start.sh +65 -0
  98. package/es6/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
  99. package/es6/src/webapi/features/auth.feature.js +390 -0
  100. package/es6/src/webapi/features/auth0-cli.js +375 -0
  101. package/es6/src/webapi/features/biome-format.js +42 -0
  102. package/es6/src/webapi/features/database.feature.js +423 -0
  103. package/es6/src/webapi/features/finalize.feature.js +85 -0
  104. package/es6/src/webapi/features/postman.feature.js +258 -0
  105. package/es6/src/webapi/models/api-package-json.model.js +55 -0
  106. package/es6/src/webapi/models/auth-config.model.js +22 -0
  107. package/es6/src/webapi/models/controller-source-file.model.js +184 -0
  108. package/es6/src/webapi/models/github-ci.model.js +186 -0
  109. package/es6/src/webapi/models/main-source-file.model.js +163 -0
  110. package/es6/src/webapi/models/production-dockerfile.model.js +148 -0
  111. package/es6/src/webapi/models/sample-files.model.js +42 -0
  112. package/es6/src/webapi/models/webapi-image.model.js +20 -0
  113. package/es6/src/webapi/postman/hello-openapi.js +168 -0
  114. package/es6/src/webapi/postman/local-view.js +169 -0
  115. package/es6/src/webapi/postman/openapi-to-postman.js +179 -0
  116. package/es6/src/webapi/workspace-readme.js +89 -0
  117. package/es6/src/webapi.action.js +20 -0
  118. package/es6/src/webapi.command.js +35 -0
  119. package/package.json +8 -8
  120. package/types/src/add-api.action.d.ts +13 -0
  121. package/types/src/add-api.command.d.ts +7 -0
  122. package/types/src/add.command.d.ts +6 -0
  123. package/types/src/add.module.d.ts +14 -0
  124. package/types/src/cli.d.ts +2 -0
  125. package/types/src/create.command.d.ts +6 -0
  126. package/types/src/create.module.d.ts +14 -0
  127. package/types/src/domain/prompt.d.ts +4 -0
  128. package/types/src/models/compose.model.d.ts +64 -0
  129. package/types/src/models/config-yaml.model.d.ts +27 -0
  130. package/types/src/models/const.d.ts +20 -0
  131. package/types/src/models/dev-container.model.d.ts +37 -0
  132. package/types/src/models/docker-image.model.d.ts +84 -0
  133. package/types/src/models/env-file.model.d.ts +16 -0
  134. package/types/src/models/gitignore.model.d.ts +7 -0
  135. package/types/src/models/launch-json.model.d.ts +7 -0
  136. package/types/src/models/package-json.model.d.ts +35 -0
  137. package/types/src/models/project.model.d.ts +60 -0
  138. package/{src/models/source-file.ts → types/src/models/source-file.d.ts} +4 -6
  139. package/types/src/models/tsconfig.model.d.ts +5 -0
  140. package/types/src/models/vitest-config.model.d.ts +5 -0
  141. package/types/src/models/vscode-settings.model.d.ts +7 -0
  142. package/types/src/program.d.ts +3 -0
  143. package/{src/resolve-target-dir.ts → types/src/resolve-target-dir.d.ts} +1 -4
  144. package/types/src/services/scaffold.service.d.ts +22 -0
  145. package/types/src/version.d.ts +6 -0
  146. package/types/src/webapi/api-name.d.ts +14 -0
  147. package/types/src/webapi/cli-options.d.ts +6 -0
  148. package/{src/webapi/const.ts → types/src/webapi/const.d.ts} +7 -21
  149. package/types/src/webapi/create-api.d.ts +15 -0
  150. package/types/src/webapi/devcontainer/codebase-rag-mcp.d.ts +32 -0
  151. package/types/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
  152. package/types/src/webapi/devcontainer/host-scripts.d.ts +7 -0
  153. package/types/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
  154. package/types/src/webapi/devcontainer/templates/initialize.sh +169 -0
  155. package/types/src/webapi/devcontainer/templates/post-create.sh +35 -0
  156. package/types/src/webapi/devcontainer/templates/post-start.sh +65 -0
  157. package/types/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
  158. package/types/src/webapi/features/auth.feature.d.ts +10 -0
  159. package/types/src/webapi/features/auth0-cli.d.ts +80 -0
  160. package/types/src/webapi/features/biome-format.d.ts +5 -0
  161. package/types/src/webapi/features/database.feature.d.ts +7 -0
  162. package/types/src/webapi/features/finalize.feature.d.ts +2 -0
  163. package/types/src/webapi/features/postman.feature.d.ts +16 -0
  164. package/types/src/webapi/models/api-package-json.model.d.ts +18 -0
  165. package/types/src/webapi/models/auth-config.model.d.ts +26 -0
  166. package/types/src/webapi/models/controller-source-file.model.d.ts +46 -0
  167. package/types/src/webapi/models/github-ci.model.d.ts +9 -0
  168. package/types/src/webapi/models/main-source-file.model.d.ts +54 -0
  169. package/types/src/webapi/models/production-dockerfile.model.d.ts +23 -0
  170. package/types/src/webapi/models/sample-files.model.d.ts +7 -0
  171. package/types/src/webapi/models/webapi-image.model.d.ts +12 -0
  172. package/types/src/webapi/postman/hello-openapi.d.ts +19 -0
  173. package/types/src/webapi/postman/local-view.d.ts +17 -0
  174. package/types/src/webapi/postman/openapi-to-postman.d.ts +62 -0
  175. package/types/src/webapi/workspace-readme.d.ts +18 -0
  176. package/types/src/webapi.action.d.ts +14 -0
  177. package/types/src/webapi.command.d.ts +11 -0
  178. package/src/add-api.action.ts +0 -25
  179. package/src/add-api.command.ts +0 -31
  180. package/src/add.command.ts +0 -20
  181. package/src/add.module.ts +0 -11
  182. package/src/cli.ts +0 -4
  183. package/src/create.command.ts +0 -20
  184. package/src/create.module.ts +0 -11
  185. package/src/domain/prompt.ts +0 -50
  186. package/src/models/compose.model.ts +0 -205
  187. package/src/models/config-yaml.model.ts +0 -83
  188. package/src/models/const.ts +0 -20
  189. package/src/models/dev-container.model.ts +0 -136
  190. package/src/models/docker-image.model.ts +0 -343
  191. package/src/models/env-file.model.ts +0 -45
  192. package/src/models/gitignore.model.ts +0 -35
  193. package/src/models/launch-json.model.ts +0 -60
  194. package/src/models/package-json.model.ts +0 -169
  195. package/src/models/project.model.ts +0 -141
  196. package/src/models/tsconfig.model.ts +0 -29
  197. package/src/models/vitest-config.model.ts +0 -26
  198. package/src/models/vscode-settings.model.ts +0 -24
  199. package/src/program.ts +0 -63
  200. package/src/services/scaffold.service.ts +0 -89
  201. package/src/version.ts +0 -56
  202. package/src/webapi/api-name.ts +0 -73
  203. package/src/webapi/cli-options.ts +0 -56
  204. package/src/webapi/create-api.ts +0 -275
  205. package/src/webapi/devcontainer/host-scripts.ts +0 -35
  206. package/src/webapi/features/auth.feature.ts +0 -454
  207. package/src/webapi/features/auth0-cli.ts +0 -421
  208. package/src/webapi/features/biome-format.ts +0 -34
  209. package/src/webapi/features/database.feature.ts +0 -522
  210. package/src/webapi/features/finalize.feature.ts +0 -112
  211. package/src/webapi/features/postman.feature.ts +0 -287
  212. package/src/webapi/models/api-package-json.model.ts +0 -60
  213. package/src/webapi/models/auth-config.model.ts +0 -36
  214. package/src/webapi/models/controller-source-file.model.ts +0 -232
  215. package/src/webapi/models/github-ci.model.ts +0 -188
  216. package/src/webapi/models/main-source-file.model.ts +0 -208
  217. package/src/webapi/models/production-dockerfile.model.ts +0 -162
  218. package/src/webapi/models/sample-files.model.ts +0 -45
  219. package/src/webapi/models/webapi-image.model.ts +0 -21
  220. package/src/webapi/postman/hello-openapi.ts +0 -92
  221. package/src/webapi/postman/local-view.ts +0 -195
  222. package/src/webapi/postman/openapi-to-postman.ts +0 -208
  223. package/src/webapi/workspace-readme.ts +0 -192
  224. package/src/webapi.action.ts +0 -22
  225. package/src/webapi.command.ts +0 -41
  226. package/tests/auth-postman.wiring.spec.ts +0 -263
  227. package/tests/auth0-cli.spec.ts +0 -232
  228. package/tests/biome-format.spec.ts +0 -49
  229. package/tests/cli.integration.spec.ts +0 -658
  230. package/tests/compose.model.spec.ts +0 -51
  231. package/tests/container-image.model.spec.ts +0 -162
  232. package/tests/dev-container.model.spec.ts +0 -29
  233. package/tests/devcontainer-base-image.spec.ts +0 -32
  234. package/tests/hello-di-inject.scaffold.spec.ts +0 -18
  235. package/tests/hello-route.contract.spec.ts +0 -94
  236. package/tests/package-json.order.spec.ts +0 -59
  237. package/tests/postman-from-openapi.spec.ts +0 -197
  238. package/tests/seed-devcontainer-templates.ts +0 -40
  239. package/tests/webapi/devcontainer/codebase-rag-mcp.spec.ts +0 -96
  240. /package/{src/index.ts → types/src/index.d.ts} +0 -0
@@ -0,0 +1,168 @@
1
+ /** Minimal OpenAPI 3 document shape used for Postman conversion. */ /**
2
+ * Canonical Hello WebAPI OpenAPI document used to generate Postman requests.
3
+ * Keep paths aligned with scaffolded HelloController (`/hello`, `/hello/{id}`).
4
+ */ export function buildHelloOpenApiDocument(projectName) {
5
+ return {
6
+ openapi: "3.0.3",
7
+ info: {
8
+ title: `${projectName} WebAPI`,
9
+ version: "1.0.0",
10
+ description: "Generated from OpenAPI for Postman. Auth/env overlays are applied separately."
11
+ },
12
+ servers: [
13
+ {
14
+ url: "{{baseUrl}}"
15
+ }
16
+ ],
17
+ paths: {
18
+ "/hello": {
19
+ get: {
20
+ operationId: "HelloController.getAll",
21
+ summary: "List (anonymous)",
22
+ tags: [
23
+ "Hello"
24
+ ],
25
+ parameters: [
26
+ {
27
+ name: "filter",
28
+ in: "query",
29
+ required: false,
30
+ schema: {
31
+ type: "string"
32
+ }
33
+ }
34
+ ],
35
+ responses: {
36
+ "200": {
37
+ description: "Successful response"
38
+ }
39
+ }
40
+ },
41
+ post: {
42
+ operationId: "HelloController.create",
43
+ summary: "Create",
44
+ tags: [
45
+ "Hello"
46
+ ],
47
+ requestBody: {
48
+ required: true,
49
+ content: {
50
+ "application/json": {
51
+ schema: {
52
+ type: "object",
53
+ properties: {
54
+ message: {
55
+ type: "string"
56
+ }
57
+ },
58
+ required: [
59
+ "message"
60
+ ],
61
+ example: {
62
+ message: "hello"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ },
68
+ responses: {
69
+ "200": {
70
+ description: "Successful response"
71
+ }
72
+ }
73
+ }
74
+ },
75
+ "/hello/{id}": {
76
+ get: {
77
+ operationId: "HelloController.getOne",
78
+ summary: "Get by id",
79
+ tags: [
80
+ "Hello"
81
+ ],
82
+ parameters: [
83
+ {
84
+ name: "id",
85
+ in: "path",
86
+ required: true,
87
+ schema: {
88
+ type: "string"
89
+ }
90
+ }
91
+ ],
92
+ responses: {
93
+ "200": {
94
+ description: "Successful response"
95
+ }
96
+ }
97
+ },
98
+ put: {
99
+ operationId: "HelloController.update",
100
+ summary: "Update",
101
+ tags: [
102
+ "Hello"
103
+ ],
104
+ parameters: [
105
+ {
106
+ name: "id",
107
+ in: "path",
108
+ required: true,
109
+ schema: {
110
+ type: "string"
111
+ }
112
+ }
113
+ ],
114
+ requestBody: {
115
+ required: true,
116
+ content: {
117
+ "application/json": {
118
+ schema: {
119
+ type: "object",
120
+ properties: {
121
+ message: {
122
+ type: "string"
123
+ }
124
+ },
125
+ required: [
126
+ "message"
127
+ ],
128
+ example: {
129
+ message: "updated"
130
+ }
131
+ }
132
+ }
133
+ }
134
+ },
135
+ responses: {
136
+ "200": {
137
+ description: "Successful response"
138
+ }
139
+ }
140
+ },
141
+ delete: {
142
+ operationId: "HelloController.remove",
143
+ summary: "Delete",
144
+ tags: [
145
+ "Hello"
146
+ ],
147
+ parameters: [
148
+ {
149
+ name: "id",
150
+ in: "path",
151
+ required: true,
152
+ schema: {
153
+ type: "string"
154
+ }
155
+ }
156
+ ],
157
+ responses: {
158
+ "200": {
159
+ description: "Successful response"
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ };
166
+ }
167
+
168
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy93ZWJhcGkvcG9zdG1hbi9oZWxsby1vcGVuYXBpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBNaW5pbWFsIE9wZW5BUEkgMyBkb2N1bWVudCBzaGFwZSB1c2VkIGZvciBQb3N0bWFuIGNvbnZlcnNpb24uICovXG5leHBvcnQgdHlwZSBTY2FmZm9sZE9wZW5BcGlEb2N1bWVudCA9IHtcblx0b3BlbmFwaTogXCIzLjAuM1wiO1xuXHRpbmZvOiB7IHRpdGxlOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZzsgZGVzY3JpcHRpb24/OiBzdHJpbmcgfTtcblx0c2VydmVycz86IEFycmF5PHsgdXJsOiBzdHJpbmc7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH0+O1xuXHRwYXRoczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xufTtcblxuLyoqXG4gKiBDYW5vbmljYWwgSGVsbG8gV2ViQVBJIE9wZW5BUEkgZG9jdW1lbnQgdXNlZCB0byBnZW5lcmF0ZSBQb3N0bWFuIHJlcXVlc3RzLlxuICogS2VlcCBwYXRocyBhbGlnbmVkIHdpdGggc2NhZmZvbGRlZCBIZWxsb0NvbnRyb2xsZXIgKGAvaGVsbG9gLCBgL2hlbGxvL3tpZH1gKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSGVsbG9PcGVuQXBpRG9jdW1lbnQocHJvamVjdE5hbWU6IHN0cmluZyk6IFNjYWZmb2xkT3BlbkFwaURvY3VtZW50IHtcblx0cmV0dXJuIHtcblx0XHRvcGVuYXBpOiBcIjMuMC4zXCIsXG5cdFx0aW5mbzoge1xuXHRcdFx0dGl0bGU6IGAke3Byb2plY3ROYW1lfSBXZWJBUElgLFxuXHRcdFx0dmVyc2lvbjogXCIxLjAuMFwiLFxuXHRcdFx0ZGVzY3JpcHRpb246XG5cdFx0XHRcdFwiR2VuZXJhdGVkIGZyb20gT3BlbkFQSSBmb3IgUG9zdG1hbi4gQXV0aC9lbnYgb3ZlcmxheXMgYXJlIGFwcGxpZWQgc2VwYXJhdGVseS5cIixcblx0XHR9LFxuXHRcdHNlcnZlcnM6IFt7IHVybDogXCJ7e2Jhc2VVcmx9fVwiIH1dLFxuXHRcdHBhdGhzOiB7XG5cdFx0XHRcIi9oZWxsb1wiOiB7XG5cdFx0XHRcdGdldDoge1xuXHRcdFx0XHRcdG9wZXJhdGlvbklkOiBcIkhlbGxvQ29udHJvbGxlci5nZXRBbGxcIixcblx0XHRcdFx0XHRzdW1tYXJ5OiBcIkxpc3QgKGFub255bW91cylcIixcblx0XHRcdFx0XHR0YWdzOiBbXCJIZWxsb1wiXSxcblx0XHRcdFx0XHRwYXJhbWV0ZXJzOiBbXG5cdFx0XHRcdFx0XHR7IG5hbWU6IFwiZmlsdGVyXCIsIGluOiBcInF1ZXJ5XCIsIHJlcXVpcmVkOiBmYWxzZSwgc2NoZW1hOiB7IHR5cGU6IFwic3RyaW5nXCIgfSB9LFxuXHRcdFx0XHRcdF0sXG5cdFx0XHRcdFx0cmVzcG9uc2VzOiB7IFwiMjAwXCI6IHsgZGVzY3JpcHRpb246IFwiU3VjY2Vzc2Z1bCByZXNwb25zZVwiIH0gfSxcblx0XHRcdFx0fSxcblx0XHRcdFx0cG9zdDoge1xuXHRcdFx0XHRcdG9wZXJhdGlvbklkOiBcIkhlbGxvQ29udHJvbGxlci5jcmVhdGVcIixcblx0XHRcdFx0XHRzdW1tYXJ5OiBcIkNyZWF0ZVwiLFxuXHRcdFx0XHRcdHRhZ3M6IFtcIkhlbGxvXCJdLFxuXHRcdFx0XHRcdHJlcXVlc3RCb2R5OiB7XG5cdFx0XHRcdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdFx0XHRcdGNvbnRlbnQ6IHtcblx0XHRcdFx0XHRcdFx0XCJhcHBsaWNhdGlvbi9qc29uXCI6IHtcblx0XHRcdFx0XHRcdFx0XHRzY2hlbWE6IHtcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGU6IFwib2JqZWN0XCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRwcm9wZXJ0aWVzOiB7IG1lc3NhZ2U6IHsgdHlwZTogXCJzdHJpbmdcIiB9IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXF1aXJlZDogW1wibWVzc2FnZVwiXSxcblx0XHRcdFx0XHRcdFx0XHRcdGV4YW1wbGU6IHsgbWVzc2FnZTogXCJoZWxsb1wiIH0sXG5cdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRyZXNwb25zZXM6IHsgXCIyMDBcIjogeyBkZXNjcmlwdGlvbjogXCJTdWNjZXNzZnVsIHJlc3BvbnNlXCIgfSB9LFxuXHRcdFx0XHR9LFxuXHRcdFx0fSxcblx0XHRcdFwiL2hlbGxvL3tpZH1cIjoge1xuXHRcdFx0XHRnZXQ6IHtcblx0XHRcdFx0XHRvcGVyYXRpb25JZDogXCJIZWxsb0NvbnRyb2xsZXIuZ2V0T25lXCIsXG5cdFx0XHRcdFx0c3VtbWFyeTogXCJHZXQgYnkgaWRcIixcblx0XHRcdFx0XHR0YWdzOiBbXCJIZWxsb1wiXSxcblx0XHRcdFx0XHRwYXJhbWV0ZXJzOiBbeyBuYW1lOiBcImlkXCIsIGluOiBcInBhdGhcIiwgcmVxdWlyZWQ6IHRydWUsIHNjaGVtYTogeyB0eXBlOiBcInN0cmluZ1wiIH0gfV0sXG5cdFx0XHRcdFx0cmVzcG9uc2VzOiB7IFwiMjAwXCI6IHsgZGVzY3JpcHRpb246IFwiU3VjY2Vzc2Z1bCByZXNwb25zZVwiIH0gfSxcblx0XHRcdFx0fSxcblx0XHRcdFx0cHV0OiB7XG5cdFx0XHRcdFx0b3BlcmF0aW9uSWQ6IFwiSGVsbG9Db250cm9sbGVyLnVwZGF0ZVwiLFxuXHRcdFx0XHRcdHN1bW1hcnk6IFwiVXBkYXRlXCIsXG5cdFx0XHRcdFx0dGFnczogW1wiSGVsbG9cIl0sXG5cdFx0XHRcdFx0cGFyYW1ldGVyczogW3sgbmFtZTogXCJpZFwiLCBpbjogXCJwYXRoXCIsIHJlcXVpcmVkOiB0cnVlLCBzY2hlbWE6IHsgdHlwZTogXCJzdHJpbmdcIiB9IH1dLFxuXHRcdFx0XHRcdHJlcXVlc3RCb2R5OiB7XG5cdFx0XHRcdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdFx0XHRcdGNvbnRlbnQ6IHtcblx0XHRcdFx0XHRcdFx0XCJhcHBsaWNhdGlvbi9qc29uXCI6IHtcblx0XHRcdFx0XHRcdFx0XHRzY2hlbWE6IHtcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGU6IFwib2JqZWN0XCIsXG5cdFx0XHRcdFx0XHRcdFx0XHRwcm9wZXJ0aWVzOiB7IG1lc3NhZ2U6IHsgdHlwZTogXCJzdHJpbmdcIiB9IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXF1aXJlZDogW1wibWVzc2FnZVwiXSxcblx0XHRcdFx0XHRcdFx0XHRcdGV4YW1wbGU6IHsgbWVzc2FnZTogXCJ1cGRhdGVkXCIgfSxcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHJlc3BvbnNlczogeyBcIjIwMFwiOiB7IGRlc2NyaXB0aW9uOiBcIlN1Y2Nlc3NmdWwgcmVzcG9uc2VcIiB9IH0sXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGRlbGV0ZToge1xuXHRcdFx0XHRcdG9wZXJhdGlvbklkOiBcIkhlbGxvQ29udHJvbGxlci5yZW1vdmVcIixcblx0XHRcdFx0XHRzdW1tYXJ5OiBcIkRlbGV0ZVwiLFxuXHRcdFx0XHRcdHRhZ3M6IFtcIkhlbGxvXCJdLFxuXHRcdFx0XHRcdHBhcmFtZXRlcnM6IFt7IG5hbWU6IFwiaWRcIiwgaW46IFwicGF0aFwiLCByZXF1aXJlZDogdHJ1ZSwgc2NoZW1hOiB7IHR5cGU6IFwic3RyaW5nXCIgfSB9XSxcblx0XHRcdFx0XHRyZXNwb25zZXM6IHsgXCIyMDBcIjogeyBkZXNjcmlwdGlvbjogXCJTdWNjZXNzZnVsIHJlc3BvbnNlXCIgfSB9LFxuXHRcdFx0XHR9LFxuXHRcdFx0fSxcblx0XHR9LFxuXHR9O1xufVxuIl0sIm5hbWVzIjpbImJ1aWxkSGVsbG9PcGVuQXBpRG9jdW1lbnQiLCJwcm9qZWN0TmFtZSIsIm9wZW5hcGkiLCJpbmZvIiwidGl0bGUiLCJ2ZXJzaW9uIiwiZGVzY3JpcHRpb24iLCJzZXJ2ZXJzIiwidXJsIiwicGF0aHMiLCJnZXQiLCJvcGVyYXRpb25JZCIsInN1bW1hcnkiLCJ0YWdzIiwicGFyYW1ldGVycyIsIm5hbWUiLCJpbiIsInJlcXVpcmVkIiwic2NoZW1hIiwidHlwZSIsInJlc3BvbnNlcyIsInBvc3QiLCJyZXF1ZXN0Qm9keSIsImNvbnRlbnQiLCJwcm9wZXJ0aWVzIiwibWVzc2FnZSIsImV4YW1wbGUiLCJwdXQiLCJkZWxldGUiXSwibWFwcGluZ3MiOiJBQUFBLGtFQUFrRSxHQVFsRTs7O0NBR0MsR0FDRCxPQUFPLFNBQVNBLDBCQUEwQkMsV0FBbUI7SUFDNUQsT0FBTztRQUNOQyxTQUFTO1FBQ1RDLE1BQU07WUFDTEMsT0FBTyxHQUFHSCxZQUFZLE9BQU8sQ0FBQztZQUM5QkksU0FBUztZQUNUQyxhQUNDO1FBQ0Y7UUFDQUMsU0FBUztZQUFDO2dCQUFFQyxLQUFLO1lBQWM7U0FBRTtRQUNqQ0MsT0FBTztZQUNOLFVBQVU7Z0JBQ1RDLEtBQUs7b0JBQ0pDLGFBQWE7b0JBQ2JDLFNBQVM7b0JBQ1RDLE1BQU07d0JBQUM7cUJBQVE7b0JBQ2ZDLFlBQVk7d0JBQ1g7NEJBQUVDLE1BQU07NEJBQVVDLElBQUk7NEJBQVNDLFVBQVU7NEJBQU9DLFFBQVE7Z0NBQUVDLE1BQU07NEJBQVM7d0JBQUU7cUJBQzNFO29CQUNEQyxXQUFXO3dCQUFFLE9BQU87NEJBQUVkLGFBQWE7d0JBQXNCO29CQUFFO2dCQUM1RDtnQkFDQWUsTUFBTTtvQkFDTFYsYUFBYTtvQkFDYkMsU0FBUztvQkFDVEMsTUFBTTt3QkFBQztxQkFBUTtvQkFDZlMsYUFBYTt3QkFDWkwsVUFBVTt3QkFDVk0sU0FBUzs0QkFDUixvQkFBb0I7Z0NBQ25CTCxRQUFRO29DQUNQQyxNQUFNO29DQUNOSyxZQUFZO3dDQUFFQyxTQUFTOzRDQUFFTixNQUFNO3dDQUFTO29DQUFFO29DQUMxQ0YsVUFBVTt3Q0FBQztxQ0FBVTtvQ0FDckJTLFNBQVM7d0NBQUVELFNBQVM7b0NBQVE7Z0NBQzdCOzRCQUNEO3dCQUNEO29CQUNEO29CQUNBTCxXQUFXO3dCQUFFLE9BQU87NEJBQUVkLGFBQWE7d0JBQXNCO29CQUFFO2dCQUM1RDtZQUNEO1lBQ0EsZUFBZTtnQkFDZEksS0FBSztvQkFDSkMsYUFBYTtvQkFDYkMsU0FBUztvQkFDVEMsTUFBTTt3QkFBQztxQkFBUTtvQkFDZkMsWUFBWTt3QkFBQzs0QkFBRUMsTUFBTTs0QkFBTUMsSUFBSTs0QkFBUUMsVUFBVTs0QkFBTUMsUUFBUTtnQ0FBRUMsTUFBTTs0QkFBUzt3QkFBRTtxQkFBRTtvQkFDcEZDLFdBQVc7d0JBQUUsT0FBTzs0QkFBRWQsYUFBYTt3QkFBc0I7b0JBQUU7Z0JBQzVEO2dCQUNBcUIsS0FBSztvQkFDSmhCLGFBQWE7b0JBQ2JDLFNBQVM7b0JBQ1RDLE1BQU07d0JBQUM7cUJBQVE7b0JBQ2ZDLFlBQVk7d0JBQUM7NEJBQUVDLE1BQU07NEJBQU1DLElBQUk7NEJBQVFDLFVBQVU7NEJBQU1DLFFBQVE7Z0NBQUVDLE1BQU07NEJBQVM7d0JBQUU7cUJBQUU7b0JBQ3BGRyxhQUFhO3dCQUNaTCxVQUFVO3dCQUNWTSxTQUFTOzRCQUNSLG9CQUFvQjtnQ0FDbkJMLFFBQVE7b0NBQ1BDLE1BQU07b0NBQ05LLFlBQVk7d0NBQUVDLFNBQVM7NENBQUVOLE1BQU07d0NBQVM7b0NBQUU7b0NBQzFDRixVQUFVO3dDQUFDO3FDQUFVO29DQUNyQlMsU0FBUzt3Q0FBRUQsU0FBUztvQ0FBVTtnQ0FDL0I7NEJBQ0Q7d0JBQ0Q7b0JBQ0Q7b0JBQ0FMLFdBQVc7d0JBQUUsT0FBTzs0QkFBRWQsYUFBYTt3QkFBc0I7b0JBQUU7Z0JBQzVEO2dCQUNBc0IsUUFBUTtvQkFDUGpCLGFBQWE7b0JBQ2JDLFNBQVM7b0JBQ1RDLE1BQU07d0JBQUM7cUJBQVE7b0JBQ2ZDLFlBQVk7d0JBQUM7NEJBQUVDLE1BQU07NEJBQU1DLElBQUk7NEJBQVFDLFVBQVU7NEJBQU1DLFFBQVE7Z0NBQUVDLE1BQU07NEJBQVM7d0JBQUU7cUJBQUU7b0JBQ3BGQyxXQUFXO3dCQUFFLE9BQU87NEJBQUVkLGFBQWE7d0JBQXNCO29CQUFFO2dCQUM1RDtZQUNEO1FBQ0Q7SUFDRDtBQUNEIn0=
@@ -0,0 +1,169 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { openApiPathParamsToColon } from "./openapi-to-postman.js";
3
+ function yamlQuote(value) {
4
+ if (/[:#{}[\],&*?|<>=!%@`]/.test(value) || value.includes("\n") || value === "") {
5
+ return JSON.stringify(value);
6
+ }
7
+ return value;
8
+ }
9
+ /** Local View / Native Git environment (YAML). */ export function buildEnvironmentYaml(name, auth, options) {
10
+ const values = [
11
+ {
12
+ key: "baseUrl",
13
+ value: "http://localhost:3000"
14
+ }
15
+ ];
16
+ if (auth?.auth0Domain) {
17
+ values.push({
18
+ key: "auth0Domain",
19
+ value: auth.auth0Domain
20
+ }, {
21
+ key: "auth0Audience",
22
+ value: auth.auth0Audience ?? ""
23
+ }, {
24
+ key: "auth0ClientId",
25
+ value: auth.auth0ClientId ?? ""
26
+ }, {
27
+ key: "authUrl",
28
+ value: `https://${auth.auth0Domain}/authorize?audience=${auth.auth0Audience ?? ""}`
29
+ }, {
30
+ key: "accessTokenUrl",
31
+ value: `https://${auth.auth0Domain}/oauth/token`
32
+ }, {
33
+ key: "callbackUrl",
34
+ value: options.callbacks[0]
35
+ }, {
36
+ key: "scope",
37
+ value: options.scopes
38
+ });
39
+ }
40
+ const lines = [
41
+ `name: ${yamlQuote(name)}`,
42
+ "values:"
43
+ ];
44
+ for (const v of values){
45
+ lines.push(` - key: ${v.key}`);
46
+ lines.push(` value: ${yamlQuote(v.value)}`);
47
+ lines.push(" enabled: true");
48
+ }
49
+ return `${lines.join("\n")}\n`;
50
+ }
51
+ /**
52
+ * Build Postman Local View multi-file YAML from a v2.1 collection (routes)
53
+ * plus hand-authored Auth0 overlay.
54
+ */ export function buildLocalViewFilesFromCollection(collection, projectName, auth, options) {
55
+ const collectionDir = `postman/collections/${projectName} WebAPI`;
56
+ const files = [];
57
+ const authBlock = auth?.auth0Domain ? [
58
+ "auth:",
59
+ ` - id: ${randomUUID()}`,
60
+ " type: oauth2",
61
+ " name: OAuth 2.0",
62
+ " credentials:",
63
+ " addTokenTo: header",
64
+ " grant_type: authorization_code_with_pkce",
65
+ ` authUrl: https://${auth.auth0Domain}/authorize?audience=${auth.auth0Audience ?? ""}`,
66
+ ` accessTokenUrl: https://${auth.auth0Domain}/oauth/token`,
67
+ ` clientId: ${yamlQuote(auth.auth0ClientId ?? "")}`,
68
+ ` scope: ${yamlQuote(options.scopes)}`,
69
+ ` redirect_uri: ${options.callbacks[0]}`,
70
+ " useBrowser: true",
71
+ " challengeAlgorithm: S256",
72
+ " client_authentication: body",
73
+ ' clientSecret: ""',
74
+ ` tokenName: ${yamlQuote(`${projectName} Access Token`)}`,
75
+ ""
76
+ ].join("\n") : "";
77
+ files.push({
78
+ filePath: `${collectionDir}/.resources/definition.yaml`,
79
+ content: [
80
+ "$kind: collection",
81
+ `name: ${yamlQuote(`${projectName} WebAPI`)}`,
82
+ "schemaVersion: '3.0'",
83
+ "description: >-",
84
+ " Open this project root in Postman Local View (Files → Open folder).",
85
+ " Select the Local environment, then Authorization → Get New Access Token (PKCE).",
86
+ " Route requests are generated from OpenAPI; Auth0 overlay is hand-authored.",
87
+ authBlock
88
+ ].filter((l)=>l !== undefined).join("\n").replace(/\n+$/, "\n")
89
+ });
90
+ let folderOrder = 1000;
91
+ for (const folder of collection.item ?? []){
92
+ if (folder.item == null) {
93
+ continue;
94
+ }
95
+ const folderName = folder.name ?? "Requests";
96
+ files.push({
97
+ filePath: `${collectionDir}/${folderName}/.resources/definition.yaml`,
98
+ content: [
99
+ "$kind: folder",
100
+ `name: ${yamlQuote(folderName)}`,
101
+ `order: ${folderOrder}`,
102
+ ""
103
+ ].join("\n")
104
+ });
105
+ folderOrder += 1000;
106
+ let requestOrder = 1000;
107
+ for (const child of folder.item){
108
+ const yaml = requestToLocalViewYaml(child, requestOrder);
109
+ if (yaml == null) {
110
+ continue;
111
+ }
112
+ const fileName = `${sanitizeFileName(child.name ?? "Request")}.request.yaml`;
113
+ files.push({
114
+ filePath: `${collectionDir}/${folderName}/${fileName}`,
115
+ content: yaml
116
+ });
117
+ requestOrder += 1000;
118
+ }
119
+ }
120
+ return files;
121
+ }
122
+ function requestToLocalViewYaml(item, order) {
123
+ const request = item.request;
124
+ if (request == null) {
125
+ return null;
126
+ }
127
+ const method = (request.method ?? "GET").toUpperCase();
128
+ const url = requestUrlForLocalView(request);
129
+ const lines = [
130
+ "$kind: http-request",
131
+ `name: ${yamlQuote(item.name ?? method)}`,
132
+ `method: ${method}`,
133
+ `url: ${yamlQuote(url)}`
134
+ ];
135
+ if (request.auth?.type === "noauth") {
136
+ lines.push("auth:", " type: noauth");
137
+ }
138
+ const contentType = request.header?.find((h)=>h.key.toLowerCase() === "content-type")?.value;
139
+ const rawBody = request.body?.raw?.trim();
140
+ if (rawBody) {
141
+ lines.push("headers:");
142
+ lines.push(` Content-Type: ${contentType ?? "application/json"}`);
143
+ lines.push("body:");
144
+ lines.push(" type: json");
145
+ lines.push(" content: |-");
146
+ for (const bodyLine of rawBody.split("\n")){
147
+ lines.push(` ${bodyLine}`);
148
+ }
149
+ }
150
+ lines.push(`order: ${order}`, "");
151
+ return lines.join("\n");
152
+ }
153
+ function requestUrlForLocalView(request) {
154
+ const url = request.url;
155
+ if (typeof url === "string") {
156
+ return openApiPathParamsToColon(url);
157
+ }
158
+ if (url?.raw) {
159
+ return openApiPathParamsToColon(url.raw);
160
+ }
161
+ const host = url?.host?.[0] ?? "{{baseUrl}}";
162
+ const path = (url?.path ?? []).map((segment)=>openApiPathParamsToColon(String(segment))).join("/");
163
+ return path ? `${host}/${path}` : host;
164
+ }
165
+ function sanitizeFileName(name) {
166
+ return name.replace(/[^\w\s()-]+/g, "").trim() || "Request";
167
+ }
168
+
169
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy93ZWJhcGkvcG9zdG1hbi9sb2NhbC12aWV3LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7XG5cdHR5cGUgQXV0aDBFbnYsXG5cdG9wZW5BcGlQYXRoUGFyYW1zVG9Db2xvbixcblx0dHlwZSBQb3N0bWFuQ29sbGVjdGlvbixcblx0dHlwZSBQb3N0bWFuSXRlbSxcblx0dHlwZSBQb3N0bWFuUmVxdWVzdCxcbn0gZnJvbSBcIi4vb3BlbmFwaS10by1wb3N0bWFuLmpzXCI7XG5cbmZ1bmN0aW9uIHlhbWxRdW90ZSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKC9bOiN7fVtcXF0sJio/fDw+PSElQGBdLy50ZXN0KHZhbHVlKSB8fCB2YWx1ZS5pbmNsdWRlcyhcIlxcblwiKSB8fCB2YWx1ZSA9PT0gXCJcIikge1xuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufVxuXG4vKiogTG9jYWwgVmlldyAvIE5hdGl2ZSBHaXQgZW52aXJvbm1lbnQgKFlBTUwpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRW52aXJvbm1lbnRZYW1sKFxuXHRuYW1lOiBzdHJpbmcsXG5cdGF1dGg6IEF1dGgwRW52IHwgdW5kZWZpbmVkLFxuXHRvcHRpb25zOiB7IGNhbGxiYWNrczogcmVhZG9ubHkgc3RyaW5nW107IHNjb3Blczogc3RyaW5nIH0sXG4pOiBzdHJpbmcge1xuXHRjb25zdCB2YWx1ZXM6IEFycmF5PHsga2V5OiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfT4gPSBbXG5cdFx0eyBrZXk6IFwiYmFzZVVybFwiLCB2YWx1ZTogXCJodHRwOi8vbG9jYWxob3N0OjMwMDBcIiB9LFxuXHRdO1xuXHRpZiAoYXV0aD8uYXV0aDBEb21haW4pIHtcblx0XHR2YWx1ZXMucHVzaChcblx0XHRcdHsga2V5OiBcImF1dGgwRG9tYWluXCIsIHZhbHVlOiBhdXRoLmF1dGgwRG9tYWluIH0sXG5cdFx0XHR7IGtleTogXCJhdXRoMEF1ZGllbmNlXCIsIHZhbHVlOiBhdXRoLmF1dGgwQXVkaWVuY2UgPz8gXCJcIiB9LFxuXHRcdFx0eyBrZXk6IFwiYXV0aDBDbGllbnRJZFwiLCB2YWx1ZTogYXV0aC5hdXRoMENsaWVudElkID8/IFwiXCIgfSxcblx0XHRcdHtcblx0XHRcdFx0a2V5OiBcImF1dGhVcmxcIixcblx0XHRcdFx0dmFsdWU6IGBodHRwczovLyR7YXV0aC5hdXRoMERvbWFpbn0vYXV0aG9yaXplP2F1ZGllbmNlPSR7YXV0aC5hdXRoMEF1ZGllbmNlID8/IFwiXCJ9YCxcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdGtleTogXCJhY2Nlc3NUb2tlblVybFwiLFxuXHRcdFx0XHR2YWx1ZTogYGh0dHBzOi8vJHthdXRoLmF1dGgwRG9tYWlufS9vYXV0aC90b2tlbmAsXG5cdFx0XHR9LFxuXHRcdFx0eyBrZXk6IFwiY2FsbGJhY2tVcmxcIiwgdmFsdWU6IG9wdGlvbnMuY2FsbGJhY2tzWzBdIH0sXG5cdFx0XHR7IGtleTogXCJzY29wZVwiLCB2YWx1ZTogb3B0aW9ucy5zY29wZXMgfSxcblx0XHQpO1xuXHR9XG5cblx0Y29uc3QgbGluZXMgPSBbYG5hbWU6ICR7eWFtbFF1b3RlKG5hbWUpfWAsIFwidmFsdWVzOlwiXTtcblx0Zm9yIChjb25zdCB2IG9mIHZhbHVlcykge1xuXHRcdGxpbmVzLnB1c2goYCAgLSBrZXk6ICR7di5rZXl9YCk7XG5cdFx0bGluZXMucHVzaChgICAgIHZhbHVlOiAke3lhbWxRdW90ZSh2LnZhbHVlKX1gKTtcblx0XHRsaW5lcy5wdXNoKFwiICAgIGVuYWJsZWQ6IHRydWVcIik7XG5cdH1cblx0cmV0dXJuIGAke2xpbmVzLmpvaW4oXCJcXG5cIil9XFxuYDtcbn1cblxuLyoqXG4gKiBCdWlsZCBQb3N0bWFuIExvY2FsIFZpZXcgbXVsdGktZmlsZSBZQU1MIGZyb20gYSB2Mi4xIGNvbGxlY3Rpb24gKHJvdXRlcylcbiAqIHBsdXMgaGFuZC1hdXRob3JlZCBBdXRoMCBvdmVybGF5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRMb2NhbFZpZXdGaWxlc0Zyb21Db2xsZWN0aW9uKFxuXHRjb2xsZWN0aW9uOiBQb3N0bWFuQ29sbGVjdGlvbixcblx0cHJvamVjdE5hbWU6IHN0cmluZyxcblx0YXV0aDogQXV0aDBFbnYgfCB1bmRlZmluZWQsXG5cdG9wdGlvbnM6IHsgY2FsbGJhY2tzOiByZWFkb25seSBzdHJpbmdbXTsgc2NvcGVzOiBzdHJpbmcgfSxcbik6IEFycmF5PHsgZmlsZVBhdGg6IHN0cmluZzsgY29udGVudDogc3RyaW5nIH0+IHtcblx0Y29uc3QgY29sbGVjdGlvbkRpciA9IGBwb3N0bWFuL2NvbGxlY3Rpb25zLyR7cHJvamVjdE5hbWV9IFdlYkFQSWA7XG5cdGNvbnN0IGZpbGVzOiBBcnJheTx7IGZpbGVQYXRoOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9PiA9IFtdO1xuXG5cdGNvbnN0IGF1dGhCbG9jayA9IGF1dGg/LmF1dGgwRG9tYWluXG5cdFx0PyBbXG5cdFx0XHRcdFwiYXV0aDpcIixcblx0XHRcdFx0YCAgLSBpZDogJHtyYW5kb21VVUlEKCl9YCxcblx0XHRcdFx0XCIgICAgdHlwZTogb2F1dGgyXCIsXG5cdFx0XHRcdFwiICAgIG5hbWU6IE9BdXRoIDIuMFwiLFxuXHRcdFx0XHRcIiAgICBjcmVkZW50aWFsczpcIixcblx0XHRcdFx0XCIgICAgICBhZGRUb2tlblRvOiBoZWFkZXJcIixcblx0XHRcdFx0XCIgICAgICBncmFudF90eXBlOiBhdXRob3JpemF0aW9uX2NvZGVfd2l0aF9wa2NlXCIsXG5cdFx0XHRcdGAgICAgICBhdXRoVXJsOiBodHRwczovLyR7YXV0aC5hdXRoMERvbWFpbn0vYXV0aG9yaXplP2F1ZGllbmNlPSR7YXV0aC5hdXRoMEF1ZGllbmNlID8/IFwiXCJ9YCxcblx0XHRcdFx0YCAgICAgIGFjY2Vzc1Rva2VuVXJsOiBodHRwczovLyR7YXV0aC5hdXRoMERvbWFpbn0vb2F1dGgvdG9rZW5gLFxuXHRcdFx0XHRgICAgICAgY2xpZW50SWQ6ICR7eWFtbFF1b3RlKGF1dGguYXV0aDBDbGllbnRJZCA/PyBcIlwiKX1gLFxuXHRcdFx0XHRgICAgICAgc2NvcGU6ICR7eWFtbFF1b3RlKG9wdGlvbnMuc2NvcGVzKX1gLFxuXHRcdFx0XHRgICAgICAgcmVkaXJlY3RfdXJpOiAke29wdGlvbnMuY2FsbGJhY2tzWzBdfWAsXG5cdFx0XHRcdFwiICAgICAgdXNlQnJvd3NlcjogdHJ1ZVwiLFxuXHRcdFx0XHRcIiAgICAgIGNoYWxsZW5nZUFsZ29yaXRobTogUzI1NlwiLFxuXHRcdFx0XHRcIiAgICAgIGNsaWVudF9hdXRoZW50aWNhdGlvbjogYm9keVwiLFxuXHRcdFx0XHQnICAgICAgY2xpZW50U2VjcmV0OiBcIlwiJyxcblx0XHRcdFx0YCAgICAgIHRva2VuTmFtZTogJHt5YW1sUXVvdGUoYCR7cHJvamVjdE5hbWV9IEFjY2VzcyBUb2tlbmApfWAsXG5cdFx0XHRcdFwiXCIsXG5cdFx0XHRdLmpvaW4oXCJcXG5cIilcblx0XHQ6IFwiXCI7XG5cblx0ZmlsZXMucHVzaCh7XG5cdFx0ZmlsZVBhdGg6IGAke2NvbGxlY3Rpb25EaXJ9Ly5yZXNvdXJjZXMvZGVmaW5pdGlvbi55YW1sYCxcblx0XHRjb250ZW50OiBbXG5cdFx0XHRcIiRraW5kOiBjb2xsZWN0aW9uXCIsXG5cdFx0XHRgbmFtZTogJHt5YW1sUXVvdGUoYCR7cHJvamVjdE5hbWV9IFdlYkFQSWApfWAsXG5cdFx0XHRcInNjaGVtYVZlcnNpb246ICczLjAnXCIsXG5cdFx0XHRcImRlc2NyaXB0aW9uOiA+LVwiLFxuXHRcdFx0XCIgIE9wZW4gdGhpcyBwcm9qZWN0IHJvb3QgaW4gUG9zdG1hbiBMb2NhbCBWaWV3IChGaWxlcyDihpIgT3BlbiBmb2xkZXIpLlwiLFxuXHRcdFx0XCIgIFNlbGVjdCB0aGUgTG9jYWwgZW52aXJvbm1lbnQsIHRoZW4gQXV0aG9yaXphdGlvbiDihpIgR2V0IE5ldyBBY2Nlc3MgVG9rZW4gKFBLQ0UpLlwiLFxuXHRcdFx0XCIgIFJvdXRlIHJlcXVlc3RzIGFyZSBnZW5lcmF0ZWQgZnJvbSBPcGVuQVBJOyBBdXRoMCBvdmVybGF5IGlzIGhhbmQtYXV0aG9yZWQuXCIsXG5cdFx0XHRhdXRoQmxvY2ssXG5cdFx0XVxuXHRcdFx0LmZpbHRlcigobCkgPT4gbCAhPT0gdW5kZWZpbmVkKVxuXHRcdFx0LmpvaW4oXCJcXG5cIilcblx0XHRcdC5yZXBsYWNlKC9cXG4rJC8sIFwiXFxuXCIpLFxuXHR9KTtcblxuXHRsZXQgZm9sZGVyT3JkZXIgPSAxMDAwO1xuXHRmb3IgKGNvbnN0IGZvbGRlciBvZiBjb2xsZWN0aW9uLml0ZW0gPz8gW10pIHtcblx0XHRpZiAoZm9sZGVyLml0ZW0gPT0gbnVsbCkge1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXHRcdGNvbnN0IGZvbGRlck5hbWUgPSBmb2xkZXIubmFtZSA/PyBcIlJlcXVlc3RzXCI7XG5cdFx0ZmlsZXMucHVzaCh7XG5cdFx0XHRmaWxlUGF0aDogYCR7Y29sbGVjdGlvbkRpcn0vJHtmb2xkZXJOYW1lfS8ucmVzb3VyY2VzL2RlZmluaXRpb24ueWFtbGAsXG5cdFx0XHRjb250ZW50OiBbXG5cdFx0XHRcdFwiJGtpbmQ6IGZvbGRlclwiLFxuXHRcdFx0XHRgbmFtZTogJHt5YW1sUXVvdGUoZm9sZGVyTmFtZSl9YCxcblx0XHRcdFx0YG9yZGVyOiAke2ZvbGRlck9yZGVyfWAsXG5cdFx0XHRcdFwiXCIsXG5cdFx0XHRdLmpvaW4oXCJcXG5cIiksXG5cdFx0fSk7XG5cdFx0Zm9sZGVyT3JkZXIgKz0gMTAwMDtcblxuXHRcdGxldCByZXF1ZXN0T3JkZXIgPSAxMDAwO1xuXHRcdGZvciAoY29uc3QgY2hpbGQgb2YgZm9sZGVyLml0ZW0pIHtcblx0XHRcdGNvbnN0IHlhbWwgPSByZXF1ZXN0VG9Mb2NhbFZpZXdZYW1sKGNoaWxkLCByZXF1ZXN0T3JkZXIpO1xuXHRcdFx0aWYgKHlhbWwgPT0gbnVsbCkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGZpbGVOYW1lID0gYCR7c2FuaXRpemVGaWxlTmFtZShjaGlsZC5uYW1lID8/IFwiUmVxdWVzdFwiKX0ucmVxdWVzdC55YW1sYDtcblx0XHRcdGZpbGVzLnB1c2goe1xuXHRcdFx0XHRmaWxlUGF0aDogYCR7Y29sbGVjdGlvbkRpcn0vJHtmb2xkZXJOYW1lfS8ke2ZpbGVOYW1lfWAsXG5cdFx0XHRcdGNvbnRlbnQ6IHlhbWwsXG5cdFx0XHR9KTtcblx0XHRcdHJlcXVlc3RPcmRlciArPSAxMDAwO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmaWxlcztcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFRvTG9jYWxWaWV3WWFtbChpdGVtOiBQb3N0bWFuSXRlbSwgb3JkZXI6IG51bWJlcik6IHN0cmluZyB8IG51bGwge1xuXHRjb25zdCByZXF1ZXN0ID0gaXRlbS5yZXF1ZXN0O1xuXHRpZiAocmVxdWVzdCA9PSBudWxsKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0Y29uc3QgbWV0aG9kID0gKHJlcXVlc3QubWV0aG9kID8/IFwiR0VUXCIpLnRvVXBwZXJDYXNlKCk7XG5cdGNvbnN0IHVybCA9IHJlcXVlc3RVcmxGb3JMb2NhbFZpZXcocmVxdWVzdCk7XG5cdGNvbnN0IGxpbmVzID0gW1xuXHRcdFwiJGtpbmQ6IGh0dHAtcmVxdWVzdFwiLFxuXHRcdGBuYW1lOiAke3lhbWxRdW90ZShpdGVtLm5hbWUgPz8gbWV0aG9kKX1gLFxuXHRcdGBtZXRob2Q6ICR7bWV0aG9kfWAsXG5cdFx0YHVybDogJHt5YW1sUXVvdGUodXJsKX1gLFxuXHRdO1xuXG5cdGlmIChyZXF1ZXN0LmF1dGg/LnR5cGUgPT09IFwibm9hdXRoXCIpIHtcblx0XHRsaW5lcy5wdXNoKFwiYXV0aDpcIiwgXCIgIHR5cGU6IG5vYXV0aFwiKTtcblx0fVxuXG5cdGNvbnN0IGNvbnRlbnRUeXBlID0gcmVxdWVzdC5oZWFkZXI/LmZpbmQoXG5cdFx0KGgpID0+IGgua2V5LnRvTG93ZXJDYXNlKCkgPT09IFwiY29udGVudC10eXBlXCIsXG5cdCk/LnZhbHVlO1xuXHRjb25zdCByYXdCb2R5ID0gcmVxdWVzdC5ib2R5Py5yYXc/LnRyaW0oKTtcblx0aWYgKHJhd0JvZHkpIHtcblx0XHRsaW5lcy5wdXNoKFwiaGVhZGVyczpcIik7XG5cdFx0bGluZXMucHVzaChgICBDb250ZW50LVR5cGU6ICR7Y29udGVudFR5cGUgPz8gXCJhcHBsaWNhdGlvbi9qc29uXCJ9YCk7XG5cdFx0bGluZXMucHVzaChcImJvZHk6XCIpO1xuXHRcdGxpbmVzLnB1c2goXCIgIHR5cGU6IGpzb25cIik7XG5cdFx0bGluZXMucHVzaChcIiAgY29udGVudDogfC1cIik7XG5cdFx0Zm9yIChjb25zdCBib2R5TGluZSBvZiByYXdCb2R5LnNwbGl0KFwiXFxuXCIpKSB7XG5cdFx0XHRsaW5lcy5wdXNoKGAgICAgJHtib2R5TGluZX1gKTtcblx0XHR9XG5cdH1cblxuXHRsaW5lcy5wdXNoKGBvcmRlcjogJHtvcmRlcn1gLCBcIlwiKTtcblx0cmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RVcmxGb3JMb2NhbFZpZXcocmVxdWVzdDogUG9zdG1hblJlcXVlc3QpOiBzdHJpbmcge1xuXHRjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcblx0aWYgKHR5cGVvZiB1cmwgPT09IFwic3RyaW5nXCIpIHtcblx0XHRyZXR1cm4gb3BlbkFwaVBhdGhQYXJhbXNUb0NvbG9uKHVybCk7XG5cdH1cblx0aWYgKHVybD8ucmF3KSB7XG5cdFx0cmV0dXJuIG9wZW5BcGlQYXRoUGFyYW1zVG9Db2xvbih1cmwucmF3KTtcblx0fVxuXHRjb25zdCBob3N0ID0gdXJsPy5ob3N0Py5bMF0gPz8gXCJ7e2Jhc2VVcmx9fVwiO1xuXHRjb25zdCBwYXRoID0gKHVybD8ucGF0aCA/PyBbXSlcblx0XHQubWFwKChzZWdtZW50KSA9PiBvcGVuQXBpUGF0aFBhcmFtc1RvQ29sb24oU3RyaW5nKHNlZ21lbnQpKSlcblx0XHQuam9pbihcIi9cIik7XG5cdHJldHVybiBwYXRoID8gYCR7aG9zdH0vJHtwYXRofWAgOiBob3N0O1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUZpbGVOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG5cdHJldHVybiBuYW1lLnJlcGxhY2UoL1teXFx3XFxzKCktXSsvZywgXCJcIikudHJpbSgpIHx8IFwiUmVxdWVzdFwiO1xufVxuIl0sIm5hbWVzIjpbInJhbmRvbVVVSUQiLCJvcGVuQXBpUGF0aFBhcmFtc1RvQ29sb24iLCJ5YW1sUXVvdGUiLCJ2YWx1ZSIsInRlc3QiLCJpbmNsdWRlcyIsIkpTT04iLCJzdHJpbmdpZnkiLCJidWlsZEVudmlyb25tZW50WWFtbCIsIm5hbWUiLCJhdXRoIiwib3B0aW9ucyIsInZhbHVlcyIsImtleSIsImF1dGgwRG9tYWluIiwicHVzaCIsImF1dGgwQXVkaWVuY2UiLCJhdXRoMENsaWVudElkIiwiY2FsbGJhY2tzIiwic2NvcGVzIiwibGluZXMiLCJ2Iiwiam9pbiIsImJ1aWxkTG9jYWxWaWV3RmlsZXNGcm9tQ29sbGVjdGlvbiIsImNvbGxlY3Rpb24iLCJwcm9qZWN0TmFtZSIsImNvbGxlY3Rpb25EaXIiLCJmaWxlcyIsImF1dGhCbG9jayIsImZpbGVQYXRoIiwiY29udGVudCIsImZpbHRlciIsImwiLCJ1bmRlZmluZWQiLCJyZXBsYWNlIiwiZm9sZGVyT3JkZXIiLCJmb2xkZXIiLCJpdGVtIiwiZm9sZGVyTmFtZSIsInJlcXVlc3RPcmRlciIsImNoaWxkIiwieWFtbCIsInJlcXVlc3RUb0xvY2FsVmlld1lhbWwiLCJmaWxlTmFtZSIsInNhbml0aXplRmlsZU5hbWUiLCJvcmRlciIsInJlcXVlc3QiLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsInVybCIsInJlcXVlc3RVcmxGb3JMb2NhbFZpZXciLCJ0eXBlIiwiY29udGVudFR5cGUiLCJoZWFkZXIiLCJmaW5kIiwiaCIsInRvTG93ZXJDYXNlIiwicmF3Qm9keSIsImJvZHkiLCJyYXciLCJ0cmltIiwiYm9keUxpbmUiLCJzcGxpdCIsImhvc3QiLCJwYXRoIiwibWFwIiwic2VnbWVudCIsIlN0cmluZyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLGNBQWM7QUFDekMsU0FFQ0Msd0JBQXdCLFFBSWxCLDBCQUEwQjtBQUVqQyxTQUFTQyxVQUFVQyxLQUFhO0lBQy9CLElBQUksd0JBQXdCQyxJQUFJLENBQUNELFVBQVVBLE1BQU1FLFFBQVEsQ0FBQyxTQUFTRixVQUFVLElBQUk7UUFDaEYsT0FBT0csS0FBS0MsU0FBUyxDQUFDSjtJQUN2QjtJQUNBLE9BQU9BO0FBQ1I7QUFFQSxnREFBZ0QsR0FDaEQsT0FBTyxTQUFTSyxxQkFDZkMsSUFBWSxFQUNaQyxJQUEwQixFQUMxQkMsT0FBeUQ7SUFFekQsTUFBTUMsU0FBZ0Q7UUFDckQ7WUFBRUMsS0FBSztZQUFXVixPQUFPO1FBQXdCO0tBQ2pEO0lBQ0QsSUFBSU8sTUFBTUksYUFBYTtRQUN0QkYsT0FBT0csSUFBSSxDQUNWO1lBQUVGLEtBQUs7WUFBZVYsT0FBT08sS0FBS0ksV0FBVztRQUFDLEdBQzlDO1lBQUVELEtBQUs7WUFBaUJWLE9BQU9PLEtBQUtNLGFBQWEsSUFBSTtRQUFHLEdBQ3hEO1lBQUVILEtBQUs7WUFBaUJWLE9BQU9PLEtBQUtPLGFBQWEsSUFBSTtRQUFHLEdBQ3hEO1lBQ0NKLEtBQUs7WUFDTFYsT0FBTyxDQUFDLFFBQVEsRUFBRU8sS0FBS0ksV0FBVyxDQUFDLG9CQUFvQixFQUFFSixLQUFLTSxhQUFhLElBQUksSUFBSTtRQUNwRixHQUNBO1lBQ0NILEtBQUs7WUFDTFYsT0FBTyxDQUFDLFFBQVEsRUFBRU8sS0FBS0ksV0FBVyxDQUFDLFlBQVksQ0FBQztRQUNqRCxHQUNBO1lBQUVELEtBQUs7WUFBZVYsT0FBT1EsUUFBUU8sU0FBUyxDQUFDLEVBQUU7UUFBQyxHQUNsRDtZQUFFTCxLQUFLO1lBQVNWLE9BQU9RLFFBQVFRLE1BQU07UUFBQztJQUV4QztJQUVBLE1BQU1DLFFBQVE7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
@@ -0,0 +1,179 @@
1
+ import converter from "openapi-to-postmanv2";
2
+ function convertAsync(data, options) {
3
+ return new Promise((resolve, reject)=>{
4
+ converter.convert({
5
+ type: "json",
6
+ data
7
+ }, options, (err, result)=>{
8
+ if (err) {
9
+ reject(err);
10
+ return;
11
+ }
12
+ resolve(result);
13
+ });
14
+ });
15
+ }
16
+ /** Convert an OpenAPI document to a Postman Collection v2.1 via openapi-to-postmanv2. */ export async function openApiToPostmanCollection(document) {
17
+ const result = await convertAsync(document, {
18
+ folderStrategy: "Tags",
19
+ requestNameSource: "Fallback",
20
+ includeAuthInfoInExample: false
21
+ });
22
+ if (!result.result || result.output?.[0]?.data == null) {
23
+ throw new Error(result.reason ?? "openapi-to-postmanv2 conversion failed");
24
+ }
25
+ return result.output[0].data;
26
+ }
27
+ /**
28
+ * Overlay Auth0 OAuth2 (PKCE) collection auth and fix Local View-friendly URLs.
29
+ * Route items come from OpenAPI; auth/env remain hand-authored.
30
+ */ export function applyPostmanAuthOverlay(collection, projectName, auth, options) {
31
+ const next = {
32
+ ...collection,
33
+ info: {
34
+ ...collection.info,
35
+ name: `${projectName} WebAPI`,
36
+ description: options.description,
37
+ schema: collection.info.schema ?? "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
38
+ }
39
+ };
40
+ if (auth?.auth0Domain) {
41
+ next.auth = {
42
+ type: "oauth2",
43
+ oauth2: [
44
+ {
45
+ key: "grant_type",
46
+ value: "authorization_code_with_pkce",
47
+ type: "string"
48
+ },
49
+ {
50
+ key: "authUrl",
51
+ value: "https://{{auth0Domain}}/authorize?audience={{auth0Audience}}",
52
+ type: "string"
53
+ },
54
+ {
55
+ key: "accessTokenUrl",
56
+ value: "https://{{auth0Domain}}/oauth/token",
57
+ type: "string"
58
+ },
59
+ {
60
+ key: "clientId",
61
+ value: "{{auth0ClientId}}",
62
+ type: "string"
63
+ },
64
+ {
65
+ key: "scope",
66
+ value: options.scopes,
67
+ type: "string"
68
+ },
69
+ {
70
+ key: "redirect_uri",
71
+ value: options.callbacks[0],
72
+ type: "string"
73
+ },
74
+ {
75
+ key: "useBrowser",
76
+ value: "true",
77
+ type: "boolean"
78
+ },
79
+ {
80
+ key: "addTokenTo",
81
+ value: "header",
82
+ type: "string"
83
+ },
84
+ {
85
+ key: "challengeAlgorithm",
86
+ value: "S256",
87
+ type: "string"
88
+ },
89
+ {
90
+ key: "client_authentication",
91
+ value: "body",
92
+ type: "string"
93
+ },
94
+ {
95
+ key: "clientSecret",
96
+ value: "",
97
+ type: "string"
98
+ },
99
+ {
100
+ key: "tokenName",
101
+ value: `${projectName} Access Token`,
102
+ type: "string"
103
+ }
104
+ ]
105
+ };
106
+ }
107
+ next.item = rewriteCollectionItems(collection.item ?? [], {
108
+ markListAnonymous: true
109
+ });
110
+ return next;
111
+ }
112
+ function rewriteCollectionItems(items, opts) {
113
+ return items.map((item)=>{
114
+ if (item.item != null) {
115
+ return {
116
+ ...item,
117
+ item: rewriteCollectionItems(item.item, opts)
118
+ };
119
+ }
120
+ const request = item.request;
121
+ if (request == null) {
122
+ return item;
123
+ }
124
+ const method = (request.method ?? "GET").toUpperCase();
125
+ const rawUrl = requestUrlRaw(request);
126
+ const nextRequest = {
127
+ ...request,
128
+ url: toPostmanUrl(rawUrl)
129
+ };
130
+ // List Hello stays anonymous (matches scaffold AllowAnonymous on GET /hello).
131
+ if (opts.markListAnonymous && method === "GET" && normalizePath(rawUrl) === "/hello" && !rawUrl.includes("/:")) {
132
+ nextRequest.auth = {
133
+ type: "noauth"
134
+ };
135
+ }
136
+ return {
137
+ ...item,
138
+ request: nextRequest
139
+ };
140
+ });
141
+ }
142
+ function requestUrlRaw(request) {
143
+ const url = request.url;
144
+ if (typeof url === "string") {
145
+ return url;
146
+ }
147
+ if (url?.raw) {
148
+ return url.raw;
149
+ }
150
+ const host = url?.host?.[0] ?? "{{baseUrl}}";
151
+ const path = (url?.path ?? []).join("/");
152
+ return path ? `${host}/${path}` : host;
153
+ }
154
+ /** OpenAPI `{id}` → Postman `:id`, without touching `{{variables}}`. */ export function openApiPathParamsToColon(url) {
155
+ return url.replace(/(?<!\{)\{([A-Za-z_][\w]*)\}(?!\})/g, ":$1");
156
+ }
157
+ function normalizePath(rawUrl) {
158
+ const withoutBase = rawUrl.replace(/\{\{baseUrl\}\}/g, "").split("?")[0] ?? "";
159
+ const withSlash = withoutBase.startsWith("/") ? withoutBase : `/${withoutBase}`;
160
+ return openApiPathParamsToColon(withSlash);
161
+ }
162
+ /** Prefer Postman template URL shape used by existing Local View / API uploads. */ function toPostmanUrl(rawUrl) {
163
+ let pathPart = rawUrl.replace(/\{\{baseUrl\}\}/g, "");
164
+ if (!pathPart.startsWith("/")) {
165
+ pathPart = `/${pathPart}`;
166
+ }
167
+ // openapi-to-postman uses {id}; Local View / prior collections use :id
168
+ pathPart = openApiPathParamsToColon(pathPart);
169
+ const segments = pathPart.split("/").filter(Boolean);
170
+ return {
171
+ raw: `{{baseUrl}}${pathPart}`,
172
+ host: [
173
+ "{{baseUrl}}"
174
+ ],
175
+ path: segments
176
+ };
177
+ }
178
+
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy93ZWJhcGkvcG9zdG1hbi9vcGVuYXBpLXRvLXBvc3RtYW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNvbnZlcnRlciBmcm9tIFwib3BlbmFwaS10by1wb3N0bWFudjJcIjtcbmltcG9ydCB0eXBlIHsgU2NhZmZvbGRPcGVuQXBpRG9jdW1lbnQgfSBmcm9tIFwiLi9oZWxsby1vcGVuYXBpLmpzXCI7XG5cbmV4cG9ydCB0eXBlIFBvc3RtYW5Db2xsZWN0aW9uID0ge1xuXHRpbmZvOiB7XG5cdFx0X3Bvc3RtYW5faWQ/OiBzdHJpbmc7XG5cdFx0bmFtZTogc3RyaW5nO1xuXHRcdHNjaGVtYTogc3RyaW5nO1xuXHRcdGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXHR9O1xuXHRhdXRoPzogdW5rbm93bjtcblx0aXRlbT86IFBvc3RtYW5JdGVtW107XG5cdHZhcmlhYmxlPzogQXJyYXk8eyBrZXk6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9Pjtcblx0W2tleTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5cbmV4cG9ydCB0eXBlIFBvc3RtYW5JdGVtID0ge1xuXHRuYW1lPzogc3RyaW5nO1xuXHRpdGVtPzogUG9zdG1hbkl0ZW1bXTtcblx0cmVxdWVzdD86IFBvc3RtYW5SZXF1ZXN0O1xuXHRba2V5OiBzdHJpbmddOiB1bmtub3duO1xufTtcblxuZXhwb3J0IHR5cGUgUG9zdG1hblJlcXVlc3QgPSB7XG5cdG1ldGhvZD86IHN0cmluZztcblx0aGVhZGVyPzogQXJyYXk8eyBrZXk6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9Pjtcblx0Ym9keT86IHsgbW9kZT86IHN0cmluZzsgcmF3Pzogc3RyaW5nIH07XG5cdHVybD86IHN0cmluZyB8IHsgcmF3Pzogc3RyaW5nOyBob3N0Pzogc3RyaW5nW107IHBhdGg/OiBzdHJpbmdbXTsgdmFyaWFibGU/OiB1bmtub3duW10gfTtcblx0YXV0aD86IHsgdHlwZTogc3RyaW5nOyBba2V5OiBzdHJpbmddOiB1bmtub3duIH07XG5cdFtrZXk6IHN0cmluZ106IHVua25vd247XG59O1xuXG5leHBvcnQgdHlwZSBBdXRoMEVudiA9IHtcblx0YXV0aDBEb21haW4/OiBzdHJpbmc7XG5cdGF1dGgwQXVkaWVuY2U/OiBzdHJpbmc7XG5cdGF1dGgwQ2xpZW50SWQ/OiBzdHJpbmc7XG59O1xuXG50eXBlIENvbnZlcnRSZXN1bHQgPSB7XG5cdHJlc3VsdDogYm9vbGVhbjtcblx0cmVhc29uPzogc3RyaW5nO1xuXHRvdXRwdXQ/OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgZGF0YTogUG9zdG1hbkNvbGxlY3Rpb24gfT47XG59O1xuXG5mdW5jdGlvbiBjb252ZXJ0QXN5bmMoXG5cdGRhdGE6IFNjYWZmb2xkT3BlbkFwaURvY3VtZW50LFxuXHRvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbik6IFByb21pc2U8Q29udmVydFJlc3VsdD4ge1xuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdGNvbnZlcnRlci5jb252ZXJ0KFxuXHRcdFx0eyB0eXBlOiBcImpzb25cIiwgZGF0YSB9LFxuXHRcdFx0b3B0aW9ucyxcblx0XHRcdChlcnI6IEVycm9yIHwgbnVsbCwgcmVzdWx0OiBDb252ZXJ0UmVzdWx0KSA9PiB7XG5cdFx0XHRcdGlmIChlcnIpIHtcblx0XHRcdFx0XHRyZWplY3QoZXJyKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0fSxcblx0XHQpO1xuXHR9KTtcbn1cblxuLyoqIENvbnZlcnQgYW4gT3BlbkFQSSBkb2N1bWVudCB0byBhIFBvc3RtYW4gQ29sbGVjdGlvbiB2Mi4xIHZpYSBvcGVuYXBpLXRvLXBvc3RtYW52Mi4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuQXBpVG9Qb3N0bWFuQ29sbGVjdGlvbihcblx0ZG9jdW1lbnQ6IFNjYWZmb2xkT3BlbkFwaURvY3VtZW50LFxuKTogUHJvbWlzZTxQb3N0bWFuQ29sbGVjdGlvbj4ge1xuXHRjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJ0QXN5bmMoZG9jdW1lbnQsIHtcblx0XHRmb2xkZXJTdHJhdGVneTogXCJUYWdzXCIsXG5cdFx0cmVxdWVzdE5hbWVTb3VyY2U6IFwiRmFsbGJhY2tcIixcblx0XHRpbmNsdWRlQXV0aEluZm9JbkV4YW1wbGU6IGZhbHNlLFxuXHR9KTtcblx0aWYgKCFyZXN1bHQucmVzdWx0IHx8IHJlc3VsdC5vdXRwdXQ/LlswXT8uZGF0YSA9PSBudWxsKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKHJlc3VsdC5yZWFzb24gPz8gXCJvcGVuYXBpLXRvLXBvc3RtYW52MiBjb252ZXJzaW9uIGZhaWxlZFwiKTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0Lm91dHB1dFswXS5kYXRhO1xufVxuXG4vKipcbiAqIE92ZXJsYXkgQXV0aDAgT0F1dGgyIChQS0NFKSBjb2xsZWN0aW9uIGF1dGggYW5kIGZpeCBMb2NhbCBWaWV3LWZyaWVuZGx5IFVSTHMuXG4gKiBSb3V0ZSBpdGVtcyBjb21lIGZyb20gT3BlbkFQSTsgYXV0aC9lbnYgcmVtYWluIGhhbmQtYXV0aG9yZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVBvc3RtYW5BdXRoT3ZlcmxheShcblx0Y29sbGVjdGlvbjogUG9zdG1hbkNvbGxlY3Rpb24sXG5cdHByb2plY3ROYW1lOiBzdHJpbmcsXG5cdGF1dGg6IEF1dGgwRW52IHwgdW5kZWZpbmVkLFxuXHRvcHRpb25zOiB7XG5cdFx0Y2FsbGJhY2tzOiByZWFkb25seSBzdHJpbmdbXTtcblx0XHRzY29wZXM6IHN0cmluZztcblx0XHRkZXNjcmlwdGlvbjogc3RyaW5nO1xuXHR9LFxuKTogUG9zdG1hbkNvbGxlY3Rpb24ge1xuXHRjb25zdCBuZXh0OiBQb3N0bWFuQ29sbGVjdGlvbiA9IHtcblx0XHQuLi5jb2xsZWN0aW9uLFxuXHRcdGluZm86IHtcblx0XHRcdC4uLmNvbGxlY3Rpb24uaW5mbyxcblx0XHRcdG5hbWU6IGAke3Byb2plY3ROYW1lfSBXZWJBUElgLFxuXHRcdFx0ZGVzY3JpcHRpb246IG9wdGlvbnMuZGVzY3JpcHRpb24sXG5cdFx0XHRzY2hlbWE6XG5cdFx0XHRcdGNvbGxlY3Rpb24uaW5mby5zY2hlbWEgPz9cblx0XHRcdFx0XCJodHRwczovL3NjaGVtYS5nZXRwb3N0bWFuLmNvbS9qc29uL2NvbGxlY3Rpb24vdjIuMS4wL2NvbGxlY3Rpb24uanNvblwiLFxuXHRcdH0sXG5cdH07XG5cblx0aWYgKGF1dGg/LmF1dGgwRG9tYWluKSB7XG5cdFx0bmV4dC5hdXRoID0ge1xuXHRcdFx0dHlwZTogXCJvYXV0aDJcIixcblx0XHRcdG9hdXRoMjogW1xuXHRcdFx0XHR7IGtleTogXCJncmFudF90eXBlXCIsIHZhbHVlOiBcImF1dGhvcml6YXRpb25fY29kZV93aXRoX3BrY2VcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0a2V5OiBcImF1dGhVcmxcIixcblx0XHRcdFx0XHR2YWx1ZTogXCJodHRwczovL3t7YXV0aDBEb21haW59fS9hdXRob3JpemU/YXVkaWVuY2U9e3thdXRoMEF1ZGllbmNlfX1cIixcblx0XHRcdFx0XHR0eXBlOiBcInN0cmluZ1wiLFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0a2V5OiBcImFjY2Vzc1Rva2VuVXJsXCIsXG5cdFx0XHRcdFx0dmFsdWU6IFwiaHR0cHM6Ly97e2F1dGgwRG9tYWlufX0vb2F1dGgvdG9rZW5cIixcblx0XHRcdFx0XHR0eXBlOiBcInN0cmluZ1wiLFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7IGtleTogXCJjbGllbnRJZFwiLCB2YWx1ZTogXCJ7e2F1dGgwQ2xpZW50SWR9fVwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG5cdFx0XHRcdHsga2V5OiBcInNjb3BlXCIsIHZhbHVlOiBvcHRpb25zLnNjb3BlcywgdHlwZTogXCJzdHJpbmdcIiB9LFxuXHRcdFx0XHR7IGtleTogXCJyZWRpcmVjdF91cmlcIiwgdmFsdWU6IG9wdGlvbnMuY2FsbGJhY2tzWzBdLCB0eXBlOiBcInN0cmluZ1wiIH0sXG5cdFx0XHRcdHsga2V5OiBcInVzZUJyb3dzZXJcIiwgdmFsdWU6IFwidHJ1ZVwiLCB0eXBlOiBcImJvb2xlYW5cIiB9LFxuXHRcdFx0XHR7IGtleTogXCJhZGRUb2tlblRvXCIsIHZhbHVlOiBcImhlYWRlclwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG5cdFx0XHRcdHsga2V5OiBcImNoYWxsZW5nZUFsZ29yaXRobVwiLCB2YWx1ZTogXCJTMjU2XCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcblx0XHRcdFx0eyBrZXk6IFwiY2xpZW50X2F1dGhlbnRpY2F0aW9uXCIsIHZhbHVlOiBcImJvZHlcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuXHRcdFx0XHR7IGtleTogXCJjbGllbnRTZWNyZXRcIiwgdmFsdWU6IFwiXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcblx0XHRcdFx0eyBrZXk6IFwidG9rZW5OYW1lXCIsIHZhbHVlOiBgJHtwcm9qZWN0TmFtZX0gQWNjZXNzIFRva2VuYCwgdHlwZTogXCJzdHJpbmdcIiB9LFxuXHRcdFx0XSxcblx0XHR9O1xuXHR9XG5cblx0bmV4dC5pdGVtID0gcmV3cml0ZUNvbGxlY3Rpb25JdGVtcyhjb2xsZWN0aW9uLml0ZW0gPz8gW10sIHtcblx0XHRtYXJrTGlzdEFub255bW91czogdHJ1ZSxcblx0fSk7XG5cdHJldHVybiBuZXh0O1xufVxuXG5mdW5jdGlvbiByZXdyaXRlQ29sbGVjdGlvbkl0ZW1zKFxuXHRpdGVtczogUG9zdG1hbkl0ZW1bXSxcblx0b3B0czogeyBtYXJrTGlzdEFub255bW91czogYm9vbGVhbiB9LFxuKTogUG9zdG1hbkl0ZW1bXSB7XG5cdHJldHVybiBpdGVtcy5tYXAoKGl0ZW0pID0+IHtcblx0XHRpZiAoaXRlbS5pdGVtICE9IG51bGwpIHtcblx0XHRcdHJldHVybiB7IC4uLml0ZW0sIGl0ZW06IHJld3JpdGVDb2xsZWN0aW9uSXRlbXMoaXRlbS5pdGVtLCBvcHRzKSB9O1xuXHRcdH1cblx0XHRjb25zdCByZXF1ZXN0ID0gaXRlbS5yZXF1ZXN0O1xuXHRcdGlmIChyZXF1ZXN0ID09IG51bGwpIHtcblx0XHRcdHJldHVybiBpdGVtO1xuXHRcdH1cblx0XHRjb25zdCBtZXRob2QgPSAocmVxdWVzdC5tZXRob2QgPz8gXCJHRVRcIikudG9VcHBlckNhc2UoKTtcblx0XHRjb25zdCByYXdVcmwgPSByZXF1ZXN0VXJsUmF3KHJlcXVlc3QpO1xuXHRcdGNvbnN0IG5leHRSZXF1ZXN0OiBQb3N0bWFuUmVxdWVzdCA9IHtcblx0XHRcdC4uLnJlcXVlc3QsXG5cdFx0XHR1cmw6IHRvUG9zdG1hblVybChyYXdVcmwpLFxuXHRcdH07XG5cdFx0Ly8gTGlzdCBIZWxsbyBzdGF5cyBhbm9ueW1vdXMgKG1hdGNoZXMgc2NhZmZvbGQgQWxsb3dBbm9ueW1vdXMgb24gR0VUIC9oZWxsbykuXG5cdFx0aWYgKFxuXHRcdFx0b3B0cy5tYXJrTGlzdEFub255bW91cyAmJlxuXHRcdFx0bWV0aG9kID09PSBcIkdFVFwiICYmXG5cdFx0XHRub3JtYWxpemVQYXRoKHJhd1VybCkgPT09IFwiL2hlbGxvXCIgJiZcblx0XHRcdCFyYXdVcmwuaW5jbHVkZXMoXCIvOlwiKVxuXHRcdCkge1xuXHRcdFx0bmV4dFJlcXVlc3QuYXV0aCA9IHsgdHlwZTogXCJub2F1dGhcIiB9O1xuXHRcdH1cblx0XHRyZXR1cm4geyAuLi5pdGVtLCByZXF1ZXN0OiBuZXh0UmVxdWVzdCB9O1xuXHR9KTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFVybFJhdyhyZXF1ZXN0OiBQb3N0bWFuUmVxdWVzdCk6IHN0cmluZyB7XG5cdGNvbnN0IHVybCA9IHJlcXVlc3QudXJsO1xuXHRpZiAodHlwZW9mIHVybCA9PT0gXCJzdHJpbmdcIikge1xuXHRcdHJldHVybiB1cmw7XG5cdH1cblx0aWYgKHVybD8ucmF3KSB7XG5cdFx0cmV0dXJuIHVybC5yYXc7XG5cdH1cblx0Y29uc3QgaG9zdCA9IHVybD8uaG9zdD8uWzBdID8/IFwie3tiYXNlVXJsfX1cIjtcblx0Y29uc3QgcGF0aCA9ICh1cmw/LnBhdGggPz8gW10pLmpvaW4oXCIvXCIpO1xuXHRyZXR1cm4gcGF0aCA/IGAke2hvc3R9LyR7cGF0aH1gIDogaG9zdDtcbn1cblxuLyoqIE9wZW5BUEkgYHtpZH1gIOKGkiBQb3N0bWFuIGA6aWRgLCB3aXRob3V0IHRvdWNoaW5nIGB7e3ZhcmlhYmxlc319YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcGVuQXBpUGF0aFBhcmFtc1RvQ29sb24odXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRyZXR1cm4gdXJsLnJlcGxhY2UoLyg/PCFcXHspXFx7KFtBLVphLXpfXVtcXHddKilcXH0oPyFcXH0pL2csIFwiOiQxXCIpO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVQYXRoKHJhd1VybDogc3RyaW5nKTogc3RyaW5nIHtcblx0Y29uc3Qgd2l0aG91dEJhc2UgPSByYXdVcmwucmVwbGFjZSgvXFx7XFx7YmFzZVVybFxcfVxcfS9nLCBcIlwiKS5zcGxpdChcIj9cIilbMF0gPz8gXCJcIjtcblx0Y29uc3Qgd2l0aFNsYXNoID0gd2l0aG91dEJhc2Uuc3RhcnRzV2l0aChcIi9cIikgPyB3aXRob3V0QmFzZSA6IGAvJHt3aXRob3V0QmFzZX1gO1xuXHRyZXR1cm4gb3BlbkFwaVBhdGhQYXJhbXNUb0NvbG9uKHdpdGhTbGFzaCk7XG59XG5cbi8qKiBQcmVmZXIgUG9zdG1hbiB0ZW1wbGF0ZSBVUkwgc2hhcGUgdXNlZCBieSBleGlzdGluZyBMb2NhbCBWaWV3IC8gQVBJIHVwbG9hZHMuICovXG5mdW5jdGlvbiB0b1Bvc3RtYW5VcmwocmF3VXJsOiBzdHJpbmcpOiBQb3N0bWFuUmVxdWVzdFtcInVybFwiXSB7XG5cdGxldCBwYXRoUGFydCA9IHJhd1VybC5yZXBsYWNlKC9cXHtcXHtiYXNlVXJsXFx9XFx9L2csIFwiXCIpO1xuXHRpZiAoIXBhdGhQYXJ0LnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG5cdFx0cGF0aFBhcnQgPSBgLyR7cGF0aFBhcnR9YDtcblx0fVxuXHQvLyBvcGVuYXBpLXRvLXBvc3RtYW4gdXNlcyB7aWR9OyBMb2NhbCBWaWV3IC8gcHJpb3IgY29sbGVjdGlvbnMgdXNlIDppZFxuXHRwYXRoUGFydCA9IG9wZW5BcGlQYXRoUGFyYW1zVG9Db2xvbihwYXRoUGFydCk7XG5cdGNvbnN0IHNlZ21lbnRzID0gcGF0aFBhcnQuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblx0cmV0dXJuIHtcblx0XHRyYXc6IGB7e2Jhc2VVcmx9fSR7cGF0aFBhcnR9YCxcblx0XHRob3N0OiBbXCJ7e2Jhc2VVcmx9fVwiXSxcblx0XHRwYXRoOiBzZWdtZW50cyxcblx0fTtcbn1cbiJdLCJuYW1lcyI6WyJjb252ZXJ0ZXIiLCJjb252ZXJ0QXN5bmMiLCJkYXRhIiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiY29udmVydCIsInR5cGUiLCJlcnIiLCJyZXN1bHQiLCJvcGVuQXBpVG9Qb3N0bWFuQ29sbGVjdGlvbiIsImRvY3VtZW50IiwiZm9sZGVyU3RyYXRlZ3kiLCJyZXF1ZXN0TmFtZVNvdXJjZSIsImluY2x1ZGVBdXRoSW5mb0luRXhhbXBsZSIsIm91dHB1dCIsIkVycm9yIiwicmVhc29uIiwiYXBwbHlQb3N0bWFuQXV0aE92ZXJsYXkiLCJjb2xsZWN0aW9uIiwicHJvamVjdE5hbWUiLCJhdXRoIiwibmV4dCIsImluZm8iLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJzY2hlbWEiLCJhdXRoMERvbWFpbiIsIm9hdXRoMiIsImtleSIsInZhbHVlIiwic2NvcGVzIiwiY2FsbGJhY2tzIiwiaXRlbSIsInJld3JpdGVDb2xsZWN0aW9uSXRlbXMiLCJtYXJrTGlzdEFub255bW91cyIsIml0ZW1zIiwib3B0cyIsIm1hcCIsInJlcXVlc3QiLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsInJhd1VybCIsInJlcXVlc3RVcmxSYXciLCJuZXh0UmVxdWVzdCIsInVybCIsInRvUG9zdG1hblVybCIsIm5vcm1hbGl6ZVBhdGgiLCJpbmNsdWRlcyIsInJhdyIsImhvc3QiLCJwYXRoIiwiam9pbiIsIm9wZW5BcGlQYXRoUGFyYW1zVG9Db2xvbiIsInJlcGxhY2UiLCJ3aXRob3V0QmFzZSIsInNwbGl0Iiwid2l0aFNsYXNoIiwic3RhcnRzV2l0aCIsInBhdGhQYXJ0Iiwic2VnbWVudHMiLCJmaWx0ZXIiLCJCb29sZWFuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxlQUFlLHVCQUF1QjtBQTRDN0MsU0FBU0MsYUFDUkMsSUFBNkIsRUFDN0JDLE9BQWdDO0lBRWhDLE9BQU8sSUFBSUMsUUFBUSxDQUFDQyxTQUFTQztRQUM1Qk4sVUFBVU8sT0FBTyxDQUNoQjtZQUFFQyxNQUFNO1lBQVFOO1FBQUssR0FDckJDLFNBQ0EsQ0FBQ00sS0FBbUJDO1lBQ25CLElBQUlELEtBQUs7Z0JBQ1JILE9BQU9HO2dCQUNQO1lBQ0Q7WUFDQUosUUFBUUs7UUFDVDtJQUVGO0FBQ0Q7QUFFQSx1RkFBdUYsR0FDdkYsT0FBTyxlQUFlQywyQkFDckJDLFFBQWlDO0lBRWpDLE1BQU1GLFNBQVMsTUFBTVQsYUFBYVcsVUFBVTtRQUMzQ0MsZ0JBQWdCO1FBQ2hCQyxtQkFBbUI7UUFDbkJDLDBCQUEwQjtJQUMzQjtJQUNBLElBQUksQ0FBQ0wsT0FBT0EsTUFBTSxJQUFJQSxPQUFPTSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUVkLFFBQVEsTUFBTTtRQUN2RCxNQUFNLElBQUllLE1BQU1QLE9BQU9RLE1BQU0sSUFBSTtJQUNsQztJQUNBLE9BQU9SLE9BQU9NLE1BQU0sQ0FBQyxFQUFFLENBQUNkLElBQUk7QUFDN0I7QUFFQTs7O0NBR0MsR0FDRCxPQUFPLFNBQVNpQix3QkFDZkMsVUFBNkIsRUFDN0JDLFdBQW1CLEVBQ25CQyxJQUEwQixFQUMxQm5CLE9BSUM7SUFFRCxNQUFNb0IsT0FBMEI7UUFDL0IsR0FBR0gsVUFBVTtRQUNiSSxNQUFNO1lBQ0wsR0FBR0osV0FBV0ksSUFBSTtZQUNsQkMsTUFBTSxHQUFHSixZ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