@peterhauge/apiops-cli 0.1.3-alpha.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 (199) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +135 -0
  3. package/dist/cli/extract-command.d.ts +12 -0
  4. package/dist/cli/extract-command.d.ts.map +1 -0
  5. package/dist/cli/extract-command.js +157 -0
  6. package/dist/cli/extract-command.js.map +1 -0
  7. package/dist/cli/index.d.ts +7 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +74 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/init-command.d.ts +11 -0
  12. package/dist/cli/init-command.d.ts.map +1 -0
  13. package/dist/cli/init-command.js +87 -0
  14. package/dist/cli/init-command.js.map +1 -0
  15. package/dist/cli/publish-command.d.ts +12 -0
  16. package/dist/cli/publish-command.d.ts.map +1 -0
  17. package/dist/cli/publish-command.js +159 -0
  18. package/dist/cli/publish-command.js.map +1 -0
  19. package/dist/clients/apim-client.d.ts +110 -0
  20. package/dist/clients/apim-client.d.ts.map +1 -0
  21. package/dist/clients/apim-client.js +586 -0
  22. package/dist/clients/apim-client.js.map +1 -0
  23. package/dist/clients/artifact-store.d.ts +23 -0
  24. package/dist/clients/artifact-store.d.ts.map +1 -0
  25. package/dist/clients/artifact-store.js +188 -0
  26. package/dist/clients/artifact-store.js.map +1 -0
  27. package/dist/clients/iapim-client.d.ts +52 -0
  28. package/dist/clients/iapim-client.d.ts.map +1 -0
  29. package/dist/clients/iapim-client.js +6 -0
  30. package/dist/clients/iapim-client.js.map +1 -0
  31. package/dist/clients/iartifact-store.d.ts +50 -0
  32. package/dist/clients/iartifact-store.d.ts.map +1 -0
  33. package/dist/clients/iartifact-store.js +6 -0
  34. package/dist/clients/iartifact-store.js.map +1 -0
  35. package/dist/lib/auto-generated.d.ts +27 -0
  36. package/dist/lib/auto-generated.d.ts.map +1 -0
  37. package/dist/lib/auto-generated.js +34 -0
  38. package/dist/lib/auto-generated.js.map +1 -0
  39. package/dist/lib/cloud-config.d.ts +29 -0
  40. package/dist/lib/cloud-config.d.ts.map +1 -0
  41. package/dist/lib/cloud-config.js +60 -0
  42. package/dist/lib/cloud-config.js.map +1 -0
  43. package/dist/lib/config-loader.d.ts +21 -0
  44. package/dist/lib/config-loader.d.ts.map +1 -0
  45. package/dist/lib/config-loader.js +131 -0
  46. package/dist/lib/config-loader.js.map +1 -0
  47. package/dist/lib/dependency-graph.d.ts +43 -0
  48. package/dist/lib/dependency-graph.d.ts.map +1 -0
  49. package/dist/lib/dependency-graph.js +163 -0
  50. package/dist/lib/dependency-graph.js.map +1 -0
  51. package/dist/lib/exit-codes.d.ts +27 -0
  52. package/dist/lib/exit-codes.d.ts.map +1 -0
  53. package/dist/lib/exit-codes.js +33 -0
  54. package/dist/lib/exit-codes.js.map +1 -0
  55. package/dist/lib/logger.d.ts +39 -0
  56. package/dist/lib/logger.d.ts.map +1 -0
  57. package/dist/lib/logger.js +128 -0
  58. package/dist/lib/logger.js.map +1 -0
  59. package/dist/lib/parallel-runner.d.ts +38 -0
  60. package/dist/lib/parallel-runner.d.ts.map +1 -0
  61. package/dist/lib/parallel-runner.js +70 -0
  62. package/dist/lib/parallel-runner.js.map +1 -0
  63. package/dist/lib/resource-path.d.ts +205 -0
  64. package/dist/lib/resource-path.d.ts.map +1 -0
  65. package/dist/lib/resource-path.js +401 -0
  66. package/dist/lib/resource-path.js.map +1 -0
  67. package/dist/lib/resource-uri.d.ts +40 -0
  68. package/dist/lib/resource-uri.d.ts.map +1 -0
  69. package/dist/lib/resource-uri.js +86 -0
  70. package/dist/lib/resource-uri.js.map +1 -0
  71. package/dist/lib/user-agent.d.ts +2 -0
  72. package/dist/lib/user-agent.d.ts.map +1 -0
  73. package/dist/lib/user-agent.js +5 -0
  74. package/dist/lib/user-agent.js.map +1 -0
  75. package/dist/models/config.d.ts +83 -0
  76. package/dist/models/config.d.ts.map +1 -0
  77. package/dist/models/config.js +6 -0
  78. package/dist/models/config.js.map +1 -0
  79. package/dist/models/resource-types.d.ts +66 -0
  80. package/dist/models/resource-types.d.ts.map +1 -0
  81. package/dist/models/resource-types.js +243 -0
  82. package/dist/models/resource-types.js.map +1 -0
  83. package/dist/models/types.d.ts +47 -0
  84. package/dist/models/types.d.ts.map +1 -0
  85. package/dist/models/types.js +6 -0
  86. package/dist/models/types.js.map +1 -0
  87. package/dist/services/api-extractor.d.ts +36 -0
  88. package/dist/services/api-extractor.d.ts.map +1 -0
  89. package/dist/services/api-extractor.js +319 -0
  90. package/dist/services/api-extractor.js.map +1 -0
  91. package/dist/services/api-publisher.d.ts +18 -0
  92. package/dist/services/api-publisher.d.ts.map +1 -0
  93. package/dist/services/api-publisher.js +290 -0
  94. package/dist/services/api-publisher.js.map +1 -0
  95. package/dist/services/delete-unmatched-service.d.ts +17 -0
  96. package/dist/services/delete-unmatched-service.d.ts.map +1 -0
  97. package/dist/services/delete-unmatched-service.js +143 -0
  98. package/dist/services/delete-unmatched-service.js.map +1 -0
  99. package/dist/services/dry-run-reporter.d.ts +30 -0
  100. package/dist/services/dry-run-reporter.d.ts.map +1 -0
  101. package/dist/services/dry-run-reporter.js +111 -0
  102. package/dist/services/dry-run-reporter.js.map +1 -0
  103. package/dist/services/extract-service.d.ts +47 -0
  104. package/dist/services/extract-service.d.ts.map +1 -0
  105. package/dist/services/extract-service.js +374 -0
  106. package/dist/services/extract-service.js.map +1 -0
  107. package/dist/services/filter-service.d.ts +29 -0
  108. package/dist/services/filter-service.d.ts.map +1 -0
  109. package/dist/services/filter-service.js +143 -0
  110. package/dist/services/filter-service.js.map +1 -0
  111. package/dist/services/git-diff-service.d.ts +23 -0
  112. package/dist/services/git-diff-service.d.ts.map +1 -0
  113. package/dist/services/git-diff-service.js +135 -0
  114. package/dist/services/git-diff-service.js.map +1 -0
  115. package/dist/services/identity-guide-service.d.ts +11 -0
  116. package/dist/services/identity-guide-service.d.ts.map +1 -0
  117. package/dist/services/identity-guide-service.js +227 -0
  118. package/dist/services/identity-guide-service.js.map +1 -0
  119. package/dist/services/init-service.d.ts +16 -0
  120. package/dist/services/init-service.d.ts.map +1 -0
  121. package/dist/services/init-service.js +304 -0
  122. package/dist/services/init-service.js.map +1 -0
  123. package/dist/services/keyvault-checker.d.ts +58 -0
  124. package/dist/services/keyvault-checker.d.ts.map +1 -0
  125. package/dist/services/keyvault-checker.js +390 -0
  126. package/dist/services/keyvault-checker.js.map +1 -0
  127. package/dist/services/override-merger.d.ts +20 -0
  128. package/dist/services/override-merger.d.ts.map +1 -0
  129. package/dist/services/override-merger.js +102 -0
  130. package/dist/services/override-merger.js.map +1 -0
  131. package/dist/services/product-extractor.d.ts +26 -0
  132. package/dist/services/product-extractor.d.ts.map +1 -0
  133. package/dist/services/product-extractor.js +141 -0
  134. package/dist/services/product-extractor.js.map +1 -0
  135. package/dist/services/product-publisher.d.ts +15 -0
  136. package/dist/services/product-publisher.d.ts.map +1 -0
  137. package/dist/services/product-publisher.js +113 -0
  138. package/dist/services/product-publisher.js.map +1 -0
  139. package/dist/services/prompt-service.d.ts +13 -0
  140. package/dist/services/prompt-service.d.ts.map +1 -0
  141. package/dist/services/prompt-service.js +69 -0
  142. package/dist/services/prompt-service.js.map +1 -0
  143. package/dist/services/publish-service.d.ts +31 -0
  144. package/dist/services/publish-service.d.ts.map +1 -0
  145. package/dist/services/publish-service.js +445 -0
  146. package/dist/services/publish-service.js.map +1 -0
  147. package/dist/services/resource-extractor.d.ts +52 -0
  148. package/dist/services/resource-extractor.d.ts.map +1 -0
  149. package/dist/services/resource-extractor.js +168 -0
  150. package/dist/services/resource-extractor.js.map +1 -0
  151. package/dist/services/resource-publisher.d.ts +23 -0
  152. package/dist/services/resource-publisher.d.ts.map +1 -0
  153. package/dist/services/resource-publisher.js +349 -0
  154. package/dist/services/resource-publisher.js.map +1 -0
  155. package/dist/services/secret-redactor.d.ts +20 -0
  156. package/dist/services/secret-redactor.d.ts.map +1 -0
  157. package/dist/services/secret-redactor.js +45 -0
  158. package/dist/services/secret-redactor.js.map +1 -0
  159. package/dist/services/transitive-resolver.d.ts +45 -0
  160. package/dist/services/transitive-resolver.d.ts.map +1 -0
  161. package/dist/services/transitive-resolver.js +177 -0
  162. package/dist/services/transitive-resolver.js.map +1 -0
  163. package/dist/services/workspace-extractor.d.ts +34 -0
  164. package/dist/services/workspace-extractor.d.ts.map +1 -0
  165. package/dist/services/workspace-extractor.js +120 -0
  166. package/dist/services/workspace-extractor.js.map +1 -0
  167. package/dist/templates/azure-devops/extract-pipeline.d.ts +9 -0
  168. package/dist/templates/azure-devops/extract-pipeline.d.ts.map +1 -0
  169. package/dist/templates/azure-devops/extract-pipeline.js +95 -0
  170. package/dist/templates/azure-devops/extract-pipeline.js.map +1 -0
  171. package/dist/templates/azure-devops/publish-pipeline.d.ts +10 -0
  172. package/dist/templates/azure-devops/publish-pipeline.d.ts.map +1 -0
  173. package/dist/templates/azure-devops/publish-pipeline.js +100 -0
  174. package/dist/templates/azure-devops/publish-pipeline.js.map +1 -0
  175. package/dist/templates/configs/filter-config.d.ts +6 -0
  176. package/dist/templates/configs/filter-config.d.ts.map +1 -0
  177. package/dist/templates/configs/filter-config.js +51 -0
  178. package/dist/templates/configs/filter-config.js.map +1 -0
  179. package/dist/templates/configs/override-config.d.ts +6 -0
  180. package/dist/templates/configs/override-config.d.ts.map +1 -0
  181. package/dist/templates/configs/override-config.js +45 -0
  182. package/dist/templates/configs/override-config.js.map +1 -0
  183. package/dist/templates/configs/package-json.d.ts +10 -0
  184. package/dist/templates/configs/package-json.d.ts.map +1 -0
  185. package/dist/templates/configs/package-json.js +19 -0
  186. package/dist/templates/configs/package-json.js.map +1 -0
  187. package/dist/templates/copilot/identity-setup-prompt.d.ts +13 -0
  188. package/dist/templates/copilot/identity-setup-prompt.d.ts.map +1 -0
  189. package/dist/templates/copilot/identity-setup-prompt.js +279 -0
  190. package/dist/templates/copilot/identity-setup-prompt.js.map +1 -0
  191. package/dist/templates/github-actions/extract-workflow.d.ts +9 -0
  192. package/dist/templates/github-actions/extract-workflow.d.ts.map +1 -0
  193. package/dist/templates/github-actions/extract-workflow.js +126 -0
  194. package/dist/templates/github-actions/extract-workflow.js.map +1 -0
  195. package/dist/templates/github-actions/publish-workflow.d.ts +10 -0
  196. package/dist/templates/github-actions/publish-workflow.d.ts.map +1 -0
  197. package/dist/templates/github-actions/publish-workflow.js +105 -0
  198. package/dist/templates/github-actions/publish-workflow.js.map +1 -0
  199. package/package.json +65 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * T025: Transitive dependency resolver
3
+ * Scan policies for named value refs, backend refs, policy fragment refs.
4
+ * Scan apiInformation.json for apiVersionSetId.
5
+ * Fixed-point expansion; --no-transitive bypass.
6
+ */
7
+ import { FilterConfig } from '../models/config.js';
8
+ import { ResourceType } from '../models/resource-types.js';
9
+ import { ResourceDescriptor } from '../models/types.js';
10
+ /**
11
+ * Represents a discovered transitive dependency.
12
+ */
13
+ export interface TransitiveDependency {
14
+ type: ResourceType;
15
+ name: string;
16
+ }
17
+ /**
18
+ * Scan policy XML content for references to other resources.
19
+ *
20
+ * Detects:
21
+ * - Named values: {{namedValueName}} syntax
22
+ * - Backends: <set-backend-service backend-id="backendName">
23
+ * - Policy fragments: <include-fragment fragment-id="fragmentName">
24
+ */
25
+ export declare function scanPolicyReferences(policyXml: string): TransitiveDependency[];
26
+ /**
27
+ * Scan API information JSON for version set reference.
28
+ */
29
+ export declare function scanApiVersionSetReference(apiJson: Record<string, unknown>): TransitiveDependency | undefined;
30
+ /**
31
+ * Resolve transitive dependencies by expanding the extraction set
32
+ * until no new dependencies are found (fixed-point).
33
+ *
34
+ * @param extractedPolicies - Map of descriptor key to policy XML content
35
+ * @param extractedApis - Map of API name to API JSON (for version set refs)
36
+ * @param currentFilter - Current filter config to expand
37
+ * @returns Updated filter config with transitive dependencies included
38
+ */
39
+ export declare function resolveTransitiveDependencies(extractedPolicies: Map<string, string>, extractedApis: Map<string, Record<string, unknown>>, currentFilter: FilterConfig): FilterConfig;
40
+ /**
41
+ * Build a set of descriptors from transitive dependency scanning.
42
+ * Returns additional descriptors that should be extracted.
43
+ */
44
+ export declare function findTransitiveDependencies(policies: Map<string, string>, apis: Map<string, Record<string, unknown>>): ResourceDescriptor[];
45
+ //# sourceMappingURL=transitive-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/services/transitive-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAUxD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAkC9E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,oBAAoB,GAAG,SAAS,CAuBlC;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnD,aAAa,EAAE,YAAY,GAC1B,YAAY,CAmCd;AAwCD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,kBAAkB,EAAE,CA4BtB"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * T025: Transitive dependency resolver
3
+ * Scan policies for named value refs, backend refs, policy fragment refs.
4
+ * Scan apiInformation.json for apiVersionSetId.
5
+ * Fixed-point expansion; --no-transitive bypass.
6
+ */
7
+ import { ResourceType } from '../models/resource-types.js';
8
+ import { logger } from '../lib/logger.js';
9
+ /**
10
+ * Reference detection patterns for policy XML content.
11
+ */
12
+ const NAMED_VALUE_PATTERN = /\{\{([^}]+)\}\}/g;
13
+ const BACKEND_PATTERN = /<set-backend-service\s+backend-id="([^"]+)"/g;
14
+ const FRAGMENT_PATTERN = /<include-fragment\s+fragment-id="([^"]+)"/g;
15
+ /**
16
+ * Scan policy XML content for references to other resources.
17
+ *
18
+ * Detects:
19
+ * - Named values: {{namedValueName}} syntax
20
+ * - Backends: <set-backend-service backend-id="backendName">
21
+ * - Policy fragments: <include-fragment fragment-id="fragmentName">
22
+ */
23
+ export function scanPolicyReferences(policyXml) {
24
+ const dependencies = [];
25
+ // Named value references
26
+ for (const match of policyXml.matchAll(NAMED_VALUE_PATTERN)) {
27
+ if (match[1]) {
28
+ dependencies.push({
29
+ type: ResourceType.NamedValue,
30
+ name: match[1].trim(),
31
+ });
32
+ }
33
+ }
34
+ // Backend references
35
+ for (const match of policyXml.matchAll(BACKEND_PATTERN)) {
36
+ if (match[1]) {
37
+ dependencies.push({
38
+ type: ResourceType.Backend,
39
+ name: match[1].trim(),
40
+ });
41
+ }
42
+ }
43
+ // Policy fragment references
44
+ for (const match of policyXml.matchAll(FRAGMENT_PATTERN)) {
45
+ if (match[1]) {
46
+ dependencies.push({
47
+ type: ResourceType.PolicyFragment,
48
+ name: match[1].trim(),
49
+ });
50
+ }
51
+ }
52
+ return dependencies;
53
+ }
54
+ /**
55
+ * Scan API information JSON for version set reference.
56
+ */
57
+ export function scanApiVersionSetReference(apiJson) {
58
+ const properties = apiJson.properties;
59
+ if (!properties) {
60
+ return undefined;
61
+ }
62
+ const versionSetId = properties.apiVersionSetId;
63
+ if (!versionSetId) {
64
+ return undefined;
65
+ }
66
+ // Extract version set name from ARM resource ID
67
+ // Format: /subscriptions/.../apiVersionSets/{name}
68
+ const parts = versionSetId.split('/');
69
+ const name = parts[parts.length - 1];
70
+ if (!name) {
71
+ return undefined;
72
+ }
73
+ return {
74
+ type: ResourceType.VersionSet,
75
+ name,
76
+ };
77
+ }
78
+ /**
79
+ * Resolve transitive dependencies by expanding the extraction set
80
+ * until no new dependencies are found (fixed-point).
81
+ *
82
+ * @param extractedPolicies - Map of descriptor key to policy XML content
83
+ * @param extractedApis - Map of API name to API JSON (for version set refs)
84
+ * @param currentFilter - Current filter config to expand
85
+ * @returns Updated filter config with transitive dependencies included
86
+ */
87
+ export function resolveTransitiveDependencies(extractedPolicies, extractedApis, currentFilter) {
88
+ const expanded = { ...currentFilter };
89
+ let changed = true;
90
+ let iterations = 0;
91
+ const maxIterations = 10; // Safety limit
92
+ while (changed && iterations < maxIterations) {
93
+ changed = false;
94
+ iterations++;
95
+ // Scan all extracted policies for references
96
+ for (const [, policyXml] of extractedPolicies) {
97
+ const refs = scanPolicyReferences(policyXml);
98
+ for (const ref of refs) {
99
+ if (addToFilter(expanded, ref)) {
100
+ changed = true;
101
+ }
102
+ }
103
+ }
104
+ // Scan API information for version set references
105
+ for (const [, apiJson] of extractedApis) {
106
+ const versionSetRef = scanApiVersionSetReference(apiJson);
107
+ if (versionSetRef && addToFilter(expanded, versionSetRef)) {
108
+ changed = true;
109
+ }
110
+ }
111
+ }
112
+ if (iterations > 1) {
113
+ logger.debug(`Transitive resolution completed in ${iterations} iterations`);
114
+ }
115
+ return expanded;
116
+ }
117
+ /**
118
+ * Add a transitive dependency to the filter config.
119
+ * Returns true if the filter was actually modified (new entry added).
120
+ */
121
+ function addToFilter(filter, dep) {
122
+ const fieldMap = {
123
+ [ResourceType.NamedValue]: 'namedValueNames',
124
+ [ResourceType.Backend]: 'backendNames',
125
+ [ResourceType.PolicyFragment]: 'policyFragmentNames',
126
+ [ResourceType.VersionSet]: 'versionSetNames',
127
+ };
128
+ const field = fieldMap[dep.type];
129
+ if (!field) {
130
+ return false;
131
+ }
132
+ // Get current array; if undefined, the type is not filtered so no need to add
133
+ const current = filter[field];
134
+ if (current === undefined) {
135
+ return false;
136
+ }
137
+ // Check if already included (case-insensitive)
138
+ const lowerName = dep.name.toLowerCase();
139
+ if (current.some((n) => n.toLowerCase() === lowerName)) {
140
+ return false;
141
+ }
142
+ // Add to filter
143
+ filter[field] = [...current, dep.name];
144
+ logger.debug(`Transitive: added ${dep.type} "${dep.name}" to filter`);
145
+ return true;
146
+ }
147
+ /**
148
+ * Build a set of descriptors from transitive dependency scanning.
149
+ * Returns additional descriptors that should be extracted.
150
+ */
151
+ export function findTransitiveDependencies(policies, apis) {
152
+ const dependencies = [];
153
+ const seen = new Set();
154
+ // Scan all policies
155
+ for (const [, policyXml] of policies) {
156
+ for (const dep of scanPolicyReferences(policyXml)) {
157
+ const key = `${dep.type}:${dep.name.toLowerCase()}`;
158
+ if (!seen.has(key)) {
159
+ seen.add(key);
160
+ dependencies.push({ type: dep.type, nameParts: [dep.name] });
161
+ }
162
+ }
163
+ }
164
+ // Scan API version set references
165
+ for (const [, apiJson] of apis) {
166
+ const dep = scanApiVersionSetReference(apiJson);
167
+ if (dep) {
168
+ const key = `${dep.type}:${dep.name.toLowerCase()}`;
169
+ if (!seen.has(key)) {
170
+ seen.add(key);
171
+ dependencies.push({ type: dep.type, nameParts: [dep.name] });
172
+ }
173
+ }
174
+ }
175
+ return dependencies;
176
+ }
177
+ //# sourceMappingURL=transitive-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitive-resolver.js","sourceRoot":"","sources":["../../src/services/transitive-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * T027: Workspace-scoped extraction
3
+ * List workspaces, extract workspace-scoped resources under workspaces/{name}/
4
+ * using same resource-extractor with workspace context prefix.
5
+ */
6
+ import { IApimClient } from '../clients/iapim-client.js';
7
+ import { IArtifactStore } from '../clients/iartifact-store.js';
8
+ import { ApimServiceContext } from '../models/types.js';
9
+ import { FilterConfig } from '../models/config.js';
10
+ /**
11
+ * Result of extracting a single workspace.
12
+ */
13
+ export interface WorkspaceExtractionResult {
14
+ workspaceName: string;
15
+ resourceCount: number;
16
+ errorCount: number;
17
+ }
18
+ /**
19
+ * Extract resources from all workspaces.
20
+ *
21
+ * Note: Workspace listing is not supported through the current IApimClient
22
+ * interface (ResourceType doesn't include Workspace). This function accepts
23
+ * workspace names from the filter config. If workspaceNames is not specified
24
+ * in the filter, workspace extraction is skipped.
25
+ *
26
+ * @param client - APIM REST client
27
+ * @param store - Artifact file store
28
+ * @param context - APIM service context
29
+ * @param outputDir - Output directory
30
+ * @param filter - Optional filter config (workspace names come from here)
31
+ * @returns Results per workspace
32
+ */
33
+ export declare function extractWorkspaces(client: IApimClient, store: IArtifactStore, context: ApimServiceContext, outputDir: string, filter?: FilterConfig): Promise<WorkspaceExtractionResult[]>;
34
+ //# sourceMappingURL=workspace-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-extractor.d.ts","sourceRoot":"","sources":["../../src/services/workspace-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAyBnD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAqBtC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * T027: Workspace-scoped extraction
3
+ * List workspaces, extract workspace-scoped resources under workspaces/{name}/
4
+ * using same resource-extractor with workspace context prefix.
5
+ */
6
+ import { ResourceType } from '../models/resource-types.js';
7
+ import { extractResourceType } from './resource-extractor.js';
8
+ import { extractApiResources } from './api-extractor.js';
9
+ import { extractProductResources } from './product-extractor.js';
10
+ import { logger } from '../lib/logger.js';
11
+ /**
12
+ * Types that can exist at the workspace level.
13
+ * Not all APIM resource types support workspace scoping.
14
+ */
15
+ const WORKSPACE_SUPPORTED_TYPES = [
16
+ ResourceType.NamedValue,
17
+ ResourceType.Tag,
18
+ ResourceType.Backend,
19
+ ResourceType.Logger,
20
+ ResourceType.Diagnostic,
21
+ ResourceType.PolicyFragment,
22
+ ResourceType.Product,
23
+ ResourceType.Api,
24
+ ResourceType.Subscription,
25
+ ResourceType.GlobalSchema,
26
+ ResourceType.Documentation,
27
+ ResourceType.Group,
28
+ ];
29
+ /**
30
+ * Extract resources from all workspaces.
31
+ *
32
+ * Note: Workspace listing is not supported through the current IApimClient
33
+ * interface (ResourceType doesn't include Workspace). This function accepts
34
+ * workspace names from the filter config. If workspaceNames is not specified
35
+ * in the filter, workspace extraction is skipped.
36
+ *
37
+ * @param client - APIM REST client
38
+ * @param store - Artifact file store
39
+ * @param context - APIM service context
40
+ * @param outputDir - Output directory
41
+ * @param filter - Optional filter config (workspace names come from here)
42
+ * @returns Results per workspace
43
+ */
44
+ export async function extractWorkspaces(client, store, context, outputDir, filter) {
45
+ const results = [];
46
+ // Workspace names must be explicitly provided via filter config
47
+ // since the IApimClient interface doesn't support listing workspaces
48
+ const workspaceNames = filter?.workspaceNames;
49
+ if (!workspaceNames || workspaceNames.length === 0) {
50
+ logger.debug('No workspace names specified in filter — skipping workspace extraction');
51
+ return results;
52
+ }
53
+ logger.info(`Extracting ${workspaceNames.length} workspace(s)...`);
54
+ for (const wsName of workspaceNames) {
55
+ const wsResult = await extractWorkspace(client, store, context, wsName, outputDir, filter);
56
+ results.push(wsResult);
57
+ }
58
+ return results;
59
+ }
60
+ /**
61
+ * Extract all resources from a single workspace.
62
+ */
63
+ async function extractWorkspace(client, store, context, workspaceName, outputDir, filter) {
64
+ logger.info(`Extracting workspace "${workspaceName}"...`);
65
+ let resourceCount = 0;
66
+ let errorCount = 0;
67
+ // Create workspace-scoped context
68
+ // Workspace resources are accessed via the same base URL but with /workspaces/{name} prefix
69
+ const wsContext = {
70
+ ...context,
71
+ baseUrl: `${context.baseUrl}/workspaces/${encodeURIComponent(workspaceName)}`,
72
+ };
73
+ // Extract each supported resource type within the workspace
74
+ for (const type of WORKSPACE_SUPPORTED_TYPES) {
75
+ try {
76
+ const result = await extractResourceType(client, store, wsContext, type, outputDir, filter, undefined, workspaceName);
77
+ resourceCount += result.extracted.filter((r) => r.status === 'success').length;
78
+ errorCount += result.errorCount;
79
+ // Handle API-specific extraction for APIs in the workspace
80
+ if (type === ResourceType.Api) {
81
+ for (const api of result.extracted) {
82
+ if (api.status !== 'success')
83
+ continue;
84
+ try {
85
+ const apiResult = await extractApiResources(client, store, wsContext, api.descriptor, api.json, outputDir, filter, workspaceName);
86
+ resourceCount += apiResult.operations.length +
87
+ apiResult.tags.length +
88
+ apiResult.schemas.length;
89
+ }
90
+ catch (error) {
91
+ logger.warn(`Failed to extract API details for workspace "${workspaceName}": ${error.message}`);
92
+ errorCount++;
93
+ }
94
+ }
95
+ }
96
+ // Handle product-specific extraction for products in the workspace
97
+ if (type === ResourceType.Product) {
98
+ for (const product of result.extracted) {
99
+ if (product.status !== 'success')
100
+ continue;
101
+ try {
102
+ await extractProductResources(client, store, wsContext, product.descriptor, outputDir, filter, workspaceName);
103
+ resourceCount++;
104
+ }
105
+ catch (error) {
106
+ logger.warn(`Failed to extract product details for workspace "${workspaceName}": ${error.message}`);
107
+ errorCount++;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ catch (error) {
113
+ logger.warn(`Failed to extract ${type} from workspace "${workspaceName}": ${error.message}`);
114
+ errorCount++;
115
+ }
116
+ }
117
+ logger.info(`Workspace "${workspaceName}": extracted ${resourceCount} resources, ${errorCount} errors`);
118
+ return { workspaceName, resourceCount, errorCount };
119
+ }
120
+ //# sourceMappingURL=workspace-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-extractor.js","sourceRoot":"","sources":["../../src/services/workspace-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * T045: Azure DevOps extract pipeline template
3
+ * Manual trigger with configuration choice and auto-PR creation
4
+ */
5
+ export interface ExtractPipelineConfig {
6
+ artifactDir: string;
7
+ }
8
+ export declare function generateExtractPipeline(config: ExtractPipelineConfig): string;
9
+ //# sourceMappingURL=extract-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-pipeline.d.ts","sourceRoot":"","sources":["../../../src/templates/azure-devops/extract-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAyF7E"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * T045: Azure DevOps extract pipeline template
3
+ * Manual trigger with configuration choice and auto-PR creation
4
+ */
5
+ export function generateExtractPipeline(config) {
6
+ return `# Azure DevOps Pipeline: Run APIM Extractor
7
+
8
+ trigger: none
9
+
10
+ parameters:
11
+ - name: CONFIGURATION_YAML_PATH
12
+ type: string
13
+ displayName: 'Choose whether to extract all APIs or use the extraction configuration file'
14
+ default: 'Extract All APIs'
15
+ values:
16
+ - 'Extract All APIs'
17
+ - 'configuration.extract.yaml'
18
+ - name: resourceGroup
19
+ type: string
20
+ displayName: 'Azure Resource Group'
21
+ default: $(APIM_RESOURCE_GROUP)
22
+ - name: serviceName
23
+ type: string
24
+ displayName: 'APIM Service Name'
25
+ default: $(APIM_SERVICE_NAME)
26
+
27
+ pool:
28
+ vmImage: 'ubuntu-latest'
29
+
30
+ variables:
31
+ - group: apim-common
32
+
33
+ steps:
34
+ - task: NodeTool@0
35
+ displayName: 'Setup Node.js'
36
+ inputs:
37
+ versionSpec: '22.x'
38
+
39
+ - script: npm ci
40
+ displayName: 'Install dependencies'
41
+
42
+ - task: AzureCLI@2
43
+ displayName: 'Run APIM Extract (All APIs)'
44
+ condition: eq('\${{ parameters.CONFIGURATION_YAML_PATH }}', 'Extract All APIs')
45
+ inputs:
46
+ azureSubscription: '$(AZURE_SERVICE_CONNECTION)'
47
+ scriptType: 'bash'
48
+ scriptLocation: 'inlineScript'
49
+ inlineScript: |
50
+ npx apiops extract \\
51
+ --resource-group \${{ parameters.resourceGroup }} \\
52
+ --service-name \${{ parameters.serviceName }} \\
53
+ --output ${config.artifactDir} \\
54
+ --subscription-id $(AZURE_SUBSCRIPTION_ID)
55
+
56
+ - task: AzureCLI@2
57
+ displayName: 'Run APIM Extract (With Configuration)'
58
+ condition: ne('\${{ parameters.CONFIGURATION_YAML_PATH }}', 'Extract All APIs')
59
+ inputs:
60
+ azureSubscription: '$(AZURE_SERVICE_CONNECTION)'
61
+ scriptType: 'bash'
62
+ scriptLocation: 'inlineScript'
63
+ inlineScript: |
64
+ npx apiops extract \\
65
+ --resource-group \${{ parameters.resourceGroup }} \\
66
+ --service-name \${{ parameters.serviceName }} \\
67
+ --output ${config.artifactDir} \\
68
+ --filter configuration.extract.yaml \\
69
+ --subscription-id $(AZURE_SUBSCRIPTION_ID)
70
+
71
+ - task: PublishPipelineArtifact@1
72
+ displayName: 'Publish artifacts'
73
+ inputs:
74
+ targetPath: ${config.artifactDir}
75
+ artifactName: apim-artifacts
76
+
77
+ - script: |
78
+ BRANCH_NAME="apim-extract-$(Build.BuildId)"
79
+ git config user.name "Azure DevOps"
80
+ git config user.email "azuredevops@microsoft.com"
81
+ git checkout -b "$BRANCH_NAME"
82
+ git add ${config.artifactDir}
83
+ if git diff --cached --quiet; then
84
+ echo "No changes to commit"
85
+ else
86
+ git commit -m "chore: update APIM artifacts from extract"
87
+ git push origin "$BRANCH_NAME"
88
+ echo "##vso[task.logissue type=warning]Branch '$BRANCH_NAME' pushed. Please create a pull request to merge the changes."
89
+ fi
90
+ displayName: 'Create branch with changes'
91
+ env:
92
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
93
+ `;
94
+ }
95
+ //# sourceMappingURL=extract-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-pipeline.js","sourceRoot":"","sources":["../../../src/templates/azure-devops/extract-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACnE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+CY,MAAM,CAAC,WAAW;;;;;;;;;;;;;;qBAclB,MAAM,CAAC,WAAW;;;;;;;oBAOnB,MAAM,CAAC,WAAW;;;;;;;;gBAQtB,MAAM,CAAC,WAAW;;;;;;;;;;;CAWjC,CAAC;AACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * T046: Azure DevOps publish pipeline template
3
+ * Multi-stage pipeline with commit ID choice, environment selection, and variable groups
4
+ */
5
+ export interface PublishPipelineConfig {
6
+ artifactDir: string;
7
+ environments: string[];
8
+ }
9
+ export declare function generatePublishPipeline(config: PublishPipelineConfig): string;
10
+ //# sourceMappingURL=publish-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-pipeline.d.ts","sourceRoot":"","sources":["../../../src/templates/azure-devops/publish-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAiG7E"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * T046: Azure DevOps publish pipeline template
3
+ * Multi-stage pipeline with commit ID choice, environment selection, and variable groups
4
+ */
5
+ export function generatePublishPipeline(config) {
6
+ const envValues = config.environments.map((env) => ` - '${env}'`).join('\n');
7
+ const stages = config.environments.map((env, idx) => {
8
+ const dependsOn = idx === 0 ? '' : ` dependsOn: Publish_${config.environments[idx - 1]}\n`;
9
+ return `${dependsOn}- stage: Publish_${env}
10
+ displayName: 'Publish to ${env}'
11
+ condition: or(eq('\${{ parameters.ENVIRONMENT }}', '${env}'), eq('\${{ parameters.ENVIRONMENT }}', 'all'))
12
+ variables:
13
+ - group: apim-${env}
14
+ jobs:
15
+ - deployment: Deploy
16
+ displayName: 'Deploy to ${env}'
17
+ environment: ${env}
18
+ pool:
19
+ vmImage: 'ubuntu-latest'
20
+ strategy:
21
+ runOnce:
22
+ deploy:
23
+ steps:
24
+ - checkout: self
25
+ fetchDepth: 2
26
+
27
+ - task: NodeTool@0
28
+ displayName: 'Setup Node.js'
29
+ inputs:
30
+ versionSpec: '22.x'
31
+
32
+ - script: npm ci
33
+ displayName: 'Install dependencies'
34
+
35
+ - task: AzureCLI@2
36
+ displayName: 'Publish to ${env} (incremental - last commit only)'
37
+ condition: ne('\${{ parameters.COMMIT_ID_CHOICE }}', 'publish-all-artifacts-in-repo')
38
+ inputs:
39
+ azureSubscription: '$(AZURE_SERVICE_CONNECTION_${env.toUpperCase()})'
40
+ scriptType: 'bash'
41
+ scriptLocation: 'inlineScript'
42
+ inlineScript: |
43
+ npx apiops publish \\
44
+ --resource-group $(APIM_RESOURCE_GROUP_${env.toUpperCase()}) \\
45
+ --service-name $(APIM_SERVICE_NAME_${env.toUpperCase()}) \\
46
+ --source ${config.artifactDir} \\
47
+ --override configuration.${env}.yaml \\
48
+ --commit-id $(Build.SourceVersion) \\
49
+ --subscription-id $(AZURE_SUBSCRIPTION_ID)
50
+
51
+ - task: AzureCLI@2
52
+ displayName: 'Publish to ${env} (all artifacts)'
53
+ condition: eq('\${{ parameters.COMMIT_ID_CHOICE }}', 'publish-all-artifacts-in-repo')
54
+ inputs:
55
+ azureSubscription: '$(AZURE_SERVICE_CONNECTION_${env.toUpperCase()})'
56
+ scriptType: 'bash'
57
+ scriptLocation: 'inlineScript'
58
+ inlineScript: |
59
+ npx apiops publish \\
60
+ --resource-group $(APIM_RESOURCE_GROUP_${env.toUpperCase()}) \\
61
+ --service-name $(APIM_SERVICE_NAME_${env.toUpperCase()}) \\
62
+ --source ${config.artifactDir} \\
63
+ --override configuration.${env}.yaml \\
64
+ --subscription-id $(AZURE_SUBSCRIPTION_ID)
65
+ `;
66
+ }).join('\n');
67
+ return `# Azure DevOps Pipeline: Run APIM Publisher
68
+
69
+ trigger:
70
+ branches:
71
+ include:
72
+ - main
73
+ paths:
74
+ include:
75
+ - '${config.artifactDir}/**'
76
+ - 'configuration.*.yaml'
77
+
78
+ pr: none
79
+
80
+ parameters:
81
+ - name: COMMIT_ID_CHOICE
82
+ type: string
83
+ displayName: 'Choose "publish-all-artifacts-in-repo" only when you want to force republishing all artifacts (e.g. after build failure). Otherwise stick with the default behavior of "publish-artifacts-in-last-commit"'
84
+ default: 'publish-artifacts-in-last-commit'
85
+ values:
86
+ - 'publish-artifacts-in-last-commit'
87
+ - 'publish-all-artifacts-in-repo'
88
+ - name: ENVIRONMENT
89
+ type: string
90
+ displayName: 'Choose which environment to publish to'
91
+ default: 'all'
92
+ values:
93
+ - 'all'
94
+ ${envValues}
95
+
96
+ stages:
97
+ ${stages}
98
+ `;
99
+ }
100
+ //# sourceMappingURL=publish-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-pipeline.js","sourceRoot":"","sources":["../../../src/templates/azure-devops/publish-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAElF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAClD,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;QAE5F,OAAO,GAAG,SAAS,oBAAoB,GAAG;6BACjB,GAAG;wDACwB,GAAG;;oBAEvC,GAAG;;;gCAGS,GAAG;qBACd,GAAG;;;;;;;;;;;;;;;;;;;2CAmBmB,GAAG;;;mEAGqB,GAAG,CAAC,WAAW,EAAE;;;;;+DAKrB,GAAG,CAAC,WAAW,EAAE;2DACrB,GAAG,CAAC,WAAW,EAAE;iCAC3C,MAAM,CAAC,WAAW;iDACF,GAAG;;;;;2CAKT,GAAG;;;mEAGqB,GAAG,CAAC,WAAW,EAAE;;;;;+DAKrB,GAAG,CAAC,WAAW,EAAE;2DACrB,GAAG,CAAC,WAAW,EAAE;iCAC3C,MAAM,CAAC,WAAW;iDACF,GAAG;;CAEnD,CAAC;IACA,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;;;;;;;;WAQE,MAAM,CAAC,WAAW;;;;;;;;;;;;;;;;;;;EAmB3B,SAAS;;;EAGT,MAAM;CACP,CAAC;AACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * T047: Sample filter configuration template
3
+ * Generates a sample configuration.extract.yaml file
4
+ */
5
+ export declare function generateFilterConfig(): string;
6
+ //# sourceMappingURL=filter-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-config.d.ts","sourceRoot":"","sources":["../../../src/templates/configs/filter-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,oBAAoB,IAAI,MAAM,CA6C7C"}