@nocobase/plugin-flow-engine 2.0.0-alpha.2

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.
Files changed (125) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +29 -0
  3. package/build.config.ts +22 -0
  4. package/client.d.ts +2 -0
  5. package/client.js +1 -0
  6. package/dist/client/index.d.ts +15 -0
  7. package/dist/client/index.js +10 -0
  8. package/dist/externalVersion.js +21 -0
  9. package/dist/index.d.ts +10 -0
  10. package/dist/index.js +48 -0
  11. package/dist/locale/en-US.json +61 -0
  12. package/dist/locale/index.d.ts +141 -0
  13. package/dist/locale/index.js +79 -0
  14. package/dist/locale/zh-CN.json +61 -0
  15. package/dist/node_modules/ses/LICENSE +201 -0
  16. package/dist/node_modules/ses/LICENSE-aura +16 -0
  17. package/dist/node_modules/ses/LICENSE-caja +13 -0
  18. package/dist/node_modules/ses/LICENSE-corejs +19 -0
  19. package/dist/node_modules/ses/LICENSE-v8 +9 -0
  20. package/dist/node_modules/ses/assert-shim.js +1 -0
  21. package/dist/node_modules/ses/compartment-shim.js +1 -0
  22. package/dist/node_modules/ses/console-shim.js +1 -0
  23. package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
  24. package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
  25. package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
  26. package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
  27. package/dist/node_modules/ses/dist/ses.cjs +1 -0
  28. package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
  29. package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
  30. package/dist/node_modules/ses/dist/types.d.cts +606 -0
  31. package/dist/node_modules/ses/index.js +18 -0
  32. package/dist/node_modules/ses/lockdown-shim.js +1 -0
  33. package/dist/node_modules/ses/lockdown.js +1 -0
  34. package/dist/node_modules/ses/package.json +1 -0
  35. package/dist/node_modules/ses/src/assert-shim.js +4 -0
  36. package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
  37. package/dist/node_modules/ses/src/cauterize-property.js +69 -0
  38. package/dist/node_modules/ses/src/commons.js +425 -0
  39. package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
  40. package/dist/node_modules/ses/src/compartment-shim.js +22 -0
  41. package/dist/node_modules/ses/src/compartment.js +477 -0
  42. package/dist/node_modules/ses/src/console-shim.js +50 -0
  43. package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
  44. package/dist/node_modules/ses/src/enablements.js +244 -0
  45. package/dist/node_modules/ses/src/error/assert.js +584 -0
  46. package/dist/node_modules/ses/src/error/console.js +541 -0
  47. package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
  48. package/dist/node_modules/ses/src/error/internal-types.js +98 -0
  49. package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
  50. package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
  51. package/dist/node_modules/ses/src/error/tame-console.js +197 -0
  52. package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
  53. package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
  54. package/dist/node_modules/ses/src/error/types.js +59 -0
  55. package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
  56. package/dist/node_modules/ses/src/eval-scope.js +89 -0
  57. package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
  58. package/dist/node_modules/ses/src/get-source-url.js +50 -0
  59. package/dist/node_modules/ses/src/global-object.js +175 -0
  60. package/dist/node_modules/ses/src/intrinsics.js +192 -0
  61. package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
  62. package/dist/node_modules/ses/src/lockdown.js +558 -0
  63. package/dist/node_modules/ses/src/make-eval-function.js +28 -0
  64. package/dist/node_modules/ses/src/make-evaluate.js +110 -0
  65. package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
  66. package/dist/node_modules/ses/src/make-hardener.js +275 -0
  67. package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
  68. package/dist/node_modules/ses/src/module-instance.js +497 -0
  69. package/dist/node_modules/ses/src/module-link.js +159 -0
  70. package/dist/node_modules/ses/src/module-load.js +719 -0
  71. package/dist/node_modules/ses/src/module-proxy.js +200 -0
  72. package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
  73. package/dist/node_modules/ses/src/permits.js +1761 -0
  74. package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
  75. package/dist/node_modules/ses/src/reporting.js +105 -0
  76. package/dist/node_modules/ses/src/scope-constants.js +180 -0
  77. package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
  78. package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
  79. package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
  80. package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
  81. package/dist/node_modules/ses/src/tame-domains.js +41 -0
  82. package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
  83. package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
  84. package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
  85. package/dist/node_modules/ses/src/tame-harden.js +29 -0
  86. package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
  87. package/dist/node_modules/ses/src/tame-math-object.js +41 -0
  88. package/dist/node_modules/ses/src/tame-module-source.js +51 -0
  89. package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
  90. package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
  91. package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
  92. package/dist/node_modules/ses/src/transforms.js +267 -0
  93. package/dist/node_modules/ses/tools.js +25 -0
  94. package/dist/node_modules/ses/types.d.ts +606 -0
  95. package/dist/server/actions/ui-schema-action.d.ts +27 -0
  96. package/dist/server/actions/ui-schema-action.js +118 -0
  97. package/dist/server/collections/flowModelTreePath.d.ts +11 -0
  98. package/dist/server/collections/flowModelTreePath.js +74 -0
  99. package/dist/server/collections/flowModels.d.ts +11 -0
  100. package/dist/server/collections/flowModels.js +57 -0
  101. package/dist/server/collections/flowsql.d.ts +10 -0
  102. package/dist/server/collections/flowsql.js +51 -0
  103. package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
  104. package/dist/server/dao/ui_schema_node_dao.js +24 -0
  105. package/dist/server/helper.d.ts +8 -0
  106. package/dist/server/helper.js +9 -0
  107. package/dist/server/index.d.ts +9 -0
  108. package/dist/server/index.js +42 -0
  109. package/dist/server/model.d.ts +12 -0
  110. package/dist/server/model.js +38 -0
  111. package/dist/server/plugin.d.ts +26 -0
  112. package/dist/server/plugin.js +270 -0
  113. package/dist/server/repository.d.ts +116 -0
  114. package/dist/server/repository.js +1209 -0
  115. package/dist/server/server.d.ts +16 -0
  116. package/dist/server/server.js +198 -0
  117. package/dist/server/template/contexts.d.ts +73 -0
  118. package/dist/server/template/contexts.js +233 -0
  119. package/dist/server/template/resolver.d.ts +30 -0
  120. package/dist/server/template/resolver.js +225 -0
  121. package/dist/server/variables/registry.d.ts +42 -0
  122. package/dist/server/variables/registry.js +299 -0
  123. package/package.json +28 -0
  124. package/server.d.ts +2 -0
  125. package/server.js +1 -0
@@ -0,0 +1,1209 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var __decorateClass = (decorators, target, key, kind) => {
38
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
39
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
40
+ if (decorator = decorators[i])
41
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
42
+ if (kind && result) __defProp(target, key, result);
43
+ return result;
44
+ };
45
+ var repository_exports = {};
46
+ __export(repository_exports, {
47
+ FlowModelRepository: () => FlowModelRepository,
48
+ default: () => repository_default,
49
+ transaction: () => transaction
50
+ });
51
+ module.exports = __toCommonJS(repository_exports);
52
+ var import_database = require("@nocobase/database");
53
+ var import_utils = require("@nocobase/utils");
54
+ var import_lodash = __toESM(require("lodash"));
55
+ const nodeKeys = ["properties", "definitions", "patternProperties", "additionalProperties", "items"];
56
+ function transaction(transactionAbleArgPosition) {
57
+ return (target, propertyKey, descriptor) => {
58
+ const originalMethod = descriptor.value;
59
+ descriptor.value = async function(...args) {
60
+ if (!import_lodash.default.isNumber(transactionAbleArgPosition)) {
61
+ transactionAbleArgPosition = originalMethod.length - 1;
62
+ }
63
+ let transaction2 = import_lodash.default.get(args, [transactionAbleArgPosition, "transaction"]);
64
+ let handleTransaction = false;
65
+ if (!transaction2) {
66
+ transaction2 = await this.database.sequelize.transaction();
67
+ handleTransaction = true;
68
+ import_lodash.default.set(args, transactionAbleArgPosition, {
69
+ ...import_lodash.default.get(args, transactionAbleArgPosition, {}),
70
+ transaction: transaction2
71
+ });
72
+ }
73
+ if (handleTransaction) {
74
+ try {
75
+ const results = await originalMethod.apply(this, args);
76
+ await transaction2.commit();
77
+ return results;
78
+ } catch (e) {
79
+ await transaction2.rollback();
80
+ throw e;
81
+ }
82
+ } else {
83
+ return await originalMethod.apply(this, args);
84
+ }
85
+ };
86
+ return descriptor;
87
+ };
88
+ }
89
+ const _FlowModelRepository = class _FlowModelRepository extends import_database.Repository {
90
+ cache;
91
+ get flowModelsTableName() {
92
+ return this.tableNameAdapter(this.model.tableName);
93
+ }
94
+ get flowModelTreePathTableName() {
95
+ const model = this.database.getCollection("flowModelTreePath").model;
96
+ return this.tableNameAdapter(model.tableName);
97
+ }
98
+ static schemaToSingleNodes(schema, carry = [], childOptions = null) {
99
+ const node = import_lodash.default.cloneDeep(
100
+ import_lodash.default.isString(schema) ? {
101
+ uid: schema
102
+ } : schema
103
+ );
104
+ if (!import_lodash.default.get(node, "name")) {
105
+ node.name = (0, import_utils.uid)();
106
+ }
107
+ if (!import_lodash.default.get(node, "uid")) {
108
+ node["uid"] = (0, import_utils.uid)();
109
+ }
110
+ if (childOptions) {
111
+ node.childOptions = childOptions;
112
+ }
113
+ carry.push(node);
114
+ for (const nodeKey of nodeKeys) {
115
+ const nodeProperty = import_lodash.default.get(node, nodeKey);
116
+ const childNodeChildOptions = {
117
+ parentUid: node["uid"],
118
+ parentPath: [node["uid"], ...import_lodash.default.get(childOptions, "parentPath", [])],
119
+ type: nodeKey
120
+ };
121
+ if (nodeKey === "items" && nodeProperty) {
122
+ const handleItems = import_lodash.default.isArray(nodeProperty) ? nodeProperty : [nodeProperty];
123
+ for (const [i, item] of handleItems.entries()) {
124
+ carry = this.schemaToSingleNodes(item, carry, { ...childNodeChildOptions, sort: i + 1 });
125
+ }
126
+ } else if (import_lodash.default.isPlainObject(nodeProperty)) {
127
+ const subNodeNames = import_lodash.default.keys(import_lodash.default.get(node, nodeKey));
128
+ delete node[nodeKey];
129
+ for (const [i, subNodeName] of subNodeNames.entries()) {
130
+ const subSchema = {
131
+ name: subNodeName,
132
+ ...import_lodash.default.get(nodeProperty, subNodeName)
133
+ };
134
+ carry = this.schemaToSingleNodes(subSchema, carry, { ...childNodeChildOptions, sort: i + 1 });
135
+ }
136
+ }
137
+ }
138
+ return carry;
139
+ }
140
+ // if you need to handle cache in repo method, so you must set cache first
141
+ setCache(cache) {
142
+ this.cache = cache;
143
+ }
144
+ /**
145
+ * clear cache with xUid which in flowModelTreePath's Path
146
+ * @param {string} xUid
147
+ * @param {Transaction} transaction
148
+ * @returns {Promise<void>}
149
+ */
150
+ async clearXUidPathCache(xUid, transaction2) {
151
+ if (!this.cache || !xUid) {
152
+ return;
153
+ }
154
+ const uiSchemaNodes = await this.database.getRepository("flowModelTreePath").find({
155
+ filter: {
156
+ descendant: xUid
157
+ },
158
+ transaction: transaction2
159
+ });
160
+ for (const uiSchemaNode of uiSchemaNodes) {
161
+ await this.cache.del(`p_${uiSchemaNode["ancestor"]}`);
162
+ await this.cache.del(`s_${uiSchemaNode["ancestor"]}`);
163
+ }
164
+ }
165
+ tableNameAdapter(tableName) {
166
+ if (this.database.sequelize.getDialect() === "postgres") {
167
+ return `"${this.database.options.schema || "public"}"."${tableName}"`;
168
+ }
169
+ return tableName;
170
+ }
171
+ sqlAdapter(sql) {
172
+ if (this.database.isMySQLCompatibleDialect()) {
173
+ return import_lodash.default.replace(sql, /"/g, "`");
174
+ }
175
+ return sql;
176
+ }
177
+ async getProperties(uid2, options = {}) {
178
+ if ((options == null ? void 0 : options.readFromCache) && this.cache) {
179
+ return this.cache.wrap(`p_${uid2}`, () => {
180
+ return this.doGetProperties(uid2, options);
181
+ });
182
+ }
183
+ return this.doGetProperties(uid2, options);
184
+ }
185
+ async getParentJsonSchema(uid2, options = {}) {
186
+ const parentUid = await this.findParentUid(uid2, options.transaction);
187
+ if (!parentUid) {
188
+ return null;
189
+ }
190
+ return this.getJsonSchema(parentUid, options);
191
+ }
192
+ async getParentProperty(uid2, options = {}) {
193
+ const parentUid = await this.findParentUid(uid2, options.transaction);
194
+ if (!parentUid) {
195
+ return null;
196
+ }
197
+ return this.getJsonSchema(parentUid, options);
198
+ }
199
+ async getJsonSchema(uid2, options) {
200
+ if ((options == null ? void 0 : options.readFromCache) && this.cache) {
201
+ return this.cache.wrap(`s_${uid2}`, () => {
202
+ return this.doGetJsonSchema(uid2, options);
203
+ });
204
+ }
205
+ return this.doGetJsonSchema(uid2, options);
206
+ }
207
+ nodesToSchema(nodes, rootUid) {
208
+ const nodeAttributeSanitize = (node) => {
209
+ const schema = {
210
+ ...this.ignoreSchemaProperties(import_lodash.default.isPlainObject(node.options) ? node.options : JSON.parse(node.options)),
211
+ ...import_lodash.default.pick(node, [...nodeKeys, "name"]),
212
+ ["uid"]: node["uid"],
213
+ ["x-async"]: !!node.async
214
+ };
215
+ if (import_lodash.default.isNumber(node.sort)) {
216
+ schema["x-index"] = node.sort;
217
+ }
218
+ return schema;
219
+ };
220
+ const buildTree = (rootNode) => {
221
+ if (!rootNode) {
222
+ return null;
223
+ }
224
+ const children = nodes.filter((node) => node.parent == rootNode["uid"]);
225
+ if (children.length > 0) {
226
+ const childrenGroupByType = import_lodash.default.groupBy(children, "type");
227
+ for (const childType of Object.keys(childrenGroupByType)) {
228
+ const properties = childrenGroupByType[childType].map((child) => buildTree(child)).sort((a, b) => a["x-index"] - b["x-index"]);
229
+ rootNode[childType] = childType == "items" ? properties.length == 1 ? properties[0] : properties : properties.reduce((carry, item) => {
230
+ carry[item.name] = item;
231
+ delete item["name"];
232
+ return carry;
233
+ }, {});
234
+ }
235
+ }
236
+ return nodeAttributeSanitize(rootNode);
237
+ };
238
+ return buildTree(nodes.find((node) => node["uid"] == rootUid));
239
+ }
240
+ async clearAncestor(uid2, options) {
241
+ await this.clearXUidPathCache(uid2, options == null ? void 0 : options.transaction);
242
+ const db = this.database;
243
+ const treeTable = this.flowModelTreePathTableName;
244
+ await db.sequelize.query(
245
+ `DELETE
246
+ FROM ${treeTable}
247
+ WHERE descendant IN
248
+ (SELECT descendant FROM (SELECT descendant FROM ${treeTable} WHERE ancestor = :uid) as descendantTable)
249
+ AND ancestor IN (SELECT ancestor
250
+ FROM (SELECT ancestor FROM ${treeTable} WHERE descendant = :uid AND ancestor != descendant) as ancestorTable)
251
+ `,
252
+ {
253
+ type: "DELETE",
254
+ replacements: {
255
+ uid: uid2
256
+ },
257
+ transaction: options.transaction
258
+ }
259
+ );
260
+ }
261
+ async emitAfterSaveEvent(s, options) {
262
+ if (!(s == null ? void 0 : s.options)) {
263
+ return;
264
+ }
265
+ const keys = [
266
+ "title",
267
+ "description",
268
+ "x-component-props.title",
269
+ "x-decorator-props.title",
270
+ "x-component-props.content"
271
+ ];
272
+ let r = false;
273
+ for (const key of keys) {
274
+ if (import_lodash.default.get(s == null ? void 0 : s.options, key)) {
275
+ r = true;
276
+ break;
277
+ }
278
+ }
279
+ if (r) {
280
+ await this.database.emitAsync(`${this.collection.name}.afterSave`, s, options);
281
+ }
282
+ }
283
+ async patch(newSchema, options) {
284
+ const { transaction: transaction2 } = options;
285
+ const rootUid = newSchema["uid"];
286
+ await this.clearXUidPathCache(rootUid, transaction2);
287
+ if (!newSchema["properties"]) {
288
+ const s = await this.model.findByPk(rootUid, { transaction: transaction2 });
289
+ s.set("options", { ...s.toJSON(), ...newSchema });
290
+ await s.save({ transaction: transaction2, hooks: false });
291
+ await this.emitAfterSaveEvent(s, options);
292
+ if (newSchema["x-server-hooks"]) {
293
+ await this.database.emitAsync(`${this.collection.name}.afterSave`, s, options);
294
+ }
295
+ return;
296
+ }
297
+ const oldTree = await this.getJsonSchema(rootUid, { transaction: transaction2 });
298
+ const traverSchemaTree = async (schema, path = []) => {
299
+ const node = schema;
300
+ const oldNode = path.length == 0 ? oldTree : import_lodash.default.get(oldTree, path);
301
+ const oldNodeUid = oldNode["uid"];
302
+ await this.updateNode(oldNodeUid, node, transaction2);
303
+ const properties = node.properties;
304
+ if (import_lodash.default.isPlainObject(properties)) {
305
+ for (const name of Object.keys(properties)) {
306
+ await traverSchemaTree(properties[name], [...path, "properties", name]);
307
+ }
308
+ }
309
+ };
310
+ await traverSchemaTree(newSchema);
311
+ }
312
+ async initializeActionContext(newSchema, options = {}) {
313
+ if (!newSchema["uid"] || !newSchema["x-action-context"]) {
314
+ return;
315
+ }
316
+ const { transaction: transaction2 } = options;
317
+ const nodeModel = await this.findOne({
318
+ filter: {
319
+ uid: newSchema["uid"]
320
+ },
321
+ transaction: transaction2
322
+ });
323
+ if (!import_lodash.default.isEmpty(nodeModel == null ? void 0 : nodeModel.get("options")["x-action-context"])) {
324
+ return;
325
+ }
326
+ return this.patch(import_lodash.default.pick(newSchema, ["uid", "x-action-context"]), options);
327
+ }
328
+ async batchPatch(schemas, options) {
329
+ const { transaction: transaction2 } = options;
330
+ for (const schema of schemas) {
331
+ await this.patch(schema, { ...options, transaction: transaction2 });
332
+ }
333
+ }
334
+ async removeEmptyParents(options) {
335
+ const { transaction: transaction2, uid: uid2, breakRemoveOn } = options;
336
+ await this.clearXUidPathCache(uid2, transaction2);
337
+ const removeParent = async (nodeUid) => {
338
+ const parent = await this.isSingleChild(nodeUid, transaction2);
339
+ if (parent && !this.breakOnMatched(parent, breakRemoveOn)) {
340
+ await removeParent(parent.get("uid"));
341
+ } else {
342
+ await this.remove(nodeUid, { transaction: transaction2 });
343
+ }
344
+ };
345
+ await removeParent(uid2);
346
+ }
347
+ async recursivelyRemoveIfNoChildren(options) {
348
+ const { uid: uid2, transaction: transaction2, breakRemoveOn } = options;
349
+ await this.clearXUidPathCache(uid2, transaction2);
350
+ const removeLeafNode = async (nodeUid) => {
351
+ const isLeafNode = await this.isLeafNode(nodeUid, transaction2);
352
+ if (isLeafNode) {
353
+ const { parentUid, schema } = await this.findNodeSchemaWithParent(nodeUid, transaction2);
354
+ if (this.breakOnMatched(schema, breakRemoveOn)) {
355
+ return;
356
+ } else {
357
+ await this.remove(nodeUid, {
358
+ transaction: transaction2
359
+ });
360
+ await removeLeafNode(parentUid);
361
+ }
362
+ }
363
+ };
364
+ await removeLeafNode(uid2);
365
+ }
366
+ async remove(uid2, options) {
367
+ const { transaction: transaction2 } = options;
368
+ await this.clearXUidPathCache(uid2, transaction2);
369
+ if (options == null ? void 0 : options.removeParentsIfNoChildren) {
370
+ await this.removeEmptyParents({ transaction: transaction2, uid: uid2, breakRemoveOn: options.breakRemoveOn });
371
+ return;
372
+ }
373
+ await this.database.sequelize.query(
374
+ this.sqlAdapter(`DELETE FROM ${this.flowModelsTableName} WHERE "uid" IN (
375
+ SELECT descendant FROM ${this.flowModelTreePathTableName} WHERE ancestor = :uid
376
+ )`),
377
+ {
378
+ replacements: {
379
+ uid: uid2
380
+ },
381
+ transaction: transaction2
382
+ }
383
+ );
384
+ await this.database.sequelize.query(
385
+ ` DELETE FROM ${this.flowModelTreePathTableName}
386
+ WHERE descendant IN (
387
+ select descendant FROM
388
+ (SELECT descendant
389
+ FROM ${this.flowModelTreePathTableName}
390
+ WHERE ancestor = :uid)as descendantTable) `,
391
+ {
392
+ replacements: {
393
+ uid: uid2
394
+ },
395
+ transaction: transaction2
396
+ }
397
+ );
398
+ }
399
+ async insertAdjacent(position, target, schema, options) {
400
+ const { transaction: transaction2 } = options;
401
+ await this.clearXUidPathCache(schema["uid"], transaction2);
402
+ if (options.wrap) {
403
+ const wrapSchemaNodes = await this.insertNewSchema(options.wrap, {
404
+ transaction: transaction2,
405
+ returnNode: true
406
+ });
407
+ const lastWrapNode = wrapSchemaNodes[wrapSchemaNodes.length - 1];
408
+ await this.insertAdjacent("afterBegin", lastWrapNode["uid"], schema, import_lodash.default.omit(options, "wrap"));
409
+ schema = wrapSchemaNodes[0]["uid"];
410
+ options.removeParentsIfNoChildren = false;
411
+ } else {
412
+ const schemaExists = await this.schemaExists(schema, { transaction: transaction2 });
413
+ if (schemaExists) {
414
+ schema = import_lodash.default.isString(schema) ? schema : schema["uid"];
415
+ } else {
416
+ const insertedSchema = await this.insertNewSchema(schema, {
417
+ transaction: transaction2,
418
+ returnNode: true
419
+ });
420
+ schema = insertedSchema[0]["uid"];
421
+ }
422
+ }
423
+ const result = await this[`insert${import_lodash.default.upperFirst(position)}`](target, schema, options);
424
+ const s = await this.model.findByPk(schema, { transaction: transaction2 });
425
+ await this.emitAfterSaveEvent(s, options);
426
+ await this.clearXUidPathCache(result["uid"], transaction2);
427
+ return result;
428
+ }
429
+ async duplicate(uid2, options) {
430
+ const s = await this.getJsonSchema(uid2, { ...options, includeAsyncNode: true });
431
+ if (!(s == null ? void 0 : s["uid"])) {
432
+ return null;
433
+ }
434
+ this.regenerateUid(s);
435
+ return this.insert(s, options);
436
+ }
437
+ async insert(schema, options) {
438
+ const nodes = _FlowModelRepository.schemaToSingleNodes(schema);
439
+ const insertedNodes = await this.insertNodes(nodes, options);
440
+ const result = await this.getJsonSchema(insertedNodes[0].get("uid"), {
441
+ transaction: options == null ? void 0 : options.transaction
442
+ });
443
+ await this.clearXUidPathCache(result["uid"], options == null ? void 0 : options.transaction);
444
+ return result;
445
+ }
446
+ async insertNewSchema(schema, options) {
447
+ const { transaction: transaction2 } = options;
448
+ const nodes = _FlowModelRepository.schemaToSingleNodes(schema);
449
+ await this.database.sequelize.query(
450
+ this.sqlAdapter(
451
+ `INSERT INTO ${this.flowModelsTableName} ("uid", "name", "options") VALUES ${nodes.map((n) => "(?)").join(",")};`
452
+ ),
453
+ {
454
+ replacements: import_lodash.default.cloneDeep(nodes).map((node) => {
455
+ const { uid: uid2, name } = this.prepareSingleNodeForInsert(node);
456
+ return [uid2, name, JSON.stringify(node)];
457
+ }),
458
+ type: "insert",
459
+ transaction: transaction2
460
+ }
461
+ );
462
+ const treePathData = import_lodash.default.cloneDeep(nodes).reduce((carry, item) => {
463
+ const { uid: uid2, childOptions, async } = this.prepareSingleNodeForInsert(item);
464
+ return [
465
+ ...carry,
466
+ // self reference
467
+ [uid2, uid2, 0, (childOptions == null ? void 0 : childOptions.type) || null, async, null],
468
+ // parent references
469
+ ...import_lodash.default.get(childOptions, "parentPath", []).map((parentUid, index) => {
470
+ return [parentUid, uid2, index + 1, null, null, childOptions.sort];
471
+ })
472
+ ];
473
+ }, []);
474
+ await this.database.sequelize.query(
475
+ this.sqlAdapter(
476
+ `INSERT INTO ${this.flowModelTreePathTableName} (ancestor, descendant, depth, type, async, sort) VALUES ${treePathData.map((item) => "(?)").join(",")}`
477
+ ),
478
+ {
479
+ replacements: treePathData,
480
+ type: "insert",
481
+ transaction: transaction2
482
+ }
483
+ );
484
+ const rootNode = nodes[0];
485
+ if (rootNode["x-server-hooks"]) {
486
+ const rootModel = await this.findOne({ filter: { uid: rootNode["uid"] }, transaction: transaction2 });
487
+ await this.database.emitAsync(`${this.collection.name}.afterCreateWithAssociations`, rootModel, options);
488
+ await this.database.emitAsync(`${this.collection.name}.afterSave`, rootModel, options);
489
+ }
490
+ if (options == null ? void 0 : options.returnNode) {
491
+ return nodes;
492
+ }
493
+ const result = await this.getJsonSchema(nodes[0]["uid"], {
494
+ transaction: transaction2
495
+ });
496
+ await this.clearXUidPathCache(result["uid"], transaction2);
497
+ return result;
498
+ }
499
+ async insertSingleNode(schema, options) {
500
+ const { transaction: transaction2 } = options;
501
+ const db = this.database;
502
+ const { uid: uid2, name, async, childOptions } = this.prepareSingleNodeForInsert(schema);
503
+ let savedNode;
504
+ const existsNode = await this.findOne({
505
+ filter: {
506
+ uid: uid2
507
+ },
508
+ transaction: transaction2
509
+ });
510
+ const treeTable = this.flowModelTreePathTableName;
511
+ if (existsNode) {
512
+ savedNode = existsNode;
513
+ } else {
514
+ savedNode = await this.insertSchemaRecord(name, uid2, schema, transaction2);
515
+ }
516
+ if (childOptions) {
517
+ const oldParentUid = await this.findParentUid(uid2, transaction2);
518
+ const parentUid = childOptions.parentUid;
519
+ const childrenCount = await this.childrenCount(uid2, transaction2);
520
+ const isTree = childrenCount > 0;
521
+ if (isTree) {
522
+ await this.clearAncestor(uid2, { transaction: transaction2 });
523
+ await db.sequelize.query(
524
+ `INSERT INTO ${treeTable} (ancestor, descendant, depth)
525
+ SELECT supertree.ancestor, subtree.descendant, supertree.depth + subtree.depth + 1
526
+ FROM ${treeTable} AS supertree
527
+ CROSS JOIN ${treeTable} AS subtree
528
+ WHERE supertree.descendant = :parentUid
529
+ AND subtree.ancestor = :uid;`,
530
+ {
531
+ type: "INSERT",
532
+ replacements: {
533
+ uid: uid2,
534
+ parentUid
535
+ },
536
+ transaction: transaction2
537
+ }
538
+ );
539
+ }
540
+ await db.sequelize.query(
541
+ `UPDATE ${treeTable} SET type = :type WHERE depth = 0 AND ancestor = :uid AND descendant = :uid`,
542
+ {
543
+ type: "update",
544
+ transaction: transaction2,
545
+ replacements: {
546
+ type: childOptions.type,
547
+ uid: uid2
548
+ }
549
+ }
550
+ );
551
+ if (!isTree) {
552
+ if (existsNode) {
553
+ await db.sequelize.query(`DELETE FROM ${treeTable} WHERE descendant = :uid AND ancestor != descendant`, {
554
+ type: "DELETE",
555
+ replacements: {
556
+ uid: uid2
557
+ },
558
+ transaction: transaction2
559
+ });
560
+ }
561
+ await db.sequelize.query(
562
+ `INSERT INTO ${treeTable} (ancestor, descendant, depth)
563
+ SELECT t.ancestor, :modelKey, depth + 1 FROM ${treeTable} AS t WHERE t.descendant = :modelParentKey `,
564
+ {
565
+ type: "INSERT",
566
+ transaction: transaction2,
567
+ replacements: {
568
+ modelKey: savedNode.get("uid"),
569
+ modelParentKey: parentUid
570
+ }
571
+ }
572
+ );
573
+ }
574
+ if (!existsNode) {
575
+ await db.sequelize.query(
576
+ `INSERT INTO ${treeTable}(ancestor, descendant, depth, type, async) VALUES (:modelKey, :modelKey, 0, :type, :async )`,
577
+ {
578
+ type: "INSERT",
579
+ replacements: {
580
+ modelKey: savedNode.get("uid"),
581
+ type: childOptions.type,
582
+ async
583
+ },
584
+ transaction: transaction2
585
+ }
586
+ );
587
+ }
588
+ const nodePosition = childOptions.position || "last";
589
+ let sort;
590
+ if (nodePosition === "first") {
591
+ sort = 1;
592
+ let updateSql2 = `UPDATE ${treeTable} as TreeTable
593
+ SET sort = TreeTable.sort + 1
594
+ FROM ${treeTable} as NodeInfo
595
+ WHERE NodeInfo.descendant = TreeTable.descendant and NodeInfo.depth = 0
596
+ AND TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor and NodeInfo.type = :type`;
597
+ if (this.database.isMySQLCompatibleDialect()) {
598
+ updateSql2 = `UPDATE ${treeTable} as TreeTable
599
+ JOIN ${treeTable} as NodeInfo ON (NodeInfo.descendant = TreeTable.descendant and NodeInfo.depth = 0)
600
+ SET TreeTable.sort = TreeTable.sort + 1
601
+ WHERE TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor and NodeInfo.type = :type`;
602
+ }
603
+ await db.sequelize.query(updateSql2, {
604
+ replacements: {
605
+ ancestor: childOptions.parentUid,
606
+ type: childOptions.type
607
+ },
608
+ transaction: transaction2
609
+ });
610
+ }
611
+ if (nodePosition === "last") {
612
+ const maxSort = await db.sequelize.query(
613
+ `SELECT ${this.database.sequelize.getDialect() === "postgres" ? "coalesce" : "ifnull"}(MAX(TreeTable.sort), 0) as maxsort FROM ${treeTable} as TreeTable
614
+ LEFT JOIN ${treeTable} as NodeInfo
615
+ ON NodeInfo.descendant = TreeTable.descendant and NodeInfo.depth = 0
616
+ WHERE TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor and NodeInfo.type = :type`,
617
+ {
618
+ type: "SELECT",
619
+ replacements: {
620
+ ancestor: childOptions.parentUid,
621
+ type: childOptions.type
622
+ },
623
+ transaction: transaction2
624
+ }
625
+ );
626
+ sort = parseInt(maxSort[0]["maxsort"]) + 1;
627
+ }
628
+ if (import_lodash.default.isPlainObject(nodePosition)) {
629
+ const targetPosition = nodePosition;
630
+ const target = targetPosition.target;
631
+ const targetSort = await db.sequelize.query(
632
+ `SELECT TreeTable.sort as sort FROM ${treeTable} as TreeTable
633
+ LEFT JOIN ${treeTable} as NodeInfo
634
+ ON NodeInfo.descendant = TreeTable.descendant and NodeInfo.depth = 0 WHERE TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor AND TreeTable.descendant = :descendant and NodeInfo.type = :type`,
635
+ {
636
+ type: "SELECT",
637
+ replacements: {
638
+ ancestor: childOptions.parentUid,
639
+ descendant: target,
640
+ type: childOptions.type
641
+ },
642
+ transaction: transaction2
643
+ }
644
+ );
645
+ sort = targetSort[0].sort;
646
+ if (targetPosition.type == "after") {
647
+ sort += 1;
648
+ }
649
+ let updateSql2 = `UPDATE ${treeTable} as TreeTable
650
+ SET sort = TreeTable.sort + 1
651
+ FROM ${treeTable} as NodeInfo
652
+ WHERE NodeInfo.descendant = TreeTable.descendant
653
+ and NodeInfo.depth = 0
654
+ AND TreeTable.depth = 1
655
+ AND TreeTable.ancestor = :ancestor
656
+ and TreeTable.sort >= :sort
657
+ and NodeInfo.type = :type`;
658
+ if (this.database.isMySQLCompatibleDialect()) {
659
+ updateSql2 = `UPDATE ${treeTable} as TreeTable
660
+ JOIN ${treeTable} as NodeInfo ON (NodeInfo.descendant = TreeTable.descendant and NodeInfo.depth = 0)
661
+ SET TreeTable.sort = TreeTable.sort + 1
662
+ WHERE TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor and TreeTable.sort >= :sort and NodeInfo.type = :type`;
663
+ }
664
+ await db.sequelize.query(updateSql2, {
665
+ replacements: {
666
+ ancestor: childOptions.parentUid,
667
+ sort,
668
+ type: childOptions.type
669
+ },
670
+ transaction: transaction2
671
+ });
672
+ }
673
+ const updateSql = `UPDATE ${treeTable} SET sort = :sort WHERE depth = 1 AND ancestor = :ancestor AND descendant = :descendant`;
674
+ await db.sequelize.query(updateSql, {
675
+ type: "UPDATE",
676
+ replacements: {
677
+ ancestor: childOptions.parentUid,
678
+ sort,
679
+ descendant: uid2
680
+ },
681
+ transaction: transaction2
682
+ });
683
+ if (oldParentUid !== null && oldParentUid !== parentUid) {
684
+ await this.database.emitAsync("uiSchemaMove", savedNode, {
685
+ transaction: transaction2,
686
+ oldParentUid,
687
+ parentUid
688
+ });
689
+ if (options.removeParentsIfNoChildren) {
690
+ await this.recursivelyRemoveIfNoChildren({
691
+ transaction: transaction2,
692
+ uid: oldParentUid,
693
+ breakRemoveOn: options.breakRemoveOn
694
+ });
695
+ }
696
+ }
697
+ } else {
698
+ await db.sequelize.query(
699
+ `INSERT INTO ${treeTable}(ancestor, descendant, depth, async) VALUES (:modelKey, :modelKey, 0, :async )`,
700
+ {
701
+ type: "INSERT",
702
+ replacements: {
703
+ modelKey: savedNode.get("uid"),
704
+ async
705
+ },
706
+ transaction: transaction2
707
+ }
708
+ );
709
+ }
710
+ await this.clearXUidPathCache(uid2, transaction2);
711
+ return savedNode;
712
+ }
713
+ async updateNode(uid2, schema, transaction2) {
714
+ const nodeModel = await this.findOne({
715
+ filter: {
716
+ uid: uid2
717
+ }
718
+ });
719
+ await nodeModel.update(
720
+ {
721
+ options: {
722
+ ...nodeModel.get("options"),
723
+ ...import_lodash.default.omit(schema, ["x-async", "name", "uid", "properties"])
724
+ }
725
+ },
726
+ {
727
+ hooks: false,
728
+ transaction: transaction2
729
+ }
730
+ );
731
+ await this.emitAfterSaveEvent(nodeModel, { transaction: transaction2 });
732
+ if (schema["x-server-hooks"]) {
733
+ await this.database.emitAsync(`${this.collection.name}.afterSave`, nodeModel, { transaction: transaction2 });
734
+ }
735
+ }
736
+ async childrenCount(uid2, transaction2) {
737
+ const db = this.database;
738
+ const countResult = await db.sequelize.query(
739
+ `SELECT COUNT(*) as count FROM ${this.flowModelTreePathTableName} where ancestor = :ancestor and depth = 1`,
740
+ {
741
+ replacements: {
742
+ ancestor: uid2
743
+ },
744
+ type: "SELECT",
745
+ transaction: transaction2
746
+ }
747
+ );
748
+ return parseInt(countResult[0]["count"]);
749
+ }
750
+ async isLeafNode(uid2, transaction2) {
751
+ const childrenCount = await this.childrenCount(uid2, transaction2);
752
+ return childrenCount === 0;
753
+ }
754
+ async findParentUid(uid2, transaction2) {
755
+ const parent = await this.database.getRepository("flowModelTreePath").findOne({
756
+ filter: {
757
+ descendant: uid2,
758
+ depth: 1
759
+ },
760
+ transaction: transaction2
761
+ });
762
+ return parent ? parent.get("ancestor") : null;
763
+ }
764
+ async findNodeSchemaWithParent(uid2, transaction2) {
765
+ const schema = await this.database.getRepository("flowModels").findOne({
766
+ filter: {
767
+ uid: uid2
768
+ },
769
+ transaction: transaction2
770
+ });
771
+ return {
772
+ parentUid: await this.findParentUid(uid2, transaction2),
773
+ schema
774
+ };
775
+ }
776
+ async isSingleChild(uid2, transaction2) {
777
+ const db = this.database;
778
+ const parent = await this.findParentUid(uid2, transaction2);
779
+ if (!parent) {
780
+ return null;
781
+ }
782
+ const parentChildrenCount = await this.childrenCount(parent, transaction2);
783
+ if (parentChildrenCount == 1) {
784
+ const schema = await db.getRepository("flowModels").findOne({
785
+ filter: {
786
+ uid: parent
787
+ },
788
+ transaction: transaction2
789
+ });
790
+ return schema;
791
+ }
792
+ return null;
793
+ }
794
+ async insertBeside(targetUid, schema, side, options) {
795
+ const { transaction: transaction2 } = options;
796
+ const targetParent = await this.findParentUid(targetUid, transaction2);
797
+ const db = this.database;
798
+ const treeTable = this.flowModelTreePathTableName;
799
+ const typeQuery = await db.sequelize.query(`SELECT type from ${treeTable} WHERE ancestor = :uid AND depth = 0;`, {
800
+ type: "SELECT",
801
+ replacements: {
802
+ uid: targetUid
803
+ },
804
+ transaction: transaction2
805
+ });
806
+ const nodes = _FlowModelRepository.schemaToSingleNodes(schema);
807
+ const rootNode = nodes[0];
808
+ rootNode.childOptions = {
809
+ parentUid: targetParent,
810
+ type: typeQuery[0]["type"],
811
+ position: {
812
+ type: side,
813
+ target: targetUid
814
+ }
815
+ };
816
+ const insertedNodes = await this.insertNodes(nodes, options);
817
+ return await this.getJsonSchema(insertedNodes[0].get("uid"), {
818
+ transaction: transaction2
819
+ });
820
+ }
821
+ async insertInner(targetUid, schema, position, options) {
822
+ const { transaction: transaction2 } = options;
823
+ const nodes = _FlowModelRepository.schemaToSingleNodes(schema);
824
+ const rootNode = nodes[0];
825
+ rootNode.childOptions = {
826
+ parentUid: targetUid,
827
+ type: import_lodash.default.get(schema, "x-node-type", "properties"),
828
+ position
829
+ };
830
+ const insertedNodes = await this.insertNodes(nodes, options);
831
+ return await this.getJsonSchema(insertedNodes[0].get("uid"), {
832
+ transaction: transaction2
833
+ });
834
+ }
835
+ async insertAfterBegin(targetUid, schema, options) {
836
+ return await this.insertInner(targetUid, schema, "first", options);
837
+ }
838
+ async insertBeforeEnd(targetUid, schema, options) {
839
+ return await this.insertInner(targetUid, schema, "last", options);
840
+ }
841
+ async insertBeforeBegin(targetUid, schema, options) {
842
+ return await this.insertBeside(targetUid, schema, "before", options);
843
+ }
844
+ async insertAfterEnd(targetUid, schema, options) {
845
+ return await this.insertBeside(targetUid, schema, "after", options);
846
+ }
847
+ async insertNodes(nodes, options) {
848
+ const { transaction: transaction2 } = options;
849
+ const insertedNodes = [];
850
+ for (const node of nodes) {
851
+ insertedNodes.push(
852
+ await this.insertSingleNode(node, {
853
+ ...options,
854
+ transaction: transaction2
855
+ })
856
+ );
857
+ }
858
+ return insertedNodes;
859
+ }
860
+ async doGetProperties(uid2, options = {}) {
861
+ const { transaction: transaction2 } = options;
862
+ const db = this.database;
863
+ const rawSql = `
864
+ SELECT "SchemaTable"."uid" as "uid", "SchemaTable"."name" as "name", "SchemaTable"."options" as "options",
865
+ TreePath.depth as depth,
866
+ NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
867
+ FROM ${this.flowModelTreePathTableName} as TreePath
868
+ LEFT JOIN ${this.flowModelsTableName} as "SchemaTable" ON "SchemaTable"."uid" = TreePath.descendant
869
+ LEFT JOIN ${this.flowModelTreePathTableName} as NodeInfo ON NodeInfo.descendant = "SchemaTable"."uid" and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
870
+ LEFT JOIN ${this.flowModelTreePathTableName} as ParentPath ON (ParentPath.descendant = "SchemaTable"."uid" AND ParentPath.depth = 1)
871
+ WHERE TreePath.ancestor = :ancestor AND (NodeInfo.async = false or TreePath.depth <= 1)`;
872
+ const nodes = await db.sequelize.query(this.sqlAdapter(rawSql), {
873
+ replacements: {
874
+ ancestor: uid2
875
+ },
876
+ transaction: transaction2
877
+ });
878
+ if (nodes[0].length == 0) {
879
+ return {};
880
+ }
881
+ const schema = this.nodesToSchema(nodes[0], uid2);
882
+ return import_lodash.default.pick(schema, ["type", "properties"]);
883
+ }
884
+ async findNodesById(uid2, options) {
885
+ const db = this.database;
886
+ const treeTable = this.flowModelTreePathTableName;
887
+ const rawSql = `
888
+ SELECT "SchemaTable"."uid" as "uid", "SchemaTable"."name" as name, "SchemaTable"."options" as "options" ,
889
+ TreePath.depth as depth,
890
+ NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
891
+ FROM ${treeTable} as TreePath
892
+ LEFT JOIN ${this.flowModelsTableName} as "SchemaTable" ON "SchemaTable"."uid" = TreePath.descendant
893
+ LEFT JOIN ${treeTable} as NodeInfo ON NodeInfo.descendant = "SchemaTable"."uid" and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
894
+ LEFT JOIN ${treeTable} as ParentPath ON (ParentPath.descendant = "SchemaTable"."uid" AND ParentPath.depth = 1)
895
+ WHERE TreePath.ancestor = :ancestor ${(options == null ? void 0 : options.includeAsyncNode) ? "" : "AND (NodeInfo.async != true or TreePath.depth = 0)"}
896
+ `;
897
+ const nodes = await db.sequelize.query(this.sqlAdapter(rawSql), {
898
+ replacements: {
899
+ ancestor: uid2
900
+ },
901
+ transaction: options == null ? void 0 : options.transaction
902
+ });
903
+ if (nodes[0].length == 0) {
904
+ return [];
905
+ }
906
+ return nodes[0];
907
+ }
908
+ async doGetJsonSchema(uid2, options) {
909
+ const nodes = await this.findNodesById(uid2, options);
910
+ return this.nodesToSchema(nodes, uid2);
911
+ }
912
+ ignoreSchemaProperties(schemaProperties) {
913
+ return import_lodash.default.omit(schemaProperties, nodeKeys);
914
+ }
915
+ breakOnMatched(schemaInstance, breakRemoveOn) {
916
+ if (!breakRemoveOn) {
917
+ return false;
918
+ }
919
+ for (const key of Object.keys(breakRemoveOn)) {
920
+ const instanceValue = schemaInstance.get(key);
921
+ const breakRemoveOnValue = breakRemoveOn[key];
922
+ if (instanceValue !== breakRemoveOnValue) {
923
+ return false;
924
+ }
925
+ }
926
+ return true;
927
+ }
928
+ async schemaExists(schema, options) {
929
+ if (import_lodash.default.isObject(schema) && !schema["uid"]) {
930
+ return false;
931
+ }
932
+ const { transaction: transaction2 } = options;
933
+ const result = await this.database.sequelize.query(
934
+ this.sqlAdapter(`select "uid" from ${this.flowModelsTableName} where "uid" = :uid`),
935
+ {
936
+ type: "SELECT",
937
+ replacements: {
938
+ uid: import_lodash.default.isString(schema) ? schema : schema["uid"]
939
+ },
940
+ transaction: transaction2
941
+ }
942
+ );
943
+ return result.length > 0;
944
+ }
945
+ regenerateUid(s) {
946
+ s["uid"] = (0, import_utils.uid)();
947
+ Object.keys(s.properties || {}).forEach((key) => {
948
+ this.regenerateUid(s.properties[key]);
949
+ });
950
+ }
951
+ async insertSchemaRecord(name, uid2, schema, transaction2) {
952
+ const node = await this.create({
953
+ values: {
954
+ name,
955
+ ["uid"]: uid2,
956
+ options: schema
957
+ },
958
+ transaction: transaction2,
959
+ context: {
960
+ disableInsertHook: true
961
+ }
962
+ });
963
+ return node;
964
+ }
965
+ prepareSingleNodeForInsert(schema) {
966
+ const uid2 = schema["uid"];
967
+ const name = schema["name"];
968
+ const async = import_lodash.default.get(schema, "x-async", false);
969
+ const childOptions = schema["childOptions"];
970
+ delete schema["uid"];
971
+ delete schema["x-async"];
972
+ delete schema["name"];
973
+ delete schema["childOptions"];
974
+ return { uid: uid2, name, async, childOptions };
975
+ }
976
+ static modelToSingleNodes(model, parentChildOptions = null) {
977
+ const { uid: oldUid, async, subModels, ...rest } = import_lodash.default.cloneDeep(model);
978
+ const currentUid = oldUid || (0, import_utils.uid)();
979
+ const node = {
980
+ uid: currentUid,
981
+ "x-async": async || false,
982
+ name: currentUid,
983
+ ...rest
984
+ };
985
+ if (parentChildOptions) {
986
+ node.childOptions = parentChildOptions;
987
+ }
988
+ const nodes = [node];
989
+ if (Object.keys(subModels || {}).length > 0) {
990
+ for (const [subKey, subItems] of Object.entries(subModels)) {
991
+ const items = import_lodash.default.castArray(subItems);
992
+ let sort = 0;
993
+ for (const item of items) {
994
+ item.subKey = subKey;
995
+ item.subType = Array.isArray(subItems) ? "array" : "object";
996
+ const childOptions = {
997
+ parentUid: currentUid,
998
+ parentPath: [currentUid, ...(parentChildOptions == null ? void 0 : parentChildOptions.parentPath) || []].filter(Boolean),
999
+ type: subKey,
1000
+ // type: 'properties',
1001
+ sort: ++sort
1002
+ };
1003
+ const children = this.modelToSingleNodes(item, childOptions);
1004
+ nodes.push(...children);
1005
+ }
1006
+ }
1007
+ }
1008
+ return nodes;
1009
+ }
1010
+ static nodeToModel(node) {
1011
+ const { uid: uid2, name, options } = node;
1012
+ const model = {
1013
+ uid: uid2,
1014
+ ...options
1015
+ };
1016
+ return model;
1017
+ }
1018
+ static nodesToModel(nodes, rootUid) {
1019
+ const nodeMap = /* @__PURE__ */ new Map();
1020
+ for (const node of nodes) {
1021
+ nodeMap.set(node["uid"], node);
1022
+ }
1023
+ const rootNode = nodeMap.get(rootUid);
1024
+ if (!rootNode) return null;
1025
+ const children = nodes.filter((n) => n.parent === rootUid);
1026
+ const subModels = {};
1027
+ for (const child of children) {
1028
+ const { subKey, subType } = child.options;
1029
+ if (!subKey) continue;
1030
+ const model = _FlowModelRepository.nodesToModel(nodes, child["uid"]) || {
1031
+ uid: child["uid"],
1032
+ ...child.options,
1033
+ sortIndex: child.sort
1034
+ };
1035
+ model.sortIndex = child.sort;
1036
+ if (subType === "array") {
1037
+ if (!subModels[subKey]) subModels[subKey] = [];
1038
+ subModels[subKey].push(model);
1039
+ } else {
1040
+ subModels[subKey] = model;
1041
+ }
1042
+ }
1043
+ for (const key in subModels) {
1044
+ if (Array.isArray(subModels[key])) {
1045
+ subModels[key].sort((a, b) => (a.sortIndex ?? 0) - (b.sortIndex ?? 0));
1046
+ }
1047
+ }
1048
+ const filteredSubModels = {};
1049
+ for (const key in subModels) {
1050
+ const value = subModels[key];
1051
+ if (Array.isArray(value) && value.length === 0) continue;
1052
+ if (!Array.isArray(value) && typeof value === "object" && value !== null && Object.keys(value).length === 0)
1053
+ continue;
1054
+ filteredSubModels[key] = value;
1055
+ }
1056
+ return {
1057
+ uid: rootNode["uid"],
1058
+ ...rootNode.options,
1059
+ ...Object.keys(filteredSubModels).length > 0 ? { subModels: filteredSubModels } : {}
1060
+ };
1061
+ }
1062
+ async insertModel(model, options) {
1063
+ const nodes = _FlowModelRepository.modelToSingleNodes(model);
1064
+ const rootUid = nodes[0]["uid"];
1065
+ await this.insertNodes(nodes, options);
1066
+ return await this.findModelById(rootUid, options);
1067
+ }
1068
+ async updateSingleNode(node, options) {
1069
+ const instance = await this.model.findByPk(node["uid"], {
1070
+ transaction: options == null ? void 0 : options.transaction
1071
+ });
1072
+ if (instance) {
1073
+ await instance.update(
1074
+ {
1075
+ options: {
1076
+ ...instance.get("options"),
1077
+ ...import_lodash.default.omit(node, ["x-async", "name", "uid", "childOptions"])
1078
+ }
1079
+ },
1080
+ {
1081
+ hooks: false,
1082
+ transaction: options == null ? void 0 : options.transaction
1083
+ }
1084
+ );
1085
+ return true;
1086
+ }
1087
+ return false;
1088
+ }
1089
+ async upsertModel(model, options) {
1090
+ let childOptions = null;
1091
+ if (model.parentId) {
1092
+ childOptions = {
1093
+ parentUid: model.parentId,
1094
+ type: model.subKey,
1095
+ // type: 'properties',
1096
+ position: "last"
1097
+ };
1098
+ }
1099
+ const nodes = _FlowModelRepository.modelToSingleNodes(model, childOptions);
1100
+ const rootUid = nodes[0]["uid"];
1101
+ for (const node of nodes) {
1102
+ const exists = await this.updateSingleNode(node, options);
1103
+ if (!exists) {
1104
+ await this.insertSingleNode(node, options);
1105
+ }
1106
+ }
1107
+ return rootUid;
1108
+ }
1109
+ async findModelById(uid2, options) {
1110
+ const nodes = await this.findNodesById(uid2, options);
1111
+ return _FlowModelRepository.nodesToModel(nodes, uid2);
1112
+ }
1113
+ async findModelByParentId(parentUid, options) {
1114
+ const r = this.database.getRepository("flowModelTreePath");
1115
+ const treePaths = await r.model.findAll({
1116
+ where: {
1117
+ ancestor: parentUid,
1118
+ depth: 1
1119
+ },
1120
+ transaction: options == null ? void 0 : options.transaction
1121
+ });
1122
+ const ancestors = treePaths.map((treePath2) => treePath2["descendant"]);
1123
+ const where = {
1124
+ ancestor: ancestors,
1125
+ depth: 0
1126
+ };
1127
+ if (options == null ? void 0 : options.subKey) {
1128
+ where["type"] = options.subKey;
1129
+ }
1130
+ const treePath = await r.model.findOne({
1131
+ where,
1132
+ transaction: options == null ? void 0 : options.transaction
1133
+ });
1134
+ if (treePath == null ? void 0 : treePath["descendant"]) {
1135
+ return this.findModelById(treePath["descendant"], options);
1136
+ }
1137
+ return null;
1138
+ }
1139
+ async move(options) {
1140
+ const { sourceId, targetId, position } = options;
1141
+ return await this.insertAdjacent(position === "after" ? "afterEnd" : "beforeBegin", targetId, {
1142
+ ["uid"]: sourceId
1143
+ });
1144
+ }
1145
+ };
1146
+ __decorateClass([
1147
+ transaction()
1148
+ ], _FlowModelRepository.prototype, "clearAncestor", 1);
1149
+ __decorateClass([
1150
+ transaction()
1151
+ ], _FlowModelRepository.prototype, "patch", 1);
1152
+ __decorateClass([
1153
+ transaction()
1154
+ ], _FlowModelRepository.prototype, "initializeActionContext", 1);
1155
+ __decorateClass([
1156
+ transaction()
1157
+ ], _FlowModelRepository.prototype, "batchPatch", 1);
1158
+ __decorateClass([
1159
+ transaction()
1160
+ ], _FlowModelRepository.prototype, "remove", 1);
1161
+ __decorateClass([
1162
+ transaction()
1163
+ ], _FlowModelRepository.prototype, "insertAdjacent", 1);
1164
+ __decorateClass([
1165
+ transaction()
1166
+ ], _FlowModelRepository.prototype, "duplicate", 1);
1167
+ __decorateClass([
1168
+ transaction()
1169
+ ], _FlowModelRepository.prototype, "insert", 1);
1170
+ __decorateClass([
1171
+ transaction()
1172
+ ], _FlowModelRepository.prototype, "insertNewSchema", 1);
1173
+ __decorateClass([
1174
+ transaction()
1175
+ ], _FlowModelRepository.prototype, "insertBeside", 1);
1176
+ __decorateClass([
1177
+ transaction()
1178
+ ], _FlowModelRepository.prototype, "insertInner", 1);
1179
+ __decorateClass([
1180
+ transaction()
1181
+ ], _FlowModelRepository.prototype, "insertAfterBegin", 1);
1182
+ __decorateClass([
1183
+ transaction()
1184
+ ], _FlowModelRepository.prototype, "insertBeforeEnd", 1);
1185
+ __decorateClass([
1186
+ transaction()
1187
+ ], _FlowModelRepository.prototype, "insertBeforeBegin", 1);
1188
+ __decorateClass([
1189
+ transaction()
1190
+ ], _FlowModelRepository.prototype, "insertAfterEnd", 1);
1191
+ __decorateClass([
1192
+ transaction()
1193
+ ], _FlowModelRepository.prototype, "insertNodes", 1);
1194
+ __decorateClass([
1195
+ transaction()
1196
+ ], _FlowModelRepository.prototype, "insertModel", 1);
1197
+ __decorateClass([
1198
+ transaction()
1199
+ ], _FlowModelRepository.prototype, "updateSingleNode", 1);
1200
+ __decorateClass([
1201
+ transaction()
1202
+ ], _FlowModelRepository.prototype, "upsertModel", 1);
1203
+ let FlowModelRepository = _FlowModelRepository;
1204
+ var repository_default = FlowModelRepository;
1205
+ // Annotate the CommonJS export names for ESM import in node:
1206
+ 0 && (module.exports = {
1207
+ FlowModelRepository,
1208
+ transaction
1209
+ });