@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.
- package/LICENSE.md +21 -0
- package/README.md +135 -0
- package/dist/cli/extract-command.d.ts +12 -0
- package/dist/cli/extract-command.d.ts.map +1 -0
- package/dist/cli/extract-command.js +157 -0
- package/dist/cli/extract-command.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +74 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +11 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +87 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/publish-command.d.ts +12 -0
- package/dist/cli/publish-command.d.ts.map +1 -0
- package/dist/cli/publish-command.js +159 -0
- package/dist/cli/publish-command.js.map +1 -0
- package/dist/clients/apim-client.d.ts +110 -0
- package/dist/clients/apim-client.d.ts.map +1 -0
- package/dist/clients/apim-client.js +586 -0
- package/dist/clients/apim-client.js.map +1 -0
- package/dist/clients/artifact-store.d.ts +23 -0
- package/dist/clients/artifact-store.d.ts.map +1 -0
- package/dist/clients/artifact-store.js +188 -0
- package/dist/clients/artifact-store.js.map +1 -0
- package/dist/clients/iapim-client.d.ts +52 -0
- package/dist/clients/iapim-client.d.ts.map +1 -0
- package/dist/clients/iapim-client.js +6 -0
- package/dist/clients/iapim-client.js.map +1 -0
- package/dist/clients/iartifact-store.d.ts +50 -0
- package/dist/clients/iartifact-store.d.ts.map +1 -0
- package/dist/clients/iartifact-store.js +6 -0
- package/dist/clients/iartifact-store.js.map +1 -0
- package/dist/lib/auto-generated.d.ts +27 -0
- package/dist/lib/auto-generated.d.ts.map +1 -0
- package/dist/lib/auto-generated.js +34 -0
- package/dist/lib/auto-generated.js.map +1 -0
- package/dist/lib/cloud-config.d.ts +29 -0
- package/dist/lib/cloud-config.d.ts.map +1 -0
- package/dist/lib/cloud-config.js +60 -0
- package/dist/lib/cloud-config.js.map +1 -0
- package/dist/lib/config-loader.d.ts +21 -0
- package/dist/lib/config-loader.d.ts.map +1 -0
- package/dist/lib/config-loader.js +131 -0
- package/dist/lib/config-loader.js.map +1 -0
- package/dist/lib/dependency-graph.d.ts +43 -0
- package/dist/lib/dependency-graph.d.ts.map +1 -0
- package/dist/lib/dependency-graph.js +163 -0
- package/dist/lib/dependency-graph.js.map +1 -0
- package/dist/lib/exit-codes.d.ts +27 -0
- package/dist/lib/exit-codes.d.ts.map +1 -0
- package/dist/lib/exit-codes.js +33 -0
- package/dist/lib/exit-codes.js.map +1 -0
- package/dist/lib/logger.d.ts +39 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +128 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/parallel-runner.d.ts +38 -0
- package/dist/lib/parallel-runner.d.ts.map +1 -0
- package/dist/lib/parallel-runner.js +70 -0
- package/dist/lib/parallel-runner.js.map +1 -0
- package/dist/lib/resource-path.d.ts +205 -0
- package/dist/lib/resource-path.d.ts.map +1 -0
- package/dist/lib/resource-path.js +401 -0
- package/dist/lib/resource-path.js.map +1 -0
- package/dist/lib/resource-uri.d.ts +40 -0
- package/dist/lib/resource-uri.d.ts.map +1 -0
- package/dist/lib/resource-uri.js +86 -0
- package/dist/lib/resource-uri.js.map +1 -0
- package/dist/lib/user-agent.d.ts +2 -0
- package/dist/lib/user-agent.d.ts.map +1 -0
- package/dist/lib/user-agent.js +5 -0
- package/dist/lib/user-agent.js.map +1 -0
- package/dist/models/config.d.ts +83 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +6 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/resource-types.d.ts +66 -0
- package/dist/models/resource-types.d.ts.map +1 -0
- package/dist/models/resource-types.js +243 -0
- package/dist/models/resource-types.js.map +1 -0
- package/dist/models/types.d.ts +47 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +6 -0
- package/dist/models/types.js.map +1 -0
- package/dist/services/api-extractor.d.ts +36 -0
- package/dist/services/api-extractor.d.ts.map +1 -0
- package/dist/services/api-extractor.js +319 -0
- package/dist/services/api-extractor.js.map +1 -0
- package/dist/services/api-publisher.d.ts +18 -0
- package/dist/services/api-publisher.d.ts.map +1 -0
- package/dist/services/api-publisher.js +290 -0
- package/dist/services/api-publisher.js.map +1 -0
- package/dist/services/delete-unmatched-service.d.ts +17 -0
- package/dist/services/delete-unmatched-service.d.ts.map +1 -0
- package/dist/services/delete-unmatched-service.js +143 -0
- package/dist/services/delete-unmatched-service.js.map +1 -0
- package/dist/services/dry-run-reporter.d.ts +30 -0
- package/dist/services/dry-run-reporter.d.ts.map +1 -0
- package/dist/services/dry-run-reporter.js +111 -0
- package/dist/services/dry-run-reporter.js.map +1 -0
- package/dist/services/extract-service.d.ts +47 -0
- package/dist/services/extract-service.d.ts.map +1 -0
- package/dist/services/extract-service.js +374 -0
- package/dist/services/extract-service.js.map +1 -0
- package/dist/services/filter-service.d.ts +29 -0
- package/dist/services/filter-service.d.ts.map +1 -0
- package/dist/services/filter-service.js +143 -0
- package/dist/services/filter-service.js.map +1 -0
- package/dist/services/git-diff-service.d.ts +23 -0
- package/dist/services/git-diff-service.d.ts.map +1 -0
- package/dist/services/git-diff-service.js +135 -0
- package/dist/services/git-diff-service.js.map +1 -0
- package/dist/services/identity-guide-service.d.ts +11 -0
- package/dist/services/identity-guide-service.d.ts.map +1 -0
- package/dist/services/identity-guide-service.js +227 -0
- package/dist/services/identity-guide-service.js.map +1 -0
- package/dist/services/init-service.d.ts +16 -0
- package/dist/services/init-service.d.ts.map +1 -0
- package/dist/services/init-service.js +304 -0
- package/dist/services/init-service.js.map +1 -0
- package/dist/services/keyvault-checker.d.ts +58 -0
- package/dist/services/keyvault-checker.d.ts.map +1 -0
- package/dist/services/keyvault-checker.js +390 -0
- package/dist/services/keyvault-checker.js.map +1 -0
- package/dist/services/override-merger.d.ts +20 -0
- package/dist/services/override-merger.d.ts.map +1 -0
- package/dist/services/override-merger.js +102 -0
- package/dist/services/override-merger.js.map +1 -0
- package/dist/services/product-extractor.d.ts +26 -0
- package/dist/services/product-extractor.d.ts.map +1 -0
- package/dist/services/product-extractor.js +141 -0
- package/dist/services/product-extractor.js.map +1 -0
- package/dist/services/product-publisher.d.ts +15 -0
- package/dist/services/product-publisher.d.ts.map +1 -0
- package/dist/services/product-publisher.js +113 -0
- package/dist/services/product-publisher.js.map +1 -0
- package/dist/services/prompt-service.d.ts +13 -0
- package/dist/services/prompt-service.d.ts.map +1 -0
- package/dist/services/prompt-service.js +69 -0
- package/dist/services/prompt-service.js.map +1 -0
- package/dist/services/publish-service.d.ts +31 -0
- package/dist/services/publish-service.d.ts.map +1 -0
- package/dist/services/publish-service.js +445 -0
- package/dist/services/publish-service.js.map +1 -0
- package/dist/services/resource-extractor.d.ts +52 -0
- package/dist/services/resource-extractor.d.ts.map +1 -0
- package/dist/services/resource-extractor.js +168 -0
- package/dist/services/resource-extractor.js.map +1 -0
- package/dist/services/resource-publisher.d.ts +23 -0
- package/dist/services/resource-publisher.d.ts.map +1 -0
- package/dist/services/resource-publisher.js +349 -0
- package/dist/services/resource-publisher.js.map +1 -0
- package/dist/services/secret-redactor.d.ts +20 -0
- package/dist/services/secret-redactor.d.ts.map +1 -0
- package/dist/services/secret-redactor.js +45 -0
- package/dist/services/secret-redactor.js.map +1 -0
- package/dist/services/transitive-resolver.d.ts +45 -0
- package/dist/services/transitive-resolver.d.ts.map +1 -0
- package/dist/services/transitive-resolver.js +177 -0
- package/dist/services/transitive-resolver.js.map +1 -0
- package/dist/services/workspace-extractor.d.ts +34 -0
- package/dist/services/workspace-extractor.d.ts.map +1 -0
- package/dist/services/workspace-extractor.js +120 -0
- package/dist/services/workspace-extractor.js.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts +9 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.js +95 -0
- package/dist/templates/azure-devops/extract-pipeline.js.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts +10 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.js +100 -0
- package/dist/templates/azure-devops/publish-pipeline.js.map +1 -0
- package/dist/templates/configs/filter-config.d.ts +6 -0
- package/dist/templates/configs/filter-config.d.ts.map +1 -0
- package/dist/templates/configs/filter-config.js +51 -0
- package/dist/templates/configs/filter-config.js.map +1 -0
- package/dist/templates/configs/override-config.d.ts +6 -0
- package/dist/templates/configs/override-config.d.ts.map +1 -0
- package/dist/templates/configs/override-config.js +45 -0
- package/dist/templates/configs/override-config.js.map +1 -0
- package/dist/templates/configs/package-json.d.ts +10 -0
- package/dist/templates/configs/package-json.d.ts.map +1 -0
- package/dist/templates/configs/package-json.js +19 -0
- package/dist/templates/configs/package-json.js.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts +13 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.js +279 -0
- package/dist/templates/copilot/identity-setup-prompt.js.map +1 -0
- package/dist/templates/github-actions/extract-workflow.d.ts +9 -0
- package/dist/templates/github-actions/extract-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/extract-workflow.js +126 -0
- package/dist/templates/github-actions/extract-workflow.js.map +1 -0
- package/dist/templates/github-actions/publish-workflow.d.ts +10 -0
- package/dist/templates/github-actions/publish-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/publish-workflow.js +105 -0
- package/dist/templates/github-actions/publish-workflow.js.map +1 -0
- 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"}
|