openxiangda-devkit-core 2.0.0-alpha.12 → 2.0.0-alpha.121
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/README.md +3 -8
- package/dist/app-spec.d.ts +228 -0
- package/dist/app-spec.d.ts.map +1 -0
- package/dist/app-spec.js +1443 -0
- package/dist/app-spec.js.map +1 -0
- package/dist/application-services.d.ts +996 -49
- package/dist/application-services.d.ts.map +1 -1
- package/dist/application-services.js +1348 -197
- package/dist/application-services.js.map +1 -1
- package/dist/application-ui-contract.d.ts +5 -0
- package/dist/application-ui-contract.d.ts.map +1 -0
- package/dist/application-ui-contract.js +149 -0
- package/dist/application-ui-contract.js.map +1 -0
- package/dist/backend-image-build.d.ts +23 -0
- package/dist/backend-image-build.d.ts.map +1 -0
- package/dist/backend-image-build.js +204 -0
- package/dist/backend-image-build.js.map +1 -0
- package/dist/command-process.d.ts +14 -0
- package/dist/command-process.d.ts.map +1 -0
- package/dist/command-process.js +51 -0
- package/dist/command-process.js.map +1 -0
- package/dist/command-registry.d.ts +123 -366
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +26 -266
- package/dist/command-registry.js.map +1 -1
- package/dist/compiler/ai-catalog.d.ts +4 -0
- package/dist/compiler/ai-catalog.d.ts.map +1 -0
- package/dist/compiler/ai-catalog.js +354 -0
- package/dist/compiler/ai-catalog.js.map +1 -0
- package/dist/compiler/application-model.d.ts +60 -0
- package/dist/compiler/application-model.d.ts.map +1 -0
- package/dist/compiler/application-model.js +141 -0
- package/dist/compiler/application-model.js.map +1 -0
- package/dist/compiler/authorization-transition.d.ts +7 -0
- package/dist/compiler/authorization-transition.d.ts.map +1 -0
- package/dist/compiler/authorization-transition.js +27 -0
- package/dist/compiler/authorization-transition.js.map +1 -0
- package/dist/compiler/bundle.d.ts +34 -0
- package/dist/compiler/bundle.d.ts.map +1 -0
- package/dist/compiler/bundle.js +1910 -0
- package/dist/compiler/bundle.js.map +1 -0
- package/dist/compiler/config.d.ts +882 -0
- package/dist/compiler/config.d.ts.map +1 -0
- package/dist/compiler/config.js +4118 -0
- package/dist/compiler/config.js.map +1 -0
- package/dist/compiler/data-policy-expression.d.ts +12 -0
- package/dist/compiler/data-policy-expression.d.ts.map +1 -0
- package/dist/compiler/data-policy-expression.js +43 -0
- package/dist/compiler/data-policy-expression.js.map +1 -0
- package/dist/compiler/field-codec.d.ts +14 -0
- package/dist/compiler/field-codec.d.ts.map +1 -0
- package/dist/compiler/field-codec.js +131 -0
- package/dist/compiler/field-codec.js.map +1 -0
- package/dist/compiler/field-physical-plan.d.ts +10 -0
- package/dist/compiler/field-physical-plan.d.ts.map +1 -0
- package/dist/compiler/field-physical-plan.js +66 -0
- package/dist/compiler/field-physical-plan.js.map +1 -0
- package/dist/compiler/field-policy-path.d.ts +10 -0
- package/dist/compiler/field-policy-path.d.ts.map +1 -0
- package/dist/compiler/field-policy-path.js +283 -0
- package/dist/compiler/field-policy-path.js.map +1 -0
- package/dist/compiler/field-query-plan.d.ts +13 -0
- package/dist/compiler/field-query-plan.d.ts.map +1 -0
- package/dist/compiler/field-query-plan.js +122 -0
- package/dist/compiler/field-query-plan.js.map +1 -0
- package/dist/compiler/field-surface.d.ts +15 -0
- package/dist/compiler/field-surface.d.ts.map +1 -0
- package/dist/compiler/field-surface.js +51 -0
- package/dist/compiler/field-surface.js.map +1 -0
- package/dist/compiler/index.d.ts +6 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +6 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/package-compiler.d.ts +22 -0
- package/dist/compiler/package-compiler.d.ts.map +1 -0
- package/dist/compiler/package-compiler.js +257 -0
- package/dist/compiler/package-compiler.js.map +1 -0
- package/dist/compiler/permission-review.d.ts +139 -0
- package/dist/compiler/permission-review.d.ts.map +1 -0
- package/dist/compiler/permission-review.js +131 -0
- package/dist/compiler/permission-review.js.map +1 -0
- package/dist/compiler/schema-composition.d.ts +21 -0
- package/dist/compiler/schema-composition.d.ts.map +1 -0
- package/dist/compiler/schema-composition.js +193 -0
- package/dist/compiler/schema-composition.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/configuration-preflight.d.ts +7 -0
- package/dist/configuration-preflight.d.ts.map +1 -0
- package/dist/configuration-preflight.js +13 -0
- package/dist/configuration-preflight.js.map +1 -0
- package/dist/connected-development.d.ts +62 -0
- package/dist/connected-development.d.ts.map +1 -0
- package/dist/connected-development.js +393 -0
- package/dist/connected-development.js.map +1 -0
- package/dist/control-plane-client.d.ts +353 -123
- package/dist/control-plane-client.d.ts.map +1 -1
- package/dist/control-plane-client.js +420 -141
- package/dist/control-plane-client.js.map +1 -1
- package/dist/delivery-cache.d.ts +34 -0
- package/dist/delivery-cache.d.ts.map +1 -0
- package/dist/delivery-cache.js +186 -0
- package/dist/delivery-cache.js.map +1 -0
- package/dist/delivery-source.d.ts +17 -0
- package/dist/delivery-source.d.ts.map +1 -0
- package/dist/delivery-source.js +85 -0
- package/dist/delivery-source.js.map +1 -0
- package/dist/deployment-observer.d.ts +14 -0
- package/dist/deployment-observer.d.ts.map +1 -0
- package/dist/deployment-observer.js +68 -0
- package/dist/deployment-observer.js.map +1 -0
- package/dist/deployment.d.ts +55 -3
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +182 -21
- package/dist/deployment.js.map +1 -1
- package/dist/design-readiness.d.ts +24 -0
- package/dist/design-readiness.d.ts.map +1 -0
- package/dist/design-readiness.js +102 -0
- package/dist/design-readiness.js.map +1 -0
- package/dist/developer-errors.d.ts +11 -0
- package/dist/developer-errors.d.ts.map +1 -0
- package/dist/developer-errors.js +16 -0
- package/dist/developer-errors.js.map +1 -0
- package/dist/developer-operations.d.ts +188 -0
- package/dist/developer-operations.d.ts.map +1 -0
- package/dist/developer-operations.js +58 -0
- package/dist/developer-operations.js.map +1 -0
- package/dist/development-lifecycle.d.ts +75 -0
- package/dist/development-lifecycle.d.ts.map +1 -0
- package/dist/development-lifecycle.js +189 -0
- package/dist/development-lifecycle.js.map +1 -0
- package/dist/documentation.d.ts +111 -0
- package/dist/documentation.d.ts.map +1 -0
- package/dist/documentation.js +112 -0
- package/dist/documentation.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/workflow.d.ts +83 -0
- package/dist/internal/workflow.d.ts.map +1 -0
- package/dist/internal/workflow.js +419 -0
- package/dist/internal/workflow.js.map +1 -0
- package/dist/nest-injection-contract.d.ts +4 -0
- package/dist/nest-injection-contract.d.ts.map +1 -0
- package/dist/nest-injection-contract.js +116 -0
- package/dist/nest-injection-contract.js.map +1 -0
- package/dist/operation-progress.d.ts +26 -0
- package/dist/operation-progress.d.ts.map +1 -0
- package/dist/operation-progress.js +92 -0
- package/dist/operation-progress.js.map +1 -0
- package/dist/optional-backend.d.ts +14 -0
- package/dist/optional-backend.d.ts.map +1 -0
- package/dist/optional-backend.js +145 -0
- package/dist/optional-backend.js.map +1 -0
- package/dist/package-compiler.d.ts +1 -1
- package/dist/package-compiler.d.ts.map +1 -1
- package/dist/package-compiler.js +1 -1
- package/dist/package-compiler.js.map +1 -1
- package/dist/session.d.ts +149 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +362 -23
- package/dist/session.js.map +1 -1
- package/dist/testing.d.ts +77 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +213 -0
- package/dist/testing.js.map +1 -0
- package/dist/toolchain-capsule.d.ts +45 -0
- package/dist/toolchain-capsule.d.ts.map +1 -0
- package/dist/toolchain-capsule.js +165 -0
- package/dist/toolchain-capsule.js.map +1 -0
- package/dist/workspace-loader.d.ts +1 -1
- package/dist/workspace-loader.d.ts.map +1 -1
- package/dist/workspace-loader.js +35 -3
- package/dist/workspace-loader.js.map +1 -1
- package/dist/workspace-operation.d.ts +3 -0
- package/dist/workspace-operation.d.ts.map +1 -0
- package/dist/workspace-operation.js +45 -0
- package/dist/workspace-operation.js.map +1 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +37 -1
- package/dist/workspace.js.map +1 -1
- package/package.json +16 -4
- package/templates/backend/Dockerfile +20 -0
- package/templates/backend/package.json +27 -0
- package/templates/backend/src/app.module.ts +23 -0
- package/templates/backend/src/main.ts +5 -0
- package/templates/backend/tsconfig.json +9 -0
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CONFIGURATION_COMPATIBILITY_CAPABILITY, CURRENT_APPLICATION_CONTRACT, OPENXIANGDA_CONTRACT_VERSION, } from "openxiangda-contracts/browser";
|
|
2
|
+
import { Agent, fetch as undiciFetch } from "undici";
|
|
3
|
+
const ARTIFACT_UPLOAD_HEADERS_TIMEOUT_MS = 30 * 60 * 1000;
|
|
4
|
+
const ARTIFACT_UPLOAD_BODY_TIMEOUT_MS = 5 * 60 * 1000;
|
|
5
|
+
function createArtifactUploadFetch() {
|
|
6
|
+
const dispatcher = new Agent({
|
|
7
|
+
headersTimeout: ARTIFACT_UPLOAD_HEADERS_TIMEOUT_MS,
|
|
8
|
+
bodyTimeout: ARTIFACT_UPLOAD_BODY_TIMEOUT_MS,
|
|
9
|
+
});
|
|
10
|
+
return async (input, init) => (await undiciFetch(input, {
|
|
11
|
+
...(init || {}),
|
|
12
|
+
dispatcher,
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
2
15
|
export class ControlPlaneError extends Error {
|
|
3
16
|
status;
|
|
4
17
|
code;
|
|
5
18
|
data;
|
|
6
|
-
|
|
19
|
+
remote;
|
|
20
|
+
constructor(status, code, message, data, remote) {
|
|
7
21
|
super(message);
|
|
8
22
|
this.status = status;
|
|
9
23
|
this.code = code;
|
|
10
24
|
this.data = data;
|
|
25
|
+
this.remote = remote;
|
|
11
26
|
this.name = "ControlPlaneError";
|
|
12
27
|
}
|
|
13
28
|
}
|
|
@@ -15,18 +30,83 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
15
30
|
options;
|
|
16
31
|
baseUrl;
|
|
17
32
|
fetch;
|
|
33
|
+
artifactUploadFetch;
|
|
18
34
|
constructor(options) {
|
|
19
35
|
this.options = options;
|
|
20
36
|
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
21
37
|
this.fetch = options.fetch || globalThis.fetch.bind(globalThis);
|
|
38
|
+
this.artifactUploadFetch = options.fetch || createArtifactUploadFetch();
|
|
22
39
|
}
|
|
23
40
|
async capabilities() {
|
|
24
41
|
const capabilities = await this.json("/openxiangda-api/v2/capabilities");
|
|
25
42
|
if (capabilities.contractVersion !== OPENXIANGDA_CONTRACT_VERSION) {
|
|
26
|
-
|
|
43
|
+
const compatibility = capabilities.configurationCompatibility;
|
|
44
|
+
throw new ControlPlaneError(409, "OPENXIANGDA_CONTRACT_VERSION_MISMATCH", `平台 contract ${capabilities.contractVersion} 与工具 ${OPENXIANGDA_CONTRACT_VERSION} 不兼容`, {
|
|
45
|
+
pointer: "/contractVersion",
|
|
46
|
+
clientContractVersion: OPENXIANGDA_CONTRACT_VERSION,
|
|
47
|
+
clientSchemaVersions: {
|
|
48
|
+
appPackage: CURRENT_APPLICATION_CONTRACT.appPackageSchemaVersion,
|
|
49
|
+
configuration: CURRENT_APPLICATION_CONTRACT.configurationBundleSchemaVersion,
|
|
50
|
+
contract: CURRENT_APPLICATION_CONTRACT.contractBundleSchemaVersion,
|
|
51
|
+
compiler: CURRENT_APPLICATION_CONTRACT.compilerContractVersion,
|
|
52
|
+
},
|
|
53
|
+
platformVersion: String(capabilities.platformVersion || "unknown"),
|
|
54
|
+
platformCapability: compatibility?.capability || {
|
|
55
|
+
code: CONFIGURATION_COMPATIBILITY_CAPABILITY,
|
|
56
|
+
version: "unknown",
|
|
57
|
+
status: "unavailable",
|
|
58
|
+
},
|
|
59
|
+
required: { ...CURRENT_APPLICATION_CONTRACT },
|
|
60
|
+
supported: (compatibility?.supportedApplicationContracts || []).slice(0, 8),
|
|
61
|
+
requiredContractVersion: OPENXIANGDA_CONTRACT_VERSION,
|
|
62
|
+
supportedContractVersion: capabilities.contractVersion,
|
|
63
|
+
});
|
|
27
64
|
}
|
|
28
65
|
return capabilities;
|
|
29
66
|
}
|
|
67
|
+
async validateConfigurationCompatibility(appCode, capabilities, input) {
|
|
68
|
+
const compatibility = capabilities.configurationCompatibility;
|
|
69
|
+
const expectedTemplate = "/openxiangda-api/v2/applications/{appCode}/configuration-compatibility";
|
|
70
|
+
if (compatibility.endpointTemplate !== expectedTemplate) {
|
|
71
|
+
throw new ControlPlaneError(409, "OPENXIANGDA_CONFIGURATION_COMPATIBILITY_ENDPOINT_INVALID", "平台配置兼容性端点不符合当前公开契约", {
|
|
72
|
+
pointer: "/configurationCompatibility/endpointTemplate",
|
|
73
|
+
clientContractVersion: OPENXIANGDA_CONTRACT_VERSION,
|
|
74
|
+
clientSchemaVersions: {
|
|
75
|
+
appPackage: input.required.appPackageSchemaVersion,
|
|
76
|
+
configuration: input.required.configurationBundleSchemaVersion,
|
|
77
|
+
contract: input.required.contractBundleSchemaVersion,
|
|
78
|
+
compiler: input.required.compilerContractVersion,
|
|
79
|
+
},
|
|
80
|
+
platformVersion: capabilities.platformVersion,
|
|
81
|
+
platformCapability: compatibility.capability,
|
|
82
|
+
required: { ...input.required },
|
|
83
|
+
supported: compatibility.supportedApplicationContracts.slice(0, 8),
|
|
84
|
+
requiredEndpointTemplate: expectedTemplate,
|
|
85
|
+
supportedEndpointTemplate: compatibility.endpointTemplate,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const body = JSON.stringify(input);
|
|
89
|
+
const requestBytes = new TextEncoder().encode(body).byteLength;
|
|
90
|
+
if (requestBytes > compatibility.limits.requestBytes) {
|
|
91
|
+
throw new ControlPlaneError(409, "OPENXIANGDA_CONFIGURATION_VALIDATION_REQUEST_TOO_LARGE", "配置兼容性请求超过目标平台公开上限", {
|
|
92
|
+
pointer: "/",
|
|
93
|
+
clientContractVersion: OPENXIANGDA_CONTRACT_VERSION,
|
|
94
|
+
clientSchemaVersions: {
|
|
95
|
+
appPackage: input.required.appPackageSchemaVersion,
|
|
96
|
+
configuration: input.required.configurationBundleSchemaVersion,
|
|
97
|
+
contract: input.required.contractBundleSchemaVersion,
|
|
98
|
+
compiler: input.required.compilerContractVersion,
|
|
99
|
+
},
|
|
100
|
+
platformVersion: capabilities.platformVersion,
|
|
101
|
+
platformCapability: compatibility.capability,
|
|
102
|
+
required: { ...input.required },
|
|
103
|
+
supported: compatibility.supportedApplicationContracts.slice(0, 8),
|
|
104
|
+
requiredRequestBytes: requestBytes,
|
|
105
|
+
supportedRequestBytes: compatibility.limits.requestBytes,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return await this.json(compatibility.endpointTemplate.replace("{appCode}", encodeURIComponent(appCode)), { method: "POST", body });
|
|
109
|
+
}
|
|
30
110
|
async provisionApplication(input) {
|
|
31
111
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(input.appCode)}/provision`, {
|
|
32
112
|
method: "POST",
|
|
@@ -36,6 +116,29 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
36
116
|
}),
|
|
37
117
|
});
|
|
38
118
|
}
|
|
119
|
+
async createConnectedDevelopmentSession(appCode, input) {
|
|
120
|
+
return await this.json(this.connectedDevelopmentSessionsPath(appCode), { method: "POST", body: JSON.stringify(input) });
|
|
121
|
+
}
|
|
122
|
+
async preparePreproductionAcceptanceIdentities(appCode, input) {
|
|
123
|
+
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/acceptance/identities/prepare`, { method: "POST", body: JSON.stringify(input) });
|
|
124
|
+
}
|
|
125
|
+
async connectedDevelopmentSession(appCode, sessionToken) {
|
|
126
|
+
return await this.json(`${this.connectedDevelopmentSessionsPath(appCode)}/current`, { headers: this.connectedDevelopmentSessionHeaders(sessionToken) });
|
|
127
|
+
}
|
|
128
|
+
async refreshConnectedDevelopmentSession(appCode, sessionToken) {
|
|
129
|
+
return await this.json(`${this.connectedDevelopmentSessionsPath(appCode)}/current/refresh`, {
|
|
130
|
+
method: "POST",
|
|
131
|
+
body: "{}",
|
|
132
|
+
headers: this.connectedDevelopmentSessionHeaders(sessionToken),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async revokeConnectedDevelopmentSession(appCode, sessionToken) {
|
|
136
|
+
await this.json(`${this.connectedDevelopmentSessionsPath(appCode)}/current/revoke`, {
|
|
137
|
+
method: "POST",
|
|
138
|
+
body: "{}",
|
|
139
|
+
headers: this.connectedDevelopmentSessionHeaders(sessionToken),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
39
142
|
async oauthClients(appCode) {
|
|
40
143
|
return await this.json(`${this.oauthPath(appCode)}/clients`);
|
|
41
144
|
}
|
|
@@ -104,16 +207,15 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
104
207
|
}
|
|
105
208
|
async applicationApiResponse(appCode, environmentKey, runtimePath, input) {
|
|
106
209
|
const path = this.applicationApiPath(appCode, environmentKey, runtimePath, input.query);
|
|
107
|
-
const { query: _query,
|
|
210
|
+
const { query: _query, perspectiveCode: _perspectiveCode, ...init } = input;
|
|
211
|
+
const token = await this.accessToken(false);
|
|
108
212
|
return await this.fetch(`${this.baseUrl}${path}`, {
|
|
109
213
|
...init,
|
|
110
214
|
credentials: init.credentials || this.options.credentials || "include",
|
|
111
215
|
headers: {
|
|
112
216
|
Accept: "application/json",
|
|
113
|
-
...(
|
|
114
|
-
|
|
115
|
-
: {}),
|
|
116
|
-
...this.optionalRoleSessionHeaders(input),
|
|
217
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
218
|
+
...this.perspectiveHeaders(input),
|
|
117
219
|
...(init.headers || {}),
|
|
118
220
|
},
|
|
119
221
|
});
|
|
@@ -143,6 +245,16 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
143
245
|
}
|
|
144
246
|
return data;
|
|
145
247
|
}
|
|
248
|
+
async artifactStatus(appCode, digest) {
|
|
249
|
+
try {
|
|
250
|
+
return await this.request(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/artifacts/${digest}`, { method: 'GET' });
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
if (error instanceof ControlPlaneError && error.status === 404 && error.code === 'DELIVERY_ARTIFACT_NOT_FOUND')
|
|
254
|
+
return null;
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
146
258
|
async uploadArtifact(input) {
|
|
147
259
|
const params = new URLSearchParams({
|
|
148
260
|
kind: input.kind,
|
|
@@ -151,7 +263,22 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
151
263
|
});
|
|
152
264
|
const form = new FormData();
|
|
153
265
|
form.append("file", new Blob([input.content], { type: input.contentType }), input.digest);
|
|
154
|
-
|
|
266
|
+
try {
|
|
267
|
+
return await this.request(`/openxiangda-api/v2/applications/${encodeURIComponent(input.appCode)}/artifacts/${input.digest}?${params}`, { method: "POST", body: form }, this.artifactUploadFetch);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
if (error instanceof ControlPlaneError)
|
|
271
|
+
throw error;
|
|
272
|
+
const causeCode = String(error?.cause?.code || error?.code || "").trim();
|
|
273
|
+
throw new ControlPlaneError(503, "OPENXIANGDA_ARTIFACT_UPLOAD_FAILED", "Application v2 制品上传连接中断", {
|
|
274
|
+
digest: input.digest,
|
|
275
|
+
kind: input.kind,
|
|
276
|
+
...(causeCode ? { causeCode } : {}),
|
|
277
|
+
}, {
|
|
278
|
+
retryable: true,
|
|
279
|
+
remediation: "重新运行 openxiangda deploy;已完成的内容寻址制品会自动去重",
|
|
280
|
+
});
|
|
281
|
+
}
|
|
155
282
|
}
|
|
156
283
|
async createDeployment(input) {
|
|
157
284
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(input.appCode)}/deployments`, {
|
|
@@ -173,6 +300,15 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
173
300
|
async deployments(appCode, limit = 20) {
|
|
174
301
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/deployments?limit=${Math.min(Math.max(Number(limit) || 20, 1), 100)}`);
|
|
175
302
|
}
|
|
303
|
+
async applicationEnvironments(appCode) {
|
|
304
|
+
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/environments`);
|
|
305
|
+
}
|
|
306
|
+
async startEnvironment(appCode, environmentKey, input) {
|
|
307
|
+
return await this.changeEnvironmentRuntimeState(appCode, environmentKey, "start", input);
|
|
308
|
+
}
|
|
309
|
+
async stopEnvironment(appCode, environmentKey, input) {
|
|
310
|
+
return await this.changeEnvironmentRuntimeState(appCode, environmentKey, "stop", input);
|
|
311
|
+
}
|
|
176
312
|
async retryDeployment(appCode, deploymentId) {
|
|
177
313
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/deployments/${encodeURIComponent(deploymentId)}/retry`, { method: "POST", body: "{}" });
|
|
178
314
|
}
|
|
@@ -182,15 +318,27 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
182
318
|
async promote(input) {
|
|
183
319
|
return await this.deployExistingVersion(input, "promotions");
|
|
184
320
|
}
|
|
321
|
+
async redeploy(input) {
|
|
322
|
+
return await this.deployExistingVersion(input, "redeployments");
|
|
323
|
+
}
|
|
185
324
|
async rollback(input) {
|
|
186
325
|
return await this.deployExistingVersion(input, "rollbacks");
|
|
187
326
|
}
|
|
188
327
|
async appVersions(appCode, limit = 30) {
|
|
189
328
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/versions?limit=${Math.min(Math.max(Number(limit) || 30, 1), 100)}`);
|
|
190
329
|
}
|
|
330
|
+
async productionPromotionPreflight(appCode, sourceDeploymentId) {
|
|
331
|
+
return this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/deployments/${encodeURIComponent(sourceDeploymentId)}/promotion-preflight`, { method: 'POST', body: '{}' });
|
|
332
|
+
}
|
|
191
333
|
async environmentHead(appCode, environmentKey) {
|
|
192
334
|
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/environment-heads/${encodeURIComponent(environmentKey)}`);
|
|
193
335
|
}
|
|
336
|
+
async changeEnvironmentRuntimeState(appCode, environmentKey, action, input) {
|
|
337
|
+
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/environments/${encodeURIComponent(environmentKey)}/${action}`, {
|
|
338
|
+
method: "POST",
|
|
339
|
+
body: JSON.stringify(input),
|
|
340
|
+
});
|
|
341
|
+
}
|
|
194
342
|
async applicationSecrets(appCode, environmentKey) {
|
|
195
343
|
return await this.json(this.applicationSecretsPath(appCode, environmentKey));
|
|
196
344
|
}
|
|
@@ -212,19 +360,12 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
212
360
|
async applicationSecretAuditEvents(appCode, environmentKey, name, limit = 100) {
|
|
213
361
|
return await this.json(`${this.applicationSecretsPath(appCode, environmentKey)}/${encodeURIComponent(name)}/audit?limit=${Math.min(Math.max(Number(limit) || 100, 1), 500)}`);
|
|
214
362
|
}
|
|
215
|
-
async createEventSubscription(input) {
|
|
216
|
-
const { appCode, ...body } = input;
|
|
217
|
-
return await this.json(`${this.eventsPath(appCode)}/subscriptions`, { method: "POST", body: JSON.stringify(body) });
|
|
218
|
-
}
|
|
219
363
|
async eventSubscriptions(appCode) {
|
|
220
364
|
return await this.json(`${this.eventsPath(appCode)}/subscriptions`);
|
|
221
365
|
}
|
|
222
366
|
async setEventSubscriptionStatus(appCode, subscriptionId, input) {
|
|
223
367
|
return await this.json(`${this.eventsPath(appCode)}/subscriptions/${encodeURIComponent(subscriptionId)}/status`, { method: "POST", body: JSON.stringify(input) });
|
|
224
368
|
}
|
|
225
|
-
async rotateEventSubscriptionSecret(appCode, subscriptionId, input) {
|
|
226
|
-
return await this.json(`${this.eventsPath(appCode)}/subscriptions/${encodeURIComponent(subscriptionId)}/rotate-secret`, { method: "POST", body: JSON.stringify(input) });
|
|
227
|
-
}
|
|
228
369
|
async eventDeliveries(appCode, limit = 100) {
|
|
229
370
|
return await this.json(`${this.eventsPath(appCode)}/deliveries?limit=${Math.min(Math.max(Number(limit) || 100, 1), 500)}`);
|
|
230
371
|
}
|
|
@@ -234,16 +375,18 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
234
375
|
body: JSON.stringify(idempotencyKey ? { idempotencyKey } : {}),
|
|
235
376
|
});
|
|
236
377
|
}
|
|
237
|
-
async createTimerSubscription(input) {
|
|
238
|
-
const { appCode, ...body } = input;
|
|
239
|
-
return await this.json(`${this.eventsPath(appCode)}/timers`, { method: "POST", body: JSON.stringify(body) });
|
|
240
|
-
}
|
|
241
378
|
async timerSubscriptions(appCode) {
|
|
242
379
|
return await this.json(`${this.eventsPath(appCode)}/timers`);
|
|
243
380
|
}
|
|
244
381
|
async setTimerSubscriptionStatus(appCode, timerId, input) {
|
|
245
382
|
return await this.json(`${this.eventsPath(appCode)}/timers/${encodeURIComponent(timerId)}/status`, { method: "POST", body: JSON.stringify(input) });
|
|
246
383
|
}
|
|
384
|
+
async dateTriggers(appCode) {
|
|
385
|
+
return await this.json(`${this.eventsPath(appCode)}/date-triggers`);
|
|
386
|
+
}
|
|
387
|
+
async setDateTriggerStatus(appCode, triggerId, input) {
|
|
388
|
+
return await this.json(`${this.eventsPath(appCode)}/date-triggers/${encodeURIComponent(triggerId)}/status`, { method: "POST", body: JSON.stringify(input) });
|
|
389
|
+
}
|
|
247
390
|
async registerWorkflowDefinition(appCode, version, definition) {
|
|
248
391
|
return await this.json(`${this.workflowPath(appCode)}/definitions`, {
|
|
249
392
|
method: "POST",
|
|
@@ -268,98 +411,173 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
268
411
|
async activateWorkflow(appCode, workflowCode, input) {
|
|
269
412
|
return await this.json(`${this.workflowPath(appCode)}/definitions/${encodeURIComponent(workflowCode)}/activate`, { method: "POST", body: JSON.stringify(input) });
|
|
270
413
|
}
|
|
271
|
-
async
|
|
272
|
-
const { appCode, workflowCode, roleSessionId, ...body } = input;
|
|
273
|
-
return await this.json(`${this.workflowPath(appCode)}/definitions/${encodeURIComponent(workflowCode)}/prepare-start`, {
|
|
274
|
-
method: "POST",
|
|
275
|
-
body: JSON.stringify(body),
|
|
276
|
-
headers: this.roleSessionHeaders({ roleSessionId }),
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
async startWorkflow(appCode, input) {
|
|
280
|
-
const { roleSessionId, ...body } = input;
|
|
281
|
-
return await this.json(`${this.workflowPath(appCode)}/instances`, {
|
|
282
|
-
method: "POST",
|
|
283
|
-
body: JSON.stringify(body),
|
|
284
|
-
headers: this.roleSessionHeaders({ roleSessionId }),
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
async createWorkflowDelegation(appCode, input, request) {
|
|
414
|
+
async createWorkflowDelegation(appCode, input) {
|
|
288
415
|
return await this.json(`${this.workflowPath(appCode)}/delegations`, {
|
|
289
416
|
method: "POST",
|
|
290
417
|
body: JSON.stringify(input),
|
|
291
|
-
headers: this.roleSessionHeaders(request),
|
|
292
418
|
});
|
|
293
419
|
}
|
|
294
|
-
async workflowDelegationTargets(appCode, userId,
|
|
295
|
-
return await this.json(`${this.workflowPath(appCode)}/delegations/targets?userId=${encodeURIComponent(userId)}
|
|
420
|
+
async workflowDelegationTargets(appCode, userId, environmentKey) {
|
|
421
|
+
return await this.json(`${this.workflowPath(appCode)}/delegations/targets?userId=${encodeURIComponent(userId)}${environmentKey ? `&environmentKey=${encodeURIComponent(environmentKey)}` : ""}`);
|
|
296
422
|
}
|
|
297
|
-
async workflowDelegations(appCode,
|
|
298
|
-
return await this.json(`${this.workflowPath(appCode)}/delegations?all=${input.all === true}
|
|
423
|
+
async workflowDelegations(appCode, input = {}) {
|
|
424
|
+
return await this.json(`${this.workflowPath(appCode)}/delegations?all=${input.all === true}${input.environmentKey
|
|
425
|
+
? `&environmentKey=${encodeURIComponent(input.environmentKey)}`
|
|
426
|
+
: ""}`);
|
|
299
427
|
}
|
|
300
|
-
async revokeWorkflowDelegation(appCode, delegationId,
|
|
301
|
-
return await this.json(`${this.workflowPath(appCode)}/delegations/${encodeURIComponent(delegationId)}/revoke
|
|
428
|
+
async revokeWorkflowDelegation(appCode, delegationId, environmentKey) {
|
|
429
|
+
return await this.json(`${this.workflowPath(appCode)}/delegations/${encodeURIComponent(delegationId)}/revoke${environmentKey
|
|
430
|
+
? `?environmentKey=${encodeURIComponent(environmentKey)}`
|
|
431
|
+
: ""}`, {
|
|
302
432
|
method: "POST",
|
|
303
|
-
headers: this.roleSessionHeaders(request),
|
|
304
433
|
});
|
|
305
434
|
}
|
|
306
|
-
async workflowTaskSurface(appCode, taskId,
|
|
307
|
-
return await this.json(`${this.workflowPath(appCode)}/tasks/${encodeURIComponent(taskId)}/surface`, { headers:
|
|
435
|
+
async workflowTaskSurface(appCode, taskId, csrfToken) {
|
|
436
|
+
return await this.json(`${this.workflowPath(appCode)}/tasks/${encodeURIComponent(taskId)}/surface`, { headers: { "X-OpenXiangda-CSRF-Token": csrfToken } });
|
|
308
437
|
}
|
|
309
|
-
async workflowInstanceSurface(appCode, instanceId,
|
|
310
|
-
return await this.json(`${this.workflowPath(appCode)}/instances/${encodeURIComponent(instanceId)}/surface`, { headers:
|
|
438
|
+
async workflowInstanceSurface(appCode, instanceId, csrfToken) {
|
|
439
|
+
return await this.json(`${this.workflowPath(appCode)}/instances/${encodeURIComponent(instanceId)}/surface`, { headers: { "X-OpenXiangda-CSRF-Token": csrfToken } });
|
|
311
440
|
}
|
|
312
|
-
async executeWorkflowTaskCommand(appCode, taskId, command, input
|
|
441
|
+
async executeWorkflowTaskCommand(appCode, taskId, command, input) {
|
|
442
|
+
const { csrfToken, ...request } = input;
|
|
313
443
|
return await this.json(`${this.workflowPath(appCode)}/tasks/${encodeURIComponent(taskId)}/commands/${encodeURIComponent(command)}`, {
|
|
314
444
|
method: "POST",
|
|
315
|
-
|
|
316
|
-
|
|
445
|
+
headers: { "X-OpenXiangda-CSRF-Token": csrfToken },
|
|
446
|
+
body: JSON.stringify(request),
|
|
317
447
|
});
|
|
318
448
|
}
|
|
319
|
-
async executeWorkflowInstanceCommand(appCode, instanceId, command, input
|
|
449
|
+
async executeWorkflowInstanceCommand(appCode, instanceId, command, input) {
|
|
450
|
+
const { csrfToken, ...request } = input;
|
|
320
451
|
return await this.json(`${this.workflowPath(appCode)}/instances/${encodeURIComponent(instanceId)}/commands/${command}`, {
|
|
321
452
|
method: "POST",
|
|
322
|
-
|
|
323
|
-
|
|
453
|
+
headers: { "X-OpenXiangda-CSRF-Token": csrfToken },
|
|
454
|
+
body: JSON.stringify(request),
|
|
324
455
|
});
|
|
325
456
|
}
|
|
326
|
-
async workflowAssignmentExplain(appCode, taskId
|
|
327
|
-
return await this.json(`${this.workflowPath(appCode)}/tasks/${encodeURIComponent(taskId)}/assignment-explain
|
|
457
|
+
async workflowAssignmentExplain(appCode, taskId) {
|
|
458
|
+
return await this.json(`${this.workflowPath(appCode)}/tasks/${encodeURIComponent(taskId)}/assignment-explain`);
|
|
328
459
|
}
|
|
329
|
-
async workflowTimeline(appCode, instanceId
|
|
330
|
-
return await this.json(`${this.workflowPath(appCode)}/instances/${encodeURIComponent(instanceId)}/timeline
|
|
460
|
+
async workflowTimeline(appCode, instanceId) {
|
|
461
|
+
return await this.json(`${this.workflowPath(appCode)}/instances/${encodeURIComponent(instanceId)}/timeline`);
|
|
331
462
|
}
|
|
332
|
-
async workflowWorkCenter(appCode,
|
|
463
|
+
async workflowWorkCenter(appCode, input = {}) {
|
|
333
464
|
const query = new URLSearchParams({
|
|
334
465
|
status: input.status || "pending",
|
|
335
466
|
limit: String(Math.min(Math.max(Number(input.limit) || 50, 1), 200)),
|
|
467
|
+
...(input.environmentKey ? { environmentKey: input.environmentKey } : {}),
|
|
336
468
|
});
|
|
337
|
-
return await this.json(`${this.workflowPath(appCode)}/work-center/items?${query}
|
|
469
|
+
return await this.json(`${this.workflowPath(appCode)}/work-center/items?${query}`);
|
|
470
|
+
}
|
|
471
|
+
async workflowDiagnostics(appCode, limit = 100) {
|
|
472
|
+
return await this.json(`${this.workflowPath(appCode)}/diagnostics?limit=${Math.min(Math.max(Number(limit) || 100, 1), 500)}`);
|
|
338
473
|
}
|
|
339
|
-
async
|
|
340
|
-
return await this.json(`${this.
|
|
474
|
+
async applicationAdministrationContext(appCode, environmentKey) {
|
|
475
|
+
return await this.json(`${this.administrationPath(appCode)}/context?${this.query({ environmentKey })}`);
|
|
341
476
|
}
|
|
342
|
-
async
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
477
|
+
async workflowNodeConfigurations(appCode, workflowCode, environmentKey) {
|
|
478
|
+
return await this.json(`${this.administrationPath(appCode)}/workflows/${encodeURIComponent(workflowCode)}/node-configurations?${this.query({ environmentKey })}`);
|
|
479
|
+
}
|
|
480
|
+
async nativeAuthorizationCatalog(appCode, input = {}) {
|
|
481
|
+
const query = this.query({
|
|
482
|
+
environmentKey: input.environmentKey || "preproduction",
|
|
346
483
|
});
|
|
347
|
-
return await this.json(`${this.
|
|
484
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/catalog?${query}`);
|
|
348
485
|
}
|
|
349
|
-
async
|
|
350
|
-
return await this.json(`${this.
|
|
486
|
+
async nativeScopeValues(appCode, input) {
|
|
487
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/scope-values?${this.query({
|
|
488
|
+
...input,
|
|
489
|
+
environmentKey: input.environmentKey || "preproduction",
|
|
490
|
+
})}`);
|
|
491
|
+
}
|
|
492
|
+
async nativeRoleMemberships(appCode, input = {}) {
|
|
493
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/memberships?${this.query({
|
|
494
|
+
...input,
|
|
495
|
+
environmentKey: input.environmentKey || "preproduction",
|
|
496
|
+
})}`);
|
|
497
|
+
}
|
|
498
|
+
async createNativeRoleMembership(appCode, input) {
|
|
499
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/memberships`, {
|
|
500
|
+
method: "POST",
|
|
501
|
+
body: JSON.stringify(input),
|
|
502
|
+
});
|
|
351
503
|
}
|
|
352
|
-
async
|
|
353
|
-
return await this.json(`${this.
|
|
504
|
+
async updateNativeRoleMembership(appCode, membershipId, input) {
|
|
505
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/memberships/${encodeURIComponent(membershipId)}/update`, {
|
|
506
|
+
method: "POST",
|
|
507
|
+
body: JSON.stringify(input),
|
|
508
|
+
});
|
|
354
509
|
}
|
|
355
|
-
async
|
|
356
|
-
return await this.json(`${this.
|
|
510
|
+
async revokeNativeRoleMembership(appCode, membershipId, input) {
|
|
511
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/memberships/${encodeURIComponent(membershipId)}/revoke`, {
|
|
357
512
|
method: "POST",
|
|
358
|
-
body: JSON.stringify(
|
|
513
|
+
body: JSON.stringify(input),
|
|
359
514
|
});
|
|
360
515
|
}
|
|
361
|
-
async
|
|
362
|
-
return await this.json(`${this.
|
|
516
|
+
async nativeRoleManagementGrants(appCode, input = {}) {
|
|
517
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/role-management-grants?${this.query({
|
|
518
|
+
...input,
|
|
519
|
+
environmentKey: input.environmentKey || "preproduction",
|
|
520
|
+
})}`);
|
|
521
|
+
}
|
|
522
|
+
async createNativeRoleManagementGrant(appCode, input) {
|
|
523
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/role-management-grants`, { method: "POST", body: JSON.stringify(input) });
|
|
524
|
+
}
|
|
525
|
+
async updateNativeRoleManagementGrant(appCode, grantId, input) {
|
|
526
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/role-management-grants/${encodeURIComponent(grantId)}/update`, { method: "POST", body: JSON.stringify(input) });
|
|
527
|
+
}
|
|
528
|
+
async revokeNativeRoleManagementGrant(appCode, grantId, input) {
|
|
529
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/role-management-grants/${encodeURIComponent(grantId)}/revoke`, { method: "POST", body: JSON.stringify(input) });
|
|
530
|
+
}
|
|
531
|
+
async nativeAuthorizationMutationReceipt(appCode, operationId) {
|
|
532
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/mutation-receipts/${encodeURIComponent(operationId)}`);
|
|
533
|
+
}
|
|
534
|
+
async nativeSuperAdmins(appCode, input = {}) {
|
|
535
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/super-admins?${this.query({ ...input, environmentKey: input.environmentKey || "preproduction" })}`);
|
|
536
|
+
}
|
|
537
|
+
async grantNativeSuperAdmin(appCode, input) {
|
|
538
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/super-admins`, {
|
|
539
|
+
method: "POST",
|
|
540
|
+
body: JSON.stringify(input),
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
async revokeNativeSuperAdmin(appCode, grantId, input) {
|
|
544
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/super-admins/${encodeURIComponent(grantId)}/revoke`, {
|
|
545
|
+
method: "POST",
|
|
546
|
+
body: JSON.stringify(input),
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
async nativeRelationshipGrants(appCode, input = {}) {
|
|
550
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/relationship-grants?${this.query({
|
|
551
|
+
...input,
|
|
552
|
+
environmentKey: input.environmentKey || "preproduction",
|
|
553
|
+
})}`);
|
|
554
|
+
}
|
|
555
|
+
async createNativeRelationshipGrant(appCode, input) {
|
|
556
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/relationship-grants`, {
|
|
557
|
+
method: "POST",
|
|
558
|
+
body: JSON.stringify(input),
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
async updateNativeRelationshipGrant(appCode, grantId, input) {
|
|
562
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/relationship-grants/${encodeURIComponent(grantId)}/update`, {
|
|
563
|
+
method: "POST",
|
|
564
|
+
body: JSON.stringify(input),
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
async revokeNativeRelationshipGrant(appCode, grantId, input) {
|
|
568
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/relationship-grants/${encodeURIComponent(grantId)}/revoke`, {
|
|
569
|
+
method: "POST",
|
|
570
|
+
body: JSON.stringify(input),
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
async nativeAuthorizationProjectionHealth(appCode, environmentKey = "preproduction") {
|
|
574
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/projections/health?${this.query({ environmentKey })}`);
|
|
575
|
+
}
|
|
576
|
+
async rebuildNativeAuthorizationProjections(appCode, input) {
|
|
577
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/projections/rebuild`, { method: "POST", body: JSON.stringify(input) });
|
|
578
|
+
}
|
|
579
|
+
async recoverNativeAuthorizationProjection(appCode, jobId, input) {
|
|
580
|
+
return await this.json(`${this.nativeAuthzManagementPath(appCode)}/projections/jobs/${encodeURIComponent(jobId)}/recover`, { method: "POST", body: JSON.stringify(input) });
|
|
363
581
|
}
|
|
364
582
|
async myRoleAssignments(appCode) {
|
|
365
583
|
return await this.json(`${this.authzPath(appCode)}/assignments/me`);
|
|
@@ -376,38 +594,37 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
376
594
|
async revokeRoleAssignment(appCode, assignmentId, expectedRevision) {
|
|
377
595
|
return await this.json(`${this.authzPath(appCode)}/assignments/${encodeURIComponent(assignmentId)}/revoke`, { method: "POST", body: JSON.stringify({ expectedRevision }) });
|
|
378
596
|
}
|
|
379
|
-
async
|
|
380
|
-
const { roleSessionId, ...body } = input;
|
|
381
|
-
return await this.json(`${this.authzPath(appCode)}/explain`, {
|
|
382
|
-
method: "POST",
|
|
383
|
-
body: JSON.stringify(body),
|
|
384
|
-
headers: this.roleSessionHeaders({ roleSessionId }),
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
async explainAuthorizations(appCode, input) {
|
|
388
|
-
return await this.json(`${this.authzPath(appCode)}/explain-batch`, {
|
|
389
|
-
method: "POST",
|
|
390
|
-
body: JSON.stringify({
|
|
391
|
-
schemaVersion: SCHEMA_VERSIONS.authorizationBatchRequest,
|
|
392
|
-
requests: input.requests,
|
|
393
|
-
}),
|
|
394
|
-
headers: this.roleSessionHeaders({
|
|
395
|
-
roleSessionId: input.roleSessionId,
|
|
396
|
-
}),
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
async searchDirectoryEntries(appCode, kind, input, request) {
|
|
597
|
+
async searchDirectoryEntries(appCode, kind, input) {
|
|
400
598
|
const query = new URLSearchParams({
|
|
401
599
|
keyword: input.keyword.trim(),
|
|
402
600
|
limit: String(Math.min(Math.max(Number(input.limit) || 20, 1), 50)),
|
|
403
601
|
});
|
|
404
|
-
return await this.json(`${this.directoryPath(appCode)}/${kind}s?${query}
|
|
602
|
+
return await this.json(`${this.directoryPath(appCode)}/${kind}s?${query}`);
|
|
603
|
+
}
|
|
604
|
+
async browseDepartmentEntries(appCode, input) {
|
|
605
|
+
const query = new URLSearchParams({
|
|
606
|
+
offset: String(Math.max(Number(input.offset) || 0, 0)),
|
|
607
|
+
limit: String(Math.min(Math.max(Number(input.limit) || 100, 1), 100)),
|
|
608
|
+
});
|
|
609
|
+
const parentId = String(input.parentId || "").trim();
|
|
610
|
+
if (parentId)
|
|
611
|
+
query.set("parentId", parentId);
|
|
612
|
+
return await this.json(`${this.directoryPath(appCode)}/departments/tree?${query}`);
|
|
613
|
+
}
|
|
614
|
+
async browseDepartmentUserEntries(appCode, input) {
|
|
615
|
+
const departmentId = String(input.departmentId || "").trim();
|
|
616
|
+
if (!departmentId)
|
|
617
|
+
throw new Error("departmentId is required");
|
|
618
|
+
const query = new URLSearchParams({
|
|
619
|
+
page: String(Math.max(Number(input.page) || 1, 1)),
|
|
620
|
+
limit: String(Math.min(Math.max(Number(input.limit) || 50, 1), 100)),
|
|
621
|
+
});
|
|
622
|
+
return await this.json(`${this.directoryPath(appCode)}/departments/${encodeURIComponent(departmentId)}/users?${query}`);
|
|
405
623
|
}
|
|
406
|
-
async resolveDirectoryEntries(appCode, input
|
|
624
|
+
async resolveDirectoryEntries(appCode, input) {
|
|
407
625
|
return await this.json(`${this.directoryPath(appCode)}/resolve`, {
|
|
408
626
|
method: "POST",
|
|
409
627
|
body: JSON.stringify(input),
|
|
410
|
-
headers: this.roleSessionHeaders(request),
|
|
411
628
|
});
|
|
412
629
|
}
|
|
413
630
|
async applyDataResource(resource, input = {}) {
|
|
@@ -445,17 +662,24 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
445
662
|
return await this.json(this.dataPath(appCode, resourceCode, "query"), {
|
|
446
663
|
method: "POST",
|
|
447
664
|
body: JSON.stringify(query),
|
|
448
|
-
headers: this.
|
|
665
|
+
headers: this.perspectiveHeaders(request),
|
|
449
666
|
});
|
|
450
667
|
}
|
|
668
|
+
async chinaDivisions(parentAdcode) {
|
|
669
|
+
const query = new URLSearchParams();
|
|
670
|
+
if (parentAdcode)
|
|
671
|
+
query.set("parentAdcode", parentAdcode);
|
|
672
|
+
const suffix = query.size ? `?${query}` : "";
|
|
673
|
+
return await this.json(`/china-divisions/${suffix}`);
|
|
674
|
+
}
|
|
451
675
|
async getData(appCode, resourceCode, id, request = {}) {
|
|
452
|
-
return await this.json(this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}`), { headers: this.
|
|
676
|
+
return await this.json(this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}`), { headers: this.perspectiveHeaders(request) });
|
|
453
677
|
}
|
|
454
678
|
async aggregateData(appCode, resourceCode, query, request = {}) {
|
|
455
679
|
return await this.json(this.dataPath(appCode, resourceCode, "aggregate"), {
|
|
456
680
|
method: "POST",
|
|
457
681
|
body: JSON.stringify(query),
|
|
458
|
-
headers: this.
|
|
682
|
+
headers: this.perspectiveHeaders(request),
|
|
459
683
|
});
|
|
460
684
|
}
|
|
461
685
|
async dataAudit(appCode, resourceCode, id, input = {}, request = {}) {
|
|
@@ -465,40 +689,45 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
465
689
|
if (input.offset !== undefined)
|
|
466
690
|
query.set("offset", String(input.offset));
|
|
467
691
|
const suffix = query.size ? `?${query}` : "";
|
|
468
|
-
return await this.json(`${this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}/audit`)}${suffix}`, { headers: this.
|
|
692
|
+
return await this.json(`${this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}/audit`)}${suffix}`, { headers: this.perspectiveHeaders(request) });
|
|
469
693
|
}
|
|
470
694
|
async initiateDataFileUpload(appCode, resourceCode, input, request = {}) {
|
|
471
695
|
return await this.json(this.dataPath(appCode, resourceCode, "files/uploads/initiate"), {
|
|
472
696
|
method: "POST",
|
|
473
697
|
body: JSON.stringify(input),
|
|
474
|
-
headers: this.
|
|
698
|
+
headers: this.perspectiveHeaders(request),
|
|
475
699
|
});
|
|
476
700
|
}
|
|
477
701
|
async completeDataFileUpload(appCode, resourceCode, fileId, request = {}) {
|
|
478
702
|
return await this.json(this.dataPath(appCode, resourceCode, `files/${encodeURIComponent(fileId)}/complete`), {
|
|
479
703
|
method: "POST",
|
|
480
704
|
body: "{}",
|
|
481
|
-
headers: this.
|
|
705
|
+
headers: this.perspectiveHeaders(request),
|
|
482
706
|
});
|
|
483
707
|
}
|
|
484
|
-
async
|
|
708
|
+
async deleteUnreferencedDataFile(appCode, resourceCode, fileId, request = {}) {
|
|
485
709
|
return await this.json(this.dataPath(appCode, resourceCode, `files/${encodeURIComponent(fileId)}/delete`), {
|
|
486
710
|
method: "POST",
|
|
487
711
|
body: "{}",
|
|
488
|
-
headers: this.
|
|
712
|
+
headers: this.perspectiveHeaders(request),
|
|
489
713
|
});
|
|
490
714
|
}
|
|
491
715
|
async dataFileContent(appCode, resourceCode, fileId, request = {}) {
|
|
492
716
|
const path = this.dataPath(appCode, resourceCode, `files/${encodeURIComponent(fileId)}/content`);
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
: {}),
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
717
|
+
const download = async (forceRefresh) => {
|
|
718
|
+
const token = await this.accessToken(forceRefresh);
|
|
719
|
+
return await this.fetch(`${this.baseUrl}${path}`, {
|
|
720
|
+
credentials: this.options.credentials || "same-origin",
|
|
721
|
+
headers: {
|
|
722
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
723
|
+
...this.perspectiveHeaders(request),
|
|
724
|
+
},
|
|
725
|
+
});
|
|
726
|
+
};
|
|
727
|
+
let response = await download(false);
|
|
728
|
+
if (response.status === 401 && this.options.tokenProvider) {
|
|
729
|
+
response = await download(true);
|
|
730
|
+
}
|
|
502
731
|
if (!response.ok) {
|
|
503
732
|
let data = null;
|
|
504
733
|
try {
|
|
@@ -515,32 +744,32 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
515
744
|
return await this.json(this.dataPath(appCode, resourceCode, "records"), {
|
|
516
745
|
method: "POST",
|
|
517
746
|
body: JSON.stringify({ data }),
|
|
518
|
-
headers: this.
|
|
747
|
+
headers: this.perspectiveHeaders(request),
|
|
519
748
|
});
|
|
520
749
|
}
|
|
521
750
|
async updateData(appCode, resourceCode, id, input, request = {}) {
|
|
522
751
|
return await this.json(this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}/update`), {
|
|
523
752
|
method: "POST",
|
|
524
753
|
body: JSON.stringify(input),
|
|
525
|
-
headers: this.
|
|
754
|
+
headers: this.perspectiveHeaders(request),
|
|
526
755
|
});
|
|
527
756
|
}
|
|
528
757
|
async deleteData(appCode, resourceCode, id, expectedRevision, request = {}) {
|
|
529
758
|
return await this.json(this.dataPath(appCode, resourceCode, `records/${encodeURIComponent(id)}/delete`), {
|
|
530
759
|
method: "POST",
|
|
531
760
|
body: JSON.stringify({ expectedRevision }),
|
|
532
|
-
headers: this.
|
|
761
|
+
headers: this.perspectiveHeaders(request),
|
|
533
762
|
});
|
|
534
763
|
}
|
|
535
764
|
async transactData(appCode, transaction, request = {}) {
|
|
536
|
-
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/data/transactions`, {
|
|
765
|
+
return await this.json(`/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/native/data/transactions`, {
|
|
537
766
|
method: "POST",
|
|
538
767
|
body: JSON.stringify(transaction),
|
|
539
|
-
headers: this.
|
|
768
|
+
headers: this.perspectiveHeaders(request),
|
|
540
769
|
});
|
|
541
770
|
}
|
|
542
771
|
dataPath(appCode, resourceCode, suffix) {
|
|
543
|
-
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/data/${encodeURIComponent(resourceCode)}/${suffix}`;
|
|
772
|
+
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/native/data/${encodeURIComponent(resourceCode)}/${suffix}`;
|
|
544
773
|
}
|
|
545
774
|
applicationApiPath(appCode, environmentKey, runtimePath, query = {}) {
|
|
546
775
|
const normalized = String(runtimePath || "")
|
|
@@ -579,6 +808,21 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
579
808
|
authzPath(appCode) {
|
|
580
809
|
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/authz`;
|
|
581
810
|
}
|
|
811
|
+
nativeAuthzPath(appCode) {
|
|
812
|
+
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/native/authz`;
|
|
813
|
+
}
|
|
814
|
+
nativeAuthzManagementPath(appCode) {
|
|
815
|
+
return `${this.nativeAuthzPath(appCode)}/management`;
|
|
816
|
+
}
|
|
817
|
+
query(input) {
|
|
818
|
+
const query = new URLSearchParams();
|
|
819
|
+
for (const [key, value] of Object.entries(input)) {
|
|
820
|
+
if (value === undefined || value === null || value === "")
|
|
821
|
+
continue;
|
|
822
|
+
query.set(key, String(value));
|
|
823
|
+
}
|
|
824
|
+
return query.toString();
|
|
825
|
+
}
|
|
582
826
|
directoryPath(appCode) {
|
|
583
827
|
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/directory`;
|
|
584
828
|
}
|
|
@@ -591,21 +835,28 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
591
835
|
eventsPath(appCode) {
|
|
592
836
|
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/events`;
|
|
593
837
|
}
|
|
838
|
+
connectedDevelopmentSessionsPath(appCode) {
|
|
839
|
+
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/dev-sessions`;
|
|
840
|
+
}
|
|
841
|
+
connectedDevelopmentSessionHeaders(sessionToken) {
|
|
842
|
+
const token = String(sessionToken || "").trim();
|
|
843
|
+
if (!token)
|
|
844
|
+
throw new Error("OPENXIANGDA_CONNECTED_DEV_SESSION_REQUIRED");
|
|
845
|
+
return { "X-OpenXiangda-Dev-Session": token };
|
|
846
|
+
}
|
|
594
847
|
workflowPath(appCode) {
|
|
595
848
|
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/workflow`;
|
|
596
849
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
throw new ControlPlaneError(400, "ROLE_SESSION_REQUIRED", "OpenXiangda v2 用户作用域请求必须显式携带 roleSessionId");
|
|
600
|
-
}
|
|
601
|
-
return {
|
|
602
|
-
"X-OpenXiangda-Role-Session-Id": request.roleSessionId,
|
|
603
|
-
};
|
|
850
|
+
administrationPath(appCode) {
|
|
851
|
+
return `/openxiangda-api/v2/applications/${encodeURIComponent(appCode)}/admin`;
|
|
604
852
|
}
|
|
605
|
-
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
|
|
853
|
+
perspectiveHeaders(request) {
|
|
854
|
+
const perspectiveCode = String(request?.perspectiveCode || "").trim();
|
|
855
|
+
if (perspectiveCode && !/^[a-z][a-z0-9._-]{0,127}$/.test(perspectiveCode)) {
|
|
856
|
+
throw new ControlPlaneError(400, "OPENXIANGDA_PERSPECTIVE_INVALID", "perspectiveCode must be a stable lowercase identifier");
|
|
857
|
+
}
|
|
858
|
+
return perspectiveCode
|
|
859
|
+
? { "X-OpenXiangda-Perspective": perspectiveCode }
|
|
609
860
|
: {};
|
|
610
861
|
}
|
|
611
862
|
basicCredentials(clientId, clientSecret) {
|
|
@@ -623,15 +874,24 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
623
874
|
},
|
|
624
875
|
});
|
|
625
876
|
}
|
|
626
|
-
async request(path, init = {}) {
|
|
627
|
-
|
|
877
|
+
async request(path, init = {}, fetcher = this.fetch) {
|
|
878
|
+
try {
|
|
879
|
+
return await this.requestOnce(path, init, false, fetcher);
|
|
880
|
+
}
|
|
881
|
+
catch (error) {
|
|
882
|
+
if (!this.options.tokenProvider || !this.isUnauthorized(error))
|
|
883
|
+
throw error;
|
|
884
|
+
return await this.requestOnce(path, init, true, fetcher);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
async requestOnce(path, init, forceRefresh, fetcher) {
|
|
888
|
+
const token = await this.accessToken(forceRefresh);
|
|
889
|
+
const response = await fetcher(`${this.baseUrl}${path}`, {
|
|
628
890
|
...init,
|
|
629
891
|
credentials: init.credentials || this.options.credentials || "same-origin",
|
|
630
892
|
headers: {
|
|
631
893
|
Accept: "application/json",
|
|
632
|
-
...(
|
|
633
|
-
? { Authorization: `Bearer ${this.options.token}` }
|
|
634
|
-
: {}),
|
|
894
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
635
895
|
...(init.headers || {}),
|
|
636
896
|
},
|
|
637
897
|
});
|
|
@@ -643,9 +903,28 @@ export class OpenXiangdaControlPlaneClient {
|
|
|
643
903
|
throw new ControlPlaneError(response.status, "CONTROL_PLANE_RESPONSE_INVALID", "平台返回的不是有效 JSON");
|
|
644
904
|
}
|
|
645
905
|
if (!response.ok || Number(envelope.code) >= 400) {
|
|
646
|
-
|
|
906
|
+
const status = response.ok ? Number(envelope.code) : response.status;
|
|
907
|
+
throw new ControlPlaneError(status, envelope.errorCode || "CONTROL_PLANE_REQUEST_FAILED", envelope.message || `平台请求失败: ${response.status}`, envelope.data, {
|
|
908
|
+
...(envelope.retryable === undefined
|
|
909
|
+
? {}
|
|
910
|
+
: { retryable: envelope.retryable }),
|
|
911
|
+
...(envelope.remediation
|
|
912
|
+
? { remediation: envelope.remediation }
|
|
913
|
+
: {}),
|
|
914
|
+
...(envelope.requestId ? { requestId: envelope.requestId } : {}),
|
|
915
|
+
...(envelope.path ? { path: envelope.path } : {}),
|
|
916
|
+
...(envelope.field ? { field: envelope.field } : {}),
|
|
917
|
+
});
|
|
647
918
|
}
|
|
648
919
|
return envelope.data;
|
|
649
920
|
}
|
|
921
|
+
isUnauthorized(error) {
|
|
922
|
+
return error instanceof ControlPlaneError && error.status === 401;
|
|
923
|
+
}
|
|
924
|
+
async accessToken(forceRefresh) {
|
|
925
|
+
return this.options.tokenProvider
|
|
926
|
+
? await this.options.tokenProvider.getAccessToken({ forceRefresh })
|
|
927
|
+
: this.options.token;
|
|
928
|
+
}
|
|
650
929
|
}
|
|
651
930
|
//# sourceMappingURL=control-plane-client.js.map
|