@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,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"}