weifuwu 0.90.0 → 0.91.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 +4 -2
- package/dist/client/components/WordCloud/WordCloud.d.ts +79 -0
- package/dist/client/components/index.d.ts +2 -0
- package/dist/client/components/index.js +33 -33
- package/dist/client/components/style.css +95 -1
- package/dist/client/layout/weifuwu-layout.css +19 -0
- package/dist/client/vdom/core/v2/diff.d.ts +2 -2
- package/dist/client/vdom/hooks/env.d.ts +20 -0
- package/dist/client/vdom/index.js +3 -3
- package/dist/client/vdom/testing.js +2 -2
- package/dist/server/ai/approvals.d.ts +24 -0
- package/dist/server/ai/assemble.d.ts +19 -0
- package/dist/server/ai/client.d.ts +22 -0
- package/dist/server/ai/contracts.d.ts +67 -2
- package/dist/server/ai/index.d.ts +14 -43
- package/dist/server/ai/memory-server.d.ts +50 -0
- package/dist/server/ai/memory.d.ts +46 -0
- package/dist/server/ai/multimodal.d.ts +52 -0
- package/dist/server/ai/openai.d.ts +16 -0
- package/dist/server/db/body.d.ts +31 -0
- package/dist/server/db/consistency.d.ts +28 -0
- package/dist/server/db/contracts.d.ts +3 -27
- package/dist/server/db/filter.d.ts +24 -0
- package/dist/server/db/gql-from-shape.d.ts +42 -0
- package/dist/server/db/http.d.ts +38 -0
- package/dist/server/db/memory-sql.d.ts +66 -8
- package/dist/server/db/ops.d.ts +70 -0
- package/dist/server/db/orm.d.ts +110 -0
- package/dist/server/db/query-builder.d.ts +4 -2
- package/dist/server/db/query.d.ts +90 -32
- package/dist/server/db/rest-from-shape.d.ts +56 -0
- package/dist/server/db/schema.d.ts +78 -0
- package/dist/server/db/server.d.ts +0 -2
- package/dist/server/db/shape.d.ts +131 -0
- package/dist/server/db/typed-query.d.ts +113 -0
- package/dist/server/email/api.d.ts +15 -0
- package/dist/server/email/contracts.d.ts +8 -3
- package/dist/server/email/index.d.ts +23 -30
- package/dist/server/email/memory-email-server.d.ts +43 -0
- package/dist/server/email/memory-email.d.ts +30 -0
- package/dist/server/index.d.ts +33 -10
- package/dist/server/index.js +9843 -4133
- package/dist/server/messager/index.d.ts +133 -12
- package/dist/server/postgres/client.d.ts +4 -4
- package/dist/server/postgres/types.d.ts +33 -13
- package/dist/server/redis/types.d.ts +2 -0
- package/dist/server/response.d.ts +3 -3
- package/dist/server/types.d.ts +2 -5
- package/dist/server/user/app-auth.d.ts +74 -0
- package/dist/server/user/index.d.ts +277 -5
- package/dist/server/workflow/contracts.d.ts +202 -0
- package/dist/server/workflow/expression.d.ts +89 -0
- package/dist/server/workflow/index.d.ts +70 -0
- package/dist/server/workflow/index.js +2476 -0
- package/dist/server/workflow/runner.d.ts +19 -0
- package/dist/server/workflow/std.d.ts +27 -0
- package/dist/server/workflow/steps.d.ts +12 -0
- package/dist/server/workflow/store.d.ts +19 -0
- package/dist/server/workflow/tojs.d.ts +28 -0
- package/dist/server/workflow/validate.d.ts +23 -0
- package/dist/server/workflow/views.d.ts +66 -0
- package/dist/server/workflow/wfjs.d.ts +27 -0
- package/dist/server/workflows/cron.d.ts +16 -0
- package/dist/server/workflows/index.d.ts +267 -0
- package/dist/shared/zod.d.ts +351 -0
- package/docs/client.md +6 -0
- package/docs/server.md +455 -11
- package/package.json +9 -3
- package/dist/server/db/postgres-server.d.ts +0 -39
- package/dist/server/db/sql-parser.d.ts +0 -24
- package/dist/server/db/test-servers.d.ts +0 -21
- package/dist/server/email/smtp.d.ts +0 -34
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Query } from './query.ts';
|
|
2
|
+
import type { QueryResult } from './contracts.ts';
|
|
3
|
+
import type { ZodRawShape } from '../../shared/zod.ts';
|
|
4
|
+
import { type GqlShapeOptions, type GqlShapeOutput } from './gql-from-shape.ts';
|
|
5
|
+
import type { SelectBuilder, InsertBuilder, UpdateBuilder, DeleteBuilder, QueryBuilder } from './query.ts';
|
|
6
|
+
import type { Infer } from '../../shared/zod.ts';
|
|
7
|
+
export interface DbAdapter {
|
|
8
|
+
/** Query AST 执行(业务主路) */
|
|
9
|
+
executeQuery(q: Query): Promise<QueryResult>;
|
|
10
|
+
/** 事务(同连接执行 fn——postgres 真事务;memory 无事务面(no-op 等价标注) */
|
|
11
|
+
transaction?<T>(fn: (execute: (q: Query) => Promise<QueryResult>) => Promise<T>): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
/** 行类型(shape 字段名 → zod Infer——编译期类型安全) */
|
|
14
|
+
export type RowOf<S extends ZodRawShape> = {
|
|
15
|
+
[K in keyof S]: Infer<S[K]>;
|
|
16
|
+
};
|
|
17
|
+
export interface OrmTable<S extends ZodRawShape> {
|
|
18
|
+
/** 列引用表(类型收窄:eq(Agent.c.type, 'ai')——值类型绑定列类型·编译期) */
|
|
19
|
+
c: {
|
|
20
|
+
[K in keyof S]: {
|
|
21
|
+
ref: string;
|
|
22
|
+
readonly __out: import('../../shared/zod.ts').Infer<S[K]>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/** 查询入口(select(cols?)——builder 链·行类型 RowOf<S>) */
|
|
26
|
+
select(...cols: string[]): SelectBuilder<RowOf<S>>;
|
|
27
|
+
/** 插入入口(values 单行或数组——shape 校验/列名翻译 orm 内部接线) */
|
|
28
|
+
insert(values: Record<string, unknown> | Record<string, unknown>[]): InsertBuilder<RowOf<S>>;
|
|
29
|
+
/** 更新入口(patch 部分更新) */
|
|
30
|
+
update(patch: Record<string, unknown>): UpdateBuilder<RowOf<S>>;
|
|
31
|
+
/** 删除入口(必须 where——builder 层防护) */
|
|
32
|
+
delete(): DeleteBuilder<RowOf<S>>;
|
|
33
|
+
/** 存在检查(isMember 样板收口——limit 1 短路) */
|
|
34
|
+
exists(where: import('./query.ts').WhereExpr): Promise<boolean>;
|
|
35
|
+
/** 列表模式(count+list 双查收口——平台列表面样板) */
|
|
36
|
+
paginate(opts: {
|
|
37
|
+
filter?: import('./query.ts').WhereExpr;
|
|
38
|
+
/** W3:sort 字段类型化(keyof S——字面量多余键编译红) */
|
|
39
|
+
sort?: {
|
|
40
|
+
field: keyof S & string;
|
|
41
|
+
dir?: 'asc' | 'desc';
|
|
42
|
+
}[];
|
|
43
|
+
limit?: number;
|
|
44
|
+
offset?: number;
|
|
45
|
+
}): Promise<{
|
|
46
|
+
rows: RowOf<S>[];
|
|
47
|
+
total: number;
|
|
48
|
+
}>;
|
|
49
|
+
/** shape 定义(元数据/变体/校验——业务类型注入) */
|
|
50
|
+
shapeDef: S;
|
|
51
|
+
/** 内部 shape 实体(gql 元数据消费) */
|
|
52
|
+
readonly __shape: import('./shape.ts').Shape<S>;
|
|
53
|
+
}
|
|
54
|
+
/** 租户 scope 配置(withCtx 自动注入面——平台 47 处手写 app_id 过滤收口) */
|
|
55
|
+
export interface OrmTenant {
|
|
56
|
+
/** scope 字段(shape 字段名) */
|
|
57
|
+
field: string;
|
|
58
|
+
/** 上下文取值(每请求 appId 等) */
|
|
59
|
+
value: (ctx: unknown) => string | undefined;
|
|
60
|
+
}
|
|
61
|
+
export interface CtxOrm extends Orm {
|
|
62
|
+
/** 租户 scope 表(自动 where/注入)——派生面 table(name) 免 shapeDef */
|
|
63
|
+
ctxTable<S extends ZodRawShape>(name: string, shapeDef: S): OrmTable<S>;
|
|
64
|
+
ctxTable(name: string): OrmTable<ZodRawShape>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 租户绑定视图:ctx.orm = orm.withCtx(ctx)——表操作自动 scope
|
|
68
|
+
* (select/update/delete 预置 where·insert 注入 field——与用户条件 AND 合并)
|
|
69
|
+
*/
|
|
70
|
+
export interface Orm {
|
|
71
|
+
/** 表注册(shape 驱动——列引用/校验/变体)——同名表幂等返回;
|
|
72
|
+
* 派生面(tx/ctx)用 table(name) 免 shapeDef(共享 registry) */
|
|
73
|
+
table<S extends ZodRawShape>(name: string, shapeDef: S): OrmTable<S>;
|
|
74
|
+
table(name: string): OrmTable<ZodRawShape>;
|
|
75
|
+
/** 租户绑定视图(ctx→自动 scope——select/insert/update/delete 预置 tenant 条件) */
|
|
76
|
+
withCtx(ctx: unknown): CtxOrm;
|
|
77
|
+
/** 兜底查询面(复杂 JOIN/嵌套——builder 原生) */
|
|
78
|
+
query: QueryBuilder;
|
|
79
|
+
/** GraphQL 生成(shape → SDL + resolvers——内置链路输入) */
|
|
80
|
+
gql<S extends ZodRawShape>(table: OrmTable<S>, opts?: GqlShapeOptions): GqlShapeOutput;
|
|
81
|
+
/** RESTful 面(W4——restFromShape 入口对称:`rest = orm.rest(table); rest.mount(app, base)`) */
|
|
82
|
+
rest<S extends ZodRawShape>(table: OrmTable<S>, opts?: import('./rest-from-shape.ts').RestShapeOptions): import('./rest-from-shape.ts').RestShapeOutput;
|
|
83
|
+
/** 事务(fn 内同连接执行——commit 可见/rollback 撤销;memory 单线程 no-op 等价) */
|
|
84
|
+
transaction<T>(fn: (tx: Orm) => Promise<T>): Promise<T>;
|
|
85
|
+
/** AST 执行面(协议层 = AST——Query 纯数据可序列化;测试播种/嵌入执行入口) */
|
|
86
|
+
execute(q: Query): Promise<QueryResult>;
|
|
87
|
+
/** 注册表枚举(state-machine 透明化——checkConsistency 输入面/诊断可见) */
|
|
88
|
+
tables(): {
|
|
89
|
+
name: string;
|
|
90
|
+
fields: Record<string, unknown>;
|
|
91
|
+
dbFields: Record<string, {
|
|
92
|
+
column?: string;
|
|
93
|
+
}>;
|
|
94
|
+
}[];
|
|
95
|
+
}
|
|
96
|
+
export declare function createOrm(adapter: DbAdapter, tenant?: OrmTenant): Orm;
|
|
97
|
+
/** postgres adapter:Query AST → compileQuery(参数化 SQL)→ 服务器(PG wire) */
|
|
98
|
+
export declare function postgresAdapter(pool: {
|
|
99
|
+
query: (sql: string, params?: unknown[]) => Promise<QueryResult>;
|
|
100
|
+
}, compile: (q: Query) => {
|
|
101
|
+
sql: string;
|
|
102
|
+
params: unknown[];
|
|
103
|
+
}): DbAdapter;
|
|
104
|
+
/** memory adapter:Query AST → 内存引擎直执行(fuzz 对账保证与 PG 等价) */
|
|
105
|
+
export declare function memoryAdapter(engine: {
|
|
106
|
+
executeQuery(q: Query): QueryResult;
|
|
107
|
+
/** 事务快照/回滚(MemorySql 提供——无则 no-op 等价标注) */
|
|
108
|
+
snapshot?(): unknown;
|
|
109
|
+
restore?(snap: unknown): void;
|
|
110
|
+
}): DbAdapter;
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
* await sql.query.insert('users').values({ email: 'a@b.c' }).returning('id').run()
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
|
-
import type {
|
|
13
|
+
import type { Row } from './contracts.ts';
|
|
14
14
|
import { type Query, type QueryBuilder } from './query.ts';
|
|
15
15
|
type Executor = (q: Query) => Promise<Row[]>;
|
|
16
|
-
export declare function createQueryBuilder(
|
|
16
|
+
export declare function createQueryBuilder(exec: Executor): QueryBuilder;
|
|
17
|
+
/** AST 构建工厂(协议层 = AST——无执行:toQuery() 产出纯数据 Query 供传输/嵌入执行) */
|
|
18
|
+
export declare function buildQuery(): QueryBuilder;
|
|
17
19
|
export {};
|
|
@@ -5,12 +5,18 @@ export interface RawSql {
|
|
|
5
5
|
}
|
|
6
6
|
/** 逃生舱:`sql.raw\`created_at > NOW() - interval '7 days'\`` */
|
|
7
7
|
export declare function rawSql(sql: string, params?: unknown[]): RawSql;
|
|
8
|
+
/** 算子值标量(列条件值——不允许裸标量/数组/null 形态直接做 WhereField) */
|
|
8
9
|
export type WhereScalar = string | number | boolean | null;
|
|
9
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* 列级条件操作符(唯一形态——算子模式):列 = 算子对象。
|
|
12
|
+
* 约定(2027-10 表达清理):值形态不再接受标量/数组/null——等值用 `{ eq: v }`·
|
|
13
|
+
* IN 用 `{ in: [...] }`·NULL 判定用 `{ isNull: true/false }`——语义显式无歧义
|
|
14
|
+
* (旧歧义:数组既是 IN 又是 jsonb 数组值;`= NULL` 恒假 vs 内存判 true)。
|
|
15
|
+
*/
|
|
10
16
|
export interface ColOps {
|
|
11
17
|
/** 列引用(非字面量):`{ 'u.email': { col: 'o.user_id' } }` → u.email = o.user_id */
|
|
12
18
|
col?: string;
|
|
13
|
-
/**
|
|
19
|
+
/** 等值 */
|
|
14
20
|
eq?: WhereScalar;
|
|
15
21
|
gt?: WhereScalar;
|
|
16
22
|
gte?: WhereScalar;
|
|
@@ -25,7 +31,10 @@ export interface ColOps {
|
|
|
25
31
|
isNull?: boolean;
|
|
26
32
|
between?: [WhereScalar, WhereScalar];
|
|
27
33
|
}
|
|
28
|
-
|
|
34
|
+
/** 算子键集(jsonb 深度等值判定:无任一算子键的对象 → 按值深度比较) */
|
|
35
|
+
export declare const COL_OPS_KEYS: readonly ["col", "eq", "gt", "gte", "lt", "lte", "ne", "in", "notIn", "like", "ilike", "isNull", "between"];
|
|
36
|
+
/** 列条件值(唯一形态):算子对象 | jsonb 值对象(无算子键——深度等值)——raw where 已删(W3a) */
|
|
37
|
+
export type WhereField = ColOps | Record<string, unknown>;
|
|
29
38
|
/**
|
|
30
39
|
* WHERE 表达式:列条件 AND 连接。
|
|
31
40
|
* 结构键:`or: WhereExpr[]`(OR 组——组间 AND)、`and: WhereExpr[]`(AND 组——
|
|
@@ -74,16 +83,16 @@ export interface SelectQuery {
|
|
|
74
83
|
fn: 'count' | 'sum' | 'avg' | 'min' | 'max';
|
|
75
84
|
col: string;
|
|
76
85
|
as: string;
|
|
86
|
+
filter?: WhereExpr;
|
|
77
87
|
}[];
|
|
78
88
|
/** count(*) 聚合(SQL parser 产出——SELECT count(*) FROM t)——结果为单行 { count } */
|
|
79
89
|
count?: boolean;
|
|
80
|
-
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
where?: string;
|
|
90
|
+
/** pgvector 相似度排序(列投影:`1 - (col <=> vec) as as` + ORDER BY col <=> vec)——
|
|
91
|
+
* 平台知识检索唯一向量面(业务零 SQL——向量为 pgvector 特化存储) */
|
|
92
|
+
vector?: {
|
|
93
|
+
col: string;
|
|
94
|
+
vec: number[];
|
|
95
|
+
as: string;
|
|
87
96
|
};
|
|
88
97
|
}
|
|
89
98
|
export interface InsertQuery {
|
|
@@ -91,10 +100,14 @@ export interface InsertQuery {
|
|
|
91
100
|
table: string;
|
|
92
101
|
rows: Row[];
|
|
93
102
|
returning?: string[] | '*';
|
|
94
|
-
/** upsert:ON CONFLICT (col) DO UPDATE SET col=EXCLUDED.col;col 省略 = 任意唯一冲突 DO NOTHING
|
|
103
|
+
/** upsert:ON CONFLICT (col) DO UPDATE SET col=EXCLUDED.col;col 省略 = 任意唯一冲突 DO NOTHING
|
|
104
|
+
* col 可为数组(复合唯一目标(department_id, agent_id)等——平台 7 处)
|
|
105
|
+
* merge:冲突列覆盖表达式(__jsonbAppend 追加 / __inc 自增 / RawSql / 标量)——
|
|
106
|
+
* jsonb `||` / hits+1 等表达更新面(业务零 SQL——经标量编码) */
|
|
95
107
|
onConflict?: {
|
|
96
|
-
col?: string;
|
|
108
|
+
col?: string | string[];
|
|
97
109
|
update?: boolean;
|
|
110
|
+
merge?: Record<string, unknown>;
|
|
98
111
|
};
|
|
99
112
|
}
|
|
100
113
|
export interface UpdateQuery {
|
|
@@ -110,10 +123,10 @@ export interface DeleteQuery {
|
|
|
110
123
|
where?: WhereExpr;
|
|
111
124
|
returning?: string[] | '*';
|
|
112
125
|
}
|
|
113
|
-
/** DDL
|
|
126
|
+
/** DDL 语句(协议层 = DDL AST——memory 直执行;真库 ddlToSql 单向编译输出 SQL) */
|
|
114
127
|
export interface DdlQuery {
|
|
115
128
|
kind: 'ddl';
|
|
116
|
-
op: 'createTable' | 'dropTable' | 'createIndex' | 'alter';
|
|
129
|
+
op: 'createTable' | 'dropTable' | 'dropEnum' | 'createIndex' | 'alter' | 'alterAddColumn' | 'createEnum' | 'alterEnumAddValue' | 'createExtension' | 'doBlock';
|
|
117
130
|
table?: string;
|
|
118
131
|
ifNotExists?: boolean;
|
|
119
132
|
/** 列定义(createTable)——约束提取(PK/UNIQUE/DEFAULT now) */
|
|
@@ -124,14 +137,47 @@ export interface DdlQuery {
|
|
|
124
137
|
unique: boolean;
|
|
125
138
|
defaultNow: boolean;
|
|
126
139
|
defaultUuid: boolean;
|
|
140
|
+
defaultVal?: unknown;
|
|
141
|
+
constraintCols?: string[];
|
|
142
|
+
nullable?: boolean;
|
|
143
|
+
ref?: {
|
|
144
|
+
table: string;
|
|
145
|
+
col?: string;
|
|
146
|
+
onDelete?: string;
|
|
147
|
+
};
|
|
127
148
|
}[];
|
|
149
|
+
/** createTable 表级 CHECK(声明枚举 IN 约束——ddlToSql 重建;内存 no-op 语义同 parser 面) */
|
|
150
|
+
checks?: {
|
|
151
|
+
col: string;
|
|
152
|
+
vals: string[];
|
|
153
|
+
}[];
|
|
154
|
+
/** createIndex:索引声明(ddlToSql 重建;内存索引 no-op) */
|
|
155
|
+
index?: {
|
|
156
|
+
name: string;
|
|
157
|
+
cols: string;
|
|
158
|
+
unique: boolean;
|
|
159
|
+
using?: string;
|
|
160
|
+
opclass?: string;
|
|
161
|
+
with?: string;
|
|
162
|
+
where?: string;
|
|
163
|
+
};
|
|
164
|
+
/** alter:DROP NOT NULL(老库升级——内存 no-op) */
|
|
165
|
+
dropNotNull?: string[];
|
|
166
|
+
/** createEnum:枚举值清单 */
|
|
167
|
+
enumValues?: string[];
|
|
168
|
+
/** alterAddColumn:增量列(列名/类型/默认值——对齐声明式迁移 ADD COLUMN IF NOT EXISTS) */
|
|
169
|
+
column?: string;
|
|
170
|
+
columnType?: string;
|
|
171
|
+
defaultVal?: unknown;
|
|
172
|
+
/** 列可空性(alterAddColumn/createTable 列——NOT NULL 重建面) */
|
|
173
|
+
nullable?: boolean;
|
|
128
174
|
}
|
|
129
175
|
export type Query = SelectQuery | InsertQuery | UpdateQuery | DeleteQuery | DdlQuery;
|
|
130
176
|
export interface QueryResultWithAffected<T = Row> extends Array<T> {
|
|
131
177
|
affectedRows?: number;
|
|
132
178
|
}
|
|
133
179
|
/** builder 链:方法返回 this;.run()/.one() 执行 */
|
|
134
|
-
export interface SelectBuilder {
|
|
180
|
+
export interface SelectBuilder<T = Row> {
|
|
135
181
|
distinct(): this;
|
|
136
182
|
select(...cols: (string | RawSql)[]): this;
|
|
137
183
|
join(table: string, on: JoinClause['on'], opts?: {
|
|
@@ -139,39 +185,49 @@ export interface SelectBuilder {
|
|
|
139
185
|
type?: 'inner' | 'left';
|
|
140
186
|
}): this;
|
|
141
187
|
where(expr: WhereExpr): this;
|
|
142
|
-
whereRaw(sql: string, params?: unknown[]): this;
|
|
143
188
|
/** IN/EXISTS 子查询 */
|
|
144
189
|
in(col: string, query: SelectQuery, not?: boolean): this;
|
|
145
190
|
exists(query: SelectQuery, not?: boolean): this;
|
|
146
191
|
groupBy(...cols: string[]): this;
|
|
147
192
|
having(expr: WhereExpr): this;
|
|
148
|
-
count(col?: string, as?: string): this;
|
|
149
|
-
sum(col: string, as?: string): this;
|
|
193
|
+
count(col?: string, as?: string, filter?: WhereExpr): this;
|
|
194
|
+
sum(col: string, as?: string, filter?: WhereExpr): this;
|
|
195
|
+
avg(col: string, as?: string, filter?: WhereExpr): this;
|
|
196
|
+
min(col: string, as?: string, filter?: WhereExpr): this;
|
|
197
|
+
max(col: string, as?: string, filter?: WhereExpr): this;
|
|
150
198
|
orderBy(col: string, dir?: 'asc' | 'desc'): this;
|
|
199
|
+
/** pgvector 相似度:注入投影 `1 - (col <=> vec) as as` + `ORDER BY col <=> vec`(知识检索面) */
|
|
200
|
+
vectorScore(col: string, vec: number[], as: string): this;
|
|
151
201
|
limit(n: number): this;
|
|
152
202
|
offset(n: number): this;
|
|
153
|
-
run(): Promise<QueryResult<
|
|
154
|
-
one(): Promise<
|
|
203
|
+
run(): Promise<QueryResult<T>>;
|
|
204
|
+
one(): Promise<T | undefined>;
|
|
205
|
+
/** AST 面:返回纯数据 Query(协议层 = AST——可序列化传输/嵌入执行) */
|
|
206
|
+
toQuery(): SelectQuery;
|
|
155
207
|
}
|
|
156
|
-
export interface InsertBuilder {
|
|
208
|
+
export interface InsertBuilder<T = Row> {
|
|
157
209
|
values(row: Row): this;
|
|
158
210
|
rows(rows: Row[]): this;
|
|
159
211
|
returning(...cols: (string | '*')[]): this;
|
|
160
|
-
onConflict(col?: string, update?: boolean): this;
|
|
161
|
-
run(): Promise<QueryResult<
|
|
212
|
+
onConflict(col?: string | string[], update?: boolean, merge?: Record<string, unknown>): this;
|
|
213
|
+
run(): Promise<QueryResult<T>>;
|
|
214
|
+
/** AST 面:返回纯数据 Query(协议层 = AST——可序列化传输/嵌入执行) */
|
|
215
|
+
toQuery(): InsertQuery;
|
|
162
216
|
}
|
|
163
|
-
export interface UpdateBuilder {
|
|
217
|
+
export interface UpdateBuilder<T = Row> {
|
|
164
218
|
set(sets: Row): this;
|
|
165
219
|
where(expr: WhereExpr): this;
|
|
166
|
-
whereRaw(sql: string, params?: unknown[]): this;
|
|
167
220
|
returning(...cols: (string | '*')[]): this;
|
|
168
|
-
run(): Promise<QueryResult<
|
|
221
|
+
run(): Promise<QueryResult<T>>;
|
|
222
|
+
/** AST 面:返回纯数据 Query(协议层 = AST——可序列化传输/嵌入执行) */
|
|
223
|
+
toQuery(): UpdateQuery;
|
|
169
224
|
}
|
|
170
|
-
export interface DeleteBuilder {
|
|
225
|
+
export interface DeleteBuilder<T = Row> {
|
|
171
226
|
where(expr: WhereExpr): this;
|
|
172
|
-
whereRaw(sql: string, params?: unknown[]): this;
|
|
173
227
|
returning(...cols: (string | '*')[]): this;
|
|
174
|
-
run(): Promise<QueryResult<
|
|
228
|
+
run(): Promise<QueryResult<T>>;
|
|
229
|
+
/** AST 面:返回纯数据 Query(协议层 = AST——可序列化传输/嵌入执行) */
|
|
230
|
+
toQuery(): DeleteQuery;
|
|
175
231
|
}
|
|
176
232
|
export interface QueryBuilder {
|
|
177
233
|
from(table: string, alias?: string): SelectBuilder;
|
|
@@ -187,9 +243,9 @@ interface Compiled {
|
|
|
187
243
|
export declare function compileSelect(q: SelectQuery): Compiled;
|
|
188
244
|
/** 编译 INSERT(多行 + RETURNING + ON CONFLICT) */
|
|
189
245
|
export declare function compileInsert(q: InsertQuery): Compiled;
|
|
190
|
-
/** 编译 UPDATE */
|
|
246
|
+
/** 编译 UPDATE —— 无 where 拒绝(防全表更新——一处防护覆盖真库/memory/gql) */
|
|
191
247
|
export declare function compileUpdate(q: UpdateQuery): Compiled;
|
|
192
|
-
/** 编译 DELETE */
|
|
248
|
+
/** 编译 DELETE —— 无 where 拒绝(防全表误删——一处防护覆盖真库/memory/gql) */
|
|
193
249
|
export declare function compileDelete(q: DeleteQuery): Compiled;
|
|
194
250
|
/** 统一编译入口 */
|
|
195
251
|
export declare function compileQuery(q: Query): Compiled;
|
|
@@ -197,7 +253,7 @@ export declare function compileQuery(q: Query): Compiled;
|
|
|
197
253
|
* 同列条件对象级合并(AND 语义)。不可合并返回 null(调用方 and 包装):
|
|
198
254
|
* ColOps × ColOps → 不相交操作符键 spread({gt:15}+{lt:35} 并存)
|
|
199
255
|
* scalar × ColOps → { eq: scalar, ...ops }(eq 登记——编译/执行双端认识)
|
|
200
|
-
* 数组(IN)/
|
|
256
|
+
* 数组(IN)/ scalar × scalar / 同键冲突 / null 标量 → null
|
|
201
257
|
*/
|
|
202
258
|
export declare function mergeWhereField(prev: WhereField, next: WhereField): WhereField | null;
|
|
203
259
|
/**
|
|
@@ -207,4 +263,6 @@ export declare function mergeWhereField(prev: WhereField, next: WhereField): Whe
|
|
|
207
263
|
export declare function addWhereCond(expr: WhereExpr, col: string, field: WhereField): void;
|
|
208
264
|
/** where 表达式合并(builder 链式追加——AND 语义,不覆盖) */
|
|
209
265
|
export declare function mergeWhere(prev: WhereExpr, next: WhereExpr): WhereExpr;
|
|
266
|
+
/** update/upsert merge 表达式编译(__jsonbAppend/__inc 标量编码——业务零 SQL) */
|
|
267
|
+
export declare function compileMergeVal(col: string, v: unknown, params: unknown[], table: string): string;
|
|
210
268
|
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/rest —— restFromShape:shape → RESTful 路由组(纯函数)
|
|
3
|
+
*
|
|
4
|
+
* 命名契约(W0):`restFromShape(shapeDef, opts)` / `orm.rest(Table)` 入口对称
|
|
5
|
+
* (orm.gql/gqlFromShape 同构)。
|
|
6
|
+
*
|
|
7
|
+
* 生成面(W4 首版——分层纪律:协议面 + 样板 handler;业务走 hooks/覆盖):
|
|
8
|
+
* - GET {base} list(query 参数:eq 直排 `?col=v` + sort
|
|
9
|
+
* `?sort=-created_at,name`(-前缀 desc·逗号多字段)+ limit/offset——
|
|
10
|
+
* eq 直排经 filterToWhere 与 gql filter 同核语义)
|
|
11
|
+
* - GET {base}/:id one(404)
|
|
12
|
+
* - POST {base} insert(201 + insertSchema 校验 400)
|
|
13
|
+
* - PATCH {base}/:id update(404/400)
|
|
14
|
+
* - DELETE {base}/:id delete(404/204)
|
|
15
|
+
*
|
|
16
|
+
* 内置承诺:
|
|
17
|
+
* - query 参数 schema 从 shape 派生(枚举白名单——`?type=robot` → 400 ·
|
|
18
|
+
* sort 字段白名单 · limit clamp)
|
|
19
|
+
* - 敏感列 fieldPolicy.hidden(SDL/返回双面不出现——与 gql 同策略)
|
|
20
|
+
* - 租户 scope:ctx.orm (CtxOrm) 的 ctxTable——与 orm 单源(无独立 tenant
|
|
21
|
+
* 配置面)
|
|
22
|
+
* - hooks 接缝(before/after——权限守卫/响应增强——业务 handler 插点)
|
|
23
|
+
*
|
|
24
|
+
* 判负(首版——后续再议):嵌套资源路由(/dept/:id/members)· 全算子 query
|
|
25
|
+
* 参数(in/gt/contains——rest 参数 flat 面只 eq 直排——复杂过滤走
|
|
26
|
+
* orm.table/gql)· 批量/upsert · 自定义错误形状
|
|
27
|
+
*/
|
|
28
|
+
import type { ZodRawShape } from '../../shared/zod.ts';
|
|
29
|
+
import type { Shape } from './shape.ts';
|
|
30
|
+
export interface RestHooks {
|
|
31
|
+
beforeList?: (req: Request, ctx: unknown) => Promise<void> | void;
|
|
32
|
+
afterList?: (rows: Record<string, unknown>[], req: Request, ctx: unknown) => Record<string, unknown>[] | Promise<Record<string, unknown>[]>;
|
|
33
|
+
beforeInsert?: (data: Record<string, unknown>, req: Request, ctx: unknown) => Promise<void> | void;
|
|
34
|
+
beforeUpdate?: (id: string, patch: Record<string, unknown>, req: Request, ctx: unknown) => Promise<void> | void;
|
|
35
|
+
beforeDelete?: (id: string, req: Request, ctx: unknown) => Promise<void> | void;
|
|
36
|
+
}
|
|
37
|
+
export interface RestShapeOptions {
|
|
38
|
+
/** 资源名(默认表名——仅元数据) */
|
|
39
|
+
name?: string;
|
|
40
|
+
/** 默认分页上限(默认 100) */
|
|
41
|
+
maxLimit?: number;
|
|
42
|
+
/** 字段策略(fieldPolicy——敏感列豁免:列表/单查/返回不出现;写入面保留) */
|
|
43
|
+
hidden?: string[];
|
|
44
|
+
/** 业务接缝(hooks——分层纪律:业务 handler 插点) */
|
|
45
|
+
hooks?: RestHooks;
|
|
46
|
+
}
|
|
47
|
+
export interface RestShapeOutput {
|
|
48
|
+
/** 挂载面(app.get/post/patch/delete 注册——`/api/agents` 等 base) */
|
|
49
|
+
mount: (app: {
|
|
50
|
+
get: (p: string, h: (req: Request, ctx: never) => Promise<Response>) => unknown;
|
|
51
|
+
post: (p: string, h: (req: Request, ctx: never) => Promise<Response>) => unknown;
|
|
52
|
+
patch: (p: string, h: (req: Request, ctx: never) => Promise<Response>) => unknown;
|
|
53
|
+
delete: (p: string, h: (req: Request, ctx: never) => Promise<Response>) => unknown;
|
|
54
|
+
}, base: string) => void;
|
|
55
|
+
}
|
|
56
|
+
export declare function restFromShape<S extends ZodRawShape>(shapeDef: Shape<S>, opts?: RestShapeOptions): RestShapeOutput;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/db — 声明式 Schema(DDL 算子化)
|
|
3
|
+
*
|
|
4
|
+
* 业务零 SQL 字符串:表结构 = 声明(ZodRawShape 列 + 表级索引/约束/FK 元数据)→
|
|
5
|
+
* compileSchemaDDL 在框架内部生成 CREATE/ALTER/INDEX 语句(字符串不外泄)→
|
|
6
|
+
* pg.runMigration(name, ddl) 执行(幂等记录)· MemorySql.applySchema 直构造元数据。
|
|
7
|
+
*
|
|
8
|
+
* 声明来源:列 = shape(类型映射 z.string→TEXT / z.number().int→INT / z.number→DOUBLE
|
|
9
|
+
* PRECISION / z.boolean→BOOLEAN / z.date→TIMESTAMPTZ / z.uuid→UUID / z.json·z.array·
|
|
10
|
+
* z.object→JSONB / z.enum→TEXT+CHECK)+ f 修饰(f.pk/f.req/f.now/f.unique/f.default/
|
|
11
|
+
* f.col);表级 = TableDecl(复合唯一/refs FK/indexes/columnTypes 注解)。
|
|
12
|
+
*
|
|
13
|
+
* 升级路径:每个表产出 CREATE TABLE IF NOT EXISTS(全列——新库)+ 每列
|
|
14
|
+
* ALTER TABLE ADD COLUMN IF NOT EXISTS(老库增量——幂等)+ CREATE INDEX IF NOT EXISTS。
|
|
15
|
+
*/
|
|
16
|
+
import type { ZodType } from '../../shared/zod.ts';
|
|
17
|
+
import type { DdlQuery } from './query.ts';
|
|
18
|
+
export interface IndexDecl {
|
|
19
|
+
/** 列(可带 DESC——`{ col: 'created_at', desc: true }`) */
|
|
20
|
+
cols: (string | {
|
|
21
|
+
col: string;
|
|
22
|
+
desc?: boolean;
|
|
23
|
+
})[];
|
|
24
|
+
/** 索引名(缺省 idx_<table>_<cols>) */
|
|
25
|
+
name?: string;
|
|
26
|
+
unique?: boolean;
|
|
27
|
+
/** 访问方法('ivfflat'/'brin'…) */
|
|
28
|
+
using?: string;
|
|
29
|
+
/** 操作符类('vector_cosine_ops') */
|
|
30
|
+
opclass?: string;
|
|
31
|
+
/** WITH 参数文本('lists = 100') */
|
|
32
|
+
with?: string;
|
|
33
|
+
/** 部分索引条件(AND 等值/不等/IS NULL 面——声明值内联(非用户输入)) */
|
|
34
|
+
where?: {
|
|
35
|
+
col: string;
|
|
36
|
+
eq?: string;
|
|
37
|
+
ne?: string;
|
|
38
|
+
isNull?: boolean;
|
|
39
|
+
}[];
|
|
40
|
+
}
|
|
41
|
+
export interface TableDecl {
|
|
42
|
+
name: string;
|
|
43
|
+
columns: Record<string, unknown>;
|
|
44
|
+
/** 复合唯一组(列级 f.unique 之外) */
|
|
45
|
+
uniques?: string[][];
|
|
46
|
+
/** 列 → 外键引用(schema REFERENCES 面;跨边界不声明 refs——应用层保证) */
|
|
47
|
+
refs?: Record<string, {
|
|
48
|
+
table: string;
|
|
49
|
+
col?: string;
|
|
50
|
+
onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
51
|
+
}>;
|
|
52
|
+
/** 列型注解(shape 默认映射外:'FLOAT8'/'vector(1024)'/'BIGSERIAL'/…) */
|
|
53
|
+
columnTypes?: Record<string, string>;
|
|
54
|
+
/** CHECK 枚举(非 z.enum 列的 IN 约束:列 → 允许值) */
|
|
55
|
+
checks?: Record<string, string[]>;
|
|
56
|
+
/** 老库升级:去掉 NOT NULL(ALTER COLUMN DROP NOT NULL——如 SSO 无密码) */
|
|
57
|
+
dropNotNull?: string[];
|
|
58
|
+
indexes?: IndexDecl[];
|
|
59
|
+
}
|
|
60
|
+
export interface EnumDecl {
|
|
61
|
+
name: string;
|
|
62
|
+
values: string[];
|
|
63
|
+
}
|
|
64
|
+
export interface SchemaModule {
|
|
65
|
+
/** 扩展('vector' 等——CREATE EXTENSION IF NOT EXISTS 前置) */
|
|
66
|
+
extensions?: string[];
|
|
67
|
+
/** PG 枚举类型(CREATE TYPE + 值补增——列型用 columnTypes: { col: 'enum名' } 引用) */
|
|
68
|
+
enums?: EnumDecl[];
|
|
69
|
+
tables: TableDecl[];
|
|
70
|
+
}
|
|
71
|
+
export declare function zodTypeOf(t: ZodType): string;
|
|
72
|
+
export declare function enumValuesOf(t: ZodType): string[] | undefined;
|
|
73
|
+
/** 声明模块 → DDL AST(封闭面:memory executeDdl 直执行——零 parse) */
|
|
74
|
+
export declare function compileSchemaDdl(mod: SchemaModule): DdlQuery[];
|
|
75
|
+
/** DDL AST → SQL(真库单向输出——封闭:AST 永远是输入,SQL 只有流出) */
|
|
76
|
+
export declare function ddlToSql(stmts: DdlQuery[]): string;
|
|
77
|
+
/** @deprecated 兼容面——W3 删除;真库面统一 ddlToSql(compileSchemaDdl(mod)) */
|
|
78
|
+
export declare function compileSchemaDDL(mod: SchemaModule): string;
|
|
@@ -26,5 +26,3 @@ export interface DBServer {
|
|
|
26
26
|
}
|
|
27
27
|
export { MemoryRedisServer } from './redis-server.ts';
|
|
28
28
|
export type { RedisServerOptions } from './redis-server.ts';
|
|
29
|
-
export { MemoryPostgresServer } from './postgres-server.ts';
|
|
30
|
-
export type { PostgresServerOptions } from './postgres-server.ts';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/shape —— 形状层(shape+operator 架构的形状基座)
|
|
3
|
+
*
|
|
4
|
+
* shape = zod schema(数据形状单源)+ db 元数据(meta——表/列语义)
|
|
5
|
+
* 派生面(与 zod 天然——零生成):
|
|
6
|
+
* - 校验:shape.parse(API 边界)
|
|
7
|
+
* - 类型:z.infer
|
|
8
|
+
* - 变体:insertSchema/updateSchema(省略自动列)
|
|
9
|
+
* - db 元数据:dbMeta(建表/算子类型收窄——后续 W3 消费)
|
|
10
|
+
*
|
|
11
|
+
* 用法:
|
|
12
|
+
* const Agent = shape({
|
|
13
|
+
* table: 'agents',
|
|
14
|
+
* fields: {
|
|
15
|
+
* id: z.uuid().meta({ pk: true, default: 'random' }),
|
|
16
|
+
* appId: z.string().meta({ column: 'app_id', notNull: true }),
|
|
17
|
+
* type: z.enum(['ai','user','webhook']).meta({ notNull: true }),
|
|
18
|
+
* name: z.string().meta({ notNull: true }),
|
|
19
|
+
* createdAt: z.date().meta({ column: 'created_at', default: 'now' }),
|
|
20
|
+
* },
|
|
21
|
+
* })
|
|
22
|
+
*/
|
|
23
|
+
import { type ZodType, type Infer, type ZodRawShape, type ZodMeta } from '../../shared/zod.ts';
|
|
24
|
+
/** meta 类型保留面:withMeta 返回交叉(meta 字面量类型不坍缩——BodyOf 推导的根基) */
|
|
25
|
+
export type WithMeta<T extends ZodType, M extends ZodMeta> = T & {
|
|
26
|
+
metaInfo: M & ZodMeta;
|
|
27
|
+
};
|
|
28
|
+
/** auto 字段(DB 侧生成——insert/update 时省略:default 'random'/'now')——从 meta 字面量推导 */
|
|
29
|
+
export type AutoFieldOf<S extends ZodRawShape> = {
|
|
30
|
+
[K in keyof S]: S[K] extends {
|
|
31
|
+
metaInfo: infer M;
|
|
32
|
+
} ? (M extends {
|
|
33
|
+
default: infer D;
|
|
34
|
+
} ? (D extends 'random' | 'now' ? K : never) : never) : never;
|
|
35
|
+
}[keyof S];
|
|
36
|
+
/** insert 输入行类型(省略 auto 列——字段精确·全字段键级可选——
|
|
37
|
+
* required/optional 精确性由运行时权威(insertSchema 校验)承载——字段名/
|
|
38
|
+
* 值类型/枚举编译期精确(核心价值)) */
|
|
39
|
+
export type BodyOf<S extends ZodRawShape> = {
|
|
40
|
+
[K in keyof S as K extends AutoFieldOf<S> ? never : K]?: Infer<S[K]>;
|
|
41
|
+
};
|
|
42
|
+
/** update/patch 输入行类型(省略 auto 列 · 全字段可缺省——与 updateSchema 运行时一致) */
|
|
43
|
+
type PatchValueOf<T extends ZodType> = T extends ZodType<infer Out> ? Out : never;
|
|
44
|
+
export type PatchOf<S extends ZodRawShape> = {
|
|
45
|
+
[K in keyof S as K extends AutoFieldOf<S> ? never : K]?: PatchValueOf<S[K]>;
|
|
46
|
+
};
|
|
47
|
+
/** 字段级 db 元数据(shape 层语义——建表/算子/校验收窄的驱动面) */
|
|
48
|
+
export interface FieldDbMeta extends ZodMeta {
|
|
49
|
+
/** 列名(默认 = 字段名) */
|
|
50
|
+
column?: string;
|
|
51
|
+
/** 主键 */
|
|
52
|
+
pk?: boolean;
|
|
53
|
+
/** 唯一 */
|
|
54
|
+
unique?: boolean;
|
|
55
|
+
/** NOT NULL(校验面 optional 之外——DB 层约束) */
|
|
56
|
+
notNull?: boolean;
|
|
57
|
+
/** 默认值('random'=gen_random_uuid · 'now'=NOW() · 字面量(string/number/boolean)) */
|
|
58
|
+
default?: 'random' | 'now' | string | number | boolean;
|
|
59
|
+
/** 外键(references 表.列——关系面) */
|
|
60
|
+
references?: string;
|
|
61
|
+
/** 级联(ON DELETE) */
|
|
62
|
+
onDelete?: 'cascade' | 'set null' | 'restrict';
|
|
63
|
+
}
|
|
64
|
+
export interface DbField {
|
|
65
|
+
name: string;
|
|
66
|
+
schema: ZodType;
|
|
67
|
+
meta: FieldDbMeta;
|
|
68
|
+
/** 输出类型(z.infer 快捷) */
|
|
69
|
+
type: unknown;
|
|
70
|
+
}
|
|
71
|
+
/** 形状(表级) */
|
|
72
|
+
export interface Shape<S extends ZodRawShape = ZodRawShape> {
|
|
73
|
+
/** 表/集合名 */
|
|
74
|
+
table: string;
|
|
75
|
+
/** 字段表(原始 zod shape) */
|
|
76
|
+
fields: S;
|
|
77
|
+
/** 字段元数据展平(name → FieldDbMeta) */
|
|
78
|
+
dbFields: Record<string, FieldDbMeta>;
|
|
79
|
+
/** 主键字段名(pk meta) */
|
|
80
|
+
pkField?: string;
|
|
81
|
+
/** infers */
|
|
82
|
+
output: {
|
|
83
|
+
[K in keyof S]: Infer<S[K]>;
|
|
84
|
+
};
|
|
85
|
+
/** 插入变体(省略 auto 列:pk+random/now 默认——类型面 = 输入行 BodyOf) */
|
|
86
|
+
insertSchema(opts?: {
|
|
87
|
+
omit?: string[];
|
|
88
|
+
}): ZodType<BodyOf<S>>;
|
|
89
|
+
/** 字段名 → 列名翻译(写入面:shape 字段名 → db 列名) */
|
|
90
|
+
toDb(record: object): Record<string, unknown>;
|
|
91
|
+
/** 列名 → 字段名翻译(读取面:db 行 → shape 字段名——GraphQL/API 输出) */
|
|
92
|
+
fromDb(record: object): Record<string, unknown>;
|
|
93
|
+
/** 更新变体(全字段 optional——部分更新面——类型面 = PatchOf) */
|
|
94
|
+
updateSchema(opts?: {
|
|
95
|
+
omit?: string[];
|
|
96
|
+
}): ZodType<PatchOf<S>>;
|
|
97
|
+
}
|
|
98
|
+
export declare function shape<S extends ZodRawShape>(def: {
|
|
99
|
+
table: string;
|
|
100
|
+
fields: S;
|
|
101
|
+
}): Shape<S>;
|
|
102
|
+
/** 字段 meta 快捷方法(shape 定义侧手感的统一入口) */
|
|
103
|
+
export declare const f: {
|
|
104
|
+
/** 主键(random uuid 默认) */
|
|
105
|
+
pk: <T extends ZodType>(t: T) => WithMeta<T, {
|
|
106
|
+
pk: true;
|
|
107
|
+
default: "random";
|
|
108
|
+
}>;
|
|
109
|
+
/** NOT NULL */
|
|
110
|
+
req: <T extends ZodType>(t: T) => WithMeta<T, {
|
|
111
|
+
notNull: true;
|
|
112
|
+
}>;
|
|
113
|
+
/** 列名映射 */
|
|
114
|
+
col: <T extends ZodType>(t: T, column: string) => WithMeta<T, {
|
|
115
|
+
column: string;
|
|
116
|
+
}>;
|
|
117
|
+
/** 默认 now */
|
|
118
|
+
now: <T extends ZodType>(t: T) => WithMeta<T, {
|
|
119
|
+
default: "now";
|
|
120
|
+
}>;
|
|
121
|
+
/** 唯一 */
|
|
122
|
+
unique: <T extends ZodType>(t: T) => WithMeta<T, {
|
|
123
|
+
unique: true;
|
|
124
|
+
}>;
|
|
125
|
+
/** 字面量默认值(DB 侧默认——body 可缺省——meta 类型保留;值域任意字面量(jsonb
|
|
126
|
+
* 默认 [] 等)——default 值的语义由 shape/DDL 面消费(string/number/boolean 主流)) */
|
|
127
|
+
dflt: <T extends ZodType, V>(t: T, v: V) => WithMeta<T, {
|
|
128
|
+
default: V;
|
|
129
|
+
}>;
|
|
130
|
+
};
|
|
131
|
+
export {};
|