@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,141 @@
1
+ /**
2
+ * T023: Product-specific extraction logic
3
+ * Product associations (apis.json, groups.json, tags.json), product policies, product wikis.
4
+ */
5
+ import { ResourceType } from '../models/resource-types.js';
6
+ import { extractResourceName } from './resource-extractor.js';
7
+ import { logger } from '../lib/logger.js';
8
+ import { getNamePart } from '../lib/resource-path.js';
9
+ /**
10
+ * Extract all product-specific resources for a single product.
11
+ * This includes API associations, group associations, policies, and wikis.
12
+ */
13
+ export async function extractProductResources(client, store, context, productDescriptor, outputDir, _filter, _workspace) {
14
+ const productName = getNamePart(productDescriptor.nameParts, 0);
15
+ const result = {
16
+ productName,
17
+ apis: [],
18
+ groups: [],
19
+ policy: undefined,
20
+ wiki: false,
21
+ tags: [],
22
+ policies: [],
23
+ };
24
+ // Extract product API associations
25
+ result.apis = await extractProductAssociations(client, store, context, productDescriptor, outputDir, 'apis');
26
+ // Extract product group associations
27
+ result.groups = await extractProductAssociations(client, store, context, productDescriptor, outputDir, 'groups');
28
+ // Extract product policy
29
+ result.policy = await extractProductPolicy(client, store, context, productDescriptor, outputDir);
30
+ if (result.policy) {
31
+ result.policies.push(result.policy);
32
+ }
33
+ // Extract product wiki
34
+ result.wiki = await extractProductWiki(client, store, context, productDescriptor, outputDir);
35
+ // Extract product tags - store as tags.json association file
36
+ result.tags = await extractProductTags(client, store, context, productDescriptor, outputDir);
37
+ return result;
38
+ }
39
+ /**
40
+ * Extract product association (apis or groups) and write to artifact store.
41
+ */
42
+ async function extractProductAssociations(client, store, context, productDescriptor, outputDir, associationType) {
43
+ const names = [];
44
+ const resourceType = associationType === 'apis'
45
+ ? ResourceType.ProductApi
46
+ : ResourceType.ProductGroup;
47
+ try {
48
+ const resources = client.listResources(context, resourceType, productDescriptor);
49
+ for await (const json of resources) {
50
+ try {
51
+ const name = extractResourceName(json);
52
+ names.push(name);
53
+ }
54
+ catch (error) {
55
+ logger.warn(`Failed to extract ${associationType} association name: ${error.message}`);
56
+ }
57
+ }
58
+ // Write association file
59
+ if (names.length > 0) {
60
+ await store.writeAssociation(outputDir, productDescriptor, associationType, names);
61
+ logger.info(`Extracted ${names.length} ${associationType} for product "${getNamePart(productDescriptor.nameParts, 0)}"`);
62
+ }
63
+ }
64
+ catch (error) {
65
+ logger.warn(`Failed to list ${associationType} for product "${getNamePart(productDescriptor.nameParts, 0)}": ${error.message}`);
66
+ }
67
+ return names;
68
+ }
69
+ /**
70
+ * Extract product tags and write to artifact store as tags.json.
71
+ */
72
+ async function extractProductTags(client, store, context, productDescriptor, outputDir) {
73
+ const names = [];
74
+ try {
75
+ const resources = client.listResources(context, ResourceType.ProductTag, productDescriptor);
76
+ for await (const json of resources) {
77
+ try {
78
+ const name = extractResourceName(json);
79
+ names.push(name);
80
+ }
81
+ catch (error) {
82
+ logger.warn(`Failed to extract tag name: ${error.message}`);
83
+ }
84
+ }
85
+ // Write tags association file
86
+ if (names.length > 0) {
87
+ await store.writeAssociation(outputDir, productDescriptor, 'tags', names);
88
+ logger.info(`Extracted ${names.length} tags for product "${getNamePart(productDescriptor.nameParts, 0)}"`);
89
+ }
90
+ }
91
+ catch (error) {
92
+ logger.warn(`Failed to list tags for product "${getNamePart(productDescriptor.nameParts, 0)}": ${error.message}`);
93
+ }
94
+ return names;
95
+ }
96
+ /**
97
+ * Extract product-level policy.
98
+ */
99
+ async function extractProductPolicy(client, store, context, productDescriptor, outputDir) {
100
+ const policyDescriptor = {
101
+ type: ResourceType.ProductPolicy,
102
+ nameParts: [...productDescriptor.nameParts],
103
+ workspace: productDescriptor.workspace,
104
+ };
105
+ const policyJson = await client.getResource(context, policyDescriptor);
106
+ if (!policyJson) {
107
+ return undefined;
108
+ }
109
+ const properties = policyJson.properties;
110
+ const policyContent = properties?.value;
111
+ if (policyContent) {
112
+ await store.writeContent(outputDir, policyDescriptor, policyContent, 'policy');
113
+ logger.debug(`Extracted policy for product "${getNamePart(productDescriptor.nameParts, 0)}"`);
114
+ return policyContent;
115
+ }
116
+ return undefined;
117
+ }
118
+ /**
119
+ * Extract product wiki.
120
+ */
121
+ async function extractProductWiki(client, store, context, productDescriptor, outputDir) {
122
+ try {
123
+ const wikiDescriptor = {
124
+ type: ResourceType.ProductWiki,
125
+ nameParts: [...productDescriptor.nameParts],
126
+ workspace: productDescriptor.workspace,
127
+ };
128
+ const wikiJson = await client.getResource(context, wikiDescriptor);
129
+ if (!wikiJson) {
130
+ return false;
131
+ }
132
+ await store.writeResource(outputDir, wikiDescriptor, wikiJson);
133
+ logger.info(`Extracted wiki for product "${getNamePart(productDescriptor.nameParts, 0)}"`);
134
+ return true;
135
+ }
136
+ catch (error) {
137
+ logger.debug(`No wiki for product "${getNamePart(productDescriptor.nameParts, 0)}": ${error.message}`);
138
+ return false;
139
+ }
140
+ }
141
+ //# sourceMappingURL=product-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-extractor.js","sourceRoot":"","sources":["../../src/services/product-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Product publisher with association handling
3
+ * Publish product and its associations (ProductApi, ProductGroup, ProductTag)
4
+ */
5
+ import type { IApimClient } from '../clients/iapim-client.js';
6
+ import type { IArtifactStore } from '../clients/iartifact-store.js';
7
+ import type { ApimServiceContext, ResourceDescriptor } from '../models/types.js';
8
+ import type { PublishConfig } from '../models/config.js';
9
+ import { type ResourcePublishResult } from './resource-publisher.js';
10
+ /**
11
+ * Publish a Product with all its associations (APIs, Groups, Tags).
12
+ * Creates product first, then publishes associations.
13
+ */
14
+ export declare function publishProduct(client: IApimClient, store: IArtifactStore, context: ApimServiceContext, descriptor: ResourceDescriptor, config: PublishConfig): Promise<ResourcePublishResult>;
15
+ //# sourceMappingURL=product-publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-publisher.d.ts","sourceRoot":"","sources":["../../src/services/product-publisher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAmB,KAAK,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAItF;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,qBAAqB,CAAC,CA8DhC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Product publisher with association handling
3
+ * Publish product and its associations (ProductApi, ProductGroup, ProductTag)
4
+ */
5
+ import { ResourceType } from '../models/resource-types.js';
6
+ import { publishResource } from './resource-publisher.js';
7
+ import { logger } from '../lib/logger.js';
8
+ import { getNamePart } from '../lib/resource-path.js';
9
+ /**
10
+ * Publish a Product with all its associations (APIs, Groups, Tags).
11
+ * Creates product first, then publishes associations.
12
+ */
13
+ export async function publishProduct(client, store, context, descriptor, config) {
14
+ try {
15
+ const productName = getNamePart(descriptor.nameParts, 0);
16
+ // Step 1: Publish the Product itself
17
+ const productResult = await publishResource(client, store, context, descriptor, config);
18
+ if (productResult.status !== 'success') {
19
+ return productResult;
20
+ }
21
+ // Step 2: Publish ProductApi associations
22
+ await publishProductAssociations(client, store, context, descriptor, config, 'apis', ResourceType.ProductApi);
23
+ // Step 3: Publish ProductGroup associations
24
+ await publishProductAssociations(client, store, context, descriptor, config, 'groups', ResourceType.ProductGroup);
25
+ // Step 4: Publish ProductTag associations
26
+ // Tags are stored in the product directory, need to check for tags
27
+ await publishProductTags(client, store, context, descriptor, config);
28
+ // Step 5: Publish ProductPolicy if exists
29
+ const policyDescriptor = {
30
+ type: ResourceType.ProductPolicy,
31
+ nameParts: [productName],
32
+ workspace: descriptor.workspace,
33
+ };
34
+ const policyContent = await store.readContent(config.sourceDir, policyDescriptor, 'policy');
35
+ if (policyContent) {
36
+ await publishResource(client, store, context, policyDescriptor, config);
37
+ logger.debug(`Published policy for product: ${productName}`);
38
+ }
39
+ logger.info(`Published product with associations: ${productName}`);
40
+ return {
41
+ descriptor,
42
+ status: 'success',
43
+ action: 'put',
44
+ };
45
+ }
46
+ catch (error) {
47
+ return {
48
+ descriptor,
49
+ status: 'failed',
50
+ action: 'noop',
51
+ error: error instanceof Error ? error : new Error(String(error)),
52
+ };
53
+ }
54
+ }
55
+ /**
56
+ * Publish associations (ProductApi or ProductGroup) for a product
57
+ */
58
+ async function publishProductAssociations(client, store, context, productDescriptor, config, associationType, resourceType) {
59
+ const productName = getNamePart(productDescriptor.nameParts, 0);
60
+ // Read association file
61
+ const names = await store.readAssociation(config.sourceDir, productDescriptor, associationType);
62
+ if (names.length === 0) {
63
+ logger.debug(`No ${associationType} associations for product: ${productName}`);
64
+ return;
65
+ }
66
+ // Create association for each name
67
+ for (const name of names) {
68
+ const assocDescriptor = {
69
+ type: resourceType,
70
+ nameParts: [productName, name],
71
+ workspace: productDescriptor.workspace,
72
+ };
73
+ try {
74
+ // PUT empty body for association (APIM uses PUT to create association)
75
+ await client.putResource(context, assocDescriptor, {});
76
+ logger.debug(`Created ${resourceType} association: ${productName}/${name}`);
77
+ }
78
+ catch (error) {
79
+ logger.warn(`Failed to create ${resourceType} association ${productName}/${name}: ${String(error)}`);
80
+ }
81
+ }
82
+ }
83
+ /**
84
+ * Publish ProductTag associations for a product.
85
+ * Tags are stored in tags.json similar to apis.json and groups.json.
86
+ */
87
+ async function publishProductTags(client, store, context, productDescriptor, config) {
88
+ const productName = getNamePart(productDescriptor.nameParts, 0);
89
+ // Read tags from tags.json association file
90
+ const tagNames = await store.readAssociation(config.sourceDir, productDescriptor, 'tags');
91
+ if (tagNames.length === 0) {
92
+ logger.debug(`No tag associations for product: ${productName}`);
93
+ return;
94
+ }
95
+ // Create association for each tag
96
+ for (const tagName of tagNames) {
97
+ const tagDescriptor = {
98
+ type: ResourceType.ProductTag,
99
+ nameParts: [productName, tagName],
100
+ workspace: productDescriptor.workspace,
101
+ };
102
+ try {
103
+ // PUT empty body for tag association
104
+ await client.putResource(context, tagDescriptor, {});
105
+ logger.debug(`Created ProductTag association: ${productName}/${tagName}`);
106
+ }
107
+ catch (error) {
108
+ logger.warn(`Failed to create ProductTag association ${productName}/${tagName}: ${String(error)}`);
109
+ }
110
+ }
111
+ logger.info(`Published ${tagNames.length} tags for product: ${productName}`);
112
+ }
113
+ //# sourceMappingURL=product-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-publisher.js","sourceRoot":"","sources":["../../src/services/product-publisher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * T049: Interactive prompt handler
3
+ * TTY detection, question prompts for CI provider/artifact dir/environments
4
+ * --non-interactive bypass per FR-022
5
+ */
6
+ export interface PromptService {
7
+ isTTY(): boolean;
8
+ askCIProvider(): Promise<'github-actions' | 'azure-devops'>;
9
+ askArtifactDir(defaultValue: string): Promise<string>;
10
+ askEnvironments(defaultValue: string[]): Promise<string[]>;
11
+ }
12
+ export declare const promptService: PromptService;
13
+ //# sourceMappingURL=prompt-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-service.d.ts","sourceRoot":"","sources":["../../src/services/prompt-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,OAAO,CAAC;IACjB,aAAa,IAAI,OAAO,CAAC,gBAAgB,GAAG,cAAc,CAAC,CAAC;IAC5D,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC5D;AA2ED,eAAO,MAAM,aAAa,EAAE,aAAuC,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * T049: Interactive prompt handler
3
+ * TTY detection, question prompts for CI provider/artifact dir/environments
4
+ * --non-interactive bypass per FR-022
5
+ */
6
+ import * as readline from 'readline';
7
+ import { logger } from '../lib/logger.js';
8
+ class PromptServiceImpl {
9
+ /**
10
+ * Check if we're running in an interactive terminal
11
+ */
12
+ isTTY() {
13
+ return process.stdin.isTTY === true && process.stdout.isTTY === true;
14
+ }
15
+ /**
16
+ * Ask user to choose CI/CD provider
17
+ */
18
+ async askCIProvider() {
19
+ const answer = await this.ask('Select CI/CD provider:\n 1) GitHub Actions\n 2) Azure DevOps\nChoice (1-2): ');
20
+ if (answer === '1') {
21
+ return 'github-actions';
22
+ }
23
+ else if (answer === '2') {
24
+ return 'azure-devops';
25
+ }
26
+ else {
27
+ logger.warn('Invalid choice, defaulting to GitHub Actions');
28
+ return 'github-actions';
29
+ }
30
+ }
31
+ /**
32
+ * Ask user for artifact directory path
33
+ */
34
+ async askArtifactDir(defaultValue) {
35
+ const answer = await this.ask(`Artifact directory path (default: ${defaultValue}): `);
36
+ return answer.trim() || defaultValue;
37
+ }
38
+ /**
39
+ * Ask user for environment names
40
+ */
41
+ async askEnvironments(defaultValue) {
42
+ const defaultStr = defaultValue.join(',');
43
+ const answer = await this.ask(`Environment names, comma-separated (default: ${defaultStr}): `);
44
+ if (!answer.trim()) {
45
+ return defaultValue;
46
+ }
47
+ return answer
48
+ .split(',')
49
+ .map((env) => env.trim())
50
+ .filter((env) => env.length > 0);
51
+ }
52
+ /**
53
+ * Low-level prompt helper
54
+ */
55
+ ask(question) {
56
+ const rl = readline.createInterface({
57
+ input: process.stdin,
58
+ output: process.stdout,
59
+ });
60
+ return new Promise((resolve) => {
61
+ rl.question(question, (answer) => {
62
+ rl.close();
63
+ resolve(answer);
64
+ });
65
+ });
66
+ }
67
+ }
68
+ export const promptService = new PromptServiceImpl();
69
+ //# sourceMappingURL=prompt-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-service.js","sourceRoot":"","sources":["../../src/services/prompt-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS1C,MAAM,iBAAiB;IACrB;;OAEG;IACH,KAAK;QACH,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAC3B,gFAAgF,CACjF,CAAC;QAEF,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,gBAAgB,CAAC;QAC1B,CAAC;aAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,cAAc,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC5D,OAAO,gBAAgB,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,YAAoB;QACvC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAC3B,qCAAqC,YAAY,KAAK,CACvD,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,YAAY,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,YAAsB;QAC1C,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAC3B,gDAAgD,UAAU,KAAK,CAChE,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,OAAO,MAAM;aACV,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,GAAG,CAAC,QAAgB;QAC1B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAkB,IAAI,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,31 @@
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 { IApimClient } from '../clients/iapim-client.js';
7
+ import { IArtifactStore } from '../clients/iartifact-store.js';
8
+ import { PublishConfig } from '../models/config.js';
9
+ import { ResourceDescriptor } from '../models/types.js';
10
+ import { DryRunReport } from './dry-run-reporter.js';
11
+ export interface PublishActionResult {
12
+ descriptor: ResourceDescriptor;
13
+ action: 'put' | 'delete' | 'noop';
14
+ status: 'success' | 'failed' | 'skipped';
15
+ error?: Error;
16
+ }
17
+ export interface PublishResult {
18
+ totalPuts: number;
19
+ totalDeletes: number;
20
+ totalErrors: number;
21
+ totalSkipped: number;
22
+ exitCode: number;
23
+ actions: PublishActionResult[];
24
+ dryRunReport?: DryRunReport;
25
+ }
26
+ /**
27
+ * Main publish orchestration function.
28
+ * Coordinates PUT/DELETE operations across dependency tiers.
29
+ */
30
+ export declare function runPublish(client: IApimClient, store: IArtifactStore, config: PublishConfig): Promise<PublishResult>;
31
+ //# sourceMappingURL=publish-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-service.d.ts","sourceRoot":"","sources":["../../src/services/publish-service.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,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAsB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAc5E,OAAO,EAAwB,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAW3E,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAiFxB"}