@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,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T037 & T038: Publish command CLI registration
|
|
3
|
+
* Commander subcommand with --resource-group, --service-name, --source,
|
|
4
|
+
* --overrides, --dry-run, --delete-unmatched flags.
|
|
5
|
+
* Includes --format json: machine-readable JSON output mode (T038).
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { runPublish } from '../services/publish-service.js';
|
|
9
|
+
import { loadOverrideConfig } from '../lib/config-loader.js';
|
|
10
|
+
import { logger, parseLogLevel } from '../lib/logger.js';
|
|
11
|
+
import { ApimClient } from '../clients/apim-client.js';
|
|
12
|
+
import { ArtifactStore } from '../clients/artifact-store.js';
|
|
13
|
+
import { getCloudConfig, buildArmBaseUrl } from '../lib/cloud-config.js';
|
|
14
|
+
/**
|
|
15
|
+
* Create and return the publish command for Commander.
|
|
16
|
+
*/
|
|
17
|
+
export function createPublishCommand() {
|
|
18
|
+
const publish = new Command('publish')
|
|
19
|
+
.description('Publish local APIM artifacts to Azure APIM service')
|
|
20
|
+
.requiredOption('--resource-group <rg>', 'Azure resource group name')
|
|
21
|
+
.requiredOption('--service-name <name>', 'APIM service instance name')
|
|
22
|
+
.option('--source <dir>', 'Source directory with artifacts', './apim-artifacts')
|
|
23
|
+
.option('--overrides <path>', 'Override configuration YAML file')
|
|
24
|
+
.option('--dry-run', 'Preview changes without applying them', false)
|
|
25
|
+
.option('--delete-unmatched', 'Delete resources in APIM not present in source', false)
|
|
26
|
+
.action(async (options, command) => {
|
|
27
|
+
const globalOpts = command.optsWithGlobals();
|
|
28
|
+
await executePublish(options, globalOpts);
|
|
29
|
+
});
|
|
30
|
+
return publish;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Execute the publish command.
|
|
34
|
+
*/
|
|
35
|
+
async function executePublish(options, globalOpts) {
|
|
36
|
+
const subscriptionId = globalOpts.subscriptionId ?? process.env.AZURE_SUBSCRIPTION_ID;
|
|
37
|
+
if (!subscriptionId) {
|
|
38
|
+
logger.error('Subscription ID required: use --subscription-id or set AZURE_SUBSCRIPTION_ID');
|
|
39
|
+
process.exit(2);
|
|
40
|
+
}
|
|
41
|
+
// Build service context
|
|
42
|
+
const apiVersion = globalOpts.apiVersion ?? process.env.AZURE_API_VERSION ?? '2024-05-01';
|
|
43
|
+
const cloudName = globalOpts.cloud ?? 'public';
|
|
44
|
+
const cloudConfig = getCloudConfig(cloudName);
|
|
45
|
+
const baseUrl = buildArmBaseUrl(cloudName, subscriptionId, options.resourceGroup, options.serviceName);
|
|
46
|
+
const context = {
|
|
47
|
+
subscriptionId,
|
|
48
|
+
resourceGroup: options.resourceGroup,
|
|
49
|
+
serviceName: options.serviceName,
|
|
50
|
+
apiVersion,
|
|
51
|
+
baseUrl,
|
|
52
|
+
};
|
|
53
|
+
// Load override config if specified
|
|
54
|
+
let overrideConfig;
|
|
55
|
+
if (options.overrides) {
|
|
56
|
+
overrideConfig = await loadOverrideConfig(options.overrides);
|
|
57
|
+
if (!overrideConfig) {
|
|
58
|
+
logger.error(`Override file not found: ${options.overrides}`);
|
|
59
|
+
process.exit(2);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Get commit ID from environment (for incremental publish)
|
|
63
|
+
const commitId = process.env.COMMIT_ID;
|
|
64
|
+
if (commitId) {
|
|
65
|
+
logger.debug(`Using incremental publish with commit ID: ${commitId}`);
|
|
66
|
+
}
|
|
67
|
+
// Build publish config
|
|
68
|
+
const publishConfig = {
|
|
69
|
+
service: context,
|
|
70
|
+
sourceDir: options.source,
|
|
71
|
+
overrides: overrideConfig,
|
|
72
|
+
dryRun: options.dryRun,
|
|
73
|
+
deleteUnmatched: options.deleteUnmatched,
|
|
74
|
+
commitId,
|
|
75
|
+
logLevel: parseLogLevel(globalOpts.logLevel ?? 'info'),
|
|
76
|
+
};
|
|
77
|
+
// Create client and store
|
|
78
|
+
const client = new ApimClient(cloudConfig.authScope);
|
|
79
|
+
const store = new ArtifactStore();
|
|
80
|
+
// Run publish
|
|
81
|
+
const result = await runPublish(client, store, publishConfig);
|
|
82
|
+
// Output results
|
|
83
|
+
if (globalOpts.format === 'json') {
|
|
84
|
+
outputJson(result);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
outputText(result, options.dryRun);
|
|
88
|
+
}
|
|
89
|
+
process.exit(result.exitCode);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* T038: JSON output mode for publish.
|
|
93
|
+
* Machine-readable JSON to stdout with action list and summary.
|
|
94
|
+
*/
|
|
95
|
+
function outputJson(result) {
|
|
96
|
+
const output = {
|
|
97
|
+
status: result.exitCode === 0
|
|
98
|
+
? 'success'
|
|
99
|
+
: result.exitCode === 1
|
|
100
|
+
? 'partial'
|
|
101
|
+
: 'error',
|
|
102
|
+
exitCode: result.exitCode,
|
|
103
|
+
summary: {
|
|
104
|
+
totalPuts: result.totalPuts,
|
|
105
|
+
totalDeletes: result.totalDeletes,
|
|
106
|
+
totalErrors: result.totalErrors,
|
|
107
|
+
totalSkipped: result.totalSkipped,
|
|
108
|
+
},
|
|
109
|
+
actions: result.actions.map((action) => ({
|
|
110
|
+
action: action.action,
|
|
111
|
+
type: action.descriptor.type,
|
|
112
|
+
nameParts: action.descriptor.nameParts,
|
|
113
|
+
status: action.status,
|
|
114
|
+
error: action.error?.message,
|
|
115
|
+
})),
|
|
116
|
+
};
|
|
117
|
+
// Add dry-run report if present
|
|
118
|
+
if (result.dryRunReport) {
|
|
119
|
+
output.dryRun = {
|
|
120
|
+
actions: result.dryRunReport.actions.map((a) => ({
|
|
121
|
+
operation: a.operation,
|
|
122
|
+
type: a.type,
|
|
123
|
+
name: a.name,
|
|
124
|
+
})),
|
|
125
|
+
summary: result.dryRunReport.summary,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
// JSON output goes to stdout (not stderr)
|
|
129
|
+
process.stdout.write(JSON.stringify(output, null, 2) + '\n');
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Text output mode (default) — per-resource status lines and summary.
|
|
133
|
+
*/
|
|
134
|
+
function outputText(result, dryRun) {
|
|
135
|
+
// Per-resource status lines are already output by publish-service
|
|
136
|
+
// Just output the summary here
|
|
137
|
+
if (dryRun && result.dryRunReport) {
|
|
138
|
+
// Dry-run mode output
|
|
139
|
+
process.stdout.write('\n--- Dry-Run Report ---\n');
|
|
140
|
+
process.stdout.write(`${result.dryRunReport.summary.creates} creates/updates\n`);
|
|
141
|
+
process.stdout.write(`${result.dryRunReport.summary.deletes} deletes\n`);
|
|
142
|
+
process.stdout.write(`${result.dryRunReport.summary.skips} skipped\n`);
|
|
143
|
+
if (result.dryRunReport.actions.length > 0) {
|
|
144
|
+
process.stdout.write('\nPlanned actions:\n');
|
|
145
|
+
for (const action of result.dryRunReport.actions) {
|
|
146
|
+
process.stdout.write(` ${action.operation} ${action.type}/${action.name}\n`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Regular publish mode summary
|
|
152
|
+
process.stdout.write('\n--- Summary ---\n');
|
|
153
|
+
process.stdout.write(`${result.totalPuts} creates/updates, ${result.totalDeletes} deletes, ${result.totalSkipped} skipped\n`);
|
|
154
|
+
if (result.totalErrors > 0) {
|
|
155
|
+
process.stdout.write(`${result.totalErrors} errors\n`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=publish-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-command.js","sourceRoot":"","sources":["../../src/cli/publish-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T016: Azure REST HTTP client implementing IApimClient
|
|
3
|
+
* Uses @azure/identity DefaultAzureCredential for auth
|
|
4
|
+
* Handles pagination, retry, rate limiting, and long-running operations
|
|
5
|
+
*/
|
|
6
|
+
import { IApimClient } from './iapim-client.js';
|
|
7
|
+
import { ApimServiceContext, ResourceDescriptor } from '../models/types.js';
|
|
8
|
+
import { ResourceType } from '../models/resource-types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Structured HTTP error that carries the response status code.
|
|
11
|
+
* Allows callers to branch on status without parsing the message string.
|
|
12
|
+
*/
|
|
13
|
+
export declare class HttpError extends Error {
|
|
14
|
+
readonly status: number;
|
|
15
|
+
readonly code?: string | undefined;
|
|
16
|
+
constructor(status: number, message: string, code?: string | undefined);
|
|
17
|
+
}
|
|
18
|
+
export declare class ApimClient implements IApimClient {
|
|
19
|
+
private credential;
|
|
20
|
+
private readonly authScope;
|
|
21
|
+
private tokenCache;
|
|
22
|
+
private tokenPromise;
|
|
23
|
+
private static readonly TOKEN_CACHE_BUFFER_MS;
|
|
24
|
+
private static readonly MAX_RETRIES;
|
|
25
|
+
private static readonly BASE_DELAY_MS;
|
|
26
|
+
private static readonly MAX_DELAY_MS;
|
|
27
|
+
private static readonly MAX_POLLING_ATTEMPTS;
|
|
28
|
+
private static readonly POLL_INTERVAL_MS;
|
|
29
|
+
/** Stable ARM API version for Resource Group existence checks */
|
|
30
|
+
private static readonly RESOURCE_GROUP_API_VERSION;
|
|
31
|
+
/**
|
|
32
|
+
* @param authScope OAuth2 scope for ARM token requests.
|
|
33
|
+
* Defaults to the Azure public cloud scope.
|
|
34
|
+
*/
|
|
35
|
+
constructor(authScope?: string);
|
|
36
|
+
/**
|
|
37
|
+
* Get bearer token for Azure Management API.
|
|
38
|
+
* Uses a promise cache to prevent duplicate token requests under concurrency.
|
|
39
|
+
*/
|
|
40
|
+
private getToken;
|
|
41
|
+
private fetchToken;
|
|
42
|
+
/**
|
|
43
|
+
* Execute HTTP request with retry logic and rate limiting.
|
|
44
|
+
* @param noRetryOn5xx - When true, 5xx responses are returned immediately
|
|
45
|
+
* without retrying (e.g. wiki endpoints that return 500 for missing wikis).
|
|
46
|
+
* @param skipAuth - When true, skip adding Authorization/Content-Type headers
|
|
47
|
+
* (e.g. blob SAS URLs that are self-authenticating).
|
|
48
|
+
* @param allowedNonOkStatuses - Status codes the caller will handle itself
|
|
49
|
+
* (response returned instead of throwing). 404 is always allowed for GETs.
|
|
50
|
+
*/
|
|
51
|
+
private request;
|
|
52
|
+
private exponentialBackoffWithJitter;
|
|
53
|
+
private delay;
|
|
54
|
+
listResources(context: ApimServiceContext, type: ResourceType, parent?: ResourceDescriptor): AsyncIterable<Record<string, unknown>>;
|
|
55
|
+
getResource(context: ApimServiceContext, descriptor: ResourceDescriptor): Promise<Record<string, unknown> | undefined>;
|
|
56
|
+
putResource(context: ApimServiceContext, descriptor: ResourceDescriptor, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
57
|
+
deleteResource(context: ApimServiceContext, descriptor: ResourceDescriptor): Promise<boolean>;
|
|
58
|
+
listApiRevisions(context: ApimServiceContext, apiName: string): AsyncIterable<Record<string, unknown>>;
|
|
59
|
+
getApiSpecification(context: ApimServiceContext, apiName: string, apiType?: string): Promise<{
|
|
60
|
+
content: string;
|
|
61
|
+
format: 'yaml' | 'json' | 'graphql' | 'wsdl' | 'wadl';
|
|
62
|
+
} | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* Fall back to the non-link (inline) WSDL/WADL export when wsdl-link / wadl-link
|
|
65
|
+
* returns HTTP 500. APIM returns the XML in `properties.value` as a JSON-escaped
|
|
66
|
+
* string. The extracted content is suitable for re-import via PUT ?import=true
|
|
67
|
+
* with the matching non-link format (e.g. format=wsdl for SOAP APIs), so SOAP
|
|
68
|
+
* round-tripping is preserved.
|
|
69
|
+
*/
|
|
70
|
+
private getInlineXmlSpecification;
|
|
71
|
+
/**
|
|
72
|
+
* Map APIM API type to the appropriate export format query parameter.
|
|
73
|
+
* All APIM export formats return a SAS blob link (link-based, not inline content).
|
|
74
|
+
*
|
|
75
|
+
* APIM properties.type values and their export format mappings:
|
|
76
|
+
* graphql-link – GraphQL SDL blob (type=graphql)
|
|
77
|
+
* wsdl-link – WSDL blob (type=soap)
|
|
78
|
+
* openapi-link – OpenAPI 3.0 YAML (type=http, default)
|
|
79
|
+
* undefined – (type=websocket — no spec; callers should skip)
|
|
80
|
+
*
|
|
81
|
+
* SOAP APIs use wsdl-link so the exported specification can be re-imported
|
|
82
|
+
* faithfully on publish (matches the Azure/apiops reference tool). APIM's
|
|
83
|
+
* wsdl-link emitter occasionally returns HTTP 500 on real-world SOAP APIs;
|
|
84
|
+
* getApiSpecification handles that by falling back to the inline (non-link)
|
|
85
|
+
* `format=wsdl` export, which returns the raw WSDL in the response body.
|
|
86
|
+
* The inline WSDL is re-importable via PUT ?import=true&format=wsdl, so SOAP
|
|
87
|
+
* round-tripping is preserved even when the link variant is broken.
|
|
88
|
+
*
|
|
89
|
+
* Additional export formats supported by APIM for type=http REST APIs:
|
|
90
|
+
* swagger-link – Swagger 2.0 YAML
|
|
91
|
+
* openapi+json-link – OpenAPI 3.0 JSON
|
|
92
|
+
* wadl-link – WADL
|
|
93
|
+
* These cannot be auto-selected from properties.type alone because all REST APIs
|
|
94
|
+
* (whether originally imported as Swagger 2.0, OpenAPI 3.0, or WADL) share
|
|
95
|
+
* type=http in APIM. openapi-link is used as the preferred modern default.
|
|
96
|
+
*
|
|
97
|
+
* Returns undefined for WebSocket APIs — they have no traditional API specification.
|
|
98
|
+
* getApiSpecification will return undefined early when this method returns undefined.
|
|
99
|
+
*/
|
|
100
|
+
private getExportFormat;
|
|
101
|
+
validatePreFlight(context: ApimServiceContext): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Rethrows HttpError 401/403 responses from pre-flight checks as actionable errors.
|
|
104
|
+
* Non-HTTP errors and other status codes are re-thrown unchanged.
|
|
105
|
+
*/
|
|
106
|
+
private throwPreFlightHttpError;
|
|
107
|
+
private detectSpecificationFormat;
|
|
108
|
+
private pollProvisioningState;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=apim-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apim-client.d.ts","sourceRoot":"","sources":["../../src/clients/apim-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAA0B,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAMnF;;;GAGG;AACH,qBAAa,SAAU,SAAQ,KAAK;aAEhB,MAAM,EAAE,MAAM;aAEd,IAAI,CAAC,EAAE,MAAM;gBAFb,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAED,qBAAa,UAAW,YAAW,WAAW;IAC5C,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,UAAU,CAAqD;IACvE,OAAO,CAAC,YAAY,CAAgC;IAEpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAC9D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAS;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IAChD,iEAAiE;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAgB;IAElE;;;OAGG;gBACS,SAAS,SAA0C;IAK/D;;;OAGG;YACW,QAAQ;YAcR,UAAU;IASxB;;;;;;;;OAQG;YACW,OAAO;IA6GrB,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,KAAK;IAIN,aAAa,CAClB,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAuEnC,WAAW,CACf,OAAO,EAAE,kBAAkB,EAC3B,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAuCzC,WAAW,CACf,OAAO,EAAE,kBAAkB,EAC3B,UAAU,EAAE,kBAAkB,EAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA0C7B,cAAc,CAClB,OAAO,EAAE,kBAAkB,EAC3B,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,OAAO,CAAC;IAwBZ,gBAAgB,CACrB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAanC,mBAAmB,CACvB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAsFlG;;;;;;OAMG;YACW,yBAAyB;IA6DvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,OAAO,CAAC,eAAe;IASjB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCnE;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAkB/B,OAAO,CAAC,yBAAyB;YAwBnB,qBAAqB;CAsCpC"}
|