@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,445 @@
1
+ /**
2
+ * T030: Publish orchestration service
3
+ * Coordinates PUT/DELETE across dependency tiers in topological order
4
+ * PUTs in dependency order (tier 1-4), DELETEs in reverse order (tier 4-1)
5
+ */
6
+ import { ResourceType } from '../models/resource-types.js';
7
+ import { getResourceTier } from '../lib/dependency-graph.js';
8
+ import { runParallel } from '../lib/parallel-runner.js';
9
+ import { logger } from '../lib/logger.js';
10
+ import { isAutoGeneratedId } from '../lib/auto-generated.js';
11
+ import { EXIT_SUCCESS, EXIT_PARTIAL, EXIT_FATAL } from '../lib/exit-codes.js';
12
+ import { buildResourceLabel } from '../lib/resource-uri.js';
13
+ import { getNamePart, isChildType } from '../lib/resource-path.js';
14
+ // Import from other agents' files (will be created in parallel)
15
+ import { publishResource } from './resource-publisher.js';
16
+ import { publishApi } from './api-publisher.js';
17
+ import { publishProduct } from './product-publisher.js';
18
+ import { generateDryRunReport } from './dry-run-reporter.js';
19
+ import { computeDeleteActions } from './delete-unmatched-service.js';
20
+ import { computeGitDiff } from './git-diff-service.js';
21
+ /**
22
+ * The APIM Backend properties.type value that identifies a pool backend.
23
+ * Pool backends reference other Backend resources and must be published
24
+ * after the individual backends they aggregate.
25
+ */
26
+ const POOL_BACKEND_TYPE = 'pool';
27
+ /**
28
+ * Main publish orchestration function.
29
+ * Coordinates PUT/DELETE operations across dependency tiers.
30
+ */
31
+ export async function runPublish(client, store, config) {
32
+ try {
33
+ // Step 0: Pre-flight validation — ensure the resource group and APIM service exist
34
+ await client.validatePreFlight(config.service);
35
+ // Step 1: Determine target descriptors based on incremental mode
36
+ const targetDescriptors = await determineTargetDescriptors(store, config);
37
+ logger.debug(`Publishing ${targetDescriptors.length} resources (dry-run: ${config.dryRun})`);
38
+ // Step 2: Handle dry-run mode
39
+ if (config.dryRun) {
40
+ const dryRunReport = await generateDryRunReport(store, client, config.service, config, targetDescriptors);
41
+ return {
42
+ totalPuts: dryRunReport.summary.creates,
43
+ totalDeletes: dryRunReport.summary.deletes,
44
+ totalErrors: 0,
45
+ totalSkipped: dryRunReport.summary.skips,
46
+ exitCode: EXIT_SUCCESS,
47
+ actions: [],
48
+ dryRunReport,
49
+ };
50
+ }
51
+ // Step 3: Execute PUTs in dependency order (tier 1 → tier 4)
52
+ const putResults = await executePuts(client, store, config.service, config, targetDescriptors);
53
+ // Step 4: Execute DELETEs in reverse dependency order (tier 4 → tier 1) if requested
54
+ let deleteResults = [];
55
+ if (config.deleteUnmatched) {
56
+ deleteResults = await executeDeletes(client, store, config.service, config);
57
+ }
58
+ // Step 5: Combine results and determine exit code
59
+ const allResults = [...putResults, ...deleteResults];
60
+ const totalPuts = putResults.length;
61
+ const totalDeletes = deleteResults.length;
62
+ const totalErrors = allResults.filter((r) => r.status === 'failed').length;
63
+ const totalSkipped = allResults.filter((r) => r.status === 'skipped').length;
64
+ const exitCode = determineExitCode(allResults);
65
+ return {
66
+ totalPuts,
67
+ totalDeletes,
68
+ totalErrors,
69
+ totalSkipped,
70
+ exitCode,
71
+ actions: allResults,
72
+ };
73
+ }
74
+ catch (error) {
75
+ logger.error('Fatal error during publish:', error);
76
+ return {
77
+ totalPuts: 0,
78
+ totalDeletes: 0,
79
+ totalErrors: 1,
80
+ totalSkipped: 0,
81
+ exitCode: EXIT_FATAL,
82
+ actions: [],
83
+ };
84
+ }
85
+ }
86
+ /**
87
+ * Determine which resources to publish based on incremental mode.
88
+ */
89
+ async function determineTargetDescriptors(store, config) {
90
+ if (config.commitId) {
91
+ // Incremental mode: use git diff
92
+ logger.debug(`Using incremental publish mode with commit ID: ${config.commitId}`);
93
+ const diffResult = await computeGitDiff(config.sourceDir, config.commitId);
94
+ return diffResult.changedDescriptors;
95
+ }
96
+ else {
97
+ // Full mode: publish all artifacts
98
+ logger.debug('Using full publish mode (all artifacts)');
99
+ return await store.listResources(config.sourceDir);
100
+ }
101
+ }
102
+ /**
103
+ * Execute PUT operations in dependency order (tier 1 → tier 4).
104
+ */
105
+ async function executePuts(client, store, context, config, targetDescriptors) {
106
+ const results = [];
107
+ // Group descriptors by tier
108
+ const tierGroups = new Map();
109
+ for (const descriptor of targetDescriptors) {
110
+ const tier = getResourceTier(descriptor.type);
111
+ if (!tierGroups.has(tier)) {
112
+ tierGroups.set(tier, []);
113
+ }
114
+ tierGroups.get(tier).push(descriptor);
115
+ }
116
+ // Build a map of parent type → Set of parent names being published in tier 2.
117
+ // Top-level types (not child types) handle their children internally,
118
+ // so we exclude those children from tiers 3/4 to avoid double-publishing.
119
+ const parentNamesByType = new Map();
120
+ for (const d of tierGroups.get(2) || []) {
121
+ // Top-level types are those that are NOT child types
122
+ if (!isChildType(d.type)) {
123
+ if (!parentNamesByType.has(d.type)) {
124
+ parentNamesByType.set(d.type, new Set());
125
+ }
126
+ parentNamesByType.get(d.type).add(getNamePart(d.nameParts, 0));
127
+ }
128
+ }
129
+ // Execute each tier in order (1, 2, 3, 4)
130
+ for (const tier of [1, 2, 3, 4]) {
131
+ const descriptors = tierGroups.get(tier) || [];
132
+ if (descriptors.length === 0)
133
+ continue;
134
+ logger.debug(`Publishing tier ${tier}: ${descriptors.length} resources`);
135
+ if (tier === 1) {
136
+ // Within Tier 1 we publish in three ordered waves to satisfy implicit
137
+ // runtime dependencies:
138
+ //
139
+ // Wave 1 — NamedValues only.
140
+ // Loggers and backends may reference named values by name in their
141
+ // configuration (e.g. AppInsights instrumentation key stored as a
142
+ // named value). Publishing named values first ensures they exist
143
+ // before any resource that references them.
144
+ //
145
+ // Wave 2 — All remaining Tier 1 resources except pool backends.
146
+ // Loggers, tags, gateways, etc. can now reference named values safely.
147
+ //
148
+ // Wave 3 — Pool backends.
149
+ // Pool backends reference individual Backend resources and must be
150
+ // published after the backends they aggregate (see pool backend
151
+ // ordering comments in splitPoolBackends).
152
+ const { namedValues, otherTier1 } = splitNamedValues(descriptors);
153
+ if (namedValues.length > 0) {
154
+ logger.debug(`Publishing ${namedValues.length} named value(s) first (wave 1 of tier 1)`);
155
+ await publishAndOutput(client, store, context, config, namedValues, results);
156
+ }
157
+ const { poolBackends, regularTier1 } = await splitPoolBackends(store, config.sourceDir, otherTier1);
158
+ await publishAndOutput(client, store, context, config, regularTier1, results);
159
+ if (poolBackends.length > 0) {
160
+ logger.debug(`Publishing ${poolBackends.length} pool backend(s) after regular backends`);
161
+ await publishAndOutput(client, store, context, config, poolBackends, results);
162
+ }
163
+ }
164
+ else {
165
+ // For tiers 3/4, exclude child resources whose parent is being published
166
+ // in tier 2 (publishApi/publishProduct handle their children internally).
167
+ // Use getParentType() to dynamically determine parent-child relationships.
168
+ let tierDescriptors = descriptors;
169
+ if (parentNamesByType.size > 0) {
170
+ const countBefore = tierDescriptors.length;
171
+ tierDescriptors = tierDescriptors.filter((d) => {
172
+ // Top-level types have no parent to check
173
+ if (!isChildType(d.type))
174
+ return true;
175
+ // Child resources have the parent name as nameParts[0]
176
+ const owningParent = getNamePart(d.nameParts, 0);
177
+ // Skip if this parent name is being published in tier 2
178
+ for (const parentNames of parentNamesByType.values()) {
179
+ if (parentNames.has(owningParent))
180
+ return false;
181
+ }
182
+ return true;
183
+ });
184
+ const skipped = countBefore - tierDescriptors.length;
185
+ if (skipped > 0) {
186
+ logger.debug(`Skipping ${skipped} child resource(s) in tier ${tier} (handled by parent publisher)`);
187
+ }
188
+ }
189
+ await publishAndOutput(client, store, context, config, tierDescriptors, results);
190
+ }
191
+ }
192
+ return results;
193
+ }
194
+ /**
195
+ * Publish a batch of descriptors and write their status lines to stdout/stderr.
196
+ */
197
+ async function publishAndOutput(client, store, context, config, descriptors, results) {
198
+ if (descriptors.length === 0)
199
+ return;
200
+ const tierResults = await publishTier(client, store, context, config, descriptors);
201
+ results.push(...tierResults);
202
+ for (const result of tierResults) {
203
+ outputActionStatus(result);
204
+ }
205
+ }
206
+ /**
207
+ * Separates NamedValue descriptors from all other descriptors in the supplied list.
208
+ *
209
+ * NamedValues must be published before loggers, backends, and other Tier 1
210
+ * resources that may reference them by name in their configuration (e.g. a
211
+ * Logger that stores its instrumentation key as a named value).
212
+ *
213
+ * Auto-generated NamedValues (24-char hex IDs like Logger credentials) are
214
+ * filtered out because APIM recreates them when the referencing Logger is
215
+ * published. Publishing them would create orphan duplicates.
216
+ */
217
+ function splitNamedValues(descriptors) {
218
+ const namedValues = [];
219
+ const otherTier1 = [];
220
+ for (const descriptor of descriptors) {
221
+ if (descriptor.type === ResourceType.NamedValue) {
222
+ // Skip auto-generated named values (24-char hex IDs) - APIM recreates
223
+ // these when publishing loggers with credential references
224
+ const name = getNamePart(descriptor.nameParts, 0);
225
+ if (isAutoGeneratedId(name)) {
226
+ logger.debug(`Skipping auto-generated named value: ${name}`);
227
+ continue;
228
+ }
229
+ namedValues.push(descriptor);
230
+ }
231
+ else {
232
+ otherTier1.push(descriptor);
233
+ }
234
+ }
235
+ return { namedValues, otherTier1 };
236
+ }
237
+ /**
238
+ * Separates Backend descriptors that are pool backends (properties.type === "Pool")
239
+ * from all other descriptors in the supplied list.
240
+ *
241
+ * Pool backends reference individual Backend resources and must therefore be
242
+ * published *after* those backends are created. Reading the artifact JSON is
243
+ * the only reliable way to detect pool backends at publish time because the
244
+ * ResourceType enum treats all backends as the same type.
245
+ */
246
+ async function splitPoolBackends(store, sourceDir, descriptors) {
247
+ const poolBackends = [];
248
+ const regularTier1 = [];
249
+ for (const descriptor of descriptors) {
250
+ if (descriptor.type === ResourceType.Backend) {
251
+ const json = await store.readResource(sourceDir, descriptor);
252
+ const props = json?.properties;
253
+ const backendType = props?.type;
254
+ if (typeof backendType === 'string' && backendType.toLowerCase() === POOL_BACKEND_TYPE) {
255
+ poolBackends.push(descriptor);
256
+ continue;
257
+ }
258
+ }
259
+ regularTier1.push(descriptor);
260
+ }
261
+ return { poolBackends, regularTier1 };
262
+ }
263
+ /**
264
+ * Publish a single tier of resources in parallel.
265
+ */
266
+ async function publishTier(client, store, context, config, descriptors) {
267
+ const tasks = descriptors.map((descriptor) => async () => {
268
+ try {
269
+ let publishResult;
270
+ // Use specialized publishers for Api and Product types
271
+ if (descriptor.type === ResourceType.Api) {
272
+ publishResult = await publishApi(client, store, context, descriptor, config);
273
+ }
274
+ else if (descriptor.type === ResourceType.Product) {
275
+ publishResult = await publishProduct(client, store, context, descriptor, config);
276
+ }
277
+ else {
278
+ publishResult = await publishResource(client, store, context, descriptor, config);
279
+ }
280
+ return convertToActionResult(publishResult);
281
+ }
282
+ catch (error) {
283
+ logger.error(`Failed to publish ${buildResourceLabel(descriptor)}:`, error);
284
+ return {
285
+ descriptor,
286
+ action: 'put',
287
+ status: 'failed',
288
+ error: error instanceof Error ? error : new Error(String(error)),
289
+ };
290
+ }
291
+ });
292
+ const taskResults = await runParallel(tasks, 5);
293
+ return taskResults.map((tr, index) => {
294
+ if (tr.status === 'fulfilled' && tr.value) {
295
+ return tr.value;
296
+ }
297
+ else {
298
+ // Should not happen given error handling above, but be defensive
299
+ const descriptor = descriptors[index];
300
+ if (!descriptor) {
301
+ throw new Error('No descriptor found for failed task');
302
+ }
303
+ return {
304
+ descriptor,
305
+ action: 'put',
306
+ status: 'failed',
307
+ error: tr.reason || new Error('Unknown error'),
308
+ };
309
+ }
310
+ });
311
+ }
312
+ /**
313
+ * Execute DELETE operations in reverse dependency order (tier 4 → tier 1).
314
+ */
315
+ async function executeDeletes(client, store, context, config) {
316
+ const deleteDescriptors = await computeDeleteActions(client, store, context, config);
317
+ if (deleteDescriptors.length === 0) {
318
+ logger.debug('No resources to delete');
319
+ return [];
320
+ }
321
+ logger.debug(`Deleting ${deleteDescriptors.length} unmatched resources`);
322
+ const results = [];
323
+ // Group by tier
324
+ const tierGroups = new Map();
325
+ for (const descriptor of deleteDescriptors) {
326
+ const tier = getResourceTier(descriptor.type);
327
+ if (!tierGroups.has(tier)) {
328
+ tierGroups.set(tier, []);
329
+ }
330
+ tierGroups.get(tier).push(descriptor);
331
+ }
332
+ // Execute in REVERSE tier order (4, 3, 2, 1)
333
+ for (const tier of [4, 3, 2, 1]) {
334
+ const descriptors = tierGroups.get(tier) || [];
335
+ if (descriptors.length === 0)
336
+ continue;
337
+ logger.debug(`Deleting tier ${tier}: ${descriptors.length} resources`);
338
+ const tierResults = await deleteTier(client, context, descriptors);
339
+ results.push(...tierResults);
340
+ // Output per-resource status lines
341
+ for (const result of tierResults) {
342
+ outputActionStatus(result);
343
+ }
344
+ }
345
+ return results;
346
+ }
347
+ /**
348
+ * Delete a single tier of resources in parallel.
349
+ */
350
+ async function deleteTier(client, context, descriptors) {
351
+ const tasks = descriptors.map((descriptor) => async () => {
352
+ try {
353
+ const deleted = await client.deleteResource(context, descriptor);
354
+ return {
355
+ descriptor,
356
+ action: 'delete',
357
+ status: deleted ? 'success' : 'skipped',
358
+ };
359
+ }
360
+ catch (error) {
361
+ logger.error(`Failed to delete ${buildResourceLabel(descriptor)}:`, error);
362
+ return {
363
+ descriptor,
364
+ action: 'delete',
365
+ status: 'failed',
366
+ error: error instanceof Error ? error : new Error(String(error)),
367
+ };
368
+ }
369
+ });
370
+ const taskResults = await runParallel(tasks, 5);
371
+ return taskResults.map((tr, index) => {
372
+ if (tr.status === 'fulfilled' && tr.value) {
373
+ return tr.value;
374
+ }
375
+ else {
376
+ const descriptor = descriptors[index];
377
+ if (!descriptor) {
378
+ throw new Error('No descriptor found for failed task');
379
+ }
380
+ return {
381
+ descriptor,
382
+ action: 'delete',
383
+ status: 'failed',
384
+ error: tr.reason || new Error('Unknown error'),
385
+ };
386
+ }
387
+ });
388
+ }
389
+ /**
390
+ * Convert ResourcePublishResult to PublishActionResult.
391
+ */
392
+ function convertToActionResult(result) {
393
+ return {
394
+ descriptor: result.descriptor,
395
+ action: result.action,
396
+ status: result.status,
397
+ error: result.error,
398
+ };
399
+ }
400
+ /**
401
+ * Output per-resource status line to stdout.
402
+ */
403
+ function outputActionStatus(result) {
404
+ const verb = result.action.toUpperCase();
405
+ const path = buildResourcePath(result.descriptor);
406
+ if (result.status === 'success') {
407
+ process.stdout.write(`${verb} ${path}\n`);
408
+ }
409
+ else if (result.status === 'skipped') {
410
+ process.stdout.write(`SKIP ${path}\n`);
411
+ }
412
+ else if (result.status === 'failed') {
413
+ process.stderr.write(`ERROR ${verb} ${path}: ${result.error?.message}\n`);
414
+ }
415
+ }
416
+ /**
417
+ * Build a human-readable path for a resource descriptor.
418
+ */
419
+ function buildResourcePath(descriptor) {
420
+ const parts = [descriptor.type.toLowerCase()];
421
+ if (descriptor.workspace) {
422
+ parts.push(`workspace:${descriptor.workspace}`);
423
+ }
424
+ parts.push(...descriptor.nameParts);
425
+ return parts.join('/');
426
+ }
427
+ /**
428
+ * Determine exit code based on results.
429
+ * Uses standardised constants from exit-codes module.
430
+ */
431
+ function determineExitCode(results) {
432
+ if (results.length === 0) {
433
+ return EXIT_SUCCESS;
434
+ }
435
+ const successCount = results.filter((r) => r.status === 'success').length;
436
+ const failedCount = results.filter((r) => r.status === 'failed').length;
437
+ if (failedCount === 0) {
438
+ return EXIT_SUCCESS;
439
+ }
440
+ if (successCount > 0) {
441
+ return EXIT_PARTIAL;
442
+ }
443
+ return EXIT_FATAL;
444
+ }
445
+ //# sourceMappingURL=publish-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-service.js","sourceRoot":"","sources":["../../src/services/publish-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * T021: Resource type extractor
3
+ * Generic extract logic: list resources via IApimClient, write each to IArtifactStore.
4
+ * Handles all 33 types using ResourceType metadata. Preserves opaque JSON per FR-009.
5
+ */
6
+ import { IApimClient } from '../clients/iapim-client.js';
7
+ import { IArtifactStore } from '../clients/iartifact-store.js';
8
+ import { ApimServiceContext, ResourceDescriptor } from '../models/types.js';
9
+ import { ResourceType } from '../models/resource-types.js';
10
+ import { FilterConfig } from '../models/config.js';
11
+ /**
12
+ * Result of extracting a single resource.
13
+ */
14
+ export interface ExtractedResource {
15
+ descriptor: ResourceDescriptor;
16
+ json: Record<string, unknown>;
17
+ status: 'success' | 'error';
18
+ error?: string;
19
+ }
20
+ /**
21
+ * Result of extracting all resources of a given type.
22
+ */
23
+ export interface TypeExtractionResult {
24
+ type: ResourceType;
25
+ extracted: ExtractedResource[];
26
+ totalCount: number;
27
+ errorCount: number;
28
+ }
29
+ /**
30
+ * Extract the ARM resource name from a raw JSON object.
31
+ * ARM resources have a 'name' field at the top level.
32
+ */
33
+ export declare function extractResourceName(json: Record<string, unknown>): string;
34
+ /**
35
+ * Extract all resources of a given type from APIM and write to artifact store.
36
+ *
37
+ * @param client - APIM REST client
38
+ * @param store - Artifact file store
39
+ * @param context - APIM service context
40
+ * @param type - Resource type to extract
41
+ * @param outputDir - Output directory
42
+ * @param filter - Optional filter config
43
+ * @param parent - Parent descriptor for child resources
44
+ * @param workspace - Optional workspace name
45
+ * @returns Extraction result
46
+ */
47
+ export declare function extractResourceType(client: IApimClient, store: IArtifactStore, context: ApimServiceContext, type: ResourceType, outputDir: string, filter?: FilterConfig, parent?: ResourceDescriptor, workspace?: string): Promise<TypeExtractionResult>;
48
+ /**
49
+ * Extract a single resource by descriptor and write to artifact store.
50
+ */
51
+ export declare function extractSingleResource(client: IApimClient, store: IArtifactStore, context: ApimServiceContext, descriptor: ResourceDescriptor, outputDir: string): Promise<ExtractedResource>;
52
+ //# sourceMappingURL=resource-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-extractor.d.ts","sourceRoot":"","sources":["../../src/services/resource-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,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAA0B,MAAM,6BAA6B,CAAC;AAGnF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAanD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMzE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,kBAAkB,EAC3B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,CAAC,CA4E/B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,CAAC,CA2B5B"}