@ai0x0/utils 0.6.0 → 0.6.1
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/es/backend/actions/create-delete-action.d.ts +2 -3
- package/es/backend/actions/create-delete-action.js +8 -44
- package/es/backend/actions/create-put-action.d.ts +1 -1
- package/es/backend/actions/create-put-action.js +15 -39
- package/es/backend/actions/get-list-query-core.d.ts +46 -0
- package/es/backend/actions/get-list-query-core.js +236 -0
- package/es/backend/actions/get-list-query.d.ts +5 -18
- package/es/backend/actions/get-list-query.js +20 -220
- package/es/backend/actions/write-action-core.d.ts +18 -0
- package/es/backend/actions/write-action-core.js +119 -0
- package/es/backend/schemas/common.d.ts +112 -0
- package/es/backend/schemas/common.js +158 -0
- package/es/backend/schemas/index.d.ts +735 -364
- package/es/backend/schemas/index.js +8 -139
- package/es/backend/sqlite/actions/create-delete-action.d.ts +1 -2
- package/es/backend/sqlite/actions/create-delete-action.js +7 -43
- package/es/backend/sqlite/actions/create-put-action.d.ts +1 -1
- package/es/backend/sqlite/actions/create-put-action.js +13 -36
- package/es/backend/sqlite/actions/get-list-query.d.ts +4 -9
- package/es/backend/sqlite/actions/get-list-query.js +20 -217
- package/es/backend/sqlite/errors.d.ts +1 -4
- package/es/backend/sqlite/errors.js +6 -31
- package/es/backend/sqlite/schemas/index.d.ts +1 -111
- package/es/backend/sqlite/schemas/index.js +8 -139
- package/lib/backend/actions/create-delete-action.d.ts +2 -3
- package/lib/backend/actions/create-delete-action.js +2 -14
- package/lib/backend/actions/create-put-action.d.ts +1 -1
- package/lib/backend/actions/create-put-action.js +3 -16
- package/lib/backend/actions/get-list-query-core.d.ts +46 -0
- package/lib/backend/actions/get-list-query-core.js +151 -0
- package/lib/backend/actions/get-list-query.d.ts +5 -18
- package/lib/backend/actions/get-list-query.js +16 -141
- package/lib/backend/actions/write-action-core.d.ts +18 -0
- package/lib/backend/actions/write-action-core.js +70 -0
- package/lib/backend/schemas/common.d.ts +112 -0
- package/lib/backend/schemas/common.js +112 -0
- package/lib/backend/schemas/index.d.ts +735 -364
- package/lib/backend/schemas/index.js +12 -83
- package/lib/backend/sqlite/actions/create-delete-action.d.ts +1 -2
- package/lib/backend/sqlite/actions/create-delete-action.js +2 -14
- package/lib/backend/sqlite/actions/create-put-action.d.ts +1 -1
- package/lib/backend/sqlite/actions/create-put-action.js +3 -16
- package/lib/backend/sqlite/actions/get-list-query.d.ts +4 -9
- package/lib/backend/sqlite/actions/get-list-query.js +16 -141
- package/lib/backend/sqlite/errors.d.ts +1 -4
- package/lib/backend/sqlite/errors.js +2 -8
- package/lib/backend/sqlite/schemas/index.d.ts +1 -111
- package/lib/backend/sqlite/schemas/index.js +12 -83
- package/package.json +1 -1
|
@@ -6,11 +6,11 @@ var __export = (target, all) => {
|
|
|
6
6
|
for (var name in all)
|
|
7
7
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
8
|
};
|
|
9
|
-
var __copyProps = (to, from, except,
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
10
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
11
|
for (let key of __getOwnPropNames(from))
|
|
12
12
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
14
|
}
|
|
15
15
|
return to;
|
|
16
16
|
};
|
|
@@ -23,145 +23,20 @@ __export(get_list_query_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(get_list_query_exports);
|
|
25
25
|
var import_drizzle_orm = require("drizzle-orm");
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
jsonArrayFields
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
orderDir = "desc",
|
|
41
|
-
...filters
|
|
42
|
-
} = params;
|
|
43
|
-
function buildBaseQuery(table2, fields2, relations2) {
|
|
44
|
-
let queryFields = { ...fields2 };
|
|
45
|
-
if (relations2 == null ? void 0 : relations2.length) {
|
|
46
|
-
for (const { select } of relations2) {
|
|
47
|
-
queryFields = { ...queryFields, ...select };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
const query2 = db.select(queryFields).from(table2);
|
|
51
|
-
if (relations2 == null ? void 0 : relations2.length) {
|
|
52
|
-
query2.groupBy(
|
|
53
|
-
table2.id,
|
|
54
|
-
...relations2.filter(({ groupBy }) => groupBy).filter(({ table: table3 }) => table3).map(({ table: table3 }) => table3.id)
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
return query2;
|
|
58
|
-
}
|
|
59
|
-
function findTargetColumn(key, table2, relations2) {
|
|
60
|
-
var _a;
|
|
61
|
-
return (_a = [table2].concat(
|
|
62
|
-
(relations2 == null ? void 0 : relations2.filter(({ table: table3 }) => table3).map(({ table: table3 }) => table3)) || []
|
|
63
|
-
).find((table3) => table3[key])) == null ? void 0 : _a[key];
|
|
64
|
-
}
|
|
65
|
-
function addCondition(conditions2, key, value, targetColumn) {
|
|
66
|
-
const isIdField = /id/i.test(key);
|
|
67
|
-
const isJsonArray = jsonArrayFields == null ? void 0 : jsonArrayFields.includes(key);
|
|
68
|
-
if (typeof value === "string") {
|
|
69
|
-
if (value.includes(",")) {
|
|
70
|
-
const values = value.split(",").map((val) => val.trim()).filter(Boolean);
|
|
71
|
-
if (values.length > 0) {
|
|
72
|
-
if (isJsonArray) {
|
|
73
|
-
conditions2.push(
|
|
74
|
-
import_drizzle_orm.sql`
|
|
75
|
-
EXISTS (
|
|
76
|
-
SELECT 1 FROM jsonb_array_elements_text(${targetColumn}) tag
|
|
77
|
-
WHERE tag LIKE ${`%${values[0]}%`}
|
|
78
|
-
)
|
|
79
|
-
`
|
|
80
|
-
);
|
|
81
|
-
} else if (isIdField) {
|
|
82
|
-
conditions2.push((0, import_drizzle_orm.inArray)(targetColumn, values));
|
|
83
|
-
} else {
|
|
84
|
-
conditions2.push(
|
|
85
|
-
(0, import_drizzle_orm.or)(
|
|
86
|
-
...values.map((val) => (0, import_drizzle_orm.ilike)(targetColumn, `%${val}%`))
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
} else {
|
|
92
|
-
if (isJsonArray) {
|
|
93
|
-
conditions2.push(
|
|
94
|
-
import_drizzle_orm.sql`
|
|
95
|
-
EXISTS (
|
|
96
|
-
SELECT 1 FROM jsonb_array_elements_text(${targetColumn}) tag
|
|
97
|
-
WHERE tag LIKE ${`%${value}%`}
|
|
98
|
-
)
|
|
99
|
-
`
|
|
100
|
-
);
|
|
101
|
-
} else if (isIdField) {
|
|
102
|
-
conditions2.push((0, import_drizzle_orm.eq)(targetColumn, value));
|
|
103
|
-
} else {
|
|
104
|
-
conditions2.push((0, import_drizzle_orm.ilike)(targetColumn, `%${value}%`));
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
conditions2.push((0, import_drizzle_orm.eq)(targetColumn, value));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
function buildConditions(filters2, table2, relations2) {
|
|
112
|
-
const conditions2 = [];
|
|
113
|
-
for (const [key, value] of Object.entries(filters2)) {
|
|
114
|
-
if (!value) {
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (key.endsWith("AtFrom") || key.endsWith("AtTo")) {
|
|
118
|
-
const baseFieldName = key.replace(/(AtFrom|AtTo)$/, "");
|
|
119
|
-
const targetColumn2 = findTargetColumn(
|
|
120
|
-
`${baseFieldName}At`,
|
|
121
|
-
table2,
|
|
122
|
-
relations2
|
|
123
|
-
);
|
|
124
|
-
if (!targetColumn2) {
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (key.endsWith("AtFrom")) {
|
|
128
|
-
conditions2.push((0, import_drizzle_orm.gte)(targetColumn2, new Date(value)));
|
|
129
|
-
} else if (key.endsWith("AtTo")) {
|
|
130
|
-
conditions2.push((0, import_drizzle_orm.lte)(targetColumn2, new Date(value)));
|
|
131
|
-
}
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
const targetColumn = findTargetColumn(
|
|
135
|
-
key,
|
|
136
|
-
table2,
|
|
137
|
-
relations2
|
|
138
|
-
);
|
|
139
|
-
if (!targetColumn) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
addCondition(conditions2, key, value, targetColumn);
|
|
143
|
-
}
|
|
144
|
-
return conditions2;
|
|
145
|
-
}
|
|
146
|
-
function buildOrderBy(table2, orderBy2, orderDir2) {
|
|
147
|
-
const orderColumn = table2[orderBy2];
|
|
148
|
-
return orderDir2 === "asc" ? (0, import_drizzle_orm.asc)(orderColumn) : (0, import_drizzle_orm.desc)(orderColumn);
|
|
149
|
-
}
|
|
150
|
-
const baseQuery = buildBaseQuery(table, fields, relations);
|
|
151
|
-
const scopeSql = (0, import_scope.scopeCondition)(table, scope);
|
|
152
|
-
const conditions = scopeSql ? [scopeSql] : [];
|
|
153
|
-
conditions.push(...buildConditions(filters, table, relations));
|
|
154
|
-
const query = baseQuery.where(conditions.length > 0 ? (0, import_drizzle_orm.and)(...conditions) : void 0).orderBy(buildOrderBy(table, orderBy, orderDir)).limit(pageSize).offset((page - 1) * pageSize);
|
|
155
|
-
const countQuery = db.select({ count: import_drizzle_orm.sql`COUNT(DISTINCT ${table.id})` }).from(table).where(conditions.length > 0 ? (0, import_drizzle_orm.and)(...conditions) : void 0);
|
|
156
|
-
if (relations == null ? void 0 : relations.length) {
|
|
157
|
-
for (const { table: relationTable, sql: joinSql } of relations) {
|
|
158
|
-
if (relationTable) {
|
|
159
|
-
query.leftJoin(relationTable, joinSql);
|
|
160
|
-
countQuery.leftJoin(relationTable, joinSql);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return { countQuery, query };
|
|
26
|
+
var import_get_list_query_core = require("./get-list-query-core");
|
|
27
|
+
var run = (0, import_get_list_query_core.createGetListQuery)({
|
|
28
|
+
contains: (column, keyword) => (0, import_drizzle_orm.ilike)(column, `%${keyword}%`),
|
|
29
|
+
// jsonb 数组展开成行再逐个 LIKE。列存的是 text[] 形状的 jsonb(见 createTableSchema 的
|
|
30
|
+
// jsonArrayFields),所以用 _text 那个变体,取到的 tag 直接就是字符串。
|
|
31
|
+
jsonArrayContains: (column, keyword) => import_drizzle_orm.sql`
|
|
32
|
+
EXISTS (
|
|
33
|
+
SELECT 1 FROM jsonb_array_elements_text(${column}) tag
|
|
34
|
+
WHERE tag LIKE ${`%${keyword}%`}
|
|
35
|
+
)
|
|
36
|
+
`
|
|
37
|
+
});
|
|
38
|
+
function getListQuery(args) {
|
|
39
|
+
return run(args);
|
|
165
40
|
}
|
|
166
41
|
// Annotate the CommonJS export names for ESM import in node:
|
|
167
42
|
0 && (module.exports = {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ScopeArg } from "../scope.js";
|
|
2
|
+
/** 核心用得到表的哪一部分:只有 id。dialect 各自的 Table 类型不进来。 */
|
|
3
|
+
export interface WriteActionTable {
|
|
4
|
+
id: unknown;
|
|
5
|
+
}
|
|
6
|
+
interface WriteActionDeps<TTable extends WriteActionTable> {
|
|
7
|
+
db: any;
|
|
8
|
+
table: TTable;
|
|
9
|
+
}
|
|
10
|
+
export declare function createPutActionCore<TTable extends WriteActionTable>({ db, table, }: WriteActionDeps<TTable>): (body: Record<string, unknown>, { scope }: {
|
|
11
|
+
scope: ScopeArg;
|
|
12
|
+
}) => Promise<unknown>;
|
|
13
|
+
export declare function createDeleteActionCore<TTable extends WriteActionTable>({ db, table, }: WriteActionDeps<TTable>): ({ id }: {
|
|
14
|
+
id: string;
|
|
15
|
+
}, { scope }: {
|
|
16
|
+
scope: ScopeArg;
|
|
17
|
+
}) => Promise<any>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/backend/actions/write-action-core.ts
|
|
20
|
+
var write_action_core_exports = {};
|
|
21
|
+
__export(write_action_core_exports, {
|
|
22
|
+
createDeleteActionCore: () => createDeleteActionCore,
|
|
23
|
+
createPutActionCore: () => createPutActionCore
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(write_action_core_exports);
|
|
26
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
27
|
+
var import_scope = require("../scope");
|
|
28
|
+
var import_errors = require("../errors");
|
|
29
|
+
var import_transform_body = require("./transform-body");
|
|
30
|
+
function byId(table, id, scope) {
|
|
31
|
+
const guard = (0, import_scope.scopeCondition)(table, scope);
|
|
32
|
+
const same = (0, import_drizzle_orm.eq)(table.id, id);
|
|
33
|
+
return guard ? (0, import_drizzle_orm.and)(same, guard) : same;
|
|
34
|
+
}
|
|
35
|
+
function createPutActionCore({
|
|
36
|
+
db,
|
|
37
|
+
table
|
|
38
|
+
}) {
|
|
39
|
+
return async (body, { scope }) => {
|
|
40
|
+
const id = body.id;
|
|
41
|
+
if (!id) {
|
|
42
|
+
throw new import_errors.HttpError(400, "缺少 id");
|
|
43
|
+
}
|
|
44
|
+
const [data] = await db.update(table).set((0, import_transform_body.transformBody)(body)).where(byId(table, id, scope)).returning();
|
|
45
|
+
if (!data && scope !== import_scope.NO_SCOPE) {
|
|
46
|
+
throw new import_errors.HttpError(404, "未找到编辑对象,或没有权限");
|
|
47
|
+
}
|
|
48
|
+
return data;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function createDeleteActionCore({
|
|
52
|
+
db,
|
|
53
|
+
table
|
|
54
|
+
}) {
|
|
55
|
+
return async ({ id }, { scope }) => {
|
|
56
|
+
if (!id) {
|
|
57
|
+
throw new import_errors.HttpError(400, "缺少 id");
|
|
58
|
+
}
|
|
59
|
+
const rows = await db.delete(table).where(byId(table, id, scope)).returning();
|
|
60
|
+
if (rows.length === 0 && scope !== import_scope.NO_SCOPE) {
|
|
61
|
+
throw new import_errors.HttpError(404, "未找到删除对象,或没有权限");
|
|
62
|
+
}
|
|
63
|
+
return rows;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 && (module.exports = {
|
|
68
|
+
createDeleteActionCore,
|
|
69
|
+
createPutActionCore
|
|
70
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* 业务侧 insert schema 需要从 drizzle-zod 生成的 schema 中排除的基础字段。
|
|
4
|
+
* 这些字段由后端在 createPostAction 中自动写入。
|
|
5
|
+
*
|
|
6
|
+
* 使用方式(在业务 schema 中):
|
|
7
|
+
* const insertFooSchema = createInsertSchema(foos)
|
|
8
|
+
* .omit(BASIC_INSERT_OMIT)
|
|
9
|
+
* .extend({ ... });
|
|
10
|
+
*
|
|
11
|
+
* 说明:上游导出为 const 而不是 helper function,是为了避免经过泛型
|
|
12
|
+
* wrapper 后 TS 把 drizzle-zod 推导出的深层条件 Shape 归约成 Omit,
|
|
13
|
+
* 从而在下游 `.extend(...)` 时丢失原有字段类型。
|
|
14
|
+
*/
|
|
15
|
+
export declare const BASIC_INSERT_OMIT: {
|
|
16
|
+
readonly id: true;
|
|
17
|
+
readonly creatorId: true;
|
|
18
|
+
readonly editorId: true;
|
|
19
|
+
readonly accessedAt: true;
|
|
20
|
+
readonly createdAt: true;
|
|
21
|
+
readonly updatedAt: true;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* 业务侧 update schema 需要从 drizzle-zod 生成的 schema 中排除的基础字段。
|
|
25
|
+
* update 保留 id(随后用 `.required({ id: true })` 变成必填),其余由
|
|
26
|
+
* 后端 createPutAction 自动维护。
|
|
27
|
+
*/
|
|
28
|
+
export declare const BASIC_UPDATE_OMIT: {
|
|
29
|
+
readonly creatorId: true;
|
|
30
|
+
readonly editorId: true;
|
|
31
|
+
readonly accessedAt: true;
|
|
32
|
+
readonly createdAt: true;
|
|
33
|
+
readonly updatedAt: true;
|
|
34
|
+
};
|
|
35
|
+
export declare const queryListSchema: <Incoming extends z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>>(schema: Incoming) => z.ZodObject<(("orderBy" | "orderDir" | "pageSize" | "creatorId" | "current" | "createdAtFrom" | "createdAtTo") & keyof Incoming["shape"] extends never ? {
|
|
36
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
37
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
38
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
39
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
40
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
41
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
42
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
43
|
+
asc: "asc";
|
|
44
|
+
desc: "desc";
|
|
45
|
+
}>>;
|
|
46
|
+
} & Incoming["shape"] : ({
|
|
47
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
48
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
49
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
50
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
51
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
52
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
53
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
asc: "asc";
|
|
55
|
+
desc: "desc";
|
|
56
|
+
}>>;
|
|
57
|
+
} extends infer T_1 extends z.core.util.SomeObject ? { [K in keyof T_1 as K extends keyof Incoming["shape"] ? never : K]: {
|
|
58
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
59
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
60
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
61
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
62
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
63
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
64
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
asc: "asc";
|
|
66
|
+
desc: "desc";
|
|
67
|
+
}>>;
|
|
68
|
+
}[K]; } : never) & (Incoming["shape"] extends infer T_2 extends z.core.util.SomeObject ? { [K_1 in keyof T_2]: Incoming["shape"][K_1]; } : never)) extends infer T ? { [k in keyof T]: (("orderBy" | "orderDir" | "pageSize" | "creatorId" | "current" | "createdAtFrom" | "createdAtTo") & keyof Incoming["shape"] extends never ? {
|
|
69
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
70
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
71
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
72
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
73
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
74
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
75
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
76
|
+
asc: "asc";
|
|
77
|
+
desc: "desc";
|
|
78
|
+
}>>;
|
|
79
|
+
} & Incoming["shape"] : ({
|
|
80
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
81
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
82
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
83
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
84
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
85
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
86
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
87
|
+
asc: "asc";
|
|
88
|
+
desc: "desc";
|
|
89
|
+
}>>;
|
|
90
|
+
} extends infer T_1 extends z.core.util.SomeObject ? { [K in keyof T_1 as K extends keyof Incoming["shape"] ? never : K]: {
|
|
91
|
+
current: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
92
|
+
pageSize: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
93
|
+
createdAtFrom: z.ZodOptional<z.ZodString>;
|
|
94
|
+
createdAtTo: z.ZodOptional<z.ZodString>;
|
|
95
|
+
orderBy: z.ZodOptional<z.ZodString>;
|
|
96
|
+
creatorId: z.ZodOptional<z.ZodString>;
|
|
97
|
+
orderDir: z.ZodOptional<z.ZodEnum<{
|
|
98
|
+
asc: "asc";
|
|
99
|
+
desc: "desc";
|
|
100
|
+
}>>;
|
|
101
|
+
}[K]; } : never) & (Incoming["shape"] extends infer T_2 extends z.core.util.SomeObject ? { [K_1 in keyof T_2]: Incoming["shape"][K_1]; } : never))[k]; } : never, Incoming["_zod"]["config"]>;
|
|
102
|
+
export declare const listBodySchema: <T extends z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>(schema: T) => z.ZodObject<{
|
|
103
|
+
total: z.ZodNumber;
|
|
104
|
+
data: z.ZodArray<T>;
|
|
105
|
+
}, z.core.$strip>;
|
|
106
|
+
/**
|
|
107
|
+
* 给 schema 上已有的字段挂说明。字段不在这个 schema 里就跳过 —— 同一张表的
|
|
108
|
+
* insert / update / select 三份含的列不一样(basicFields 只在 select 里),一份说明表要能同时
|
|
109
|
+
* 喂给三者,就不能对「字段一定存在」有要求。**不给不存在的字段凭空造一个。**
|
|
110
|
+
*/
|
|
111
|
+
export declare const describeFields: <T extends z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>>(schema: T, notes: Record<string, string>) => T;
|
|
112
|
+
export declare const describeBasicFields: <T extends z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>>(schema: T) => T;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/backend/schemas/common.ts
|
|
20
|
+
var common_exports = {};
|
|
21
|
+
__export(common_exports, {
|
|
22
|
+
BASIC_INSERT_OMIT: () => BASIC_INSERT_OMIT,
|
|
23
|
+
BASIC_UPDATE_OMIT: () => BASIC_UPDATE_OMIT,
|
|
24
|
+
describeBasicFields: () => describeBasicFields,
|
|
25
|
+
describeFields: () => describeFields,
|
|
26
|
+
listBodySchema: () => listBodySchema,
|
|
27
|
+
queryListSchema: () => queryListSchema
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(common_exports);
|
|
30
|
+
var import_zod = require("zod");
|
|
31
|
+
var BASIC_INSERT_OMIT = {
|
|
32
|
+
id: true,
|
|
33
|
+
creatorId: true,
|
|
34
|
+
editorId: true,
|
|
35
|
+
accessedAt: true,
|
|
36
|
+
createdAt: true,
|
|
37
|
+
updatedAt: true
|
|
38
|
+
};
|
|
39
|
+
var BASIC_UPDATE_OMIT = {
|
|
40
|
+
creatorId: true,
|
|
41
|
+
editorId: true,
|
|
42
|
+
accessedAt: true,
|
|
43
|
+
createdAt: true,
|
|
44
|
+
updatedAt: true
|
|
45
|
+
};
|
|
46
|
+
var queryListSchema = (schema) => import_zod.z.object({
|
|
47
|
+
current: import_zod.z.string().optional().default("1").describe("Page number, starting at 1."),
|
|
48
|
+
pageSize: import_zod.z.string().optional().default("10").describe(
|
|
49
|
+
"Rows per page. Omitting it yields only 10 — pass a larger value to get the whole set."
|
|
50
|
+
),
|
|
51
|
+
createdAtFrom: import_zod.z.string().optional().describe(
|
|
52
|
+
"Keep only rows created at or after this instant (ISO 8601, e.g. 2026-08-01T00:00:00Z)."
|
|
53
|
+
),
|
|
54
|
+
createdAtTo: import_zod.z.string().optional().describe("Keep only rows created at or before this instant."),
|
|
55
|
+
orderBy: import_zod.z.string().optional().describe(
|
|
56
|
+
"Column to sort by — a column name of this resource (createdAt / updatedAt and the like)."
|
|
57
|
+
),
|
|
58
|
+
creatorId: import_zod.z.string().optional().describe(
|
|
59
|
+
"Keep only rows created by this user. Useful in shared spaces to filter down to one member."
|
|
60
|
+
),
|
|
61
|
+
orderDir: import_zod.z.enum(["asc", "desc"]).optional().describe("Sort ascending or descending.")
|
|
62
|
+
}).merge(schema);
|
|
63
|
+
var listBodySchema = (schema) => import_zod.z.object({
|
|
64
|
+
total: import_zod.z.number().describe(
|
|
65
|
+
"Total number of rows matching the filters — not the length of `data`. Use it to decide whether another page exists."
|
|
66
|
+
),
|
|
67
|
+
data: import_zod.z.array(schema).describe("This page's rows.")
|
|
68
|
+
});
|
|
69
|
+
var BASIC_FIELD_NOTES = {
|
|
70
|
+
creatorId: "User id of the creator. Stamped by the server; clients cannot send it.",
|
|
71
|
+
editorId: "User id of whoever changed this row last. Stamped by the server; clients cannot send it.",
|
|
72
|
+
id: "Primary key of this row (uuid)."
|
|
73
|
+
};
|
|
74
|
+
var BASIC_TIMESTAMP_NOTES = {
|
|
75
|
+
accessedAt: "When this row was last accessed.",
|
|
76
|
+
createdAt: "When this row was created.",
|
|
77
|
+
updatedAt: "When this row was last modified."
|
|
78
|
+
};
|
|
79
|
+
var describeFields = (schema, notes) => {
|
|
80
|
+
const overlay = {};
|
|
81
|
+
for (const [field, note] of Object.entries(notes)) {
|
|
82
|
+
const existing = schema.shape[field];
|
|
83
|
+
if (existing) {
|
|
84
|
+
overlay[field] = existing.describe(note);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return Object.keys(overlay).length ? schema.extend(overlay) : schema;
|
|
88
|
+
};
|
|
89
|
+
var describeBasicFields = (schema) => {
|
|
90
|
+
const withNotes = describeFields(schema, BASIC_FIELD_NOTES);
|
|
91
|
+
const overlay = {};
|
|
92
|
+
for (const [field, note] of Object.entries(BASIC_TIMESTAMP_NOTES)) {
|
|
93
|
+
const existing = withNotes.shape[field];
|
|
94
|
+
if (existing) {
|
|
95
|
+
overlay[field] = existing.meta({
|
|
96
|
+
description: note,
|
|
97
|
+
format: "date-time",
|
|
98
|
+
type: "string"
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return Object.keys(overlay).length ? withNotes.extend(overlay) : withNotes;
|
|
103
|
+
};
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
BASIC_INSERT_OMIT,
|
|
107
|
+
BASIC_UPDATE_OMIT,
|
|
108
|
+
describeBasicFields,
|
|
109
|
+
describeFields,
|
|
110
|
+
listBodySchema,
|
|
111
|
+
queryListSchema
|
|
112
|
+
});
|