@flusys/nestjs-entity-builder 9.1.0 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +52 -25
  2. package/config/entity-builder.constants.d.ts +2 -0
  3. package/config/message-keys.d.ts +93 -12
  4. package/controllers/definition-bundle.controller.d.ts +15 -0
  5. package/controllers/flow-definition.controller.d.ts +7 -1
  6. package/controllers/index.d.ts +1 -1
  7. package/dtos/definition-bundle.dto.d.ts +57 -0
  8. package/dtos/flow.dto.d.ts +12 -20
  9. package/dtos/index.d.ts +1 -0
  10. package/entities/flow-definition.entity.d.ts +3 -9
  11. package/entities/flow-execution.entity.d.ts +3 -0
  12. package/entities/flow-version.entity.d.ts +10 -0
  13. package/entities/index.d.ts +3 -3
  14. package/fesm/21.js +96 -14
  15. package/fesm/458.js +695 -0
  16. package/fesm/{489.js → 582.js} +22 -30
  17. package/fesm/{996.js → 677.js} +1453 -1078
  18. package/fesm/794.js +135 -240
  19. package/fesm/{719.js → 870.js} +1955 -220
  20. package/fesm/{362.js → 897.js} +566 -2
  21. package/fesm/{606.js → 946.js} +564 -290
  22. package/fesm/config/index.js +15 -2
  23. package/fesm/controllers/index.js +9 -9
  24. package/fesm/docs/index.js +7 -4
  25. package/fesm/dtos/index.js +451 -256
  26. package/fesm/entities/index.js +58 -3
  27. package/fesm/guards/index.js +101 -22
  28. package/fesm/index.js +429 -948
  29. package/fesm/interfaces/index.js +19 -2
  30. package/fesm/modules/index.js +10 -628
  31. package/fesm/rule-engine/index.js +12 -3
  32. package/fesm/services/index.js +97 -27
  33. package/flow-engine/flow-api-key.d.ts +3 -7
  34. package/flow-engine/flow-graph.validator.d.ts +4 -2
  35. package/flow-engine/flow-permission-logic.d.ts +2 -0
  36. package/flow-engine/flow-run.types.d.ts +17 -8
  37. package/flow-engine/flow.types.d.ts +101 -13
  38. package/guards/designer-writable.interceptor.d.ts +12 -0
  39. package/guards/index.d.ts +1 -0
  40. package/interfaces/definition-bundle.interface.d.ts +111 -0
  41. package/interfaces/entity-builder-module.interface.d.ts +6 -0
  42. package/interfaces/flow-definition.interface.d.ts +13 -9
  43. package/interfaces/index.d.ts +1 -0
  44. package/package.json +5 -5
  45. package/rule-engine/rule-engine.service.d.ts +1 -0
  46. package/rule-engine/rule-permission.d.ts +3 -7
  47. package/services/definition-bundle.diff.d.ts +62 -0
  48. package/services/definition-bundle.file.d.ts +7 -0
  49. package/services/definition-bundle.service.d.ts +32 -0
  50. package/services/entity-builder-config.service.d.ts +2 -0
  51. package/services/entity-flow-scaffold.d.ts +1 -1
  52. package/services/flow-definition.service.d.ts +25 -12
  53. package/services/flow-execution.service.d.ts +7 -0
  54. package/services/flow-executor.service.d.ts +8 -8
  55. package/services/generic-entity.service.d.ts +1 -1
  56. package/services/index.d.ts +3 -1
  57. package/services/schema-evolution.service.d.ts +3 -1
  58. package/services/schema-sync.service.d.ts +5 -1
  59. package/controllers/flow-api-key.controller.d.ts +0 -14
  60. package/entities/flow-api-key.entity.d.ts +0 -10
  61. package/services/flow-api-key.service.d.ts +0 -31
@@ -2,9 +2,49 @@ import * as __rspack_external__flusys_nestjs_shared_dtos_c4585026 from "@flusys/
2
2
  import * as __rspack_external__nestjs_swagger_7cd450b5 from "@nestjs/swagger";
3
3
  import * as __rspack_external_class_transformer_c5a479fb from "class-transformer";
4
4
  import * as __rspack_external_class_validator_7b99ef4d from "class-validator";
5
- export const __rspack_esm_id = 362;
6
- export const __rspack_esm_ids = [362];
5
+ import * as __rspack_external_node_crypto_2e7c4b46 from "node:crypto";
6
+ import * as __rspack_external_typeorm from "typeorm";
7
+ export const __rspack_esm_id = 897;
8
+ export const __rspack_esm_ids = [897];
7
9
  export const __webpack_modules__ = {
10
+ 6576(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
11
+ const ENTITY_BUILDER_MODULE_OPTIONS = 'ENTITY_BUILDER_MODULE_OPTIONS';
12
+ /**
13
+ * Largest bundle file plan-import / apply-import accept. The bundle is uploaded as a file, so the app's
14
+ * JSON body limit (Express's 100kb default) never applies to it and the app needs no setup for it.
15
+ */ const ENTITY_BUNDLE_MAX_BYTES = 20 * 1024 * 1024;
16
+ /** A name `${var:NAME}` can carry; any other name could never be resolved on import. */ const BUNDLE_VARIABLE_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
17
+ /**
18
+ * Identifier whitelist enforced on every EntityDefinition/FieldDefinition `code`.
19
+ * Also the exact contract SchemaSyncService's DDL engine validates against
20
+ * before generating a table/column name.
21
+ */ const ENTITY_CODE_PATTERN = /^[a-z][a-z0-9_]{2,59}$/;
22
+ /** Matches the `code` column length on both EntityDefinition and FieldDefinition. */ const ENTITY_CODE_MAX_LENGTH = 63;
23
+ /** Defense-in-depth prefix applied to every dynamically created table name. */ const ENTITY_TABLE_PREFIX = 'eb_';
24
+ /** The generic API controller's record endpoints - each can be created as a ready-made flow with the entity. */ const ENTITY_FLOW_ENDPOINTS = [
25
+ 'insert',
26
+ 'insertMany',
27
+ 'getById',
28
+ 'getByIds',
29
+ 'getAll',
30
+ 'getByFilter',
31
+ 'update',
32
+ 'updateMany',
33
+ 'bulkUpsert',
34
+ 'delete'
35
+ ];
36
+
37
+ __webpack_require__.d(__webpack_exports__, {
38
+ }, {
39
+ CP: ENTITY_BUILDER_MODULE_OPTIONS,
40
+ EA: ENTITY_BUNDLE_MAX_BYTES,
41
+ JI: BUNDLE_VARIABLE_NAME_PATTERN,
42
+ WT: ENTITY_FLOW_ENDPOINTS,
43
+ vs: ENTITY_CODE_PATTERN
44
+ });
45
+
46
+
47
+ },
8
48
  680(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
9
49
  /* import */ var _flusys_nestjs_shared_dtos__rspack_import_0 = __webpack_require__(6873);
10
50
  /* import */ var _nestjs_swagger__rspack_import_1 = __webpack_require__(6176);
@@ -1045,6 +1085,518 @@ __webpack_require__.d(__webpack_exports__, {
1045
1085
  });
1046
1086
 
1047
1087
 
1088
+ },
1089
+ 1313(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1090
+ /**
1091
+ * Lifecycle status of an EntityDefinition.
1092
+ * DRAFT - metadata created, table not yet materialized.
1093
+ * ACTIVE - table exists; flows read and write its records.
1094
+ * DEPRECATED - no new writes; physical table/data left intact.
1095
+ */ var EntityStatus = /*#__PURE__*/ function(EntityStatus) {
1096
+ EntityStatus["DRAFT"] = "DRAFT";
1097
+ EntityStatus["ACTIVE"] = "ACTIVE";
1098
+ EntityStatus["DEPRECATED"] = "DEPRECATED";
1099
+ return EntityStatus;
1100
+ }({});
1101
+
1102
+ __webpack_require__.d(__webpack_exports__, {
1103
+ c: () => (EntityStatus)
1104
+ });
1105
+
1106
+
1107
+ },
1108
+ 9614(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1109
+ /**
1110
+ * Storable field types a FieldDefinition can declare.
1111
+ * Mapped to a driver-specific column type by SchemaDialectAdapterService.
1112
+ */ var FieldType = /*#__PURE__*/ function(FieldType) {
1113
+ FieldType["TEXT"] = "TEXT";
1114
+ FieldType["LONG_TEXT"] = "LONG_TEXT";
1115
+ FieldType["INTEGER"] = "INTEGER";
1116
+ FieldType["DECIMAL"] = "DECIMAL";
1117
+ FieldType["BOOLEAN"] = "BOOLEAN";
1118
+ FieldType["DATE"] = "DATE";
1119
+ FieldType["DATETIME"] = "DATETIME";
1120
+ FieldType["EMAIL"] = "EMAIL";
1121
+ FieldType["SINGLE_SELECT"] = "SINGLE_SELECT";
1122
+ FieldType["MULTI_SELECT"] = "MULTI_SELECT";
1123
+ FieldType["RELATION"] = "RELATION";
1124
+ FieldType["JSON"] = "JSON";
1125
+ FieldType["FILE"] = "FILE";
1126
+ return FieldType;
1127
+ }({});
1128
+
1129
+ __webpack_require__.d(__webpack_exports__, {
1130
+ P: () => (FieldType)
1131
+ });
1132
+
1133
+
1134
+ },
1135
+ 6256(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1136
+ const FLOW_NODE_TYPES = [
1137
+ 'trigger',
1138
+ 'validate',
1139
+ 'permission_check',
1140
+ 'company_branch_check',
1141
+ 'set',
1142
+ 'condition',
1143
+ 'switch',
1144
+ 'foreach',
1145
+ 'entity_insert',
1146
+ 'entity_update',
1147
+ 'entity_delete',
1148
+ 'entity_get',
1149
+ 'entity_query',
1150
+ 'commit',
1151
+ 'call_flow',
1152
+ 'http_request',
1153
+ 'publish_event',
1154
+ 'send_notification',
1155
+ 'send_email',
1156
+ 'respond',
1157
+ 'code'
1158
+ ];
1159
+ /** A failure of these always ends the run: checks can never be carried past, and Save progress cannot run in a savepoint. */ const NON_CONTINUABLE_NODE_TYPES = new Set([
1160
+ 'validate',
1161
+ 'permission_check',
1162
+ 'company_branch_check',
1163
+ 'commit'
1164
+ ]);
1165
+ /**
1166
+ * Who may start a run at a Request step. `internal` (other flows only): the step has no URL - only
1167
+ * other flows' `call_flow` steps start there, and the run takes its caller's user.
1168
+ */ const FLOW_AUTH_MODES = [
1169
+ 'public',
1170
+ 'api_key',
1171
+ 'jwt',
1172
+ 'permission',
1173
+ 'internal'
1174
+ ];
1175
+ /** A Request step that sets no access: any signed-in user. */ const DEFAULT_AUTH_MODE = 'jwt';
1176
+ /** Modes a caller reaches without signing in: the run has no `user`. */ const KEYLESS_AUTH_MODES = new Set([
1177
+ 'public',
1178
+ 'api_key'
1179
+ ]);
1180
+ /** object: the body is one object and the fields are its keys (`input.<name>`). list: the body is a list and the fields describe each item (`input.0.<name>`). */ const FLOW_BODY_TYPES = [
1181
+ 'object',
1182
+ 'list'
1183
+ ];
1184
+ const FLOW_INPUT_TYPES = [
1185
+ 'string',
1186
+ 'text',
1187
+ 'number',
1188
+ 'integer',
1189
+ 'boolean',
1190
+ 'date',
1191
+ 'datetime',
1192
+ 'email',
1193
+ 'uuid',
1194
+ 'object',
1195
+ 'array',
1196
+ 'choice'
1197
+ ];
1198
+ /** How a step is named in messages: its name, or its id when it was left unnamed. */ const nodeLabel = (node)=>node.name || node.id;
1199
+ /** caller (default): the signed-in user. user: the user `userId` names, checked without them being signed in. */ const FLOW_ACCESS_SUBJECTS = [
1200
+ 'caller',
1201
+ 'user'
1202
+ ];
1203
+ /**
1204
+ * How a branch passes. direct (default): it is granted to the user. within: it is granted, or sits
1205
+ * anywhere under a granted branch - a child needs no grant of its own.
1206
+ */ const FLOW_BRANCH_MATCHES = [
1207
+ 'direct',
1208
+ 'within'
1209
+ ];
1210
+ /**
1211
+ * Which companies' branches a branch check counts. any (default): every company of the user.
1212
+ * current: the caller's current company (not for another user, who has none).
1213
+ */ const FLOW_BRANCH_COMPANIES = [
1214
+ 'any',
1215
+ 'current'
1216
+ ];
1217
+ /**
1218
+ * Which records a write node touches. one (default): a single record. many: one per item of `items`,
1219
+ * whose per-record expressions read the item as `loop.item` (a loop around the node becomes
1220
+ * `loop.parent`). filter: every record matching `filter`, read as `loop.item`.
1221
+ */ const RECORD_WRITE_TARGETS = [
1222
+ 'one',
1223
+ 'many',
1224
+ 'filter'
1225
+ ];
1226
+ function isStoredApiKey(value) {
1227
+ const key = value;
1228
+ return typeof key?.prefix === 'string' && typeof key.hash === 'string' && /^[0-9a-f]{64}$/.test(key.hash);
1229
+ }
1230
+ /** The app modules a message step sends through; a step whose module is not installed cannot be saved or run. */ const FLOW_MESSAGE_SERVICES = {
1231
+ send_notification: 'notification',
1232
+ send_email: 'email'
1233
+ };
1234
+ const isMessageNode = (type)=>Object.hasOwn(FLOW_MESSAGE_SERVICES, type);
1235
+ const FLOW_NOTIFICATION_TYPES = [
1236
+ 'info',
1237
+ 'success',
1238
+ 'warning',
1239
+ 'error'
1240
+ ];
1241
+ /**
1242
+ * Who a notification step sends to. one (default): one notification to the users `userIds` names.
1243
+ * many: one per item of `items`, each read with the item as `loop.item`. company: every active member
1244
+ * of `companyIds` (one or a list; with `branchIds`, only those also in one of those branches), shown under that company.
1245
+ */ const FLOW_NOTIFICATION_TARGETS = [
1246
+ 'one',
1247
+ 'many',
1248
+ 'company'
1249
+ ];
1250
+ /** one (default): one email. many: one per item of `items`, each read with the item as `loop.item`. */ const FLOW_EMAIL_TARGETS = [
1251
+ 'one',
1252
+ 'many'
1253
+ ];
1254
+ const FLOW_EMAIL_MODES = [
1255
+ 'content',
1256
+ 'template'
1257
+ ];
1258
+ const FLOW_EMAIL_FORMATS = [
1259
+ 'text',
1260
+ 'html'
1261
+ ];
1262
+ const FLOW_LIMITS = {
1263
+ MAX_NODES: 100,
1264
+ MAX_EDGES: 300,
1265
+ /** Room for a full foreach (MAX_FOREACH_ITEMS) with a few steps per item. */ MAX_STEPS_PER_RUN: 5000,
1266
+ MAX_FOREACH_ITEMS: 1000,
1267
+ MAX_LOOP_DEPTH: 3,
1268
+ MAX_CALL_DEPTH: 5,
1269
+ MAX_HTTP_CALLS: 10,
1270
+ /** Notification and email steps sent per run (a loop counts every pass). */ MAX_MESSAGES_PER_RUN: 100,
1271
+ MAX_NOTIFICATION_RECIPIENTS: 500,
1272
+ /** All members of the companies a company-wide notification step reaches. */ MAX_COMPANY_NOTIFICATION_RECIPIENTS: 5000,
1273
+ /** to + cc + bcc of one email. */ MAX_EMAIL_RECIPIENTS: 50,
1274
+ MAX_NOTIFICATION_TITLE_LENGTH: 255,
1275
+ MAX_EMAIL_SUBJECT_LENGTH: 255,
1276
+ MAX_EMAIL_TEMPLATE_SLUG_LENGTH: 255,
1277
+ MAX_HTTP_TIMEOUT_MS: 15_000,
1278
+ MAX_HTTP_RESPONSE_BYTES: 1_000_000,
1279
+ MAX_QUERY_LIMIT: 200,
1280
+ MAX_WRITE_ITEMS: 1000,
1281
+ DEFAULT_WRITE_FILTER_LIMIT: 100,
1282
+ MAX_CHILD_INSERTS: 10,
1283
+ MAX_WRITES_PER_RUN: 5000,
1284
+ DEFAULT_TIMEOUT_MS: 30_000,
1285
+ MIN_TIMEOUT_MS: 1000,
1286
+ MAX_TIMEOUT_MS: 120_000,
1287
+ DEFAULT_RATE_LIMIT_PER_MINUTE: 60,
1288
+ MAX_RATE_LIMIT_PER_MINUTE: 100_000,
1289
+ TRACE_PREVIEW_CHARS: 2000,
1290
+ MAX_INPUT_FIELDS: 50,
1291
+ /** How deep object/list-of-object fields may nest inside the request body. */ MAX_INPUT_DEPTH: 4,
1292
+ MAX_VALIDATE_CHECKS: 50,
1293
+ MAX_CODE_LENGTH: 20_000,
1294
+ DEFAULT_CODE_TIMEOUT_MS: 1000,
1295
+ MIN_CODE_TIMEOUT_MS: 10,
1296
+ MAX_CODE_TIMEOUT_MS: 5000,
1297
+ CODE_MEMORY_LIMIT_BYTES: 32 * 1024 * 1024,
1298
+ CODE_STACK_SIZE_BYTES: 512 * 1024,
1299
+ MAX_CODE_OUTPUT_BYTES: 1_000_000,
1300
+ MAX_CODE_LOG_LINES: 50,
1301
+ MAX_CODE_LOG_LINE_CHARS: 500
1302
+ };
1303
+ const FLOW_NODE_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,39}$/;
1304
+ const FLOW_SLUG_PATTERN = /^[a-z][a-z0-9-]{2,62}$/;
1305
+ const FLOW_INPUT_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,59}$/;
1306
+ const FLOW_ENDPOINT_PATH_PATTERN = /^[a-z][a-z0-9-]{0,62}$/;
1307
+ /** A record, user or company id. */ const FLOW_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1308
+ /** Who may start a run at a Request step; an unknown mode reads as the default, which the validator refuses on save. */ function endpointAuth(config) {
1309
+ const authMode = config.authMode && FLOW_AUTH_MODES.includes(config.authMode) ? config.authMode : DEFAULT_AUTH_MODE;
1310
+ return {
1311
+ authMode,
1312
+ permissions: authMode === 'permission' ? config.permissions ?? null : null
1313
+ };
1314
+ }
1315
+ /** A flow whose every Request step is `internal`: a function, with no URL of its own. */ const isFunctionFlow = (flow)=>{
1316
+ const endpoints = flowEndpoints(flow);
1317
+ return endpoints.length > 0 && endpoints.every((endpoint)=>endpoint.authMode === 'internal');
1318
+ };
1319
+ /** A Request step's path, or null when it answers on the flow's own URL. */ function triggerPath(node) {
1320
+ const path = node.config?.path;
1321
+ return typeof path === 'string' && path.trim() ? path.trim() : null;
1322
+ }
1323
+ /** Every Request step of a flow as a URL, with the body and access it sets. */ function flowEndpoints(flow) {
1324
+ return (flow.nodes ?? []).filter((node)=>node?.type === 'trigger').map((node)=>{
1325
+ const path = triggerPath(node);
1326
+ const config = node.config ?? {};
1327
+ return {
1328
+ nodeId: node.id,
1329
+ path,
1330
+ bodyType: config.bodyType ?? 'object',
1331
+ inputSchema: Array.isArray(config.inputSchema) ? config.inputSchema : [],
1332
+ ...endpointAuth(config),
1333
+ isTransactional: config.isTransactional === true,
1334
+ timeoutMs: config.timeoutMs ?? FLOW_LIMITS.DEFAULT_TIMEOUT_MS,
1335
+ rateLimitPerMinute: config.rateLimitPerMinute ?? FLOW_LIMITS.DEFAULT_RATE_LIMIT_PER_MINUTE,
1336
+ apiKey: isStoredApiKey(config.apiKey) ? config.apiKey : null
1337
+ };
1338
+ });
1339
+ }
1340
+ /** The URL a call came in on: `path` of a Request step, or null / empty for the flow's own URL. */ function findEndpoint(flow, path) {
1341
+ const wanted = path?.trim() || null;
1342
+ return flowEndpoints(flow).find((endpoint)=>endpoint.path === wanted);
1343
+ }
1344
+ /** The Request step a run starts at: by its id, or the one on the flow's own URL when none is named. */ function startEndpoint(flow, nodeId) {
1345
+ return nodeId ? flowEndpoints(flow).find((endpoint)=>endpoint.nodeId === nodeId) : findEndpoint(flow);
1346
+ }
1347
+ /** Output ports a node of this type can have (a `respond` node ends the flow: none). */ function portsOf(node) {
1348
+ switch(node.type){
1349
+ case 'condition':
1350
+ return [
1351
+ 'true',
1352
+ 'false'
1353
+ ];
1354
+ case 'switch':
1355
+ return [
1356
+ ...(node.config.cases ?? []).map((c)=>c.id),
1357
+ 'default'
1358
+ ];
1359
+ case 'foreach':
1360
+ return [
1361
+ 'each',
1362
+ 'done'
1363
+ ];
1364
+ case 'permission_check':
1365
+ case 'company_branch_check':
1366
+ return node.config.onDenied === 'branch' ? [
1367
+ 'allowed',
1368
+ 'denied'
1369
+ ] : [
1370
+ 'out'
1371
+ ];
1372
+ case 'respond':
1373
+ return [];
1374
+ case 'trigger':
1375
+ case 'validate':
1376
+ case 'set':
1377
+ case 'commit':
1378
+ return [
1379
+ 'out'
1380
+ ];
1381
+ default:
1382
+ return [
1383
+ 'out',
1384
+ 'error'
1385
+ ];
1386
+ }
1387
+ }
1388
+
1389
+ __webpack_require__.d(__webpack_exports__, {
1390
+ IE: () => (startEndpoint),
1391
+ Xr: () => (flowEndpoints),
1392
+ a5: () => (portsOf),
1393
+ um: () => (triggerPath),
1394
+ vS: () => (findEndpoint),
1395
+ xA: () => (isStoredApiKey)
1396
+ }, {
1397
+ At: NON_CONTINUABLE_NODE_TYPES,
1398
+ B9: FLOW_EMAIL_TARGETS,
1399
+ Dn: RECORD_WRITE_TARGETS,
1400
+ E2: FLOW_ID_PATTERN,
1401
+ Et: FLOW_BRANCH_MATCHES,
1402
+ FU: FLOW_EMAIL_FORMATS,
1403
+ KF: FLOW_MESSAGE_SERVICES,
1404
+ LG: FLOW_NOTIFICATION_TYPES,
1405
+ Or: FLOW_LIMITS,
1406
+ Q7: FLOW_INPUT_TYPES,
1407
+ SE: isMessageNode,
1408
+ Y3: FLOW_BODY_TYPES,
1409
+ YD: FLOW_SLUG_PATTERN,
1410
+ YO: FLOW_ENDPOINT_PATH_PATTERN,
1411
+ as: FLOW_NOTIFICATION_TARGETS,
1412
+ d7: KEYLESS_AUTH_MODES,
1413
+ dA: nodeLabel,
1414
+ fO: FLOW_AUTH_MODES,
1415
+ fP: isFunctionFlow,
1416
+ fZ: FLOW_INPUT_NAME_PATTERN,
1417
+ iM: FLOW_ACCESS_SUBJECTS,
1418
+ q2: FLOW_NODE_TYPES,
1419
+ sk: FLOW_BRANCH_COMPANIES,
1420
+ v1: FLOW_EMAIL_MODES,
1421
+ z6: FLOW_NODE_ID_PATTERN
1422
+ });
1423
+
1424
+
1425
+ },
1426
+ 5313(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1427
+ /* import */ var node_crypto__rspack_import_0 = __webpack_require__(2561);
1428
+ /* import */ var typeorm__rspack_import_1 = __webpack_require__(7158);
1429
+ /* import */ var _enums_field_type_enum_js__rspack_import_2 = __webpack_require__(9614);
1430
+
1431
+
1432
+
1433
+ /** Columns every dynamic table may carry (the `Identity` contract). Everything else is a designed field. */ const SYSTEM_COLUMN_NAMES = [
1434
+ 'id',
1435
+ 'created_at',
1436
+ 'updated_at',
1437
+ 'deleted_at',
1438
+ 'created_by_id',
1439
+ 'updated_by_id',
1440
+ 'deleted_by_id'
1441
+ ];
1442
+ /** Field types stored as unbounded text or JSON: an index or unique constraint on them fails (MySQL) or breaks on large values (PostgreSQL). */ const NON_INDEXABLE_FIELD_TYPES = [
1443
+ _enums_field_type_enum_js__rspack_import_2/* .FieldType.LONG_TEXT */.P.LONG_TEXT,
1444
+ _enums_field_type_enum_js__rspack_import_2/* .FieldType.JSON */.P.JSON,
1445
+ _enums_field_type_enum_js__rspack_import_2/* .FieldType.MULTI_SELECT */.P.MULTI_SELECT
1446
+ ];
1447
+ const isIndexableFieldType = (fieldType)=>!NON_INDEXABLE_FIELD_TYPES.includes(fieldType);
1448
+ const uuidColumn = (name, driver, options = {})=>new typeorm__rspack_import_1.TableColumn({
1449
+ name,
1450
+ ...driver === 'postgres' ? {
1451
+ type: 'uuid'
1452
+ } : {
1453
+ type: 'char',
1454
+ length: '36'
1455
+ },
1456
+ ...options
1457
+ });
1458
+ function buildSystemColumns(flags, driver) {
1459
+ const columns = [
1460
+ uuidColumn('id', driver, {
1461
+ isPrimary: true,
1462
+ isGenerated: true,
1463
+ generationStrategy: 'uuid'
1464
+ }),
1465
+ new typeorm__rspack_import_1.TableColumn({
1466
+ name: 'created_at',
1467
+ type: 'timestamp',
1468
+ isNullable: false,
1469
+ default: 'CURRENT_TIMESTAMP'
1470
+ }),
1471
+ new typeorm__rspack_import_1.TableColumn({
1472
+ name: 'updated_at',
1473
+ type: 'timestamp',
1474
+ isNullable: false,
1475
+ default: 'CURRENT_TIMESTAMP'
1476
+ })
1477
+ ];
1478
+ if (flags.isSoftDeleteEnabled) columns.push(softDeleteColumn());
1479
+ if (flags.isAuditEnabled) columns.push(...auditColumns(driver));
1480
+ return columns;
1481
+ }
1482
+ const softDeleteColumn = ()=>new typeorm__rspack_import_1.TableColumn({
1483
+ name: 'deleted_at',
1484
+ type: 'timestamp',
1485
+ isNullable: true
1486
+ });
1487
+ const auditColumns = (driver)=>[
1488
+ uuidColumn('created_by_id', driver, {
1489
+ isNullable: true
1490
+ }),
1491
+ uuidColumn('updated_by_id', driver, {
1492
+ isNullable: true
1493
+ }),
1494
+ uuidColumn('deleted_by_id', driver, {
1495
+ isNullable: true
1496
+ })
1497
+ ];
1498
+ const sameColumns = (columnNames, expected)=>columnNames.length === expected.length && expected.every((c)=>columnNames.includes(c));
1499
+ const NAME_HASH_LENGTH = 8;
1500
+ /**
1501
+ * Deterministic index/constraint name within the driver's identifier limit. The hash of
1502
+ * `table.column` keeps names distinct when the readable part is cut short, and when two
1503
+ * table/column pairs would read the same (`eb_a_b` + `c` vs `eb_a` + `b_c`).
1504
+ */ function indexName(prefix, table, column, maxLength) {
1505
+ const hash = (0,node_crypto__rspack_import_0.createHash)('sha256').update(`${table}.${column}`).digest('hex').slice(0, NAME_HASH_LENGTH);
1506
+ const room = maxLength - prefix.length - hash.length - 2;
1507
+ return `${prefix}_${`${table}_${column}`.slice(0, room)}_${hash}`;
1508
+ }
1509
+ const plainIndex = (table, column, driver, adapter)=>new typeorm__rspack_import_1.TableIndex({
1510
+ name: indexName('idx', table, column, adapter.maxIdentifierLength(driver)),
1511
+ columnNames: [
1512
+ column
1513
+ ]
1514
+ });
1515
+ const tableUnique = (table, column, driver, adapter)=>new typeorm__rspack_import_1.TableUnique({
1516
+ name: indexName('uq', table, column, adapter.maxIdentifierLength(driver)),
1517
+ columnNames: [
1518
+ column
1519
+ ]
1520
+ });
1521
+ /** MySQL has no unique constraints (TypeORM refuses them), only unique indexes. */ async function addUnique(qr, table, column, driver, adapter) {
1522
+ const name = indexName('uq', table.name, column, adapter.maxIdentifierLength(driver));
1523
+ if (driver === 'mysql') {
1524
+ await qr.createIndex(table, new typeorm__rspack_import_1.TableIndex({
1525
+ name,
1526
+ columnNames: [
1527
+ column
1528
+ ],
1529
+ isUnique: true
1530
+ }));
1531
+ return;
1532
+ }
1533
+ await qr.createUniqueConstraint(table, new typeorm__rspack_import_1.TableUnique({
1534
+ name,
1535
+ columnNames: [
1536
+ column
1537
+ ]
1538
+ }));
1539
+ }
1540
+ /** The stored column type, with a `uuid` stored before MySQL support became char(36) resolved to what MySQL accepts. */ function columnType(field, driver, adapter) {
1541
+ const type = field.dbType || adapter.mapFieldType(field.fieldType, driver);
1542
+ return driver === 'mysql' && type === 'uuid' ? 'char' : type;
1543
+ }
1544
+ /**
1545
+ * Column for a field. `enforceNotNull` controls whether the DB column is NOT NULL: true when
1546
+ * the table is brand new (no rows can violate it); false when adding to a table that already
1547
+ * has rows (the NOT NULL is applied afterwards, once the column has been backfilled).
1548
+ */ function buildFieldColumn(field, driver, adapter, options) {
1549
+ const sizing = adapter.getColumnSizing(field.fieldType, driver);
1550
+ return new typeorm__rspack_import_1.TableColumn({
1551
+ name: field.code,
1552
+ type: columnType(field, driver, adapter),
1553
+ length: sizing.length,
1554
+ precision: sizing.precision ?? undefined,
1555
+ scale: sizing.scale,
1556
+ isNullable: options.enforceNotNull ? field.nullable : true,
1557
+ isUnique: options.withUnique ? field.unique : false
1558
+ });
1559
+ }
1560
+ /** The SQL type text for a field type on a driver, e.g. `varchar(255)`, `numeric(18,4)`, `char(36)`. */ function sqlTypeFor(fieldType, driver, adapter) {
1561
+ const base = adapter.mapFieldType(fieldType, driver);
1562
+ const sizing = adapter.getColumnSizing(fieldType, driver);
1563
+ if (sizing.length) return `${base}(${sizing.length})`;
1564
+ if (sizing.precision !== undefined) return `${base}(${sizing.precision},${sizing.scale ?? 0})`;
1565
+ return base;
1566
+ }
1567
+ /** Coarse type family, so `character varying` (pg) and `varchar` (mysql) compare equal. */ function typeFamily(type) {
1568
+ const t = type.toLowerCase();
1569
+ if (t === 'uuid') return 'uuid';
1570
+ if (t.includes('json')) return 'json';
1571
+ if (t.includes('timestamp') || t === 'datetime') return 'timestamp';
1572
+ if (t === 'date') return 'date';
1573
+ if (t.includes('bool') || t === 'tinyint') return 'boolean';
1574
+ if (t.includes('int') && !t.includes('point')) return 'integer';
1575
+ if (t.includes('numeric') || t.includes('decimal')) return 'numeric';
1576
+ if (t.includes('char') || t === 'varchar') return 'varchar';
1577
+ if (t.includes('text')) return 'text';
1578
+ return t;
1579
+ }
1580
+
1581
+ __webpack_require__.d(__webpack_exports__, {
1582
+ $6: () => (addUnique),
1583
+ Rm: () => (buildSystemColumns),
1584
+ cg: () => (sqlTypeFor),
1585
+ fu: () => (buildFieldColumn),
1586
+ jp: () => (typeFamily),
1587
+ mo: () => (indexName)
1588
+ }, {
1589
+ G7: sameColumns,
1590
+ HK: auditColumns,
1591
+ OG: softDeleteColumn,
1592
+ d4: isIndexableFieldType,
1593
+ gW: NON_INDEXABLE_FIELD_TYPES,
1594
+ mq: SYSTEM_COLUMN_NAMES,
1595
+ uy: tableUnique,
1596
+ v7: plainIndex
1597
+ });
1598
+
1599
+
1048
1600
  },
1049
1601
  6873(module) {
1050
1602
 
@@ -1069,6 +1621,18 @@ module.exports = __rspack_external_class_transformer_c5a479fb;
1069
1621
  module.exports = __rspack_external_class_validator_7b99ef4d;
1070
1622
 
1071
1623
 
1624
+ },
1625
+ 2561(module) {
1626
+
1627
+ module.exports = __rspack_external_node_crypto_2e7c4b46;
1628
+
1629
+
1630
+ },
1631
+ 7158(module) {
1632
+
1633
+ module.exports = __rspack_external_typeorm;
1634
+
1635
+
1072
1636
  },
1073
1637
 
1074
1638
  };