@eggjs/dal-runtime 3.33.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.
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _DataSource_instances, _DataSource_paginateCount;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DataSource = void 0;
10
+ const TableModelInstanceBuilder_1 = require("./TableModelInstanceBuilder");
11
+ const PAGINATE_COUNT_WRAPPER = ['SELECT COUNT(0) as count FROM (', ') AS T'];
12
+ class DataSource {
13
+ constructor(tableModel, mysqlDataSource, sqlMap) {
14
+ _DataSource_instances.add(this);
15
+ this.tableModel = tableModel;
16
+ this.mysqlDataSource = mysqlDataSource;
17
+ this.sqlMap = sqlMap;
18
+ }
19
+ generateSql(sqlName, data) {
20
+ const sql = this.sqlMap.generate(sqlName, data, this.mysqlDataSource.timezone);
21
+ const sqlType = this.sqlMap.getType(sqlName);
22
+ const template = this.sqlMap.getTemplateString(sqlName);
23
+ return {
24
+ sql,
25
+ sqlType,
26
+ template,
27
+ };
28
+ }
29
+ async count(sqlName, data) {
30
+ const newData = Object.assign({ $$count: true }, data);
31
+ const executeSql = this.generateSql(sqlName, newData);
32
+ return await __classPrivateFieldGet(this, _DataSource_instances, "m", _DataSource_paginateCount).call(this, executeSql.sql);
33
+ }
34
+ async execute(sqlName, data) {
35
+ const executeSql = this.generateSql(sqlName, data);
36
+ const rows = await this.mysqlDataSource.query(executeSql.sql);
37
+ return rows.map(t => {
38
+ return TableModelInstanceBuilder_1.TableModelInstanceBuilder.buildInstance(this.tableModel, t);
39
+ });
40
+ }
41
+ async executeRaw(sqlName, data) {
42
+ const executeSql = this.generateSql(sqlName, data);
43
+ return await this.mysqlDataSource.query(executeSql.sql);
44
+ }
45
+ async executeScalar(sqlName, data) {
46
+ const ret = await this.execute(sqlName, data);
47
+ if (!Array.isArray(ret))
48
+ return ret || null;
49
+ return ret[0] || null;
50
+ }
51
+ async executeRawScalar(sqlName, data) {
52
+ const ret = await this.executeRaw(sqlName, data);
53
+ if (!Array.isArray(ret))
54
+ return (ret || null);
55
+ return ret[0] || null;
56
+ }
57
+ async paginate(sqlName, data, currentPage, perPageCount) {
58
+ const limit = `LIMIT ${(currentPage - 1) * perPageCount}, ${perPageCount}`;
59
+ const sql = this.generateSql(sqlName, data).sql + ' ' + limit;
60
+ const countSql = this.generateSql(sqlName, Object.assign({ $$count: true }, data)).sql;
61
+ const ret = await Promise.all([
62
+ this.mysqlDataSource.query(sql),
63
+ __classPrivateFieldGet(this, _DataSource_instances, "m", _DataSource_paginateCount).call(this, countSql),
64
+ ]);
65
+ return {
66
+ total: ret[1],
67
+ pageNum: currentPage,
68
+ rows: ret[0].map(t => TableModelInstanceBuilder_1.TableModelInstanceBuilder.buildInstance(this.tableModel, t)),
69
+ };
70
+ }
71
+ }
72
+ exports.DataSource = DataSource;
73
+ _DataSource_instances = new WeakSet(), _DataSource_paginateCount = async function _DataSource_paginateCount(baseSQL) {
74
+ const sql = `${PAGINATE_COUNT_WRAPPER[0]}${baseSQL}${PAGINATE_COUNT_WRAPPER[1]}`;
75
+ const result = await this.mysqlDataSource.query(sql);
76
+ return result[0].count;
77
+ };
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGF0YVNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9EYXRhU291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUdBLDJFQUF3RTtBQVF4RSxNQUFNLHNCQUFzQixHQUFHLENBQUUsaUNBQWlDLEVBQUUsUUFBUSxDQUFFLENBQUM7QUFFL0UsTUFBYSxVQUFVO0lBS3JCLFlBQVksVUFBeUIsRUFBRSxlQUFnQyxFQUFFLE1BQW1COztRQUMxRixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUN2QyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRU8sV0FBVyxDQUFDLE9BQWUsRUFBRSxJQUFZO1FBQy9DLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFTLENBQUMsQ0FBQztRQUNoRixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELE9BQU87WUFDTCxHQUFHO1lBQ0gsT0FBTztZQUNQLFFBQVE7U0FDVCxDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBZSxFQUFFLElBQVU7UUFDckMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN2RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RCxPQUFPLE1B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
@@ -0,0 +1,15 @@
1
+ import type { RDSClientOptions } from '@eggjs/rds/lib/types';
2
+ import Base from 'sdk-base';
3
+ export interface DataSourceOptions extends RDSClientOptions {
4
+ name: string;
5
+ initSql?: string;
6
+ }
7
+ export declare class MysqlDataSource extends Base {
8
+ private readonly client;
9
+ private readonly initSql;
10
+ readonly name: string;
11
+ readonly timezone?: string;
12
+ constructor(options: DataSourceOptions);
13
+ protected _init(): Promise<void>;
14
+ query<T = any>(sql: string): Promise<T>;
15
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MysqlDataSource = void 0;
7
+ const rds_1 = require("@eggjs/rds");
8
+ const sdk_base_1 = __importDefault(require("sdk-base"));
9
+ const DEFAULT_OPTIONS = {
10
+ supportBigNumbers: true,
11
+ bigNumberStrings: true,
12
+ trace: true,
13
+ };
14
+ class MysqlDataSource extends sdk_base_1.default {
15
+ constructor(options) {
16
+ super({ initMethod: '_init' });
17
+ const { name, initSql, ...mysqlOptions } = options;
18
+ this.client = new rds_1.RDSClient(Object.assign({}, DEFAULT_OPTIONS, mysqlOptions));
19
+ this.initSql = initSql ?? 'SELECT 1 + 1';
20
+ this.name = name;
21
+ this.timezone = options.timezone;
22
+ }
23
+ async _init() {
24
+ if (this.initSql) {
25
+ await this.client.query(this.initSql);
26
+ }
27
+ }
28
+ async query(sql) {
29
+ return this.client.query(sql);
30
+ }
31
+ }
32
+ exports.MysqlDataSource = MysqlDataSource;
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXlTcWxEYXRhU291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL015U3FsRGF0YVNvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvQ0FBdUM7QUFHdkMsd0RBQTRCO0FBUTVCLE1BQU0sZUFBZSxHQUFxQjtJQUN4QyxpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLGdCQUFnQixFQUFFLElBQUk7SUFDdEIsS0FBSyxFQUFFLElBQUk7Q0FDWixDQUFDO0FBRUYsTUFBYSxlQUFnQixTQUFRLGtCQUFJO0lBTXZDLFlBQVksT0FBMEI7UUFDcEMsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDL0IsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxZQUFZLEVBQUUsR0FBRyxPQUFPLENBQUM7UUFDbkQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGVBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUM5RSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxjQUFjLENBQUM7UUFDekMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQ25DLENBQUM7SUFFUyxLQUFLLENBQUMsS0FBSztRQUNuQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLLENBQVUsR0FBVztRQUM5QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7Q0FDRjtBQXhCRCwwQ0F3QkMifQ==
@@ -0,0 +1,73 @@
1
+ export declare class NunjucksConverter {
2
+ /**
3
+ * 将变量 HTML 转义的逻辑改为 MySQL 防注入转义
4
+ *
5
+ * eg:
6
+ *
7
+ * output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "allColumns")
8
+ *
9
+ * 转换为
10
+ *
11
+ * output += runtime.escapeSQL.call(this, "allColumns", runtime.contextOrFrameLookup(context, frame, "allColumns")
12
+ *
13
+ * @param {String} code 转换前的代码
14
+ * @return {String} 转换后的代码
15
+ */
16
+ static convertNormalVariableCode(code: string): string;
17
+ /**
18
+ * 三目运算的 MySQL 防注入转义
19
+ *
20
+ * eg:
21
+ *
22
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(context, frame, "$gmtCreate") !== \
23
+ * runtime.contextOrFrameLookup(context, frame, "undefined")?runtime.contextOrFrameLookup(context,\
24
+ * frame, "$gmtCreate"):"NOW()"), env.opts.autoescape);
25
+ *
26
+ * 转换为
27
+ *
28
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(...) != ...) ?
29
+ * runtime.escapeSQL.call(this, "...", runtime.contextOrFrameLookup(...)) :
30
+ * ...)
31
+ *
32
+ * @param {String} code 转换前的代码
33
+ * @return {String} 转换后的代码
34
+ */
35
+ static convertTernaryCode(code: string): string;
36
+ /**
37
+ * 对象的属性,如 `user.id` 防注入转义
38
+ *
39
+ * eg:
40
+ * output += runtime.suppressValue(runtime.memberLookup(\
41
+ * (runtime.contextOrFrameLookup(context, frame, "user")),"id"), env.opts.autoescape);
42
+ *
43
+ * 转换为
44
+ *
45
+ * output += runtime.escapeSQL.call(this, "<...>", runtime.memberLookup(...), env.opts.autoescape);
46
+ *
47
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
48
+ * 所以找一个绝对不会匹配的 "<...>" 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
49
+ *
50
+ * @param {String} code 转换前的代码
51
+ * @return {String} 转换后的代码
52
+ */
53
+ static convertNestedObjectCode(code: string): string;
54
+ /**
55
+ * For 中的 `t_xxx` 要被转义:
56
+ *
57
+ * eg:
58
+ * frame.set("...", t_...);
59
+ * ...
60
+ * output += runtime.suppressValue(t_.., env.opts.autoscape);
61
+ *
62
+ * 转换为
63
+ *
64
+ * output += runtime.escapeSQL.call(this, "for.t_...", t_..., env.opts.autoescape);
65
+ *
66
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
67
+ * 所以找一个绝对不会匹配的 "for.t_..." 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
68
+ *
69
+ * @param {String} code 转换前的代码
70
+ * @return {String} 转换后的代码
71
+ */
72
+ static convertValueInsideFor(code: string): string;
73
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NunjucksConverter = void 0;
4
+ class NunjucksConverter {
5
+ /**
6
+ * 将变量 HTML 转义的逻辑改为 MySQL 防注入转义
7
+ *
8
+ * eg:
9
+ *
10
+ * output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "allColumns")
11
+ *
12
+ * 转换为
13
+ *
14
+ * output += runtime.escapeSQL.call(this, "allColumns", runtime.contextOrFrameLookup(context, frame, "allColumns")
15
+ *
16
+ * @param {String} code 转换前的代码
17
+ * @return {String} 转换后的代码
18
+ */
19
+ static convertNormalVariableCode(code) {
20
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(runtime\.contextOrFrameLookup\((.+?),(.*?),\W*?"(.+?)"\)/g, '\noutput += runtime.escapeSQL.call(this, "$3", runtime.contextOrFrameLookup($1, $2, "$3")');
21
+ }
22
+ /**
23
+ * 三目运算的 MySQL 防注入转义
24
+ *
25
+ * eg:
26
+ *
27
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(context, frame, "$gmtCreate") !== \
28
+ * runtime.contextOrFrameLookup(context, frame, "undefined")?runtime.contextOrFrameLookup(context,\
29
+ * frame, "$gmtCreate"):"NOW()"), env.opts.autoescape);
30
+ *
31
+ * 转换为
32
+ *
33
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(...) != ...) ?
34
+ * runtime.escapeSQL.call(this, "...", runtime.contextOrFrameLookup(...)) :
35
+ * ...)
36
+ *
37
+ * @param {String} code 转换前的代码
38
+ * @return {String} 转换后的代码
39
+ */
40
+ static convertTernaryCode(code) {
41
+ // 先找到所有的 runtime.suppressValue((...?...:...), env...)
42
+ const ternaryBefore = code.match(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(\(.*\W*?\?\W*?.*?:.*\),\W*?env\.opts\.autoescape/g) || [];
43
+ // 进行逐一处理
44
+ const ternaryAfter = ternaryBefore.map(str => {
45
+ return str.replace(/([\?:])runtime\.contextOrFrameLookup\((.+?),(.*?),\W*?"(.+?)"\)/g, '$1runtime.escapeSQL.call(this, "$4", runtime.contextOrFrameLookup($2, $3, "$4"))')
46
+ .replace(/env.opts.autoescape$/g, 'false');
47
+ });
48
+ // 统一替换
49
+ for (let i = 0; i < ternaryBefore.length; i++) {
50
+ code = code.replace(ternaryBefore[i], ternaryAfter[i]);
51
+ }
52
+ return code;
53
+ }
54
+ /**
55
+ * 对象的属性,如 `user.id` 防注入转义
56
+ *
57
+ * eg:
58
+ * output += runtime.suppressValue(runtime.memberLookup(\
59
+ * (runtime.contextOrFrameLookup(context, frame, "user")),"id"), env.opts.autoescape);
60
+ *
61
+ * 转换为
62
+ *
63
+ * output += runtime.escapeSQL.call(this, "<...>", runtime.memberLookup(...), env.opts.autoescape);
64
+ *
65
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
66
+ * 所以找一个绝对不会匹配的 "<...>" 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
67
+ *
68
+ * @param {String} code 转换前的代码
69
+ * @return {String} 转换后的代码
70
+ */
71
+ static convertNestedObjectCode(code) {
72
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(runtime\.memberLookup\((.+?)\), env\.opts\.autoescape\)/g, '\noutput += runtime.escapeSQL.call(this, "<...>", runtime.memberLookup($1), env.opts.autoescape)');
73
+ }
74
+ /**
75
+ * For 中的 `t_xxx` 要被转义:
76
+ *
77
+ * eg:
78
+ * frame.set("...", t_...);
79
+ * ...
80
+ * output += runtime.suppressValue(t_.., env.opts.autoscape);
81
+ *
82
+ * 转换为
83
+ *
84
+ * output += runtime.escapeSQL.call(this, "for.t_...", t_..., env.opts.autoescape);
85
+ *
86
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
87
+ * 所以找一个绝对不会匹配的 "for.t_..." 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
88
+ *
89
+ * @param {String} code 转换前的代码
90
+ * @return {String} 转换后的代码
91
+ */
92
+ static convertValueInsideFor(code) {
93
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\((t_\d+), env\.opts\.autoescape\)/g, '\noutput += runtime.escapeSQL.call(this, "for.$1", $1, env.opts.autoescape)');
94
+ }
95
+ }
96
+ exports.NunjucksConverter = NunjucksConverter;
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTnVuanVja3NDb252ZXJ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvTnVuanVja3NDb252ZXJ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBYSxpQkFBaUI7SUFDNUI7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxJQUFZO1FBQzNDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsc0dBQXNHLEVBQ3RHLDJGQUEyRixDQUFDLENBQUM7SUFDakcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFZO1FBQ3BDLHNEQUFzRDtRQUN0RCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUM5Qiw4RkFBOEYsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV4RyxTQUFTO1FBQ1QsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUMzQyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQ2hCLGtFQUFrRSxFQUNsRSxrRkFBa0YsQ0FDbkY7aUJBQ0UsT0FBTyxDQUNOLHVCQUF1QixFQUN2QixPQUFPLENBQ1IsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTztRQUNQLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDOUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNILE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxJQUFZO1FBQ3pDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIscUdBQXFHLEVBQ3JHLGtHQUFrRyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNILE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxJQUFZO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsOEVBQThFLEVBQzlFLDZFQUE2RSxDQUFDLENBQUM7SUFDbkYsQ0FBQztDQUVGO0FBL0dELDhDQStHQyJ9
@@ -0,0 +1,5 @@
1
+ import nunjucks from 'nunjucks';
2
+ export declare class NunjucksUtils {
3
+ static createEnv(modelName: string): nunjucks.Environment;
4
+ static compile(modelName: string, sqlName: string, sql: string): nunjucks.Template;
5
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.NunjucksUtils = void 0;
30
+ const nunjucks_1 = __importStar(require("nunjucks"));
31
+ const sqlstring_1 = __importDefault(require("sqlstring"));
32
+ const NunjucksConverter_1 = require("./NunjucksConverter");
33
+ const SqlUtil_1 = require("./SqlUtil");
34
+ const compiler = nunjucks_1.default.compiler;
35
+ const envs = {};
36
+ const ROOT_RENDER_FUNC = Symbol('rootRenderFunc');
37
+ const RUNTIME = Object.assign({}, nunjucks_1.default.runtime, {
38
+ escapeSQL: function escapeSQL(key, value) {
39
+ // 如果是预定义 block 则不转义
40
+ if (this.env.globals[key])
41
+ return value;
42
+ return sqlstring_1.default.escape(value, true, this.env.timezone);
43
+ },
44
+ });
45
+ function _replaceCodeWithSQLFeature(source) {
46
+ const funcs = [
47
+ 'convertNormalVariableCode', // 普通变量
48
+ 'convertTernaryCode', // 三目运算
49
+ 'convertNestedObjectCode', // 对象中的变量,如 `user.id`
50
+ 'convertValueInsideFor', // for 中的值需要转义
51
+ ];
52
+ return funcs.reduce((source, func) => NunjucksConverter_1.NunjucksConverter[func](source), source);
53
+ }
54
+ /**
55
+ * compile the string into function
56
+ * @see https://github.com/mozilla/nunjucks/blob/2fd547f/src/environment.js#L571-L592
57
+ */
58
+ function _compile() {
59
+ let source = compiler.compile(this.tmplStr, this.env.asyncFilters, this.env.extensionsList, this.path, this.env.opts);
60
+ /**
61
+ * 将一些 Nunjucks 的 HTML 转义的代码转换成 SQL 防注入的代码
62
+ */
63
+ source = _replaceCodeWithSQLFeature(source);
64
+ // eslint-disable-next-line
65
+ const props = (new Function(source))();
66
+ this.blocks = this._getBlocks(props);
67
+ this[ROOT_RENDER_FUNC] = props.root;
68
+ this.rootRenderFunc = function (env, context, frame, _runtime, cb) {
69
+ /**
70
+ * 1. 将 runtime 遗弃,用新的
71
+ * 2. 移除 SQL 语句中多余空白符
72
+ */
73
+ return this[ROOT_RENDER_FUNC](env, context, frame, RUNTIME, function (err, ret) {
74
+ // istanbul ignore if
75
+ if (err)
76
+ return cb(err, ret);
77
+ return cb(err, SqlUtil_1.SqlUtil.minify(ret || ''));
78
+ });
79
+ };
80
+ this.compiled = true;
81
+ }
82
+ class NunjucksUtils {
83
+ static createEnv(modelName) {
84
+ if (envs[modelName])
85
+ return envs[modelName];
86
+ const env = envs[modelName] = nunjucks_1.default.configure({
87
+ autoescape: false,
88
+ });
89
+ return env;
90
+ }
91
+ static compile(modelName, sqlName, sql) {
92
+ // istanbul ignore if
93
+ if (!envs[modelName]) {
94
+ throw new Error(`you should create an Environment for ${modelName} first.`);
95
+ }
96
+ const template = new nunjucks_1.Template(sql, envs[modelName], `egg-dal:MySQL:${modelName}:${sqlName}`, false);
97
+ // 做一些 hack,使得支持 MySQL 的一些 Escape
98
+ template._compile = _compile;
99
+ template.compile();
100
+ return template;
101
+ }
102
+ }
103
+ exports.NunjucksUtils = NunjucksUtils;
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTnVuanVja3NVdGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL051bmp1Y2tzVXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUFnRTtBQUNoRSwwREFBa0M7QUFDbEMsMkRBQXdEO0FBQ3hELHVDQUFvQztBQUVwQyxNQUFNLFFBQVEsR0FBSSxrQkFBZ0IsQ0FBQyxRQUFRLENBQUM7QUFDNUMsTUFBTSxJQUFJLEdBQWdDLEVBQUUsQ0FBQztBQUU3QyxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ2xELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGtCQUFRLENBQUMsT0FBTyxFQUFFO0lBQ2xELFNBQVMsRUFBRSxTQUFTLFNBQVMsQ0FBWSxHQUFHLEVBQUUsS0FBSztRQUNqRCxvQkFBb0I7UUFDcEIsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN4QyxPQUFPLG1CQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRCxDQUFDO0NBQ0YsQ0FBQyxDQUFDO0FBRUgsU0FBUywwQkFBMEIsQ0FBQyxNQUFNO0lBQ3hDLE1BQU0sS0FBSyxHQUFHO1FBQ1osMkJBQTJCLEVBQUUsT0FBTztRQUNwQyxvQkFBb0IsRUFBRSxPQUFPO1FBQzdCLHlCQUF5QixFQUFFLHFCQUFxQjtRQUNoRCx1QkFBdUIsRUFBRSxjQUFjO0tBQ3hDLENBQUM7SUFFRixPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFN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
@@ -0,0 +1,9 @@
1
+ import { TableModel } from '@eggjs/dal-decorator';
2
+ export declare class SqlGenerator {
3
+ private formatComment;
4
+ private generateColumn;
5
+ private generateColumnType;
6
+ private generateIndex;
7
+ private generateTableOptions;
8
+ generate(tableModel: TableModel): string;
9
+ }