openxiangda-devkit-core 2.0.0-alpha.100
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 +13 -0
- package/dist/app-spec.d.ts +210 -0
- package/dist/app-spec.d.ts.map +1 -0
- package/dist/app-spec.js +1262 -0
- package/dist/app-spec.js.map +1 -0
- package/dist/application-services.d.ts +600 -0
- package/dist/application-services.d.ts.map +1 -0
- package/dist/application-services.js +1603 -0
- package/dist/application-services.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 +209 -0
- package/dist/backend-image-build.js.map +1 -0
- package/dist/command-registry.d.ts +177 -0
- package/dist/command-registry.d.ts.map +1 -0
- package/dist/command-registry.js +27 -0
- package/dist/command-registry.js.map +1 -0
- 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 +353 -0
- package/dist/compiler/ai-catalog.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 +1865 -0
- package/dist/compiler/bundle.js.map +1 -0
- package/dist/compiler/config.d.ts +857 -0
- package/dist/compiler/config.d.ts.map +1 -0
- package/dist/compiler/config.js +3848 -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 +246 -0
- package/dist/compiler/package-compiler.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 +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.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 +684 -0
- package/dist/control-plane-client.d.ts.map +1 -0
- package/dist/control-plane-client.js +860 -0
- package/dist/control-plane-client.js.map +1 -0
- package/dist/deployment.d.ts +67 -0
- package/dist/deployment.d.ts.map +1 -0
- package/dist/deployment.js +311 -0
- package/dist/deployment.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- 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/package-compiler.d.ts +2 -0
- package/dist/package-compiler.d.ts.map +1 -0
- package/dist/package-compiler.js +2 -0
- package/dist/package-compiler.js.map +1 -0
- package/dist/session.d.ts +143 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +351 -0
- package/dist/session.js.map +1 -0
- 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/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/dist/workspace-loader.d.ts +17 -0
- package/dist/workspace-loader.d.ts.map +1 -0
- package/dist/workspace-loader.js +140 -0
- package/dist/workspace-loader.js.map +1 -0
- package/dist/workspace.d.ts +15 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +69 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +44 -0
package/dist/testing.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
export class PermissionMatrixError extends Error {
|
|
2
|
+
results;
|
|
3
|
+
constructor(results) {
|
|
4
|
+
super(`权限矩阵失败: ${results
|
|
5
|
+
.filter(result => !result.passed)
|
|
6
|
+
.map(result => `${result.name} expected=${result.expected} actual=${result.actual}`)
|
|
7
|
+
.join(", ")}`);
|
|
8
|
+
this.results = results;
|
|
9
|
+
this.name = "PermissionMatrixError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function currentUserFixture(options = {}) {
|
|
13
|
+
return {
|
|
14
|
+
userId: options.userId || "user-test",
|
|
15
|
+
appCode: options.appCode || "reference-app",
|
|
16
|
+
environmentKey: options.environmentKey || "preproduction",
|
|
17
|
+
roleCodes: normalized(options.roleCodes || ["instrument_admin"]),
|
|
18
|
+
capabilityCodes: normalized(options.capabilityCodes || []),
|
|
19
|
+
isAppSuperAdmin: options.isAppSuperAdmin === true,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function dataRecordEventFixture(options = {}) {
|
|
23
|
+
const eventType = options.eventType || "openxiangda.data.record.updated.v2";
|
|
24
|
+
const operation = eventType.endsWith(".created.v2")
|
|
25
|
+
? "created"
|
|
26
|
+
: eventType.endsWith(".deleted.v2")
|
|
27
|
+
? "deleted"
|
|
28
|
+
: "updated";
|
|
29
|
+
const resourceCode = options.resourceCode || "instruments";
|
|
30
|
+
const recordId = options.recordId || "00000000-0000-4000-8000-000000000001";
|
|
31
|
+
const changedFields = normalized(options.changedFields || ["status"]);
|
|
32
|
+
return {
|
|
33
|
+
specversion: "1.0",
|
|
34
|
+
id: options.eventId || "00000000-0000-4000-8000-000000000010",
|
|
35
|
+
type: eventType,
|
|
36
|
+
source: `/applications/${options.appCode || "reference-app"}/data-resources/${resourceCode}`,
|
|
37
|
+
subject: `/records/${recordId}`,
|
|
38
|
+
time: options.time || "2026-08-24T00:00:00.000Z",
|
|
39
|
+
datacontenttype: "application/json",
|
|
40
|
+
dataschema: `openxiangda://events/openxiangda.data.record/${eventType.split(".").at(-1)}`,
|
|
41
|
+
tenantid: options.tenantId || "tenant-test",
|
|
42
|
+
appcode: options.appCode || "reference-app",
|
|
43
|
+
environment: options.environmentKey || "preproduction",
|
|
44
|
+
traceid: "trace-test",
|
|
45
|
+
schemaversion: "2.0.0",
|
|
46
|
+
data: {
|
|
47
|
+
resourceCode,
|
|
48
|
+
recordId,
|
|
49
|
+
operation,
|
|
50
|
+
revision: options.revision ?? 2,
|
|
51
|
+
changedFields,
|
|
52
|
+
changes: options.changes ||
|
|
53
|
+
Object.fromEntries(changedFields.map(field => [field, { before: "before", after: "after" }])),
|
|
54
|
+
projection: options.projection || {},
|
|
55
|
+
actor: { principalType: "user", subjectId: "user-test" },
|
|
56
|
+
cause: { eventId: null, subscriptionCode: null, depth: 0 },
|
|
57
|
+
capturePlanRevision: 1,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function signedEventDeliveryFixture(input) {
|
|
62
|
+
const rawBody = JSON.stringify(input.event);
|
|
63
|
+
const timestamp = String(input.timestamp ?? Math.floor(Date.now() / 1000));
|
|
64
|
+
const signingKeyVersion = String(input.signingKeyVersion ?? 1);
|
|
65
|
+
const handlerManifestDigest = sha256Digest(input.handlerManifest);
|
|
66
|
+
const signature = createHmac('sha256', input.signingSecret)
|
|
67
|
+
.update(eventDeliverySignatureContentV2({
|
|
68
|
+
timestamp,
|
|
69
|
+
signingKeyVersion,
|
|
70
|
+
deliveryId: input.deliveryId,
|
|
71
|
+
eventId: input.event.id,
|
|
72
|
+
subscriptionCode: input.subscriptionCode,
|
|
73
|
+
handlerManifestDigest,
|
|
74
|
+
rawBody,
|
|
75
|
+
}))
|
|
76
|
+
.digest('hex');
|
|
77
|
+
return {
|
|
78
|
+
rawBody,
|
|
79
|
+
handlerManifestDigest,
|
|
80
|
+
headers: {
|
|
81
|
+
'content-type': 'application/cloudevents+json; charset=utf-8',
|
|
82
|
+
'x-openxiangda-event-id': input.event.id,
|
|
83
|
+
'x-openxiangda-delivery-id': input.deliveryId,
|
|
84
|
+
'x-openxiangda-subscription-code': input.subscriptionCode,
|
|
85
|
+
'x-openxiangda-timestamp': timestamp,
|
|
86
|
+
'x-openxiangda-signing-key-version': signingKeyVersion,
|
|
87
|
+
'x-openxiangda-handler-manifest-digest': handlerManifestDigest,
|
|
88
|
+
'x-openxiangda-signature': `v2=${signature}`,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function eventMatchesSubscription(event, filter = {}) {
|
|
93
|
+
if (filter.resourceCodes?.length &&
|
|
94
|
+
!filter.resourceCodes.includes(event.data.resourceCode)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (filter.subject?.equals !== undefined &&
|
|
98
|
+
event.subject !== filter.subject.equals) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (filter.subject?.prefix !== undefined &&
|
|
102
|
+
!String(event.subject || "").startsWith(filter.subject.prefix)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const changed = new Set(event.data.changedFields);
|
|
106
|
+
if (filter.changedFields?.anyOf?.length &&
|
|
107
|
+
!filter.changedFields.anyOf.some(field => changed.has(field))) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (filter.changedFields?.allOf?.length &&
|
|
111
|
+
!filter.changedFields.allOf.every(field => changed.has(field))) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (filter.changedFields?.noneOf?.some(field => changed.has(field))) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (filter.changes?.some(change => !eventChangeMatches(event.data, change))) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return filter.where ? eventConditionMatches(event.data, filter.where) : true;
|
|
121
|
+
}
|
|
122
|
+
export function simulateEventSubscription(event, input) {
|
|
123
|
+
if (!eventMatchesSubscription(event, input.filter || {})) {
|
|
124
|
+
return { matched: false, event: null };
|
|
125
|
+
}
|
|
126
|
+
const fields = input.payload?.fields || [];
|
|
127
|
+
const projection = Object.fromEntries(fields
|
|
128
|
+
.filter(field => Object.prototype.hasOwnProperty.call(event.data.projection, field))
|
|
129
|
+
.map(field => [field, event.data.projection[field]]));
|
|
130
|
+
return {
|
|
131
|
+
matched: true,
|
|
132
|
+
event: {
|
|
133
|
+
...event,
|
|
134
|
+
data: {
|
|
135
|
+
...event.data,
|
|
136
|
+
changes: input.payload?.includeChanges === false ? {} : event.data.changes,
|
|
137
|
+
projection,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export async function runPermissionMatrix(cases, authorize) {
|
|
143
|
+
const results = [];
|
|
144
|
+
for (const testCase of cases) {
|
|
145
|
+
const actual = (await authorize(testCase)) ? "allow" : "deny";
|
|
146
|
+
results.push({
|
|
147
|
+
name: testCase.name,
|
|
148
|
+
expected: testCase.expected,
|
|
149
|
+
actual,
|
|
150
|
+
passed: actual === testCase.expected,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return results;
|
|
154
|
+
}
|
|
155
|
+
export async function assertPermissionMatrix(cases, authorize) {
|
|
156
|
+
const results = await runPermissionMatrix(cases, authorize);
|
|
157
|
+
if (results.some(result => !result.passed)) {
|
|
158
|
+
throw new PermissionMatrixError(results);
|
|
159
|
+
}
|
|
160
|
+
return results;
|
|
161
|
+
}
|
|
162
|
+
function normalized(values) {
|
|
163
|
+
return [...new Set(values.map(String).map(value => value.trim()).filter(Boolean))]
|
|
164
|
+
.sort();
|
|
165
|
+
}
|
|
166
|
+
function eventConditionMatches(data, condition) {
|
|
167
|
+
if ("change" in condition)
|
|
168
|
+
return eventChangeMatches(data, condition.change);
|
|
169
|
+
if ("all" in condition) {
|
|
170
|
+
return condition.all.every(item => eventConditionMatches(data, item));
|
|
171
|
+
}
|
|
172
|
+
if ("any" in condition) {
|
|
173
|
+
return condition.any.some(item => eventConditionMatches(data, item));
|
|
174
|
+
}
|
|
175
|
+
return !eventConditionMatches(data, condition.not);
|
|
176
|
+
}
|
|
177
|
+
function eventChangeMatches(data, filter) {
|
|
178
|
+
const change = data.changes[filter.field];
|
|
179
|
+
if (!change)
|
|
180
|
+
return false;
|
|
181
|
+
return ((!filter.before || eventPredicateMatches(change.before, filter.before)) &&
|
|
182
|
+
(!filter.after || eventPredicateMatches(change.after, filter.after)));
|
|
183
|
+
}
|
|
184
|
+
function eventPredicateMatches(value, predicate) {
|
|
185
|
+
if ("exists" in predicate)
|
|
186
|
+
return predicate.exists === (value !== undefined);
|
|
187
|
+
if ("eq" in predicate)
|
|
188
|
+
return canonicalEqual(value, predicate.eq);
|
|
189
|
+
if ("ne" in predicate)
|
|
190
|
+
return !canonicalEqual(value, predicate.ne);
|
|
191
|
+
if ("in" in predicate) {
|
|
192
|
+
return (predicate.in || []).some(item => canonicalEqual(value, item));
|
|
193
|
+
}
|
|
194
|
+
return !(predicate.notIn || []).some(item => canonicalEqual(value, item));
|
|
195
|
+
}
|
|
196
|
+
function canonicalEqual(left, right) {
|
|
197
|
+
return canonicalJsonValue(left) === canonicalJsonValue(right);
|
|
198
|
+
}
|
|
199
|
+
function canonicalJsonValue(value) {
|
|
200
|
+
if (Array.isArray(value)) {
|
|
201
|
+
return `[${value.map(canonicalJsonValue).join(",")}]`;
|
|
202
|
+
}
|
|
203
|
+
if (value && typeof value === "object") {
|
|
204
|
+
return `{${Object.entries(value)
|
|
205
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
206
|
+
.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJsonValue(item)}`)
|
|
207
|
+
.join(",")}}`;
|
|
208
|
+
}
|
|
209
|
+
return JSON.stringify(value);
|
|
210
|
+
}
|
|
211
|
+
import { eventDeliverySignatureContentV2, sha256Digest, } from "openxiangda-contracts";
|
|
212
|
+
import { createHmac } from 'node:crypto';
|
|
213
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type Diagnostic } from "openxiangda-contracts";
|
|
2
|
+
export declare const TOOLCHAIN_CAPSULE_SCHEMA_VERSION: "openxiangda.toolchain-capsule/v1";
|
|
3
|
+
export declare const TOOLCHAIN_CAPSULE_MAX_PACKAGE_FILES = 2000;
|
|
4
|
+
export declare const TOOLCHAIN_CAPSULE_MAX_MANIFEST_BYTES = 1000000;
|
|
5
|
+
/**
|
|
6
|
+
* These are the minimum app-facing packages owned by the official application
|
|
7
|
+
* template. This is a contract boundary, not a version table: versions are
|
|
8
|
+
* always read from the current template/package manifests. Additional
|
|
9
|
+
* openxiangda-* packages discovered in the template are included as well.
|
|
10
|
+
*/
|
|
11
|
+
export declare const TOOLCHAIN_CAPSULE_PACKAGE_NAMES: readonly ["openxiangda"];
|
|
12
|
+
export declare function isOpenXiangdaPackageName(name: string): boolean;
|
|
13
|
+
export type ToolchainCapsulePackageName = (typeof TOOLCHAIN_CAPSULE_PACKAGE_NAMES)[number];
|
|
14
|
+
export interface ToolchainCapsule {
|
|
15
|
+
readonly schemaVersion: typeof TOOLCHAIN_CAPSULE_SCHEMA_VERSION;
|
|
16
|
+
readonly owner: "cli-template" | "devkit-core";
|
|
17
|
+
readonly packages: Readonly<Record<string, string>>;
|
|
18
|
+
}
|
|
19
|
+
export interface WorkspaceToolchainDependency {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly specifier: string;
|
|
22
|
+
readonly packageFile: string;
|
|
23
|
+
readonly section: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ToolchainCapsuleMismatch {
|
|
26
|
+
readonly expected: string | null;
|
|
27
|
+
readonly actual: string;
|
|
28
|
+
readonly packageFile: string;
|
|
29
|
+
readonly section: string;
|
|
30
|
+
}
|
|
31
|
+
export declare class ToolchainCapsuleScanLimitError extends Error {
|
|
32
|
+
readonly code: "OPENXIANGDA_WORKSPACE_CAPSULE_SCAN_LIMIT";
|
|
33
|
+
constructor(message: string);
|
|
34
|
+
}
|
|
35
|
+
export declare function createToolchainCapsule(packages: ReadonlyMap<string, string> | Readonly<Record<string, string>>, owner?: ToolchainCapsule["owner"]): ToolchainCapsule;
|
|
36
|
+
/**
|
|
37
|
+
* A framework-neutral devkit caller has no CLI template owner. It can still
|
|
38
|
+
* reject a stale core/contracts pair using the two versions it actually
|
|
39
|
+
* executes and imports.
|
|
40
|
+
*/
|
|
41
|
+
export declare function defaultDevkitCoreToolchainCapsule(): ToolchainCapsule;
|
|
42
|
+
export declare function collectWorkspaceToolchainDependencies(root: string): WorkspaceToolchainDependency[];
|
|
43
|
+
export declare function toolchainCapsuleMismatches(dependencies: readonly WorkspaceToolchainDependency[], capsule: ToolchainCapsule): ToolchainCapsuleMismatch[];
|
|
44
|
+
export declare function toolchainCapsuleDiagnostic(dependencies: readonly WorkspaceToolchainDependency[], capsule: ToolchainCapsule): Diagnostic | undefined;
|
|
45
|
+
//# sourceMappingURL=toolchain-capsule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolchain-capsule.d.ts","sourceRoot":"","sources":["../src/toolchain-capsule.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,gCAAgC,EAC3C,kCAA2C,CAAC;AAC9C,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AACzD,eAAO,MAAM,oCAAoC,UAAY,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,0BAA2B,CAAC;AAExE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,WAEpD;AAED,MAAM,MAAM,2BAA2B,GACrC,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,OAAO,gCAAgC,CAAC;IAChE,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,EAAG,0CAA0C,CAAU;gBAExD,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxE,KAAK,GAAE,gBAAgB,CAAC,OAAO,CAAkB,GAChD,gBAAgB,CAiBlB;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,IAAI,gBAAgB,CAmBpE;AAED,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,MAAM,GACX,4BAA4B,EAAE,CA2EhC;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,SAAS,4BAA4B,EAAE,EACrD,OAAO,EAAE,gBAAgB,GACxB,wBAAwB,EAAE,CA+B5B;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,SAAS,4BAA4B,EAAE,EACrD,OAAO,EAAE,gBAAgB,GACxB,UAAU,GAAG,SAAS,CAmBxB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { SCHEMA_VERSIONS, } from "openxiangda-contracts";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
|
+
import { OPENXIANGDA_TOOLCHAIN_VERSION } from "./version.js";
|
|
5
|
+
export const TOOLCHAIN_CAPSULE_SCHEMA_VERSION = "openxiangda.toolchain-capsule/v1";
|
|
6
|
+
export const TOOLCHAIN_CAPSULE_MAX_PACKAGE_FILES = 2_000;
|
|
7
|
+
export const TOOLCHAIN_CAPSULE_MAX_MANIFEST_BYTES = 1_000_000;
|
|
8
|
+
/**
|
|
9
|
+
* These are the minimum app-facing packages owned by the official application
|
|
10
|
+
* template. This is a contract boundary, not a version table: versions are
|
|
11
|
+
* always read from the current template/package manifests. Additional
|
|
12
|
+
* openxiangda-* packages discovered in the template are included as well.
|
|
13
|
+
*/
|
|
14
|
+
export const TOOLCHAIN_CAPSULE_PACKAGE_NAMES = ["openxiangda"];
|
|
15
|
+
export function isOpenXiangdaPackageName(name) {
|
|
16
|
+
return name === "openxiangda" || name.startsWith("openxiangda-");
|
|
17
|
+
}
|
|
18
|
+
export class ToolchainCapsuleScanLimitError extends Error {
|
|
19
|
+
code = "OPENXIANGDA_WORKSPACE_CAPSULE_SCAN_LIMIT";
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "ToolchainCapsuleScanLimitError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function createToolchainCapsule(packages, owner = "cli-template") {
|
|
26
|
+
const entries = packages instanceof Map
|
|
27
|
+
? [...packages.entries()]
|
|
28
|
+
: Object.entries(packages);
|
|
29
|
+
const normalized = Object.fromEntries(entries
|
|
30
|
+
.filter(([name, version]) => isOpenXiangdaPackageName(name) && Boolean(String(version).trim()))
|
|
31
|
+
.map(([name, version]) => [name, String(version).trim()])
|
|
32
|
+
.sort(([left], [right]) => left.localeCompare(right)));
|
|
33
|
+
return Object.freeze({
|
|
34
|
+
schemaVersion: TOOLCHAIN_CAPSULE_SCHEMA_VERSION,
|
|
35
|
+
owner,
|
|
36
|
+
packages: Object.freeze(normalized),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A framework-neutral devkit caller has no CLI template owner. It can still
|
|
41
|
+
* reject a stale core/contracts pair using the two versions it actually
|
|
42
|
+
* executes and imports.
|
|
43
|
+
*/
|
|
44
|
+
export function defaultDevkitCoreToolchainCapsule() {
|
|
45
|
+
const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
46
|
+
const contractsVersion = String(manifest.dependencies?.["openxiangda-contracts"] || "").trim();
|
|
47
|
+
if (!contractsVersion || /[<>=*^~| ]/.test(contractsVersion)) {
|
|
48
|
+
throw new Error("OPENXIANGDA_CONTRACT_DEPENDENCY_NOT_EXACT");
|
|
49
|
+
}
|
|
50
|
+
return createToolchainCapsule(new Map([
|
|
51
|
+
["openxiangda-contracts", contractsVersion],
|
|
52
|
+
["openxiangda-devkit-core", OPENXIANGDA_TOOLCHAIN_VERSION],
|
|
53
|
+
]), "devkit-core");
|
|
54
|
+
}
|
|
55
|
+
export function collectWorkspaceToolchainDependencies(root) {
|
|
56
|
+
const dependencies = [];
|
|
57
|
+
let packageFileCount = 0;
|
|
58
|
+
const visit = (directory) => {
|
|
59
|
+
for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
|
|
60
|
+
if ([
|
|
61
|
+
"node_modules",
|
|
62
|
+
"dist",
|
|
63
|
+
"coverage",
|
|
64
|
+
"playwright-report",
|
|
65
|
+
"test-results",
|
|
66
|
+
".git",
|
|
67
|
+
".openxiangda",
|
|
68
|
+
".turbo",
|
|
69
|
+
].includes(entry.name)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const path = join(directory, entry.name);
|
|
73
|
+
if (entry.isDirectory()) {
|
|
74
|
+
visit(path);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!entry.isFile() || entry.name !== "package.json")
|
|
78
|
+
continue;
|
|
79
|
+
packageFileCount += 1;
|
|
80
|
+
if (packageFileCount > TOOLCHAIN_CAPSULE_MAX_PACKAGE_FILES) {
|
|
81
|
+
throw new ToolchainCapsuleScanLimitError(`workspace package.json count exceeds ${TOOLCHAIN_CAPSULE_MAX_PACKAGE_FILES}`);
|
|
82
|
+
}
|
|
83
|
+
const manifestBytes = statSync(path).size;
|
|
84
|
+
if (manifestBytes > TOOLCHAIN_CAPSULE_MAX_MANIFEST_BYTES) {
|
|
85
|
+
throw new ToolchainCapsuleScanLimitError(`${relative(root, path)} exceeds ${TOOLCHAIN_CAPSULE_MAX_MANIFEST_BYTES} bytes`);
|
|
86
|
+
}
|
|
87
|
+
const packageJson = JSON.parse(readFileSync(path, "utf8"));
|
|
88
|
+
for (const section of [
|
|
89
|
+
"dependencies",
|
|
90
|
+
"devDependencies",
|
|
91
|
+
"peerDependencies",
|
|
92
|
+
"optionalDependencies",
|
|
93
|
+
]) {
|
|
94
|
+
const values = packageJson[section];
|
|
95
|
+
if (!values || typeof values !== "object")
|
|
96
|
+
continue;
|
|
97
|
+
for (const [name, specifier] of Object.entries(values)) {
|
|
98
|
+
if (!isOpenXiangdaPackageName(name)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
dependencies.push({
|
|
102
|
+
name,
|
|
103
|
+
specifier: String(specifier),
|
|
104
|
+
packageFile: relative(root, path).replaceAll("\\", "/"),
|
|
105
|
+
section,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (!existsSync(root))
|
|
112
|
+
return dependencies;
|
|
113
|
+
visit(root);
|
|
114
|
+
return dependencies.sort((left, right) => left.name.localeCompare(right.name) ||
|
|
115
|
+
left.packageFile.localeCompare(right.packageFile) ||
|
|
116
|
+
left.section.localeCompare(right.section));
|
|
117
|
+
}
|
|
118
|
+
export function toolchainCapsuleMismatches(dependencies, capsule) {
|
|
119
|
+
const expected = capsule.packages;
|
|
120
|
+
const relevant = dependencies.filter(item => isOpenXiangdaPackageName(item.name) &&
|
|
121
|
+
(capsule.owner === "cli-template" ||
|
|
122
|
+
Object.prototype.hasOwnProperty.call(expected, item.name)));
|
|
123
|
+
const actualByName = new Map();
|
|
124
|
+
for (const dependency of relevant) {
|
|
125
|
+
const values = actualByName.get(dependency.name) || new Set();
|
|
126
|
+
values.add(dependency.specifier);
|
|
127
|
+
actualByName.set(dependency.name, values);
|
|
128
|
+
}
|
|
129
|
+
const mismatches = [];
|
|
130
|
+
for (const dependency of relevant) {
|
|
131
|
+
const expectedVersion = String(expected[dependency.name] || "");
|
|
132
|
+
const values = actualByName.get(dependency.name) || new Set();
|
|
133
|
+
if (dependency.specifier !== expectedVersion ||
|
|
134
|
+
values.size > 1) {
|
|
135
|
+
mismatches.push({
|
|
136
|
+
expected: expectedVersion || null,
|
|
137
|
+
actual: dependency.specifier,
|
|
138
|
+
packageFile: dependency.packageFile,
|
|
139
|
+
section: dependency.section,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return mismatches;
|
|
144
|
+
}
|
|
145
|
+
export function toolchainCapsuleDiagnostic(dependencies, capsule) {
|
|
146
|
+
const mismatches = toolchainCapsuleMismatches(dependencies, capsule);
|
|
147
|
+
if (mismatches.length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
return {
|
|
150
|
+
schemaVersion: SCHEMA_VERSIONS.diagnostic,
|
|
151
|
+
code: "OPENXIANGDA_WORKSPACE_CAPSULE_MISMATCH",
|
|
152
|
+
severity: "error",
|
|
153
|
+
message: "工作区 OpenXiangda 依赖与当前 CLI 模板版本胶囊不一致",
|
|
154
|
+
path: "package.json",
|
|
155
|
+
retryable: false,
|
|
156
|
+
remediation: "使用当前 CLI 重新 create,或将所有 OpenXiangda 包更新为胶囊中的精确版本后运行 pnpm install --frozen-lockfile",
|
|
157
|
+
details: {
|
|
158
|
+
owner: capsule.owner,
|
|
159
|
+
schemaVersion: capsule.schemaVersion,
|
|
160
|
+
expected: capsule.packages,
|
|
161
|
+
mismatches,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=toolchain-capsule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolchain-capsule.js","sourceRoot":"","sources":["../src/toolchain-capsule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAeA,sEAAsE;AACtE,eAAO,MAAM,6BAA6B,QAAyB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
function readToolchainVersion() {
|
|
3
|
+
const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
4
|
+
const version = String(manifest.version || '').trim();
|
|
5
|
+
if (!version)
|
|
6
|
+
throw new Error('OPENXIANGDA_TOOLCHAIN_VERSION_MISSING');
|
|
7
|
+
return version;
|
|
8
|
+
}
|
|
9
|
+
/** Runtime version of this independently published Devkit package. */
|
|
10
|
+
export const OPENXIANGDA_TOOLCHAIN_VERSION = readToolchainVersion();
|
|
11
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,SAAS,oBAAoB;IAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAC/C,CAAC;IACrB,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACvE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,6BAA6B,GAAG,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type OpenXiangdaAppConfig } from './compiler/config.js';
|
|
2
|
+
import { createWorkspaceContext } from './workspace.js';
|
|
3
|
+
export interface LoadedWorkspace {
|
|
4
|
+
root: string;
|
|
5
|
+
configPath: string;
|
|
6
|
+
config: OpenXiangdaAppConfig;
|
|
7
|
+
packageJson: Record<string, unknown>;
|
|
8
|
+
context: ReturnType<typeof createWorkspaceContext>;
|
|
9
|
+
}
|
|
10
|
+
export declare function loadWorkspace(start?: string, toolchainVersion?: string): Promise<LoadedWorkspace>;
|
|
11
|
+
export declare function discoverWorkspace(start?: string): {
|
|
12
|
+
root: string;
|
|
13
|
+
configPath: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function loadAppConfig(configPath: string): Promise<OpenXiangdaAppConfig>;
|
|
16
|
+
export declare function git(root: string, args: string[]): string;
|
|
17
|
+
//# sourceMappingURL=workspace-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-loader.d.ts","sourceRoot":"","sources":["../src/workspace-loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;CACpD;AAED,wBAAsB,aAAa,CACjC,KAAK,SAAgB,EACrB,gBAAgB,SAAgC,GAC/C,OAAO,CAAC,eAAe,CAAC,CAyB1B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,SAAgB;;;EAetD;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,iCAuDrD;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAS/C"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, parse, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { build } from 'esbuild';
|
|
6
|
+
import { defineOpenXiangdaApp, } from './compiler/config.js';
|
|
7
|
+
import { OPENXIANGDA_TOOLCHAIN_VERSION } from './version.js';
|
|
8
|
+
import { createWorkspaceContext } from './workspace.js';
|
|
9
|
+
const CONFIG_NAMES = ['openxiangda.config.ts', 'openxiangda-app.config.ts'];
|
|
10
|
+
export async function loadWorkspace(start = process.cwd(), toolchainVersion = OPENXIANGDA_TOOLCHAIN_VERSION) {
|
|
11
|
+
const { root, configPath } = discoverWorkspace(start);
|
|
12
|
+
const config = await loadAppConfig(configPath);
|
|
13
|
+
const packageJson = readJson(join(root, 'package.json'));
|
|
14
|
+
const revision = git(root, ['rev-parse', 'HEAD']);
|
|
15
|
+
const repository = git(root, ['config', '--get', 'remote.origin.url']);
|
|
16
|
+
const dirty = Boolean(git(root, ['status', '--porcelain']));
|
|
17
|
+
const changedDomains = changedAreas(root);
|
|
18
|
+
const packageManager = String(packageJson.packageManager || 'pnpm');
|
|
19
|
+
return {
|
|
20
|
+
root,
|
|
21
|
+
configPath,
|
|
22
|
+
config,
|
|
23
|
+
packageJson,
|
|
24
|
+
context: createWorkspaceContext(config, {
|
|
25
|
+
root,
|
|
26
|
+
toolchainVersion,
|
|
27
|
+
nodeVersion: process.version,
|
|
28
|
+
packageManager,
|
|
29
|
+
...(repository ? { repository } : {}),
|
|
30
|
+
...(revision ? { revision } : {}),
|
|
31
|
+
dirty,
|
|
32
|
+
changedDomains,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function discoverWorkspace(start = process.cwd()) {
|
|
37
|
+
let current = resolve(start);
|
|
38
|
+
const filesystemRoot = parse(current).root;
|
|
39
|
+
while (true) {
|
|
40
|
+
for (const name of CONFIG_NAMES) {
|
|
41
|
+
const configPath = join(current, name);
|
|
42
|
+
if (existsSync(configPath))
|
|
43
|
+
return { root: current, configPath };
|
|
44
|
+
}
|
|
45
|
+
if (current === filesystemRoot)
|
|
46
|
+
break;
|
|
47
|
+
current = dirname(current);
|
|
48
|
+
}
|
|
49
|
+
throw Object.assign(new Error('未找到 openxiangda.config.ts;当前目录不是 2.0 应用工作区'), { code: 'OPENXIANGDA_V2_WORKSPACE_NOT_FOUND' });
|
|
50
|
+
}
|
|
51
|
+
export async function loadAppConfig(configPath) {
|
|
52
|
+
const moduleRoot = dirname(fileURLToPath(import.meta.url));
|
|
53
|
+
const schemaCompositionModule = [
|
|
54
|
+
join(moduleRoot, 'compiler', 'schema-composition.js'),
|
|
55
|
+
join(moduleRoot, 'compiler', 'schema-composition.ts'),
|
|
56
|
+
].find(existsSync);
|
|
57
|
+
if (!schemaCompositionModule) {
|
|
58
|
+
throw new Error('OPENXIANGDA_CONFIG_SCHEMA_HELPERS_MISSING');
|
|
59
|
+
}
|
|
60
|
+
const result = await build({
|
|
61
|
+
entryPoints: [configPath],
|
|
62
|
+
bundle: true,
|
|
63
|
+
format: 'esm',
|
|
64
|
+
platform: 'node',
|
|
65
|
+
target: 'node20',
|
|
66
|
+
// Application workspace packages expose committed JavaScript for normal
|
|
67
|
+
// Node/Vite execution and their current TypeScript sources only to the
|
|
68
|
+
// declaration compiler. This prevents stale dist files from being sealed
|
|
69
|
+
// while keeping production runtimes free of TypeScript loaders.
|
|
70
|
+
conditions: ['openxiangda-source', 'import', 'default'],
|
|
71
|
+
write: false,
|
|
72
|
+
sourcemap: false,
|
|
73
|
+
logLevel: 'silent',
|
|
74
|
+
plugins: [
|
|
75
|
+
{
|
|
76
|
+
name: 'openxiangda-config-contract',
|
|
77
|
+
setup(context) {
|
|
78
|
+
context.onResolve({ filter: /^openxiangda-schema-composition$/ }, () => ({ path: schemaCompositionModule }));
|
|
79
|
+
context.onResolve({ filter: /^openxiangda\/config$/ }, () => ({ path: 'config', namespace: 'openxiangda-config' }));
|
|
80
|
+
context.onLoad({ filter: /.*/, namespace: 'openxiangda-config' }, () => ({
|
|
81
|
+
loader: 'js',
|
|
82
|
+
contents: 'export const defineOpenXiangdaApp = value => Object.freeze(value); export const defineAdminNavigation = value => Object.freeze(value); export const adminNavigationGroup = (code, label, items, options = {}) => ({ code, label, items, ...options }); export const adminResourcePage = (resourceCode, options = {}) => ({ page: { kind: "resource", resourceCode }, ...options }); export const adminOperationPage = (routeCode, options = {}) => ({ page: { kind: "operation", routeCode }, ...options }); export const resourceCapabilityCodes = (appCode, resourceCode) => { const prefix = `app:${appCode}:data:${resourceCode}`; return { read: `${prefix}:read`, create: `${prefix}:create`, update: `${prefix}:update`, delete: `${prefix}:delete` }; }; export const currentUserDataPolicy = input => ({ code: input.code, name: input.name, resourceCode: input.resourceCode, ...(input.unrestrictedRoleCodes ? { unrestrictedRoleCodes: [...input.unrestrictedRoleCodes] } : {}), matchMode: "AND", rules: [{ subject: "current_user", field: input.field, roleCodes: [...input.roleCodes] }] }); export const dataPolicyExpression = { allOf: (...values) => ({ allOf: values }), anyOf: (...values) => ({ anyOf: values }), constant: input => ({ ...input }), null: input => ({ ...input }), databaseNow: input => ({ ...input, operand: "db_now" }), currentUser: input => ({ ...input, subject: "current_user" }), dimension: input => ({ ...input }), relation: input => ({ ...input }) }; export const resourceReadPolicy = input => ({ code: input.code, name: input.name, resourceCode: input.resourceCode, ...(input.unrestrictedRoleCodes ? { unrestrictedRoleCodes: [...input.unrestrictedRoleCodes] } : {}), matchMode: input.writeBoundary === "capability_only" ? "AND" : input.matchMode, rules: input.writeBoundary === "capability_only" ? [] : input.rules, readExpression: input.expression, ...(input.writeBoundary === "capability_only" ? { writeBoundary: "capability_only" } : {}) });' +
|
|
83
|
+
' export { composeAppOperationSchemas, composeJsonSchema, resourceRecordSchema, schemaRef } from "openxiangda-schema-composition";',
|
|
84
|
+
}));
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
});
|
|
89
|
+
const source = result.outputFiles[0]?.text;
|
|
90
|
+
if (!source)
|
|
91
|
+
throw new Error('OPENXIANGDA_V2_CONFIG_COMPILE_EMPTY');
|
|
92
|
+
const module = (await import(`data:text/javascript;base64,${Buffer.from(source).toString('base64')}`));
|
|
93
|
+
if (!module.default)
|
|
94
|
+
throw new Error('OPENXIANGDA_V2_CONFIG_DEFAULT_REQUIRED');
|
|
95
|
+
return defineOpenXiangdaApp(module.default);
|
|
96
|
+
}
|
|
97
|
+
export function git(root, args) {
|
|
98
|
+
try {
|
|
99
|
+
return execFileSync('git', ['-C', root, ...args], {
|
|
100
|
+
encoding: 'utf8',
|
|
101
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
102
|
+
}).trim();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function readJson(path) {
|
|
109
|
+
try {
|
|
110
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function changedAreas(root) {
|
|
117
|
+
const paths = git(root, ['status', '--porcelain'])
|
|
118
|
+
.split('\n')
|
|
119
|
+
.map(line => line.slice(3).trim())
|
|
120
|
+
.filter(Boolean);
|
|
121
|
+
const values = new Set();
|
|
122
|
+
for (const path of paths) {
|
|
123
|
+
if (path.startsWith('apps/web/'))
|
|
124
|
+
values.add('frontend');
|
|
125
|
+
else if (path.startsWith('apps/server/'))
|
|
126
|
+
values.add('backend');
|
|
127
|
+
else if (path.startsWith('platform/data/'))
|
|
128
|
+
values.add('data');
|
|
129
|
+
else if (path.startsWith('platform/authz/'))
|
|
130
|
+
values.add('authz');
|
|
131
|
+
else if (path.startsWith('platform/events/'))
|
|
132
|
+
values.add('events');
|
|
133
|
+
else if (path.startsWith('platform/workflows/'))
|
|
134
|
+
values.add('workflow');
|
|
135
|
+
else
|
|
136
|
+
values.add('config');
|
|
137
|
+
}
|
|
138
|
+
return [...values];
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=workspace-loader.js.map
|