@restforgejs/platform 5.0.1 → 5.0.8

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 (182) hide show
  1. package/build-info.json +2 -2
  2. package/cli/consumer-deploy.js +1 -1
  3. package/cli/consumer.js +1 -1
  4. package/generators/cli/dashboard/create.js +1 -1
  5. package/generators/cli/endpoint/create.js +1 -1
  6. package/generators/cli/processor/create.js +1 -1
  7. package/generators/lib/dbschema-kit/apply-executor.js +15 -1
  8. package/generators/lib/dbschema-kit/dialect/mysql.js +2 -0
  9. package/generators/lib/dbschema-kit/dialect/oracle.js +2 -0
  10. package/generators/lib/dbschema-kit/dialect/postgres.js +3 -0
  11. package/generators/lib/dbschema-kit/dialect/sqlite.js +2 -0
  12. package/generators/lib/dbschema-kit/emitters/alter-table.js +7 -0
  13. package/generators/lib/dbschema-kit/emitters/create-table.js +31 -3
  14. package/generators/lib/dbschema-kit/statement-modifier.js +12 -2
  15. package/generators/lib/migrate/migrate-runner.js +393 -393
  16. package/generators/lib/payload/payload-runner.js +64 -2
  17. package/generators/lib/payload/schema-diff.js +31 -1
  18. package/generators/lib/templates/dashboard-catalog.js +1 -1
  19. package/generators/lib/templates/db-connection-env.js +1 -1
  20. package/generators/lib/templates/dbschema-catalog.js +1 -1
  21. package/generators/lib/templates/field-validation-catalog.js +1 -1
  22. package/generators/lib/templates/mysql-template.js +1 -1
  23. package/generators/lib/templates/oracle-template.js +1 -1
  24. package/generators/lib/templates/postgres-template.js +1 -1
  25. package/generators/lib/templates/query-declarative-catalog.js +1 -1
  26. package/generators/lib/templates/sqlite-template.js +1 -1
  27. package/generators/lib/utils/database-introspector.js +417 -6
  28. package/generators/lib/validators/argument-validator.js +2 -2
  29. package/integrity-manifest.json +18 -18
  30. package/package.json +4 -2
  31. package/scripts/verify-integrity.js +1 -1
  32. package/server.js +1 -1
  33. package/src/components/handlers/adjust_handler.js +1 -1
  34. package/src/components/handlers/audit_handler.js +1 -1
  35. package/src/components/handlers/delete_handler.js +1 -1
  36. package/src/components/handlers/export_handler.js +1 -1
  37. package/src/components/handlers/import_handler.js +1 -1
  38. package/src/components/handlers/insert_handler.js +1 -1
  39. package/src/components/handlers/update_handler.js +1 -1
  40. package/src/components/handlers/upload_handler.js +1 -1
  41. package/src/components/handlers/workflow_handler.js +1 -1
  42. package/src/components/integrations/webhook.js +1 -1
  43. package/src/consumers/baseConsumer.js +1 -1
  44. package/src/consumers/declarativeMapper.js +1 -1
  45. package/src/consumers/handlers/apiHandler.js +1 -1
  46. package/src/consumers/handlers/consoleHandler.js +1 -1
  47. package/src/consumers/handlers/databaseHandler.js +1 -1
  48. package/src/consumers/handlers/index.js +1 -1
  49. package/src/consumers/handlers/kafkaHandler.js +1 -1
  50. package/src/consumers/index.js +1 -1
  51. package/src/consumers/messageTransformer.js +1 -1
  52. package/src/consumers/validator.js +1 -1
  53. package/src/core/db/dialect/base-dialect.js +1 -1
  54. package/src/core/db/dialect/index.js +1 -1
  55. package/src/core/db/dialect/mysql-dialect.js +1 -1
  56. package/src/core/db/dialect/oracle-dialect.js +1 -1
  57. package/src/core/db/dialect/postgres-dialect.js +1 -1
  58. package/src/core/db/dialect/sqlite-dialect.js +1 -1
  59. package/src/core/db/flatten-helper.js +1 -1
  60. package/src/core/db/query-builder-error.js +1 -1
  61. package/src/core/db/query-builder.js +1 -1
  62. package/src/core/db/relation-helper.js +1 -1
  63. package/src/core/handlers/delete_handler.js +1 -1
  64. package/src/core/handlers/insert_handler.js +1 -1
  65. package/src/core/handlers/update_handler.js +1 -1
  66. package/src/core/models/base-model.js +1 -1
  67. package/src/core/utils/cache-manager.js +1 -1
  68. package/src/core/utils/component-engine.js +1 -1
  69. package/src/core/utils/context-builder.js +1 -1
  70. package/src/core/utils/datetime-formatter.js +1 -1
  71. package/src/core/utils/datetime-parser.js +1 -1
  72. package/src/core/utils/db.js +1 -1
  73. package/src/core/utils/logger.js +1 -1
  74. package/src/core/utils/payload-loader.js +1 -1
  75. package/src/core/utils/security-checks.js +1 -1
  76. package/src/middleware/body-options.js +1 -1
  77. package/src/middleware/cors.js +1 -1
  78. package/src/middleware/idempotency.js +1 -1
  79. package/src/middleware/rate-limiter.js +1 -1
  80. package/src/middleware/request-logger.js +1 -1
  81. package/src/middleware/security-headers.js +1 -1
  82. package/src/models/base-model-mysql.js +1 -1
  83. package/src/models/base-model-oracle.js +1 -1
  84. package/src/models/base-model-sqlite.js +1 -1
  85. package/src/models/base-model.js +1 -1
  86. package/src/pro/caching/redis-client.js +1 -1
  87. package/src/pro/caching/redis-helper.js +1 -1
  88. package/src/pro/consumers/baseConsumer.js +1 -1
  89. package/src/pro/consumers/declarativeMapper.js +1 -1
  90. package/src/pro/consumers/handlers/apiHandler.js +1 -1
  91. package/src/pro/consumers/handlers/consoleHandler.js +1 -1
  92. package/src/pro/consumers/handlers/databaseHandler.js +1 -1
  93. package/src/pro/consumers/handlers/index.js +1 -1
  94. package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
  95. package/src/pro/consumers/index.js +1 -1
  96. package/src/pro/consumers/messageTransformer.js +1 -1
  97. package/src/pro/consumers/validator.js +1 -1
  98. package/src/pro/database/base-model-mysql.js +1 -1
  99. package/src/pro/database/base-model-oracle.js +1 -1
  100. package/src/pro/database/base-model-sqlite.js +1 -1
  101. package/src/pro/database/db-mysql.js +1 -1
  102. package/src/pro/database/db-oracle.js +1 -1
  103. package/src/pro/database/db-sqlite.js +1 -1
  104. package/src/pro/excel/excel-generator.js +1 -1
  105. package/src/pro/excel/excel-parser.js +1 -1
  106. package/src/pro/excel/export-service.js +1 -1
  107. package/src/pro/excel/export_handler.js +1 -1
  108. package/src/pro/excel/import-service.js +1 -1
  109. package/src/pro/excel/import-validator.js +1 -1
  110. package/src/pro/excel/import_handler.js +1 -1
  111. package/src/pro/excel/upsert-builder.js +1 -1
  112. package/src/pro/idgen/idgen-routes.js +1 -1
  113. package/src/pro/integrations/lookup-resolver.js +1 -1
  114. package/src/pro/integrations/upload-handler-v2.js +1 -1
  115. package/src/pro/integrations/upload-handler.js +1 -1
  116. package/src/pro/integrations/webhook.js +1 -1
  117. package/src/pro/locking/lock-routes.js +1 -1
  118. package/src/pro/locking/resource-lock-manager.js +1 -1
  119. package/src/pro/messaging/kafkaConsumerService.js +1 -1
  120. package/src/pro/messaging/kafkaService.js +1 -1
  121. package/src/pro/messaging/messagehubService.js +1 -1
  122. package/src/pro/messaging/rabbitmqService.js +1 -1
  123. package/src/pro/scheduler/job-manager.js +1 -1
  124. package/src/pro/scheduler/job-routes.js +1 -1
  125. package/src/pro/scheduler/job-validator.js +1 -1
  126. package/src/pro/storage/base-storage-provider.js +1 -1
  127. package/src/pro/storage/file-metadata-helper.js +1 -1
  128. package/src/pro/storage/index.js +1 -1
  129. package/src/pro/storage/local-storage-provider.js +1 -1
  130. package/src/pro/storage/s3-storage-provider.js +1 -1
  131. package/src/pro/storage/upload-cleanup-job.js +1 -1
  132. package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
  133. package/src/pro/storage/upload-pending-tracker.js +1 -1
  134. package/src/pro/websocket/broadcast-helper.js +1 -1
  135. package/src/pro/websocket/index.js +1 -1
  136. package/src/pro/websocket/livesync-server.js +1 -1
  137. package/src/pro/websocket/ws-broadcaster.js +1 -1
  138. package/src/services/export-service.js +1 -1
  139. package/src/services/import-service.js +1 -1
  140. package/src/services/kafkaConsumerService.js +1 -1
  141. package/src/services/kafkaService.js +1 -1
  142. package/src/services/messagehubService.js +1 -1
  143. package/src/services/rabbitmqService.js +1 -1
  144. package/src/utils/cache-invalidation-registry.js +1 -1
  145. package/src/utils/cache-manager.js +1 -1
  146. package/src/utils/component-engine.js +1 -1
  147. package/src/utils/config-extractor.js +1 -1
  148. package/src/utils/consumerLogger.js +1 -1
  149. package/src/utils/context-builder.js +1 -1
  150. package/src/utils/dashboard-helpers.js +1 -1
  151. package/src/utils/dateHelper.js +1 -1
  152. package/src/utils/datetime-formatter.js +1 -1
  153. package/src/utils/datetime-parser.js +1 -1
  154. package/src/utils/db-bootstrap.js +1 -1
  155. package/src/utils/db-mysql.js +1 -1
  156. package/src/utils/db-oracle.js +1 -1
  157. package/src/utils/db-sqlite.js +1 -1
  158. package/src/utils/db.js +1 -1
  159. package/src/utils/demo-generator.js +1 -1
  160. package/src/utils/excel-generator.js +1 -1
  161. package/src/utils/excel-parser.js +1 -1
  162. package/src/utils/file-watcher.js +1 -1
  163. package/src/utils/id-generator.js +1 -1
  164. package/src/utils/idempotency-manager.js +1 -1
  165. package/src/utils/import-validator.js +1 -1
  166. package/src/utils/license-client.js +1 -1
  167. package/src/utils/lock-manager.js +1 -1
  168. package/src/utils/logger.js +1 -1
  169. package/src/utils/lookup-resolver.js +1 -1
  170. package/src/utils/payload-loader.js +1 -1
  171. package/src/utils/processor-response.js +1 -1
  172. package/src/utils/rabbitmq.js +1 -1
  173. package/src/utils/redis-client.js +1 -1
  174. package/src/utils/redis-helper.js +1 -1
  175. package/src/utils/request-scope.js +1 -1
  176. package/src/utils/security-checks.js +1 -1
  177. package/src/utils/service-resolver.js +1 -1
  178. package/src/utils/shutdown-coordinator.js +1 -1
  179. package/src/utils/trusted-keys.js +1 -1
  180. package/src/utils/upload-handler.js +1 -1
  181. package/src/utils/upsert-builder.js +1 -1
  182. package/src/utils/workflow-hook-executor.js +1 -1
@@ -879,7 +879,7 @@ module.exports = {
879
879
  type: 'string',
880
880
  required: false,
881
881
  default: null,
882
- description: 'Tipe database (postgres|mysql|oracle). Default: postgres'
882
+ description: 'Tipe database (postgres|mysql|oracle|sqlite). Default: postgres'
883
883
  },
884
884
  force: {
885
885
  type: 'boolean',
@@ -59,7 +59,21 @@ async function connectMysql(driver, config) {
59
59
  multipleStatements: false
60
60
  });
61
61
  return {
62
- exec: (sql) => conn.query(sql),
62
+ exec: async (sql) => {
63
+ try {
64
+ return await conn.query(sql);
65
+ } catch (err) {
66
+ // Idempotensi migrate: MySQL tidak punya `CREATE INDEX IF NOT EXISTS`
67
+ // (lihat statement-modifier.js) sehingga re-run pada index yang sudah
68
+ // ada melempar ER_DUP_KEYNAME (errno 1061). Abaikan khusus untuk
69
+ // CREATE INDEX — setara dengan suppression ORA-00955 di jalur Oracle.
70
+ const isDupIndex = err && (err.errno === 1061 || err.code === 'ER_DUP_KEYNAME');
71
+ if (isDupIndex && /^\s*CREATE\s+(?:UNIQUE\s+)?INDEX\b/i.test(sql)) {
72
+ return [{ affectedRows: 0, suppressed: 'ER_DUP_KEYNAME' }];
73
+ }
74
+ throw err;
75
+ }
76
+ },
63
77
  close: () => conn.end()
64
78
  };
65
79
  }
@@ -82,6 +82,8 @@ function formatReferentialAction(action) {
82
82
  module.exports = {
83
83
  name: 'mysql',
84
84
  maxIdentifierLength: 64,
85
+ // Boolean disimpan sebagai VARCHAR(5) 'true'/'false'; bukan native.
86
+ nativeBoolean: false,
85
87
  mapType,
86
88
  formatDefault,
87
89
  quoteIdentifier,
@@ -87,6 +87,8 @@ module.exports = {
87
87
  // RESTForge target Oracle 19c+ (default COMPATIBLE >= 12.2). Override via
88
88
  // --max-name-length=30 if deploying to legacy database.
89
89
  maxIdentifierLength: 128,
90
+ // Boolean disimpan sebagai VARCHAR2(5) 'true'/'false'; bukan native.
91
+ nativeBoolean: false,
90
92
  mapType,
91
93
  formatDefault,
92
94
  quoteIdentifier,
@@ -81,6 +81,9 @@ function formatReferentialAction(action) {
81
81
  module.exports = {
82
82
  name: 'postgres',
83
83
  maxIdentifierLength: 63,
84
+ // PostgreSQL punya tipe BOOLEAN native; dialect lain menyimpan boolean
85
+ // sebagai VARCHAR 'true'/'false' dan butuh CHECK sebagai penanda boolean.
86
+ nativeBoolean: true,
84
87
  mapType,
85
88
  formatDefault,
86
89
  quoteIdentifier,
@@ -85,6 +85,8 @@ module.exports = {
85
85
  name: 'sqlite',
86
86
  // SQLite has no hard identifier limit; cap at 63 to stay portable with PG/MySQL.
87
87
  maxIdentifierLength: 63,
88
+ // Boolean disimpan sebagai VARCHAR(5) 'true'/'false'; bukan native.
89
+ nativeBoolean: false,
88
90
  mapType,
89
91
  formatDefault,
90
92
  quoteIdentifier,
@@ -54,6 +54,13 @@ function emitAddColumn(tableIR, fieldName, field, dialect) {
54
54
  parts.push(`DEFAULT ${dialect.formatDefault(field.default)}`);
55
55
  }
56
56
 
57
+ // Penanda boolean untuk dialect varchar (selaras dengan create-table emitter):
58
+ // CHECK inline pada kolom agar introspeksi dapat mengenalinya kembali sebagai
59
+ // boolean. PostgreSQL (nativeBoolean) memakai tipe BOOLEAN native, dikecualikan.
60
+ if (field.type === 'boolean' && dialect.nativeBoolean !== true) {
61
+ parts.push(`CHECK (${column} IN ('true', 'false'))`);
62
+ }
63
+
57
64
  if (dialect.name === 'oracle') {
58
65
  // Oracle membungkus column definition di dalam parentheses untuk ADD,
59
66
  // konvensi yang juga mendukung multi-column add bila diperlukan nanti.
@@ -44,9 +44,14 @@ function emitCreateTable(ir, dialect) {
44
44
  lines.push(emitForeignKey(tableName, relName, rel, dialect));
45
45
  }
46
46
 
47
- const checkNames = resolveCheckNames(tableName, checks, dialect.maxIdentifierLength);
48
- for (let i = 0; i < checks.length; i++) {
49
- const check = checks[i];
47
+ // Gabungkan CHECK eksplisit (dari SDF) dengan CHECK boolean yang di-derive
48
+ // otomatis untuk dialect non-native-boolean (mysql/oracle/sqlite). CHECK ini
49
+ // menjadi penanda deterministik agar introspeksi dapat mengenali kembali kolom
50
+ // VARCHAR sebagai boolean (lihat database-introspector.getBooleanColumns).
51
+ const allChecks = (Array.isArray(checks) ? checks : []).concat(deriveBooleanChecks(fields, dialect));
52
+ const checkNames = resolveCheckNames(tableName, allChecks, dialect.maxIdentifierLength);
53
+ for (let i = 0; i < allChecks.length; i++) {
54
+ const check = allChecks[i];
50
55
  if (check._invalid) continue;
51
56
  lines.push(emitCheck(check, checkNames[i], dialect));
52
57
  }
@@ -54,6 +59,29 @@ function emitCreateTable(ir, dialect) {
54
59
  return `CREATE TABLE ${dialect.formatTableIdentifier(ir)} (\n${lines.join(',\n')}\n)`;
55
60
  }
56
61
 
62
+ /**
63
+ * Derive CHECK constraint penanda boolean untuk dialect yang menyimpan boolean
64
+ * sebagai VARCHAR (mysql/oracle/sqlite). Bentuk: `col IN ('true','false')`.
65
+ *
66
+ * PostgreSQL (nativeBoolean === true) memakai tipe BOOLEAN native sehingga tidak
67
+ * memerlukan penanda dan dikecualikan. CHECK ini TIDAK ditulis user di SDF;
68
+ * kata kunci `boolean` di field sudah cukup, generator yang menyisipkannya.
69
+ *
70
+ * @param {Object} fields - Map fieldName -> field IR (punya .type)
71
+ * @param {Object} dialect - Dialect aktif
72
+ * @returns {Array<{field:string, op:string, value:string[]}>}
73
+ */
74
+ function deriveBooleanChecks(fields, dialect) {
75
+ if (dialect.nativeBoolean === true) return [];
76
+ const derived = [];
77
+ for (const [fieldName, field] of Object.entries(fields)) {
78
+ if (field && field.type === 'boolean') {
79
+ derived.push({ field: fieldName, op: 'in', value: ['true', 'false'] });
80
+ }
81
+ }
82
+ return derived;
83
+ }
84
+
57
85
  function emitColumn(fieldName, field, dialect) {
58
86
  const parts = [`${COLUMN_INDENT}${dialect.quoteIdentifier(fieldName)}`, dialect.mapType(field)];
59
87
 
@@ -13,8 +13,12 @@ const RE_BEGIN = /^\s*BEGIN\b/i;
13
13
  * `--drop=false` (statement re-run idempotent).
14
14
  *
15
15
  * Rules per dialect:
16
- * - postgres / mysql / sqlite: insert `IF NOT EXISTS ` after `CREATE TABLE `
17
- * or `CREATE INDEX ` (also `CREATE UNIQUE INDEX `).
16
+ * - postgres / sqlite: insert `IF NOT EXISTS ` after `CREATE TABLE ` or
17
+ * `CREATE INDEX ` (also `CREATE UNIQUE INDEX `).
18
+ * - mysql: insert `IF NOT EXISTS ` after `CREATE TABLE ` saja. MySQL TIDAK
19
+ * mendukung `CREATE INDEX IF NOT EXISTS` (syntax error), jadi CREATE INDEX
20
+ * dibiarkan apa adanya — valid pada first-run; re-run index yang sudah ada
21
+ * akan gagal duplicate (keterbatasan MySQL, gunakan --drop untuk recreate).
18
22
  * - oracle: wrap CREATE TABLE / CREATE INDEX in a PL/SQL block that suppresses
19
23
  * SQLCODE -955 (ORA-00955: name is already used by an existing object).
20
24
  * - DROP statements pass through unchanged (the emitter already uses IF EXISTS).
@@ -53,6 +57,12 @@ function applyIfNotExistsModifier(statement, dialect) {
53
57
  return statement.replace(RE_CREATE_TABLE, '$1CREATE TABLE IF NOT EXISTS ');
54
58
  }
55
59
 
60
+ // MySQL tidak mendukung `CREATE INDEX IF NOT EXISTS` (parser error). Biarkan
61
+ // statement CREATE INDEX apa adanya; valid pada first-run.
62
+ if (dialect === 'mysql') {
63
+ return statement;
64
+ }
65
+
56
66
  return statement.replace(RE_CREATE_INDEX, (match, leading, unique) => {
57
67
  const uniquePart = unique ? 'UNIQUE ' : '';
58
68
  return `${leading}CREATE ${uniquePart}INDEX IF NOT EXISTS `;