@ctil/gql 1.0.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/.vscode/launch.json +18 -0
- package/README.md +248 -0
- package/cc-request-1.0.0.tgz +0 -0
- package/dist/fp.esm-VY6KF7TP.js +2699 -0
- package/dist/fp.esm-VY6KF7TP.js.map +1 -0
- package/dist/index.cjs +4632 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +300 -0
- package/dist/index.d.ts +300 -0
- package/dist/index.js +1865 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
- package/src/builders/auth.ts +182 -0
- package/src/builders/baseType.ts +194 -0
- package/src/builders/index.ts +5 -0
- package/src/builders/mutation.ts +341 -0
- package/src/builders/query.ts +180 -0
- package/src/builders/sms.ts +59 -0
- package/src/cache/memoryCache.ts +34 -0
- package/src/core/api/auth.ts +86 -0
- package/src/core/api/gql.ts +22 -0
- package/src/core/api/mutation.ts +100 -0
- package/src/core/api/query.ts +82 -0
- package/src/core/api/sms.ts +18 -0
- package/src/core/client.ts +47 -0
- package/src/core/core.ts +281 -0
- package/src/core/executor.ts +19 -0
- package/src/core/type.ts +76 -0
- package/src/device/index.ts +116 -0
- package/src/index.ts +60 -0
- package/src/rateLimit/rateLimit.ts +51 -0
- package/src/rateLimit/rateLimitConfig.ts +12 -0
- package/src/test.ts +80 -0
- package/tsconfig.json +17 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export type FieldInput =
|
|
2
|
+
| string
|
|
3
|
+
| { [key: string]: FieldNode };
|
|
4
|
+
|
|
5
|
+
export interface FieldNode {
|
|
6
|
+
fields: FieldInput[];
|
|
7
|
+
where?: WhereInput;
|
|
8
|
+
orderBy?: Record<string, any>;
|
|
9
|
+
distinctOn?: string[];
|
|
10
|
+
limit?: number;
|
|
11
|
+
offset?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// where条件
|
|
15
|
+
export interface WhereInput {
|
|
16
|
+
_and?: WhereInput[];
|
|
17
|
+
_or?: WhereInput[];
|
|
18
|
+
_not?: WhereInput;
|
|
19
|
+
[field: string]: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/** 构造 where 字段,所有非变量都转成字符串 */
|
|
24
|
+
export function buildWhere(where: WhereInput): string {
|
|
25
|
+
if (!where) return "";
|
|
26
|
+
const parts: string[] = [];
|
|
27
|
+
for (const key in where) {
|
|
28
|
+
const value = where[key];
|
|
29
|
+
if (key === "_and" || key === "_or") {
|
|
30
|
+
const sub = (value as WhereInput[])
|
|
31
|
+
.map(w => `{ ${buildWhere(w)} }`)
|
|
32
|
+
.filter(Boolean)
|
|
33
|
+
.join(", ");
|
|
34
|
+
if (sub) parts.push(`${key}: [${sub}]`);
|
|
35
|
+
} else if (key === "_not") {
|
|
36
|
+
const sub = buildWhere(value as WhereInput);
|
|
37
|
+
if (sub) parts.push(`${key}: { ${sub} }`);
|
|
38
|
+
} else if (typeof value === "object" && value !== null) {
|
|
39
|
+
const conds = Object.entries(value)
|
|
40
|
+
.map(([op, val]) => {
|
|
41
|
+
if (typeof val === "string" && val.startsWith("$")) return `${op}: ${val}`;
|
|
42
|
+
return `${op}: ${JSON.stringify(String(val))}`; // 强制转字符串
|
|
43
|
+
})
|
|
44
|
+
.join(", ");
|
|
45
|
+
parts.push(`${key}: { ${conds} }`);
|
|
46
|
+
} else {
|
|
47
|
+
if (typeof value === "string" && value.startsWith("$")) {
|
|
48
|
+
parts.push(`${key}: ${value}`);
|
|
49
|
+
} else {
|
|
50
|
+
parts.push(`${key}: ${JSON.stringify(String(value))}`); // 强制转字符串
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return parts.join(", ");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 构造字段 */
|
|
58
|
+
export function buildFields(fields: FieldInput[]): string {
|
|
59
|
+
return fields
|
|
60
|
+
.map(f => {
|
|
61
|
+
if (typeof f === "string") return f;
|
|
62
|
+
const [key, node] = Object.entries(f)[0];
|
|
63
|
+
const args: string[] = [];
|
|
64
|
+
if (node.where) args.push(`where: { ${buildWhere(node.where)} }`);
|
|
65
|
+
if (node.distinctOn) args.push(`distinct_on: [${node.distinctOn.map(s => `${s}`).join(" ")}]`);
|
|
66
|
+
if (node.orderBy)
|
|
67
|
+
args.push(
|
|
68
|
+
`order_by: {${Object.entries(node.orderBy)
|
|
69
|
+
.map(([k, v]) => `${k}: ${v}`) // order_by 值不加引号
|
|
70
|
+
.join(" ")}}`
|
|
71
|
+
);
|
|
72
|
+
if (node.limit !== undefined) args.push(`limit: ${node.limit}`);
|
|
73
|
+
if (node.offset !== undefined) args.push(`offset: ${node.offset}`);
|
|
74
|
+
const argsStr = args.length ? `(${args.join(" ")})` : "";
|
|
75
|
+
return `${key}${argsStr} { ${buildFields(node.fields)} }`;
|
|
76
|
+
})
|
|
77
|
+
.join(" ");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// =================== 返回字段类型 ===================
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/** 构建 mutation 返回字段 */
|
|
88
|
+
export function buildMutationFields(fields: FieldInput[]): string {
|
|
89
|
+
return `affected_rows returning { ${buildFields(fields)} }`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** 构建对象数据为 GraphQL 参数格式 */
|
|
93
|
+
export function buildDataValue(data: Record<string, any>): string {
|
|
94
|
+
// 构建嵌套对象结构
|
|
95
|
+
const parts: string[] = [];
|
|
96
|
+
for (const key in data) {
|
|
97
|
+
const value = data[key];
|
|
98
|
+
if (value === null || value === undefined) continue;
|
|
99
|
+
|
|
100
|
+
if (typeof value === 'string' && value.startsWith('$')) {
|
|
101
|
+
// 变量引用,不加引号
|
|
102
|
+
parts.push(`${key}: ${value}`);
|
|
103
|
+
} else if (typeof value === 'object' && !Array.isArray(value) && value.constructor === Object) {
|
|
104
|
+
// 嵌套对象(纯对象)
|
|
105
|
+
parts.push(`${key}: { ${buildDataValue(value as Record<string, any>)} }`);
|
|
106
|
+
} else if (Array.isArray(value)) {
|
|
107
|
+
// 数组
|
|
108
|
+
const arrStr = value
|
|
109
|
+
.map(v => {
|
|
110
|
+
if (typeof v === 'string' && v.startsWith('$')) return v;
|
|
111
|
+
if (typeof v === 'object' && v !== null && v.constructor === Object) {
|
|
112
|
+
return `{ ${buildDataValue(v as Record<string, any>)} }`;
|
|
113
|
+
}
|
|
114
|
+
return formatGraphQLValue(v);
|
|
115
|
+
})
|
|
116
|
+
.join(' ');
|
|
117
|
+
parts.push(`${key}: [${arrStr}]`);
|
|
118
|
+
} else {
|
|
119
|
+
// 基本类型
|
|
120
|
+
parts.push(`${key}: ${formatGraphQLValue(value)}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return parts.join(' ');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** 格式化 GraphQL 值 */
|
|
127
|
+
export function formatGraphQLValue(value: any): string {
|
|
128
|
+
if (value === null) return 'null';
|
|
129
|
+
if (typeof value === 'string') {
|
|
130
|
+
// 字符串需要加引号
|
|
131
|
+
return JSON.stringify(value);
|
|
132
|
+
}
|
|
133
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
134
|
+
// 数字和布尔值不加引号
|
|
135
|
+
return String(value);
|
|
136
|
+
}
|
|
137
|
+
// 其他类型转为 JSON
|
|
138
|
+
return JSON.stringify(value);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 根据 Java 命名规则生成 GraphQL 实际操作名
|
|
145
|
+
* @param entityName 实体名(首字母大写或驼峰)
|
|
146
|
+
* @param original Java 方法名(例如 "gql_insertOne")
|
|
147
|
+
*/
|
|
148
|
+
export function generateOperationName(entityName: string, original: string): string {
|
|
149
|
+
const lower = original.toLowerCase();
|
|
150
|
+
const e = entityName.toLowerCase();
|
|
151
|
+
|
|
152
|
+
if (original.startsWith("gql_")) {
|
|
153
|
+
if (lower.endsWith("pagelist")) return `get${toPascalCase(entityName)}PageList`;
|
|
154
|
+
if (lower.endsWith("querylist")) return `${e}s`;
|
|
155
|
+
if (lower.endsWith("getbyid")) return `${e}_by_pk`;
|
|
156
|
+
if (lower.endsWith("aggregate")) return `${e}_aggregateount`;
|
|
157
|
+
|
|
158
|
+
if (lower.endsWith("insertone")) return `insert_${e}_one`;
|
|
159
|
+
if (lower.endsWith("batchinsert")) return `insert_${e}s`;
|
|
160
|
+
|
|
161
|
+
if (lower.endsWith("batchupdate")) return `update_${e}_many`;
|
|
162
|
+
if (lower.endsWith("updatebypk")) return `update_${e}_by_pk`;
|
|
163
|
+
if (lower.endsWith("update")) return `update_${e}`;
|
|
164
|
+
|
|
165
|
+
if (lower.endsWith("deletebyid")) return `delete_${e}_by_pk`;
|
|
166
|
+
if (lower.endsWith("delete")) return `delete_${e}`;
|
|
167
|
+
}
|
|
168
|
+
return original;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
// 首字母大写函数
|
|
173
|
+
export function toPascalCase(str: string): string {
|
|
174
|
+
const camel = str
|
|
175
|
+
.replace(/[-_ ]+(\w)/g, (_, c) => (c ? c.toUpperCase() : ''))
|
|
176
|
+
.replace(/^\w/, c => c.toLowerCase());
|
|
177
|
+
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
// ------------------- 通用:CommonResult 选择集构建 -------------------
|
|
183
|
+
export function buildCommonResultSelection(dataFields?: FieldInput[]): string {
|
|
184
|
+
if (dataFields && dataFields.length > 0) {
|
|
185
|
+
return `success code message data { ${buildFields(dataFields)} }`;
|
|
186
|
+
}
|
|
187
|
+
// data 为标量(例如 Boolean)时,不能选择子字段
|
|
188
|
+
return `success code message data`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { buildWhere, buildFields, buildDataValue,formatGraphQLValue,buildMutationFields,buildCommonResultSelection } from './baseType.ts';
|
|
2
|
+
import type { WhereInput, FieldInput } from './baseType.ts';
|
|
3
|
+
|
|
4
|
+
// =================== 插入 ===================
|
|
5
|
+
|
|
6
|
+
// 单个插入入参
|
|
7
|
+
export interface InsertOneInput {
|
|
8
|
+
operationName: string; // 实体名,例如 user
|
|
9
|
+
fields: FieldInput[]; // 返回字段
|
|
10
|
+
data: Record<string, any>; // 插入的数据
|
|
11
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 批量插入入参
|
|
15
|
+
export interface BatchInsertInput {
|
|
16
|
+
operationName: string; // 实体名,例如 user
|
|
17
|
+
fields: FieldInput[]; // 返回字段
|
|
18
|
+
datas: Record<string, any>[]; // 插入的数据列表
|
|
19
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// =================== 修改 ===================
|
|
23
|
+
|
|
24
|
+
// 根据条件更新入参
|
|
25
|
+
export interface UpdateInput {
|
|
26
|
+
operationName: string; // 实体名,例如 user
|
|
27
|
+
fields: FieldInput[]; // 返回字段
|
|
28
|
+
_set: Record<string, any>; // 更新的数据
|
|
29
|
+
where: WhereInput; // 条件(必需)
|
|
30
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 批量更新入参(根据 ID)
|
|
34
|
+
export interface BatchUpdateInput {
|
|
35
|
+
operationName: string; // 实体名,例如 user
|
|
36
|
+
fields: FieldInput[]; // 返回字段
|
|
37
|
+
_set: Record<string, any>[]; // 更新的数据列表(每条必须包含 id)
|
|
38
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 根据主键更新入参
|
|
42
|
+
export interface UpdateByPkInput {
|
|
43
|
+
operationName: string; // 实体名,例如 user
|
|
44
|
+
fields: FieldInput[]; // 返回字段
|
|
45
|
+
_set: Record<string, any>; // 更新的数据
|
|
46
|
+
pk_columns: string | number; // 主键ID
|
|
47
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// =================== 删除 ===================
|
|
51
|
+
|
|
52
|
+
// 根据主键删除入参
|
|
53
|
+
export interface DeleteByIdInput {
|
|
54
|
+
operationName: string; // 实体名,例如 user
|
|
55
|
+
fields: FieldInput[]; // 返回字段(删除前的数据)
|
|
56
|
+
pk_columns: string | number; // 主键ID
|
|
57
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 根据条件删除入参
|
|
61
|
+
export interface DeleteInput {
|
|
62
|
+
operationName: string; // 实体名,例如 user
|
|
63
|
+
fields: FieldInput[]; // 返回字段(删除前的数据)
|
|
64
|
+
where: WhereInput; // 条件(必需)
|
|
65
|
+
variables?: Record<string, any>; // 传入的变量名和初始值
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// =================== 返回字段类型 ===================
|
|
69
|
+
|
|
70
|
+
// Mutation 返回字段
|
|
71
|
+
export type MutationField = {
|
|
72
|
+
affected_rows?: boolean; // 是否返回受影响行数
|
|
73
|
+
returning?: FieldInput[]; // 返回的数据字段
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
// =================== 插入操作 ===================
|
|
80
|
+
|
|
81
|
+
/** 生成单个插入的 GraphQL mutation */
|
|
82
|
+
export function buildGraphQLMutationInsertOne(input: InsertOneInput) {
|
|
83
|
+
const { operationName, fields, data, variables } = input;
|
|
84
|
+
const entityName = operationName.toLowerCase();
|
|
85
|
+
|
|
86
|
+
// 生成变量定义
|
|
87
|
+
const varDefs = variables
|
|
88
|
+
? Object.keys(variables)
|
|
89
|
+
.map(k => `$${k}: String!`)
|
|
90
|
+
.join(', ')
|
|
91
|
+
: '';
|
|
92
|
+
|
|
93
|
+
// 构建 data 参数(可以作为变量传入,或直接内联)
|
|
94
|
+
let dataArg: string;
|
|
95
|
+
if (variables && variables.data) {
|
|
96
|
+
dataArg = '$data';
|
|
97
|
+
} else {
|
|
98
|
+
dataArg = `{ ${buildDataValue(data)} }`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 更新 variables
|
|
102
|
+
const finalVariables: Record<string, any> = variables || {};
|
|
103
|
+
if (!variables || !variables.data) {
|
|
104
|
+
finalVariables.data = data;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const mutationName = `insert_${entityName}_one`;
|
|
108
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
109
|
+
${mutationName}(${operationName}: ${dataArg}) {
|
|
110
|
+
${buildMutationFields(fields)}
|
|
111
|
+
}
|
|
112
|
+
}`;
|
|
113
|
+
|
|
114
|
+
return { query, variables: finalVariables };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** 生成批量插入的 GraphQL mutation */
|
|
118
|
+
export function buildGraphQLMutationBatchInsert(input: BatchInsertInput) {
|
|
119
|
+
const { operationName, fields, datas, variables } = input;
|
|
120
|
+
const entityName = operationName.toLowerCase();
|
|
121
|
+
|
|
122
|
+
// 生成变量定义
|
|
123
|
+
const varDefs = variables
|
|
124
|
+
? Object.keys(variables)
|
|
125
|
+
.map(k => `$${k}: String!`)
|
|
126
|
+
.join(', ')
|
|
127
|
+
: '';
|
|
128
|
+
|
|
129
|
+
// 构建 datas 参数
|
|
130
|
+
let datasArg: string;
|
|
131
|
+
if (variables && variables.datas) {
|
|
132
|
+
datasArg = '$datas';
|
|
133
|
+
} else {
|
|
134
|
+
const datasArr = datas.map(d => `{ ${buildDataValue(d)} }`).join(' ');
|
|
135
|
+
datasArg = `[${datasArr}]`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 更新 variables
|
|
139
|
+
const finalVariables: Record<string, any> = variables || {};
|
|
140
|
+
if (!variables || !variables.datas) {
|
|
141
|
+
finalVariables.datas = datas;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const mutationName = `insert_${entityName}s`;
|
|
145
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
146
|
+
${mutationName}(${operationName}s: ${datasArg}) {
|
|
147
|
+
affected_rows
|
|
148
|
+
returning { ${buildFields(fields)} }
|
|
149
|
+
}
|
|
150
|
+
}`;
|
|
151
|
+
|
|
152
|
+
return { query, variables: finalVariables };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
// =================== 修改操作 ===================
|
|
159
|
+
|
|
160
|
+
/** 生成根据条件更新的 GraphQL mutation */
|
|
161
|
+
export function buildGraphQLMutationUpdate(input: UpdateInput) {
|
|
162
|
+
const { operationName, fields, _set, where, variables } = input;
|
|
163
|
+
const entityName = operationName.toLowerCase();
|
|
164
|
+
|
|
165
|
+
// 生成变量定义
|
|
166
|
+
const varDefs = variables
|
|
167
|
+
? Object.keys(variables)
|
|
168
|
+
.map(k => `$${k}: String!`)
|
|
169
|
+
.join(', ')
|
|
170
|
+
: '';
|
|
171
|
+
|
|
172
|
+
// 构建参数
|
|
173
|
+
const args: string[] = [];
|
|
174
|
+
|
|
175
|
+
// _set 参数
|
|
176
|
+
let setArg: string;
|
|
177
|
+
if (variables && variables._set) {
|
|
178
|
+
setArg = '$_set';
|
|
179
|
+
} else {
|
|
180
|
+
setArg = `{ ${buildDataValue(_set)} }`;
|
|
181
|
+
}
|
|
182
|
+
args.push(`_set: ${setArg}`);
|
|
183
|
+
|
|
184
|
+
// where 参数
|
|
185
|
+
args.push(`where: { ${buildWhere(where)} }`);
|
|
186
|
+
|
|
187
|
+
// 更新 variables
|
|
188
|
+
const finalVariables: Record<string, any> = variables || {};
|
|
189
|
+
if (!variables || !variables._set) {
|
|
190
|
+
finalVariables._set = _set;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const mutationName = `update_${entityName}`;
|
|
194
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
195
|
+
${mutationName}(${args.join(', ')}) {
|
|
196
|
+
${buildMutationFields(fields)}
|
|
197
|
+
}
|
|
198
|
+
}`;
|
|
199
|
+
|
|
200
|
+
return { query, variables: finalVariables };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** 生成批量更新的 GraphQL mutation(根据 ID) */
|
|
204
|
+
export function buildGraphQLMutationBatchUpdate(input: BatchUpdateInput) {
|
|
205
|
+
const { operationName, fields, _set, variables } = input;
|
|
206
|
+
const entityName = operationName.toLowerCase();
|
|
207
|
+
|
|
208
|
+
// 生成变量定义
|
|
209
|
+
const varDefs = variables
|
|
210
|
+
? Object.keys(variables)
|
|
211
|
+
.map(k => `$${k}: String!`)
|
|
212
|
+
.join(', ')
|
|
213
|
+
: '';
|
|
214
|
+
|
|
215
|
+
// 构建 _set 参数
|
|
216
|
+
let setArg: string;
|
|
217
|
+
if (variables && variables._set) {
|
|
218
|
+
setArg = '$_set';
|
|
219
|
+
} else {
|
|
220
|
+
const setsArr = _set.map(s => `{ ${buildDataValue(s)} }`).join(' ');
|
|
221
|
+
setArg = `[${setsArr}]`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 更新 variables
|
|
225
|
+
const finalVariables: Record<string, any> = variables || {};
|
|
226
|
+
if (!variables || !variables._set) {
|
|
227
|
+
finalVariables._set = _set;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const mutationName = `update_${entityName}_many`;
|
|
231
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
232
|
+
${mutationName}(_set: ${setArg}) {
|
|
233
|
+
affected_rows
|
|
234
|
+
returning { ${buildFields(fields)} }
|
|
235
|
+
}
|
|
236
|
+
}`;
|
|
237
|
+
|
|
238
|
+
return { query, variables: finalVariables };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** 生成根据主键更新的 GraphQL mutation */
|
|
242
|
+
export function buildGraphQLMutationUpdateByPk(input: UpdateByPkInput) {
|
|
243
|
+
const { operationName, fields, _set, pk_columns, variables } = input;
|
|
244
|
+
const entityName = operationName.toLowerCase();
|
|
245
|
+
|
|
246
|
+
// 生成变量定义
|
|
247
|
+
const varDefs = variables
|
|
248
|
+
? Object.keys(variables)
|
|
249
|
+
.map(k => `$${k}: String!`)
|
|
250
|
+
.join(', ')
|
|
251
|
+
: '';
|
|
252
|
+
|
|
253
|
+
// 构建参数
|
|
254
|
+
const args: string[] = [];
|
|
255
|
+
|
|
256
|
+
// _set 参数
|
|
257
|
+
let setArg: string;
|
|
258
|
+
if (variables && variables._set) {
|
|
259
|
+
setArg = '$_set';
|
|
260
|
+
} else {
|
|
261
|
+
setArg = `{ ${buildDataValue(_set)} }`;
|
|
262
|
+
}
|
|
263
|
+
args.push(`_set: ${setArg}`);
|
|
264
|
+
|
|
265
|
+
// pk_columns 参数(固定使用 Long! 类型)
|
|
266
|
+
args.push(`pk_columns: ${formatGraphQLValue(pk_columns)}`);
|
|
267
|
+
|
|
268
|
+
// 更新 variables
|
|
269
|
+
const finalVariables: Record<string, any> = variables || {};
|
|
270
|
+
if (!variables || !variables._set) {
|
|
271
|
+
finalVariables._set = _set;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const mutationName = `update_${entityName}_by_pk`;
|
|
275
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
276
|
+
${mutationName}(${args.join(', ')}) {
|
|
277
|
+
${buildMutationFields(fields)}
|
|
278
|
+
}
|
|
279
|
+
}`;
|
|
280
|
+
|
|
281
|
+
return { query, variables: finalVariables };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
// =================== 删除操作 ===================
|
|
287
|
+
|
|
288
|
+
/** 生成根据主键删除的 GraphQL mutation */
|
|
289
|
+
export function buildGraphQLMutationDeleteById(input: DeleteByIdInput) {
|
|
290
|
+
const { operationName, fields, pk_columns, variables } = input;
|
|
291
|
+
const entityName = operationName.toLowerCase();
|
|
292
|
+
|
|
293
|
+
// 生成变量定义
|
|
294
|
+
const varDefs = variables
|
|
295
|
+
? Object.keys(variables)
|
|
296
|
+
.map(k => `$${k}: String!`)
|
|
297
|
+
.join(', ')
|
|
298
|
+
: '';
|
|
299
|
+
|
|
300
|
+
// pk_columns 参数(固定使用 Long! 类型)
|
|
301
|
+
const args = `pk_columns: ${formatGraphQLValue(pk_columns)}`;
|
|
302
|
+
|
|
303
|
+
const mutationName = `delete_${entityName}_by_pk`;
|
|
304
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
305
|
+
${mutationName}(${args}) {
|
|
306
|
+
${buildMutationFields(fields)}
|
|
307
|
+
}
|
|
308
|
+
}`;
|
|
309
|
+
|
|
310
|
+
return { query, variables: variables || {} };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** 生成根据条件删除的 GraphQL mutation */
|
|
314
|
+
export function buildGraphQLMutationDelete(input: DeleteInput) {
|
|
315
|
+
const { operationName, fields, where, variables } = input;
|
|
316
|
+
const entityName = operationName.toLowerCase();
|
|
317
|
+
|
|
318
|
+
// 生成变量定义
|
|
319
|
+
const varDefs = variables
|
|
320
|
+
? Object.keys(variables)
|
|
321
|
+
.map(k => `$${k}: String!`)
|
|
322
|
+
.join(', ')
|
|
323
|
+
: '';
|
|
324
|
+
|
|
325
|
+
// where 参数
|
|
326
|
+
const args = `where: { ${buildWhere(where)} }`;
|
|
327
|
+
|
|
328
|
+
const mutationName = `delete_${entityName}`;
|
|
329
|
+
const query = `mutation ${mutationName}${varDefs ? `(${varDefs})` : ''} {
|
|
330
|
+
${mutationName}(${args}) {
|
|
331
|
+
affected_rows
|
|
332
|
+
returning { ${buildFields(fields)} }
|
|
333
|
+
}
|
|
334
|
+
}`;
|
|
335
|
+
|
|
336
|
+
return { query, variables: variables || {} };
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|