@restforgejs/platform 5.0.9 → 5.1.4

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 (181) 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/data/pull.js +95 -0
  5. package/generators/cli/data/push.js +85 -0
  6. package/generators/cli/fast-track.js +950 -0
  7. package/generators/cli/payload/sync.js +18 -2
  8. package/generators/cli/schema/introspect.js +10 -10
  9. package/generators/lib/data/db-executor.js +440 -0
  10. package/generators/lib/data/dialect-kit.js +56 -0
  11. package/generators/lib/data/envelope.js +220 -0
  12. package/generators/lib/data/pull-runner.js +407 -0
  13. package/generators/lib/data/push-runner.js +382 -0
  14. package/generators/lib/data/sdf-reader.js +132 -0
  15. package/generators/lib/data/table-order.js +126 -0
  16. package/generators/lib/data/value-codec.js +188 -0
  17. package/generators/lib/migrate/field-type-resolver.js +18 -5
  18. package/generators/lib/payload/payload-runner.js +724 -39
  19. package/generators/lib/templates/dashboard-catalog.js +1 -1
  20. package/generators/lib/templates/db-connection-env.js +1 -1
  21. package/generators/lib/templates/dbschema-catalog.js +1 -1
  22. package/generators/lib/templates/field-validation-catalog.js +1 -1
  23. package/generators/lib/templates/mysql-template.js +1 -1
  24. package/generators/lib/templates/oracle-template.js +1 -1
  25. package/generators/lib/templates/postgres-template.js +1 -1
  26. package/generators/lib/templates/query-declarative-catalog.js +1 -1
  27. package/generators/lib/templates/sqlite-template.js +1 -1
  28. package/integrity-manifest.json +18 -18
  29. package/package.json +1 -1
  30. package/scripts/verify-integrity.js +1 -1
  31. package/server.js +1 -1
  32. package/src/components/handlers/adjust_handler.js +1 -1
  33. package/src/components/handlers/audit_handler.js +1 -1
  34. package/src/components/handlers/delete_handler.js +1 -1
  35. package/src/components/handlers/export_handler.js +1 -1
  36. package/src/components/handlers/import_handler.js +1 -1
  37. package/src/components/handlers/insert_handler.js +1 -1
  38. package/src/components/handlers/update_handler.js +1 -1
  39. package/src/components/handlers/upload_handler.js +1 -1
  40. package/src/components/handlers/workflow_handler.js +1 -1
  41. package/src/components/integrations/webhook.js +1 -1
  42. package/src/consumers/baseConsumer.js +1 -1
  43. package/src/consumers/declarativeMapper.js +1 -1
  44. package/src/consumers/handlers/apiHandler.js +1 -1
  45. package/src/consumers/handlers/consoleHandler.js +1 -1
  46. package/src/consumers/handlers/databaseHandler.js +1 -1
  47. package/src/consumers/handlers/index.js +1 -1
  48. package/src/consumers/handlers/kafkaHandler.js +1 -1
  49. package/src/consumers/index.js +1 -1
  50. package/src/consumers/messageTransformer.js +1 -1
  51. package/src/consumers/validator.js +1 -1
  52. package/src/core/db/dialect/base-dialect.js +1 -1
  53. package/src/core/db/dialect/index.js +1 -1
  54. package/src/core/db/dialect/mysql-dialect.js +1 -1
  55. package/src/core/db/dialect/oracle-dialect.js +1 -1
  56. package/src/core/db/dialect/postgres-dialect.js +1 -1
  57. package/src/core/db/dialect/sqlite-dialect.js +1 -1
  58. package/src/core/db/flatten-helper.js +1 -1
  59. package/src/core/db/query-builder-error.js +1 -1
  60. package/src/core/db/query-builder.js +1 -1
  61. package/src/core/db/relation-helper.js +1 -1
  62. package/src/core/handlers/delete_handler.js +1 -1
  63. package/src/core/handlers/insert_handler.js +1 -1
  64. package/src/core/handlers/update_handler.js +1 -1
  65. package/src/core/models/base-model.js +1 -1
  66. package/src/core/utils/cache-manager.js +1 -1
  67. package/src/core/utils/component-engine.js +1 -1
  68. package/src/core/utils/context-builder.js +1 -1
  69. package/src/core/utils/datetime-formatter.js +1 -1
  70. package/src/core/utils/datetime-parser.js +1 -1
  71. package/src/core/utils/db.js +1 -1
  72. package/src/core/utils/logger.js +1 -1
  73. package/src/core/utils/payload-loader.js +1 -1
  74. package/src/core/utils/security-checks.js +1 -1
  75. package/src/middleware/body-options.js +1 -1
  76. package/src/middleware/cors.js +1 -1
  77. package/src/middleware/idempotency.js +1 -1
  78. package/src/middleware/rate-limiter.js +1 -1
  79. package/src/middleware/request-logger.js +1 -1
  80. package/src/middleware/security-headers.js +1 -1
  81. package/src/models/base-model-mysql.js +1 -1
  82. package/src/models/base-model-oracle.js +1 -1
  83. package/src/models/base-model-sqlite.js +1 -1
  84. package/src/models/base-model.js +1 -1
  85. package/src/pro/caching/redis-client.js +1 -1
  86. package/src/pro/caching/redis-helper.js +1 -1
  87. package/src/pro/consumers/baseConsumer.js +1 -1
  88. package/src/pro/consumers/declarativeMapper.js +1 -1
  89. package/src/pro/consumers/handlers/apiHandler.js +1 -1
  90. package/src/pro/consumers/handlers/consoleHandler.js +1 -1
  91. package/src/pro/consumers/handlers/databaseHandler.js +1 -1
  92. package/src/pro/consumers/handlers/index.js +1 -1
  93. package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
  94. package/src/pro/consumers/index.js +1 -1
  95. package/src/pro/consumers/messageTransformer.js +1 -1
  96. package/src/pro/consumers/validator.js +1 -1
  97. package/src/pro/database/base-model-mysql.js +1 -1
  98. package/src/pro/database/base-model-oracle.js +1 -1
  99. package/src/pro/database/base-model-sqlite.js +1 -1
  100. package/src/pro/database/db-mysql.js +1 -1
  101. package/src/pro/database/db-oracle.js +1 -1
  102. package/src/pro/database/db-sqlite.js +1 -1
  103. package/src/pro/excel/excel-generator.js +1 -1
  104. package/src/pro/excel/excel-parser.js +1 -1
  105. package/src/pro/excel/export-service.js +1 -1
  106. package/src/pro/excel/export_handler.js +1 -1
  107. package/src/pro/excel/import-service.js +1 -1
  108. package/src/pro/excel/import-validator.js +1 -1
  109. package/src/pro/excel/import_handler.js +1 -1
  110. package/src/pro/excel/upsert-builder.js +1 -1
  111. package/src/pro/idgen/idgen-routes.js +1 -1
  112. package/src/pro/integrations/lookup-resolver.js +1 -1
  113. package/src/pro/integrations/upload-handler-v2.js +1 -1
  114. package/src/pro/integrations/upload-handler.js +1 -1
  115. package/src/pro/integrations/webhook.js +1 -1
  116. package/src/pro/locking/lock-routes.js +1 -1
  117. package/src/pro/locking/resource-lock-manager.js +1 -1
  118. package/src/pro/messaging/kafkaConsumerService.js +1 -1
  119. package/src/pro/messaging/kafkaService.js +1 -1
  120. package/src/pro/messaging/messagehubService.js +1 -1
  121. package/src/pro/messaging/rabbitmqService.js +1 -1
  122. package/src/pro/scheduler/job-manager.js +1 -1
  123. package/src/pro/scheduler/job-routes.js +1 -1
  124. package/src/pro/scheduler/job-validator.js +1 -1
  125. package/src/pro/storage/base-storage-provider.js +1 -1
  126. package/src/pro/storage/file-metadata-helper.js +1 -1
  127. package/src/pro/storage/index.js +1 -1
  128. package/src/pro/storage/local-storage-provider.js +1 -1
  129. package/src/pro/storage/s3-storage-provider.js +1 -1
  130. package/src/pro/storage/upload-cleanup-job.js +1 -1
  131. package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
  132. package/src/pro/storage/upload-pending-tracker.js +1 -1
  133. package/src/pro/websocket/broadcast-helper.js +1 -1
  134. package/src/pro/websocket/index.js +1 -1
  135. package/src/pro/websocket/livesync-server.js +1 -1
  136. package/src/pro/websocket/ws-broadcaster.js +1 -1
  137. package/src/services/export-service.js +1 -1
  138. package/src/services/import-service.js +1 -1
  139. package/src/services/kafkaConsumerService.js +1 -1
  140. package/src/services/kafkaService.js +1 -1
  141. package/src/services/messagehubService.js +1 -1
  142. package/src/services/rabbitmqService.js +1 -1
  143. package/src/utils/cache-invalidation-registry.js +1 -1
  144. package/src/utils/cache-manager.js +1 -1
  145. package/src/utils/component-engine.js +1 -1
  146. package/src/utils/config-extractor.js +1 -1
  147. package/src/utils/consumerLogger.js +1 -1
  148. package/src/utils/context-builder.js +1 -1
  149. package/src/utils/dashboard-helpers.js +1 -1
  150. package/src/utils/dateHelper.js +1 -1
  151. package/src/utils/datetime-formatter.js +1 -1
  152. package/src/utils/datetime-parser.js +1 -1
  153. package/src/utils/db-bootstrap.js +1 -1
  154. package/src/utils/db-mysql.js +1 -1
  155. package/src/utils/db-oracle.js +1 -1
  156. package/src/utils/db-sqlite.js +1 -1
  157. package/src/utils/db.js +1 -1
  158. package/src/utils/demo-generator.js +1 -1
  159. package/src/utils/excel-generator.js +1 -1
  160. package/src/utils/excel-parser.js +1 -1
  161. package/src/utils/file-watcher.js +1 -1
  162. package/src/utils/id-generator.js +1 -1
  163. package/src/utils/idempotency-manager.js +1 -1
  164. package/src/utils/import-validator.js +1 -1
  165. package/src/utils/license-client.js +1 -1
  166. package/src/utils/lock-manager.js +1 -1
  167. package/src/utils/logger.js +1 -1
  168. package/src/utils/lookup-resolver.js +1 -1
  169. package/src/utils/payload-loader.js +1 -1
  170. package/src/utils/processor-response.js +1 -1
  171. package/src/utils/rabbitmq.js +1 -1
  172. package/src/utils/redis-client.js +1 -1
  173. package/src/utils/redis-helper.js +1 -1
  174. package/src/utils/request-scope.js +1 -1
  175. package/src/utils/security-checks.js +1 -1
  176. package/src/utils/service-resolver.js +1 -1
  177. package/src/utils/shutdown-coordinator.js +1 -1
  178. package/src/utils/trusted-keys.js +1 -1
  179. package/src/utils/upload-handler.js +1 -1
  180. package/src/utils/upsert-builder.js +1 -1
  181. package/src/utils/workflow-hook-executor.js +1 -1
@@ -0,0 +1,188 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * value-codec — Encoding nilai canonical ↔ representasi text untuk envelope.
5
+ *
6
+ * Mengacu pada docs/plan/data-pull-push/data-pull-push-03-data-format.md.
7
+ *
8
+ * - `encodeValue`: nilai mentah hasil SELECT (driver) → representasi envelope.
9
+ * Mayoritas scalar menjadi string ("nilai text") agar portable; kolom `json`
10
+ * adalah pengecualian (disimpan sebagai nilai JSON nested asli).
11
+ * - `decodeValue`: representasi envelope → nilai bindable untuk driver target,
12
+ * dibedakan per dialect untuk boolean dan json.
13
+ *
14
+ * Sistem tipe: 10 canonical (shorthand-parser): string, text, integer, bigint,
15
+ * decimal, boolean, date, timestamp, uuid, json.
16
+ *
17
+ * @module generators/lib/data/value-codec
18
+ */
19
+
20
+ /**
21
+ * Normalisasi argumen dialect menjadi nama kanonik lowercase.
22
+ * Menerima string ('postgres'/'postgresql'/'mysql'/'oracle'/'sqlite') atau
23
+ * instance dialect (punya properti `.name`).
24
+ *
25
+ * @param {string|Object} dialect
26
+ * @returns {string} 'postgresql' | 'mysql' | 'oracle' | 'sqlite' | string apa adanya
27
+ */
28
+ function dialectName(dialect) {
29
+ const raw = typeof dialect === 'string' ? dialect : (dialect && dialect.name);
30
+ const d = (raw || '').toLowerCase();
31
+ if (d === 'postgres' || d === 'pg') return 'postgresql';
32
+ return d;
33
+ }
34
+
35
+ /**
36
+ * Format objek Date menjadi 'YYYY-MM-DD' memakai komponen lokal.
37
+ * Driver pg mengembalikan kolom DATE sebagai Date pada tengah malam lokal,
38
+ * sehingga komponen lokal memberi tanggal yang benar tanpa pergeseran zona.
39
+ *
40
+ * @param {Date} d
41
+ * @returns {string}
42
+ */
43
+ function formatDateOnly(d) {
44
+ const yyyy = String(d.getFullYear()).padStart(4, '0');
45
+ const mm = String(d.getMonth() + 1).padStart(2, '0');
46
+ const dd = String(d.getDate()).padStart(2, '0');
47
+ return `${yyyy}-${mm}-${dd}`;
48
+ }
49
+
50
+ /**
51
+ * Normalisasi nilai boolean mentah menjadi 'true' / 'false'.
52
+ * Menangani boolean asli, string ('true'/'false'/'t'/'f', case-insensitive),
53
+ * dan angka (1/0) yang mungkin dikembalikan beberapa driver.
54
+ *
55
+ * @param {*} raw
56
+ * @returns {string} 'true' | 'false'
57
+ */
58
+ function normalizeBoolean(raw) {
59
+ if (typeof raw === 'boolean') return raw ? 'true' : 'false';
60
+ if (typeof raw === 'number') return raw !== 0 ? 'true' : 'false';
61
+ if (typeof raw === 'string') {
62
+ const s = raw.trim().toLowerCase();
63
+ if (s === 'true' || s === 't' || s === '1') return 'true';
64
+ if (s === 'false' || s === 'f' || s === '0') return 'false';
65
+ }
66
+ // Fallback: pertahankan determinisme via truthiness JS.
67
+ return raw ? 'true' : 'false';
68
+ }
69
+
70
+ /**
71
+ * Encode nilai mentah dari driver menjadi representasi envelope.
72
+ *
73
+ * @param {*} raw - Nilai hasil SELECT
74
+ * @param {string} canonicalType - Salah satu dari 10 tipe canonical
75
+ * @returns {*} Representasi envelope (string, null, atau nilai JSON nested untuk json)
76
+ */
77
+ function encodeValue(raw, canonicalType) {
78
+ if (raw === null || raw === undefined) return null;
79
+
80
+ switch (canonicalType) {
81
+ case 'boolean':
82
+ return normalizeBoolean(raw);
83
+
84
+ case 'integer':
85
+ case 'bigint':
86
+ case 'decimal':
87
+ // String menjaga presisi (bigint di luar batas Number, scale decimal).
88
+ // bigint JS → String tanpa suffix 'n'.
89
+ return String(raw);
90
+
91
+ case 'date':
92
+ if (raw instanceof Date) return formatDateOnly(raw);
93
+ // String dari driver (MySQL dateStrings / Oracle NLS / SQLite text).
94
+ // Ambil porsi tanggal bila ada komponen waktu.
95
+ return String(raw).slice(0, 10);
96
+
97
+ case 'timestamp':
98
+ // ISO-8601, zona dipertahankan bila ada. Date JS → toISOString (UTC 'Z').
99
+ if (raw instanceof Date) return raw.toISOString();
100
+ // String dari driver: normalisasi SATU separator tanggal-waktu spasi → 'T'
101
+ // (mis. MySQL dateStrings '2026-01-02 08:00:00' → '2026-01-02T08:00:00').
102
+ // Hanya separator yang diubah; nilai waktu dan zona/offset dipertahankan apa
103
+ // adanya. String yang sudah ber-'T' (tanpa spasi separator) tidak terpengaruh.
104
+ return String(raw).replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, '$1T$2');
105
+
106
+ case 'json':
107
+ // Nilai JSON nested asli (object/array), BUKAN string ter-escape.
108
+ // Driver yang menyimpan JSON sebagai TEXT/CLOB (SQLite/Oracle) mengembalikan
109
+ // string → parse kembali ke nilai nested. PG/MySQL sudah object.
110
+ if (typeof raw === 'string') {
111
+ try {
112
+ return JSON.parse(raw);
113
+ } catch (_e) {
114
+ // String yang bukan JSON valid: pertahankan apa adanya agar tidak
115
+ // menyembunyikan data secara diam-diam.
116
+ return raw;
117
+ }
118
+ }
119
+ return raw;
120
+
121
+ case 'uuid':
122
+ case 'string':
123
+ case 'text':
124
+ default:
125
+ return String(raw);
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Decode representasi envelope menjadi nilai bindable untuk driver target.
131
+ *
132
+ * @param {*} text - Nilai dari envelope (string, null, atau nilai JSON nested)
133
+ * @param {string} canonicalType - Salah satu dari 10 tipe canonical
134
+ * @param {string|Object} dialect - Nama dialect atau instance dialect
135
+ * @returns {*} Nilai siap di-bind ke driver
136
+ */
137
+ function decodeValue(text, canonicalType, dialect) {
138
+ if (text === null || text === undefined) return null;
139
+
140
+ const d = dialectName(dialect);
141
+
142
+ switch (canonicalType) {
143
+ case 'boolean': {
144
+ const norm = normalizeBoolean(text);
145
+ // PostgreSQL: kolom boolean native → bind JS boolean.
146
+ // MySQL/Oracle/SQLite: kolom VARCHAR 'true'/'false' → bind string.
147
+ if (d === 'postgresql') return norm === 'true';
148
+ return norm;
149
+ }
150
+
151
+ case 'integer':
152
+ case 'bigint':
153
+ case 'decimal':
154
+ // Boleh string sesuai driver; bigint/decimal tetap string menjaga presisi.
155
+ // Driver/DB melakukan cast text → numeric pada kolom target.
156
+ return String(text);
157
+
158
+ case 'date':
159
+ case 'timestamp':
160
+ // String; driver/NLS menangani konversi. Oracle via ALTER SESSION NLS.
161
+ return String(text);
162
+
163
+ case 'json':
164
+ // Stringify untuk dialect yang menerima JSON sebagai TEXT:
165
+ // - SQLite/Oracle menyimpan JSON sebagai TEXT/CLOB.
166
+ // - PostgreSQL: cast text→jsonb. WAJIB string karena driver `pg`
167
+ // menserialisasi JS array sebagai PostgreSQL array literal ('{...}'),
168
+ // bukan JSON, sehingga bind array ke kolom JSONB gagal (phase 05b).
169
+ // MySQL: tetap object native (driver men-serialize ke JSON); sudah PASS.
170
+ if (d === 'sqlite' || d === 'oracle' || d === 'postgresql') {
171
+ return JSON.stringify(text);
172
+ }
173
+ return text;
174
+
175
+ case 'uuid':
176
+ case 'string':
177
+ case 'text':
178
+ default:
179
+ return String(text);
180
+ }
181
+ }
182
+
183
+ module.exports = {
184
+ encodeValue,
185
+ decodeValue,
186
+ // Diekspor untuk reuse/test internal.
187
+ _internal: { dialectName, formatDateOnly, normalizeBoolean }
188
+ };
@@ -24,6 +24,19 @@ const AUDIT_FIELDS = ['created_at', 'created_by', 'updated_at', 'updated_by'];
24
24
  const TEXTAREA_FIELDS = ['address', 'description', 'notes'];
25
25
  const TEXTAREA_PREFIXES = ['remark'];
26
26
 
27
+ // Tipe numerik kanonik RDF (lihat handbook catalogs/rdf/field-validation.md).
28
+ // Ketiganya dipetakan ke form input `number` di UDF.
29
+ const NUMERIC_TYPES = ['integer', 'decimal', 'number'];
30
+
31
+ // Mengambil nilai `constraints.default` apa adanya bila ada. Constraint `default`
32
+ // berlaku universal untuk semua tipe field (handbook field-validation.md), sehingga
33
+ // nilai default dari SDF/RDF harus terbawa ke `defaultValue` UDF.
34
+ function extractDefault(constraints) {
35
+ return Object.prototype.hasOwnProperty.call(constraints, 'default')
36
+ ? constraints.default
37
+ : undefined;
38
+ }
39
+
27
40
  const CHECKBOX_TEXT_DEFAULT = { checked: 'Yes', unchecked: 'No' };
28
41
  const CHECKBOX_TEXT_MAP = {
29
42
  is_active: { checked: 'Active', unchecked: 'Inactive' },
@@ -202,8 +215,8 @@ class FieldTypeResolver {
202
215
  };
203
216
  }
204
217
 
205
- // Rule 4: Number
206
- if (valType === 'number') {
218
+ // Rule 4: Number (integer / decimal / number)
219
+ if (NUMERIC_TYPES.includes(valType)) {
207
220
  const extra = {};
208
221
  for (const key of ['min', 'max', 'step']) {
209
222
  if (Object.prototype.hasOwnProperty.call(constraints, key)) {
@@ -219,7 +232,7 @@ class FieldTypeResolver {
219
232
  inTable,
220
233
  tableOrder,
221
234
  tableField: null,
222
- defaultValue: undefined,
235
+ defaultValue: extractDefault(constraints),
223
236
  extra
224
237
  };
225
238
  }
@@ -293,7 +306,7 @@ class FieldTypeResolver {
293
306
  inTable,
294
307
  tableOrder,
295
308
  tableField: null,
296
- defaultValue: undefined,
309
+ defaultValue: extractDefault(constraints),
297
310
  extra: { rows: 3, maxlength: maxlen }
298
311
  };
299
312
  }
@@ -316,7 +329,7 @@ class FieldTypeResolver {
316
329
  inTable,
317
330
  tableOrder,
318
331
  tableField: null,
319
- defaultValue: undefined,
332
+ defaultValue: extractDefault(constraints),
320
333
  extra
321
334
  };
322
335
  }