@yss123/cage-kernel 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -9
- package/dist/authorization.d.ts +34 -0
- package/dist/authorization.js +89 -0
- package/dist/authorization.js.map +1 -0
- package/dist/brands.d.ts +10 -0
- package/dist/brands.js +11 -1
- package/dist/brands.js.map +1 -1
- package/dist/db/connect.d.ts +14 -0
- package/dist/db/connect.js +18 -2
- package/dist/db/connect.js.map +1 -1
- package/dist/db/ddl.d.ts +40 -1
- package/dist/db/ddl.js +111 -7
- package/dist/db/ddl.js.map +1 -1
- package/dist/db/event-version-schema.d.ts +9 -0
- package/dist/db/event-version-schema.js +10 -0
- package/dist/db/event-version-schema.js.map +1 -0
- package/dist/db/index.d.ts +4 -0
- package/dist/db/index.js +4 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrate.d.ts +10 -0
- package/dist/db/migrate.js +9 -1
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/rows.d.ts +2 -0
- package/dist/db/rows.js +6 -0
- package/dist/db/rows.js.map +1 -1
- package/dist/db/runtime-schema.d.ts +9 -0
- package/dist/db/runtime-schema.js +41 -0
- package/dist/db/runtime-schema.js.map +1 -0
- package/dist/db/session.d.ts +6 -0
- package/dist/db/session.js +6 -0
- package/dist/db/session.js.map +1 -1
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -1
- package/dist/files/links.d.ts +10 -0
- package/dist/files/links.js +50 -0
- package/dist/files/links.js.map +1 -0
- package/dist/files/schema.d.ts +9 -0
- package/dist/files/schema.js +51 -0
- package/dist/files/schema.js.map +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel.d.ts +88 -0
- package/dist/kernel.js +82 -41
- package/dist/kernel.js.map +1 -1
- package/dist/mask.d.ts +7 -1
- package/dist/mask.js +11 -0
- package/dist/mask.js.map +1 -1
- package/dist/org.d.ts +7 -0
- package/dist/org.js +5 -0
- package/dist/org.js.map +1 -1
- package/dist/pipeline/draft.d.ts +16 -0
- package/dist/pipeline/draft.js +39 -0
- package/dist/pipeline/draft.js.map +1 -0
- package/dist/pipeline/idempotency.d.ts +6 -0
- package/dist/pipeline/idempotency.js +6 -0
- package/dist/pipeline/idempotency.js.map +1 -1
- package/dist/pipeline/invoker.d.ts +9 -0
- package/dist/pipeline/invoker.js +22 -0
- package/dist/pipeline/invoker.js.map +1 -0
- package/dist/pipeline/load.d.ts +13 -0
- package/dist/pipeline/load.js +22 -6
- package/dist/pipeline/load.js.map +1 -1
- package/dist/primitives/aggregate.d.ts +95 -2
- package/dist/primitives/aggregate.js +15 -1
- package/dist/primitives/aggregate.js.map +1 -1
- package/dist/primitives/business-process.d.ts +128 -0
- package/dist/primitives/business-process.js +62 -0
- package/dist/primitives/business-process.js.map +1 -0
- package/dist/primitives/collection.d.ts +65 -0
- package/dist/primitives/collection.js +79 -0
- package/dist/primitives/collection.js.map +1 -0
- package/dist/primitives/command.d.ts +110 -11
- package/dist/primitives/command.js +16 -0
- package/dist/primitives/command.js.map +1 -1
- package/dist/primitives/constraints.d.ts +30 -1
- package/dist/primitives/constraints.js +14 -0
- package/dist/primitives/constraints.js.map +1 -1
- package/dist/primitives/event.d.ts +36 -0
- package/dist/primitives/event.js +12 -1
- package/dist/primitives/event.js.map +1 -1
- package/dist/primitives/fields.d.ts +176 -36
- package/dist/primitives/fields.js +134 -14
- package/dist/primitives/fields.js.map +1 -1
- package/dist/primitives/flow.d.ts +173 -8
- package/dist/primitives/flow.js +29 -2
- package/dist/primitives/flow.js.map +1 -1
- package/dist/primitives/states.d.ts +34 -2
- package/dist/primitives/states.js +15 -0
- package/dist/primitives/states.js.map +1 -1
- package/dist/read.d.ts +39 -3
- package/dist/read.js +193 -48
- package/dist/read.js.map +1 -1
- package/dist/registry.d.ts +51 -1
- package/dist/registry.js +105 -5
- package/dist/registry.js.map +1 -1
- package/dist/relations.d.ts +21 -0
- package/dist/relations.js +65 -0
- package/dist/relations.js.map +1 -0
- package/dist/runtime.d.ts +35 -0
- package/dist/runtime.js +9 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scope/index.d.ts +5 -0
- package/dist/scope/index.js +5 -0
- package/dist/scope/index.js.map +1 -1
- package/dist/telemetry.d.ts +8 -0
- package/dist/telemetry.js +28 -3
- package/dist/telemetry.js.map +1 -1
- package/dist/transfer/csv.d.ts +19 -0
- package/dist/transfer/csv.js +125 -0
- package/dist/transfer/csv.js.map +1 -0
- package/dist/transfer/index.d.ts +67 -0
- package/dist/transfer/index.js +271 -0
- package/dist/transfer/index.js.map +1 -0
- package/dist/transfer/schema.d.ts +9 -0
- package/dist/transfer/schema.js +36 -0
- package/dist/transfer/schema.js.map +1 -0
- package/dist/types.d.ts +38 -2
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/dist/util/names.d.ts +6 -0
- package/dist/util/names.js +6 -0
- package/dist/util/names.js.map +1 -1
- package/dist/worker/consumers.d.ts +7 -0
- package/dist/worker/consumers.js +21 -9
- package/dist/worker/consumers.js.map +1 -1
- package/dist/worker/health.d.ts +38 -0
- package/dist/worker/health.js +20 -0
- package/dist/worker/health.js.map +1 -0
- package/dist/worker/index.d.ts +34 -1
- package/dist/worker/index.js +176 -37
- package/dist/worker/index.js.map +1 -1
- package/dist/worker/outbox.d.ts +25 -2
- package/dist/worker/outbox.js +40 -2
- package/dist/worker/outbox.js.map +1 -1
- package/dist/worker/scheduler.d.ts +10 -1
- package/dist/worker/scheduler.js +34 -4
- package/dist/worker/scheduler.js.map +1 -1
- package/package.json +1 -1
package/dist/errors.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** 协议级错误到 HTTP 的唯一映射;业务细分原因放 domainCode,避免扩张协议枚举。 */
|
|
1
2
|
export declare const ERROR_HTTP: {
|
|
2
3
|
readonly UNAUTHENTICATED: 401;
|
|
3
4
|
readonly FORBIDDEN: 403;
|
|
@@ -12,6 +13,10 @@ export declare const ERROR_HTTP: {
|
|
|
12
13
|
readonly INTERNAL: 500;
|
|
13
14
|
};
|
|
14
15
|
export type CageErrorCode = keyof typeof ERROR_HTTP;
|
|
16
|
+
/**
|
|
17
|
+
* 可跨内核/HTTP 边界传递的预期失败。detail 只应包含允许对调用人公开的诊断信息;
|
|
18
|
+
* toJSON 不输出 Error 堆栈,服务端内部异常应交给日志系统单独记录。
|
|
19
|
+
*/
|
|
15
20
|
export declare class CageError extends Error {
|
|
16
21
|
readonly code: CageErrorCode;
|
|
17
22
|
readonly http: number;
|
|
@@ -25,7 +30,9 @@ export declare class CageError extends Error {
|
|
|
25
30
|
code: "UNAUTHENTICATED" | "FORBIDDEN" | "NOT_FOUND" | "INVALID_INPUT" | "INVALID_TRANSITION" | "CONSTRAINT_VIOLATED" | "INVARIANT_VIOLATED" | "CONFLICT" | "DOMAIN_ERROR" | "RATE_LIMITED" | "INTERNAL";
|
|
26
31
|
};
|
|
27
32
|
}
|
|
33
|
+
/** 创建协议错误但不抛出;调用者决定在哪一层终止事务或转换为结果对象。 */
|
|
28
34
|
export declare function cageError(code: CageErrorCode, detail?: unknown): CageError;
|
|
35
|
+
/** 同时识别本模块实例和跨包副本的结构化错误,避免重复安装破坏协议转换。 */
|
|
29
36
|
export declare function isCageError(e: unknown): e is CageError;
|
|
30
37
|
declare const DOMAIN: unique symbol;
|
|
31
38
|
/** handler 返回的业务错误。整个事务回滚,HTTP 返回 422 + 业务码。 */
|
|
@@ -36,8 +43,13 @@ export interface DomainError<C extends string = string> {
|
|
|
36
43
|
}
|
|
37
44
|
/** 在 handler 里返回业务错误:return fail('STOCK_SHORT', short) */
|
|
38
45
|
export declare function fail<C extends string>(code: C, detail?: unknown): DomainError<C>;
|
|
46
|
+
/** 使用全局 Symbol 识别 handler 的返回值,不把普通含 code 字段的数据当作拒绝。 */
|
|
39
47
|
export declare function isDomainError(v: unknown): v is DomainError;
|
|
40
48
|
/** 把任何异常转换成 CageError,不泄露堆栈。 */
|
|
49
|
+
/**
|
|
50
|
+
* 仅保留已知异常的公开语义:并发冲突可重试,约束错误属于输入问题;未知异常统一 INTERNAL。
|
|
51
|
+
* 这里不重试、不记审计,也不恢复事务,原调用层仍负责回滚和服务端诊断。
|
|
52
|
+
*/
|
|
41
53
|
export declare function toCageError(err: unknown): CageError;
|
|
42
54
|
/** 声明期错误(构建时抛出),带错误码,agent 可以查 docs/errors。 */
|
|
43
55
|
export declare function declError(code: string, message: string): Error;
|
package/dist/errors.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// 内核错误码:机器可读,前端与 agent 都按码处理(设计文档第 5 节)。
|
|
2
|
+
/** 协议级错误到 HTTP 的唯一映射;业务细分原因放 domainCode,避免扩张协议枚举。 */
|
|
2
3
|
export const ERROR_HTTP = {
|
|
3
4
|
UNAUTHENTICATED: 401,
|
|
4
5
|
FORBIDDEN: 403,
|
|
@@ -12,6 +13,10 @@ export const ERROR_HTTP = {
|
|
|
12
13
|
RATE_LIMITED: 429,
|
|
13
14
|
INTERNAL: 500,
|
|
14
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* 可跨内核/HTTP 边界传递的预期失败。detail 只应包含允许对调用人公开的诊断信息;
|
|
18
|
+
* toJSON 不输出 Error 堆栈,服务端内部异常应交给日志系统单独记录。
|
|
19
|
+
*/
|
|
15
20
|
export class CageError extends Error {
|
|
16
21
|
code;
|
|
17
22
|
http;
|
|
@@ -30,9 +35,11 @@ export class CageError extends Error {
|
|
|
30
35
|
return { code: this.code, ...(this.domainCode ? { domainCode: this.domainCode } : {}), detail: this.detail };
|
|
31
36
|
}
|
|
32
37
|
}
|
|
38
|
+
/** 创建协议错误但不抛出;调用者决定在哪一层终止事务或转换为结果对象。 */
|
|
33
39
|
export function cageError(code, detail) {
|
|
34
40
|
return new CageError(code, detail);
|
|
35
41
|
}
|
|
42
|
+
/** 同时识别本模块实例和跨包副本的结构化错误,避免重复安装破坏协议转换。 */
|
|
36
43
|
export function isCageError(e) {
|
|
37
44
|
return e instanceof CageError || (!!e && e.name === 'CageError' && typeof e.code === 'string');
|
|
38
45
|
}
|
|
@@ -41,10 +48,15 @@ const DOMAIN = Symbol.for('cage.domainError');
|
|
|
41
48
|
export function fail(code, detail) {
|
|
42
49
|
return Object.freeze({ [DOMAIN]: true, code, detail });
|
|
43
50
|
}
|
|
51
|
+
/** 使用全局 Symbol 识别 handler 的返回值,不把普通含 code 字段的数据当作拒绝。 */
|
|
44
52
|
export function isDomainError(v) {
|
|
45
53
|
return !!v && typeof v === 'object' && v[DOMAIN] === true;
|
|
46
54
|
}
|
|
47
55
|
/** 把任何异常转换成 CageError,不泄露堆栈。 */
|
|
56
|
+
/**
|
|
57
|
+
* 仅保留已知异常的公开语义:并发冲突可重试,约束错误属于输入问题;未知异常统一 INTERNAL。
|
|
58
|
+
* 这里不重试、不记审计,也不恢复事务,原调用层仍负责回滚和服务端诊断。
|
|
59
|
+
*/
|
|
48
60
|
export function toCageError(err) {
|
|
49
61
|
if (isCageError(err))
|
|
50
62
|
return err;
|
|
@@ -55,6 +67,8 @@ export function toCageError(err) {
|
|
|
55
67
|
return new CageError('INVALID_INPUT', anyErr.message);
|
|
56
68
|
if (anyErr?.statusCode === 429)
|
|
57
69
|
return new CageError('RATE_LIMITED');
|
|
70
|
+
if (anyErr?.statusCode === 413)
|
|
71
|
+
return new CageError('INVALID_INPUT', '请求体超过大小限制');
|
|
58
72
|
if (anyErr?.statusCode === 403 && /csrf/i.test(String(anyErr?.message)))
|
|
59
73
|
return new CageError('FORBIDDEN', 'CSRF');
|
|
60
74
|
if (anyErr?.statusCode === 404)
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Transaction } from 'kysely';
|
|
2
|
+
import type { AnyAggregate } from '../primitives/aggregate.js';
|
|
3
|
+
import type { Ctx } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 把已完成临时上传绑定到业务对象,或将被移除附件退回临时状态;全程处于主命令事务中。
|
|
6
|
+
* 先归一化 ID/拒绝重复,再按 ID 排序加锁,与清理任务争用同一行锁以避免刚绑定就被清掉。
|
|
7
|
+
* 新增必须属于当前真人、聚合、字段与目标对象,且状态 ready、未过期、符合当前字段政策。
|
|
8
|
+
* 移除只解绑,不立即删除字节;延长 24 小时临时期限后交由文件清理服务处理。
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeFileLinks(tx: Transaction<any>, agg: AnyAggregate, previous: Record<string, any>, next: Record<string, any>, ctx: Ctx): Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { cageError } from '../errors.js';
|
|
2
|
+
import { isFile } from '../primitives/fields.js';
|
|
3
|
+
/**
|
|
4
|
+
* 把已完成临时上传绑定到业务对象,或将被移除附件退回临时状态;全程处于主命令事务中。
|
|
5
|
+
* 先归一化 ID/拒绝重复,再按 ID 排序加锁,与清理任务争用同一行锁以避免刚绑定就被清掉。
|
|
6
|
+
* 新增必须属于当前真人、聚合、字段与目标对象,且状态 ready、未过期、符合当前字段政策。
|
|
7
|
+
* 移除只解绑,不立即删除字节;延长 24 小时临时期限后交由文件清理服务处理。
|
|
8
|
+
*/
|
|
9
|
+
export async function writeFileLinks(tx, agg, previous, next, ctx) {
|
|
10
|
+
const changes = [];
|
|
11
|
+
const ids = (value) => value == null ? [] : (Array.isArray(value) ? value : [value]);
|
|
12
|
+
for (const [key, field] of Object.entries(agg.fields))
|
|
13
|
+
if (isFile(field)) {
|
|
14
|
+
const old = ids(previous[key]), current = ids(next[key]).map(id => id.toLowerCase());
|
|
15
|
+
if (new Set(current).size !== current.length)
|
|
16
|
+
throw cageError('INVALID_INPUT', { field: key, message: '附件不能重复' });
|
|
17
|
+
next[key] = field.kind === 'files' ? current : current[0] ?? null;
|
|
18
|
+
changes.push({ key, added: current.filter(id => !old.includes(id)), removed: old.filter(id => !current.includes(id)) });
|
|
19
|
+
}
|
|
20
|
+
const all = [...new Set(changes.flatMap(c => [...c.added, ...c.removed]))].sort();
|
|
21
|
+
if (!all.length)
|
|
22
|
+
return;
|
|
23
|
+
const rows = await tx.selectFrom('sys.file_upload').selectAll().where('tenant_id', '=', ctx.tenantId).where('id', 'in', all).orderBy('id').forUpdate().execute();
|
|
24
|
+
const byId = new Map(rows.map(row => [row.id, row]));
|
|
25
|
+
for (const { key, added, removed } of changes) {
|
|
26
|
+
const policy = agg.fields[key].filePolicy;
|
|
27
|
+
for (const id of added) {
|
|
28
|
+
const row = byId.get(id);
|
|
29
|
+
if (!row || row.aggregate_name !== agg.name || row.field_name !== key ||
|
|
30
|
+
row.user_id !== (ctx.userId ?? ctx.onBehalfOf) || (row.target_id && row.target_id !== next.id))
|
|
31
|
+
throw cageError('NOT_FOUND');
|
|
32
|
+
if (row.status !== 'ready' || new Date(row.expires_at) <= new Date())
|
|
33
|
+
throw cageError('CONFLICT', '附件未完成、已绑定或已过期');
|
|
34
|
+
if (Number(row.bytes) > policy.maxBytes || !policy.accept.includes(row.content_type))
|
|
35
|
+
throw cageError('INVALID_INPUT', { field: key, message: '附件不符合当前字段限制' });
|
|
36
|
+
await tx.updateTable('sys.file_upload').set({ status: 'bound', bound_id: next.id }).where('id', '=', id).execute();
|
|
37
|
+
// 同一事务若试图把一个文件绑定到多个字段/对象,也会被拒绝。
|
|
38
|
+
row.status = 'bound';
|
|
39
|
+
row.bound_id = next.id;
|
|
40
|
+
}
|
|
41
|
+
for (const id of removed) {
|
|
42
|
+
const row = byId.get(id);
|
|
43
|
+
if (!row || row.status !== 'bound' || row.bound_id !== next.id || row.aggregate_name !== agg.name || row.field_name !== key)
|
|
44
|
+
throw cageError('CONFLICT', '附件关联不一致');
|
|
45
|
+
// 移除后保留一段时间供恢复;下载不再沿用原业务对象的权限。
|
|
46
|
+
await tx.updateTable('sys.file_upload').set({ status: 'ready', bound_id: null, expires_at: new Date(Date.now() + 86400_000) }).where('id', '=', id).execute();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/files/links.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAe,MAAM,yBAAyB,CAAC;AAG9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EAAoB,EAAE,GAAiB,EAAE,QAA6B,EAAE,IAAyB,EAAE,GAAQ;IAC9I,MAAM,OAAO,GAA0D,EAAE,CAAC;IAC1E,MAAM,GAAG,GAAG,CAAC,KAAc,EAAY,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAa,CAAC;IACpH,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAgB,CAAC;QAAE,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACnF,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YACrF,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM;gBAAE,MAAM,SAAS,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAClH,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1H,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClF,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,OAAO;IACxB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC;IACjK,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrD,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAI,GAAG,CAAC,MAAiB,CAAC,GAAG,CAAC,CAAC,UAAW,CAAC;QACvD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG;gBACjE,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE,CAAC;gBAAE,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;YACjI,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,EAAE;gBAAE,MAAM,SAAS,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YACnH,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;gBAAE,MAAM,SAAS,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;YAC/J,MAAM,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACnH,gCAAgC;YAChC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC;YAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QAC/C,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,cAAc,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG;gBACzH,MAAM,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACzC,+BAA+B;YAC/B,MAAM,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAChK,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 上传会话记录用户、目标命令/字段、字节政策和幂等摘要;bound 与 bound_id 的约束固定文件归属。
|
|
3
|
+
* 分片由 upload_id/number 唯一定位,token/lease_until 解决并发写入和中断恢复,storage_key 指向字节存储。
|
|
4
|
+
* bound 文件不按临时会话过期清理;SQL 是历史迁移,修改结构须追加迁移而非编辑字符串。
|
|
5
|
+
*/
|
|
6
|
+
export declare const FILE_MIGRATION: {
|
|
7
|
+
name: string;
|
|
8
|
+
sql: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// 追加系统迁移,文件字节不进入数据库、审计或 outbox。
|
|
2
|
+
/**
|
|
3
|
+
* 上传会话记录用户、目标命令/字段、字节政策和幂等摘要;bound 与 bound_id 的约束固定文件归属。
|
|
4
|
+
* 分片由 upload_id/number 唯一定位,token/lease_until 解决并发写入和中断恢复,storage_key 指向字节存储。
|
|
5
|
+
* bound 文件不按临时会话过期清理;SQL 是历史迁移,修改结构须追加迁移而非编辑字符串。
|
|
6
|
+
*/
|
|
7
|
+
export const FILE_MIGRATION = {
|
|
8
|
+
name: 'cage:0004_files',
|
|
9
|
+
sql: `
|
|
10
|
+
CREATE TABLE sys.file_upload (
|
|
11
|
+
id uuid PRIMARY KEY,
|
|
12
|
+
tenant_id uuid NOT NULL,
|
|
13
|
+
user_id uuid NOT NULL,
|
|
14
|
+
aggregate_name text NOT NULL,
|
|
15
|
+
field_name text NOT NULL,
|
|
16
|
+
command_name text NOT NULL,
|
|
17
|
+
target_id uuid,
|
|
18
|
+
filename text NOT NULL,
|
|
19
|
+
content_type text NOT NULL,
|
|
20
|
+
bytes bigint NOT NULL CHECK (bytes > 0),
|
|
21
|
+
part_bytes int NOT NULL CHECK (part_bytes > 0),
|
|
22
|
+
part_count int NOT NULL CHECK (part_count > 0),
|
|
23
|
+
storage text NOT NULL,
|
|
24
|
+
storage_key text,
|
|
25
|
+
status text NOT NULL CHECK (status IN ('uploading','completing','ready','bound','deleting','deleted')),
|
|
26
|
+
bound_id uuid,
|
|
27
|
+
operation_token uuid,
|
|
28
|
+
lease_until timestamptz,
|
|
29
|
+
pruned_at timestamptz,
|
|
30
|
+
idempotency_key text NOT NULL,
|
|
31
|
+
request_hash text NOT NULL,
|
|
32
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
33
|
+
expires_at timestamptz NOT NULL DEFAULT now() + interval '24 hours',
|
|
34
|
+
UNIQUE (tenant_id, user_id, idempotency_key),
|
|
35
|
+
CHECK ((status = 'bound') = (bound_id IS NOT NULL))
|
|
36
|
+
);
|
|
37
|
+
CREATE INDEX file_upload_owner_idx ON sys.file_upload(tenant_id, user_id, created_at DESC);
|
|
38
|
+
CREATE INDEX file_upload_expiry_idx ON sys.file_upload(expires_at) WHERE status <> 'bound';
|
|
39
|
+
CREATE TABLE sys.file_part (
|
|
40
|
+
upload_id uuid NOT NULL REFERENCES sys.file_upload(id),
|
|
41
|
+
number int NOT NULL CHECK (number > 0),
|
|
42
|
+
bytes int NOT NULL CHECK (bytes > 0),
|
|
43
|
+
sha256 text NOT NULL,
|
|
44
|
+
token uuid NOT NULL,
|
|
45
|
+
storage_key text,
|
|
46
|
+
lease_until timestamptz,
|
|
47
|
+
PRIMARY KEY (upload_id, number)
|
|
48
|
+
);
|
|
49
|
+
`,
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/files/schema.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,iBAAiB;IACvB,GAAG,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCN;CACA,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 公共入口按声明原语、执行服务和基础类型组织;业务应优先消费声明与受限运行接口。
|
|
3
|
+
* 数据库迁移/连接与 worker 生命周期另有子路径入口,浏览器只依赖生成契约和 client。
|
|
4
|
+
* 增加导出意味着扩大公开 API,应同步能力发现和学习资料,不能仅凭实现文件存在让应用深层导入。
|
|
5
|
+
*/
|
|
1
6
|
export * from './brands.js';
|
|
2
7
|
export * from './errors.js';
|
|
3
8
|
export * from './types.js';
|
|
4
|
-
export {
|
|
9
|
+
export { runtimeServices, type RuntimeDefinition, type RuntimeService } from './runtime.js';
|
|
10
|
+
export { Field, text, int, number, money, id, date, datetime, bool, enumOf, ref, hasMany, manyToMany, isRelation, file, files, isFile, list, json, isField, objectSchema, SENSITIVE_KINDS, type SensitiveKind, type FieldKind, type FieldMeta, type FilePolicy, type AnyField, type Fields, type FieldValues, type ValueOf, } from './primitives/fields.js';
|
|
5
11
|
export { states, isStates, DEFAULT_STATES, type StatesDef } from './primitives/states.js';
|
|
12
|
+
export { businessProcess, type BusinessProcess, type BusinessStage, type BusinessAction, type BusinessTransition } from './primitives/business-process.js';
|
|
6
13
|
export { aggregate, isAggregate, hasStates, hiddenFields, sensitiveFields, RESERVED_FIELDS, type Aggregate, type AnyAggregate, type Snapshot, type SnapshotOf, type StateOf, type FieldsOf, type FieldValuesOf, type SystemCols, } from './primitives/aggregate.js';
|
|
7
14
|
export { command, isCommand, idOnly, empty, type Command, type AnyCommand, type Reads, type ReadRepo, type DepsOf, type Draft, type HandlerCtx, type HandlerResult, type Invoker, type FindOptions, } from './primitives/command.js';
|
|
8
15
|
export { event, emit, isEvent, defaultPayload, type Event, type AnyEvent, type PayloadOf, type EmitSpec } from './primitives/event.js';
|
|
16
|
+
export { reactionEach, reactionInputs } from './primitives/collection.js';
|
|
9
17
|
export { sod, ceiling, stepUp, ok, violation, type Constraint, type ConstraintResult, type ConstraintMeta, } from './primitives/constraints.js';
|
|
10
18
|
export { reaction, query, approval, job, unsafe, daysAgo, type Reaction, type AnyReaction, type Query, type AnyQuery, type Approval, type Job, type JobApi, type JobQueryApi, type TxMode, type UnsafeTag, } from './primitives/flow.js';
|
|
11
19
|
export { scope, compileScope, compileGrant, scopeMatches, grantsFor, DEFAULT_GRANTS, type ScopeSpec } from './scope/index.js';
|
|
12
|
-
export { buildRegistry, type Registry, type RegisteredCommand, type CatalogEntry, type RegistryOptions, type RuntimeExtension } from './registry.js';
|
|
20
|
+
export { buildRegistry, registryFingerprint, type Registry, type RegisteredCommand, type CatalogEntry, type RegistryOptions, type RuntimeExtension } from './registry.js';
|
|
13
21
|
export { Kernel, createKernel, type KernelOptions, type AuditEntry, type BatchResult, type EmittedEvent } from './kernel.js';
|
|
22
|
+
export { explainAuthorization, type AuthorizationCheck } from './authorization.js';
|
|
14
23
|
export { ReadSide, compileNamedSql, type ListParams, type Page } from './read.js';
|
|
24
|
+
export { DataTransfers, importRequestSchema, type TransferTask } from './transfer/index.js';
|
|
15
25
|
export { maskValue, present, canUnmask, auditDiff } from './mask.js';
|
|
16
26
|
export { mergeCaps, mergeScopes, unmaskFrom, loadUserGrants, userCtx, anonymousCtx, systemCtx, type UserGrants, type RoleGrantRow } from './org.js';
|
|
17
27
|
export { step, traceCarrier, withCarrier, consoleLogger, silentLogger, type Logger } from './telemetry.js';
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
// @yss123/cage-kernel:声明原语、写入流水线、范围组合子、读侧上下文。不含任何业务名词。
|
|
2
|
+
/**
|
|
3
|
+
* 公共入口按声明原语、执行服务和基础类型组织;业务应优先消费声明与受限运行接口。
|
|
4
|
+
* 数据库迁移/连接与 worker 生命周期另有子路径入口,浏览器只依赖生成契约和 client。
|
|
5
|
+
* 增加导出意味着扩大公开 API,应同步能力发现和学习资料,不能仅凭实现文件存在让应用深层导入。
|
|
6
|
+
*/
|
|
2
7
|
export * from './brands.js';
|
|
3
8
|
export * from './errors.js';
|
|
4
9
|
export * from './types.js';
|
|
5
|
-
export {
|
|
10
|
+
export { runtimeServices } from './runtime.js';
|
|
11
|
+
export { Field, text, int, number, money, id, date, datetime, bool, enumOf, ref, hasMany, manyToMany, isRelation, file, files, isFile, list, json, isField, objectSchema, SENSITIVE_KINDS, } from './primitives/fields.js';
|
|
6
12
|
export { states, isStates, DEFAULT_STATES } from './primitives/states.js';
|
|
13
|
+
export { businessProcess } from './primitives/business-process.js';
|
|
7
14
|
export { aggregate, isAggregate, hasStates, hiddenFields, sensitiveFields, RESERVED_FIELDS, } from './primitives/aggregate.js';
|
|
8
15
|
export { command, isCommand, idOnly, empty, } from './primitives/command.js';
|
|
9
16
|
export { event, emit, isEvent, defaultPayload } from './primitives/event.js';
|
|
17
|
+
export { reactionEach, reactionInputs } from './primitives/collection.js';
|
|
10
18
|
export { sod, ceiling, stepUp, ok, violation, } from './primitives/constraints.js';
|
|
11
19
|
export { reaction, query, approval, job, unsafe, daysAgo, } from './primitives/flow.js';
|
|
12
20
|
export { scope, compileScope, compileGrant, scopeMatches, grantsFor, DEFAULT_GRANTS } from './scope/index.js';
|
|
13
|
-
export { buildRegistry } from './registry.js';
|
|
21
|
+
export { buildRegistry, registryFingerprint } from './registry.js';
|
|
14
22
|
export { Kernel, createKernel } from './kernel.js';
|
|
23
|
+
export { explainAuthorization } from './authorization.js';
|
|
15
24
|
export { ReadSide, compileNamedSql } from './read.js';
|
|
25
|
+
export { DataTransfers, importRequestSchema } from './transfer/index.js';
|
|
16
26
|
export { maskValue, present, canUnmask, auditDiff } from './mask.js';
|
|
17
27
|
export { mergeCaps, mergeScopes, unmaskFrom, loadUserGrants, userCtx, anonymousCtx, systemCtx } from './org.js';
|
|
18
28
|
export { step, traceCarrier, withCarrier, consoleLogger, silentLogger } from './telemetry.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAA+C,MAAM,cAAc,CAAC;AAC5F,OAAO,EACL,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAC/J,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAkB,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAA0F,MAAM,kCAAkC,CAAC;AAC3J,OAAO,EACL,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,GAElF,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,GAElC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAA4D,MAAM,uBAAuB,CAAC;AACvI,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EACL,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GACpC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAEhD,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAkB,MAAM,kBAAkB,CAAC;AAC9H,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAyG,MAAM,eAAe,CAAC;AAC1K,OAAO,EAAE,MAAM,EAAE,YAAY,EAA4E,MAAM,aAAa,CAAC;AAC7H,OAAO,EAAE,oBAAoB,EAA2B,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,eAAe,EAA8B,MAAM,WAAW,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAqB,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAsC,MAAM,UAAU,CAAC;AACpJ,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAe,MAAM,gBAAgB,CAAC;AAC3G,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAqB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/kernel.d.ts
CHANGED
|
@@ -7,80 +7,167 @@ import { ReadSide } from './read.js';
|
|
|
7
7
|
import { type RegisteredCommand, type Registry, type RegistryOptions } from './registry.js';
|
|
8
8
|
import { type Logger } from './telemetry.js';
|
|
9
9
|
import type { CapabilityParams, Ctx } from './types.js';
|
|
10
|
+
import { DataTransfers } from './transfer/index.js';
|
|
11
|
+
/** 内核实例配置;传 db 时连接归宿主所有,传 urls 时内核自行创建并在 close 时销毁池。 */
|
|
10
12
|
export interface KernelOptions {
|
|
11
13
|
/** domain 包的导出(可以是多个模块,例如框架自带的组织模型 + 业务声明) */
|
|
12
14
|
domain: object | object[];
|
|
13
15
|
/** 数据库连接串;或者直接传入已有的连接 */
|
|
14
16
|
urls?: DatabaseUrls;
|
|
17
|
+
/** 宿主注入的写库与只读库句柄;提供后优先于 urls,close 不销毁这些外部连接。 */
|
|
15
18
|
db?: {
|
|
16
19
|
app: Kysely<any>;
|
|
17
20
|
read: Kysely<any>;
|
|
18
21
|
};
|
|
22
|
+
/** 注册表的额外能力等选项;不用于运行期动态改变角色授权。 */
|
|
19
23
|
registryOptions?: RegistryOptions;
|
|
24
|
+
/** 结构化日志实现;省略时使用默认 consoleLogger,调用方仍不能在元数据中塞入敏感业务原文。 */
|
|
20
25
|
logger?: Logger;
|
|
21
26
|
/** 同事务反应的最大嵌套深度 */
|
|
22
27
|
maxReactionDepth?: number;
|
|
23
28
|
/** 连接池大小 */
|
|
24
29
|
poolSize?: number;
|
|
25
30
|
}
|
|
31
|
+
/** 当前事务已登记的事件,含 outbox ID;事务尚未提交时不可将其视为外部已收到的事实。 */
|
|
26
32
|
export interface EmittedEvent {
|
|
33
|
+
/** 同事务写入的 outbox 数字 ID,用于关联投递记录;不是业务对象 ID。 */
|
|
27
34
|
outboxId: number;
|
|
35
|
+
/** 已注册的事件名称,决定匹配哪些消费者。 */
|
|
28
36
|
event: string;
|
|
37
|
+
/** 通过事件 schema 校验的业务载荷,仅供内部消费者使用,不可直接作为公共诊断响应。 */
|
|
29
38
|
payload: Record<string, unknown>;
|
|
30
39
|
}
|
|
40
|
+
/** index 为输入行的 0 基索引;atomic 模式任一失败会把其余行标为已回滚,不能交付暂存成功结果。 */
|
|
31
41
|
export interface BatchResult {
|
|
42
|
+
/** 输入 rows 中从零开始的位置,调用方据此对应原始导入行。 */
|
|
32
43
|
index: number;
|
|
44
|
+
/** 该行最终是否成功提交;整批原子失败时此前暂存成功也会被改为失败。 */
|
|
33
45
|
ok: boolean;
|
|
46
|
+
/** 成功时可交付的记录快照,已按主体权限处理敏感字段;失败时省略。 */
|
|
34
47
|
data?: Record<string, unknown>;
|
|
48
|
+
/** 失败时的框架错误码、可选领域码和详情;不包含成功数据。 */
|
|
35
49
|
error?: {
|
|
36
50
|
code: string;
|
|
37
51
|
domainCode?: string;
|
|
38
52
|
detail?: unknown;
|
|
39
53
|
};
|
|
40
54
|
}
|
|
55
|
+
/** 审计写入规格;diff/client 必须由可信调用方脱敏,writeAudit 不推断业务字段的敏感政策。 */
|
|
41
56
|
export interface AuditEntry {
|
|
57
|
+
/** 审计所属租户,必须来自可信执行上下文。 */
|
|
42
58
|
tenantId: string;
|
|
59
|
+
/** 实际执行主体标识,可能是真人用户 ID 或流程/任务身份名。 */
|
|
43
60
|
actor: string;
|
|
61
|
+
/** 执行主体种类,与 actor 共同解释身份;不能仅凭字符串把系统主体当作真人。 */
|
|
44
62
|
actorKind: string;
|
|
63
|
+
/** 系统执行代表的真人 ID;没有委托时省略或 null。 */
|
|
45
64
|
onBehalfOf?: string | null;
|
|
65
|
+
/** 触发入口来源,如 api、process、job、external;用于追踪,不授予权限。 */
|
|
46
66
|
source: string;
|
|
67
|
+
/** write 业务写审计、read 读取审计、denied 拒绝记录、ops 运维动作。 */
|
|
47
68
|
kind: 'write' | 'read' | 'denied' | 'ops';
|
|
69
|
+
/** 本次操作关联的能力名;无单一能力时可空。 */
|
|
48
70
|
capability?: string | null;
|
|
71
|
+
/** 关联的完整命令名;读取或普通运维事件可空。 */
|
|
49
72
|
command?: string | null;
|
|
73
|
+
/** 关联聚合名;无具体业务对象时可空。 */
|
|
50
74
|
aggregate?: string | null;
|
|
75
|
+
/** 单一关联记录 ID;多记录读取或无对象时可空。 */
|
|
51
76
|
aggregateId?: string | null;
|
|
77
|
+
/** 执行结论或机器错误码,由调用者按实际提交/拒绝结果填写。 */
|
|
52
78
|
result: string;
|
|
79
|
+
/** 经调用方脱敏的变化或操作摘要;writeAudit 不替调用方恢复字段策略。 */
|
|
53
80
|
diff?: unknown;
|
|
81
|
+
/** 跨 HTTP、命令和异步事件关联的追踪标识;省略或 null 表示未提供。 */
|
|
54
82
|
requestId?: string | null;
|
|
83
|
+
/** 本次逻辑提交的去重键,仅记录审计关联,不在本方法执行去重。 */
|
|
55
84
|
idempotencyKey?: string | null;
|
|
85
|
+
/** 调用方允许记录的客户端摘要,例如 IP/UA;不得包含 Cookie、密码或完整请求体。 */
|
|
56
86
|
client?: unknown;
|
|
57
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* 领域写入的统一执行器。权限、版本、状态、约束、不变量、关联、审计和事件在此汇合,
|
|
90
|
+
* 业务 handler 仅计算字段变化,不能越过这些阶段。读服务使用独立账号,worker 复用注册规格。
|
|
91
|
+
* 实例关闭只释放自身创建的池;运行时扩展和 worker 的生命周期由其装配方先行停止。
|
|
92
|
+
*/
|
|
58
93
|
export declare class Kernel {
|
|
94
|
+
/** 解释能力、范围、状态及约束的当前证据,不执行 handler 或提交业务写入;结果不是未来执行一定成功的承诺。 */
|
|
95
|
+
explain(capability: string, input: Record<string, unknown>, ctx: Ctx): Promise<{
|
|
96
|
+
command: string;
|
|
97
|
+
actor: import("./types.js").Actor | null;
|
|
98
|
+
observedAt: string;
|
|
99
|
+
allowed: boolean;
|
|
100
|
+
checks: import("./authorization.js").AuthorizationCheck[];
|
|
101
|
+
scope?: undefined;
|
|
102
|
+
params?: undefined;
|
|
103
|
+
limitations?: undefined;
|
|
104
|
+
} | {
|
|
105
|
+
command: string;
|
|
106
|
+
actor: import("./types.js").Actor | null;
|
|
107
|
+
observedAt: string;
|
|
108
|
+
allowed: boolean | null;
|
|
109
|
+
checks: import("./authorization.js").AuthorizationCheck[];
|
|
110
|
+
scope: import("./types.js").ScopeGrant[];
|
|
111
|
+
params: CapabilityParams;
|
|
112
|
+
limitations: string[];
|
|
113
|
+
}>;
|
|
114
|
+
/** 由 domain 导出建立的运行规格,供命令解析、读侧、DDL 和 worker 共享。 */
|
|
59
115
|
readonly registry: Registry;
|
|
116
|
+
/** 内部写账号连接;业务应用应走命令,不能据此绕过流水线直接写表。 */
|
|
60
117
|
readonly app: Kysely<any>;
|
|
118
|
+
/** 只读账号连接,用于 safe 视图事务;不能用写账号代替以省略数据库权限隔离。 */
|
|
61
119
|
readonly readDb: Kysely<any>;
|
|
120
|
+
/** 按当前 Ctx 授权、范围与掩码读取的公共读服务。 */
|
|
62
121
|
readonly read: ReadSide;
|
|
122
|
+
/** 后台导入导出协调器,任务状态和结果文件不等同于单次同步读写返回。 */
|
|
123
|
+
readonly transfers: DataTransfers;
|
|
124
|
+
/** 实例日志出口,用于安全元数据与机器码,不传未经处理的敏感业务数据。 */
|
|
63
125
|
readonly log: Logger;
|
|
64
126
|
private readonly handles;
|
|
65
127
|
private readonly maxDepth;
|
|
66
128
|
constructor(opts: KernelOptions);
|
|
129
|
+
/** 释放由本实例创建的数据库句柄;外部注入 db 不在 handles 中,不会被擅自销毁。 */
|
|
67
130
|
close(): Promise<void>;
|
|
131
|
+
/** 按能力字符串或声明对象解析命令;未从 domain 导出时明确报错,不动态注册陌生命令。 */
|
|
68
132
|
resolve(ref: string | AnyCommand): RegisteredCommand;
|
|
69
133
|
/** 执行一个命令(自己开事务)。返回按当前主体掩码后的新快照。 */
|
|
134
|
+
/**
|
|
135
|
+
* 事务拥有者:run 任一阶段失败都会回滚,最终返回掩码后的结果或已提交幂等回放。
|
|
136
|
+
* 预期拒绝转换为统一错误;部分拒绝另做尽力审计,审计失败不改变原请求的拒绝结论。
|
|
137
|
+
*/
|
|
70
138
|
execute(ref: string | AnyCommand, raw: unknown, ctx: Ctx): Promise<Record<string, any>>;
|
|
71
139
|
/** 在已有事务里执行(同事务反应、审批桥接、批量整批原子模式用)。返回未掩码的快照。 */
|
|
140
|
+
/** 外层持有提交权;返回完整内部快照只供受信任框架流程使用,不可直接写入 HTTP 响应。 */
|
|
72
141
|
executeIn(tx: Transaction<any>, ref: string | AnyCommand, raw: unknown, ctx: Ctx, depth?: number): Promise<Record<string, any>>;
|
|
142
|
+
/** 可选服务在同一事务登记执行回执时使用;只返回可交付字段,避免泄漏内部快照。 */
|
|
143
|
+
executePresentedIn(tx: Transaction<any>, ref: string | AnyCommand, raw: unknown, ctx: Ctx): Promise<Record<string, any>>;
|
|
73
144
|
/** 批量写入:每一行都完整走 12 关;默认逐行独立提交,可选整批原子。批量没有快捷路径。 */
|
|
74
145
|
executeBatch(ref: string | AnyCommand, rows: unknown[], ctx: Ctx, opts?: {
|
|
75
146
|
atomic?: boolean;
|
|
76
147
|
}): Promise<BatchResult[]>;
|
|
148
|
+
/**
|
|
149
|
+
* 完整事务流水线:输入/身份→幂等→加锁加载→状态/版本→硬约束→受限 handler→合并/不变量→持久化。
|
|
150
|
+
* 写记录、关系、附件、成功审计、outbox 和 same 反应共同提交;任何失败都必须传播到事务拥有者。
|
|
151
|
+
* depth 限制同事务递归,只在最外层使用请求幂等键,避免不同反应错误共享同一回放结果。
|
|
152
|
+
* next 是内部完整快照,presented 是可交付快照,replay 是已有请求结果,三者用途不可混淆。
|
|
153
|
+
*/
|
|
77
154
|
private run;
|
|
155
|
+
/**
|
|
156
|
+
* 在业务事务内映射并校验每个事件,遮盖敏感载荷后持久化提交版本、真人委托与追踪上下文。
|
|
157
|
+
* 任一映射/schema 错误使整个命令回滚;NOTIFY 也随事务提交生效,不会唤醒 worker 消费未提交数据。
|
|
158
|
+
*/
|
|
78
159
|
private enqueueEvents;
|
|
160
|
+
/**
|
|
161
|
+
* 只负责持久化审计,不吞异常。传事务时与业务共同提交;可靠读审计失败应阻止交付明文。
|
|
162
|
+
* 拒绝审计等尽力路径由上层自行 catch,不能在此统一忽略错误而破坏成功写入的审计保证。
|
|
163
|
+
*/
|
|
79
164
|
writeAudit(db: Transaction<any> | Kysely<any>, e: AuditEntry): Promise<void>;
|
|
80
165
|
/** 被拒绝的尝试异步记录,用于发现探测和配置问题;记录失败不影响请求 */
|
|
81
166
|
auditDenied(rc: RegisteredCommand, raw: unknown, ctx: Ctx, err: CageError): Promise<void>;
|
|
82
167
|
private catalogCache?;
|
|
168
|
+
/** 当前实例注册表固定,故可缓存能力名称;角色实际授权仍需按用户从数据库读取。 */
|
|
83
169
|
catalogCaps(): string[];
|
|
170
|
+
/** 实时加载真人能力供额度约束使用;用户不存在或禁用时返回空集合。 */
|
|
84
171
|
capabilitiesOf(userId: string, tenantId: string): Promise<Map<string, CapabilityParams>>;
|
|
85
172
|
/** 把一个用户解析成上下文(HTTP 层会加缓存) */
|
|
86
173
|
contextFor(userId: string, tenantId: string, extra?: Partial<Ctx>): Promise<Ctx | null>;
|
|
@@ -93,5 +180,6 @@ export declare class Kernel {
|
|
|
93
180
|
requestId?: string;
|
|
94
181
|
}): Ctx;
|
|
95
182
|
}
|
|
183
|
+
/** 构造注册表、连接句柄及读/传输服务;不会自动迁移、初始化组织或启动 worker。 */
|
|
96
184
|
export declare function createKernel(opts: KernelOptions): Kernel;
|
|
97
185
|
export type { AnyAggregate };
|