@restforgejs/platform 5.1.21 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) 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/catalog/dashboard.js +1 -1
  5. package/generators/cli/catalog/dbschema.js +3 -3
  6. package/generators/cli/catalog/field-validation.js +1 -1
  7. package/generators/cli/catalog/query-declarative.js +1 -1
  8. package/generators/cli/config/clear-default.js +1 -1
  9. package/generators/cli/config/get-default.js +1 -1
  10. package/generators/cli/config/list.js +1 -1
  11. package/generators/cli/config/schema.js +1 -1
  12. package/generators/cli/config/set-default.js +2 -2
  13. package/generators/cli/config/template.js +1 -1
  14. package/generators/cli/dashboard/create.js +7 -7
  15. package/generators/cli/data/pull.js +12 -12
  16. package/generators/cli/data/push.js +9 -9
  17. package/generators/cli/endpoint/create.js +11 -11
  18. package/generators/cli/endpoint/list.js +3 -3
  19. package/generators/cli/fast-track.js +7 -7
  20. package/generators/cli/init.js +2 -2
  21. package/generators/cli/kafka/consumer-create.js +5 -5
  22. package/generators/cli/key/generate.js +3 -3
  23. package/generators/cli/key/list.js +2 -2
  24. package/generators/cli/key/revoke.js +3 -3
  25. package/generators/cli/payload/diff.js +3 -3
  26. package/generators/cli/payload/generate.js +5 -5
  27. package/generators/cli/payload/sync.js +5 -5
  28. package/generators/cli/payload/validate.js +3 -3
  29. package/generators/cli/processor/create.js +7 -7
  30. package/generators/cli/processor/list.js +3 -3
  31. package/generators/cli/project/delete.js +2 -2
  32. package/generators/cli/project/list.js +1 -1
  33. package/generators/cli/query/validate.js +3 -3
  34. package/generators/cli/schema/apply.js +13 -13
  35. package/generators/cli/schema/describe.js +6 -6
  36. package/generators/cli/schema/diff.js +10 -10
  37. package/generators/cli/schema/generate-ddl.js +11 -11
  38. package/generators/cli/schema/init.js +95 -95
  39. package/generators/cli/schema/introspect.js +8 -8
  40. package/generators/cli/schema/list.js +6 -6
  41. package/generators/cli/schema/migrate.js +91 -13
  42. package/generators/cli/schema/models.js +6 -6
  43. package/generators/cli/schema/template.js +223 -222
  44. package/generators/cli/schema/validate.js +6 -6
  45. package/generators/cli/test/generate.js +6 -6
  46. package/generators/lib/dbschema-kit/introspect-mapper.js +20 -0
  47. package/generators/lib/templates/dashboard-catalog.js +1 -1
  48. package/generators/lib/templates/db-connection-env.js +1 -1
  49. package/generators/lib/templates/dbschema-catalog.js +1 -1
  50. package/generators/lib/templates/field-validation-catalog.js +1 -1
  51. package/generators/lib/templates/mysql-template.js +1 -1
  52. package/generators/lib/templates/oracle-template.js +1 -1
  53. package/generators/lib/templates/postgres-template.js +1 -1
  54. package/generators/lib/templates/query-declarative-catalog.js +1 -1
  55. package/generators/lib/templates/sqlite-template.js +1 -1
  56. package/integrity-manifest.json +18 -18
  57. package/package.json +1 -1
  58. package/scripts/verify-integrity.js +1 -1
  59. package/server.js +1 -1
  60. package/src/components/handlers/adjust_handler.js +1 -1
  61. package/src/components/handlers/audit_handler.js +1 -1
  62. package/src/components/handlers/delete_handler.js +1 -1
  63. package/src/components/handlers/export_handler.js +1 -1
  64. package/src/components/handlers/import_handler.js +1 -1
  65. package/src/components/handlers/insert_handler.js +1 -1
  66. package/src/components/handlers/update_handler.js +1 -1
  67. package/src/components/handlers/upload_handler.js +1 -1
  68. package/src/components/handlers/workflow_handler.js +1 -1
  69. package/src/components/integrations/webhook.js +1 -1
  70. package/src/consumers/baseConsumer.js +1 -1
  71. package/src/consumers/declarativeMapper.js +1 -1
  72. package/src/consumers/handlers/apiHandler.js +1 -1
  73. package/src/consumers/handlers/consoleHandler.js +1 -1
  74. package/src/consumers/handlers/databaseHandler.js +1 -1
  75. package/src/consumers/handlers/index.js +1 -1
  76. package/src/consumers/handlers/kafkaHandler.js +1 -1
  77. package/src/consumers/index.js +1 -1
  78. package/src/consumers/messageTransformer.js +1 -1
  79. package/src/consumers/validator.js +1 -1
  80. package/src/core/db/dialect/base-dialect.js +1 -1
  81. package/src/core/db/dialect/index.js +1 -1
  82. package/src/core/db/dialect/mysql-dialect.js +1 -1
  83. package/src/core/db/dialect/oracle-dialect.js +1 -1
  84. package/src/core/db/dialect/postgres-dialect.js +1 -1
  85. package/src/core/db/dialect/sqlite-dialect.js +1 -1
  86. package/src/core/db/flatten-helper.js +1 -1
  87. package/src/core/db/query-builder-error.js +1 -1
  88. package/src/core/db/query-builder.js +1 -1
  89. package/src/core/db/relation-helper.js +1 -1
  90. package/src/core/handlers/delete_handler.js +1 -1
  91. package/src/core/handlers/insert_handler.js +1 -1
  92. package/src/core/handlers/update_handler.js +1 -1
  93. package/src/core/models/base-model.js +1 -1
  94. package/src/core/utils/cache-manager.js +1 -1
  95. package/src/core/utils/component-engine.js +1 -1
  96. package/src/core/utils/context-builder.js +1 -1
  97. package/src/core/utils/datetime-formatter.js +1 -1
  98. package/src/core/utils/datetime-parser.js +1 -1
  99. package/src/core/utils/db.js +1 -1
  100. package/src/core/utils/logger.js +1 -1
  101. package/src/core/utils/payload-loader.js +1 -1
  102. package/src/core/utils/security-checks.js +1 -1
  103. package/src/middleware/body-options.js +1 -1
  104. package/src/middleware/cors.js +1 -1
  105. package/src/middleware/idempotency.js +1 -1
  106. package/src/middleware/rate-limiter.js +1 -1
  107. package/src/middleware/request-logger.js +1 -1
  108. package/src/middleware/security-headers.js +1 -1
  109. package/src/models/base-model-mysql.js +1 -1
  110. package/src/models/base-model-oracle.js +1 -1
  111. package/src/models/base-model-sqlite.js +1 -1
  112. package/src/models/base-model.js +1 -1
  113. package/src/pro/caching/redis-client.js +1 -1
  114. package/src/pro/caching/redis-helper.js +1 -1
  115. package/src/pro/consumers/baseConsumer.js +1 -1
  116. package/src/pro/consumers/declarativeMapper.js +1 -1
  117. package/src/pro/consumers/handlers/apiHandler.js +1 -1
  118. package/src/pro/consumers/handlers/consoleHandler.js +1 -1
  119. package/src/pro/consumers/handlers/databaseHandler.js +1 -1
  120. package/src/pro/consumers/handlers/index.js +1 -1
  121. package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
  122. package/src/pro/consumers/index.js +1 -1
  123. package/src/pro/consumers/messageTransformer.js +1 -1
  124. package/src/pro/consumers/validator.js +1 -1
  125. package/src/pro/database/base-model-mysql.js +1 -1
  126. package/src/pro/database/base-model-oracle.js +1 -1
  127. package/src/pro/database/base-model-sqlite.js +1 -1
  128. package/src/pro/database/db-mysql.js +1 -1
  129. package/src/pro/database/db-oracle.js +1 -1
  130. package/src/pro/database/db-sqlite.js +1 -1
  131. package/src/pro/excel/excel-generator.js +1 -1
  132. package/src/pro/excel/excel-parser.js +1 -1
  133. package/src/pro/excel/export-service.js +1 -1
  134. package/src/pro/excel/export_handler.js +1 -1
  135. package/src/pro/excel/import-service.js +1 -1
  136. package/src/pro/excel/import-validator.js +1 -1
  137. package/src/pro/excel/import_handler.js +1 -1
  138. package/src/pro/excel/upsert-builder.js +1 -1
  139. package/src/pro/idgen/idgen-routes.js +1 -1
  140. package/src/pro/integrations/lookup-resolver.js +1 -1
  141. package/src/pro/integrations/upload-handler-v2.js +1 -1
  142. package/src/pro/integrations/upload-handler.js +1 -1
  143. package/src/pro/integrations/webhook.js +1 -1
  144. package/src/pro/locking/lock-routes.js +1 -1
  145. package/src/pro/locking/resource-lock-manager.js +1 -1
  146. package/src/pro/messaging/kafkaConsumerService.js +1 -1
  147. package/src/pro/messaging/kafkaService.js +1 -1
  148. package/src/pro/messaging/messagehubService.js +1 -1
  149. package/src/pro/messaging/rabbitmqService.js +1 -1
  150. package/src/pro/scheduler/job-manager.js +1 -1
  151. package/src/pro/scheduler/job-routes.js +1 -1
  152. package/src/pro/scheduler/job-validator.js +1 -1
  153. package/src/pro/storage/base-storage-provider.js +1 -1
  154. package/src/pro/storage/file-metadata-helper.js +1 -1
  155. package/src/pro/storage/index.js +1 -1
  156. package/src/pro/storage/local-storage-provider.js +1 -1
  157. package/src/pro/storage/s3-storage-provider.js +1 -1
  158. package/src/pro/storage/upload-cleanup-job.js +1 -1
  159. package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
  160. package/src/pro/storage/upload-pending-tracker.js +1 -1
  161. package/src/pro/websocket/broadcast-helper.js +1 -1
  162. package/src/pro/websocket/index.js +1 -1
  163. package/src/pro/websocket/livesync-server.js +1 -1
  164. package/src/pro/websocket/ws-broadcaster.js +1 -1
  165. package/src/services/export-service.js +1 -1
  166. package/src/services/import-service.js +1 -1
  167. package/src/services/kafkaConsumerService.js +1 -1
  168. package/src/services/kafkaService.js +1 -1
  169. package/src/services/messagehubService.js +1 -1
  170. package/src/services/rabbitmqService.js +1 -1
  171. package/src/utils/cache-invalidation-registry.js +1 -1
  172. package/src/utils/cache-manager.js +1 -1
  173. package/src/utils/component-engine.js +1 -1
  174. package/src/utils/config-extractor.js +1 -1
  175. package/src/utils/consumerLogger.js +1 -1
  176. package/src/utils/context-builder.js +1 -1
  177. package/src/utils/dashboard-helpers.js +1 -1
  178. package/src/utils/dateHelper.js +1 -1
  179. package/src/utils/datetime-formatter.js +1 -1
  180. package/src/utils/datetime-parser.js +1 -1
  181. package/src/utils/db-bootstrap.js +1 -1
  182. package/src/utils/db-mysql.js +1 -1
  183. package/src/utils/db-oracle.js +1 -1
  184. package/src/utils/db-sqlite.js +1 -1
  185. package/src/utils/db.js +1 -1
  186. package/src/utils/demo-generator.js +1 -1
  187. package/src/utils/excel-generator.js +1 -1
  188. package/src/utils/excel-parser.js +1 -1
  189. package/src/utils/file-watcher.js +1 -1
  190. package/src/utils/id-generator.js +1 -1
  191. package/src/utils/idempotency-manager.js +1 -1
  192. package/src/utils/import-validator.js +1 -1
  193. package/src/utils/license-client.js +1 -1
  194. package/src/utils/lock-manager.js +1 -1
  195. package/src/utils/logger.js +1 -1
  196. package/src/utils/lookup-resolver.js +1 -1
  197. package/src/utils/payload-loader.js +1 -1
  198. package/src/utils/processor-response.js +1 -1
  199. package/src/utils/rabbitmq.js +1 -1
  200. package/src/utils/redis-client.js +1 -1
  201. package/src/utils/redis-helper.js +1 -1
  202. package/src/utils/request-scope.js +1 -1
  203. package/src/utils/security-checks.js +1 -1
  204. package/src/utils/service-resolver.js +1 -1
  205. package/src/utils/shutdown-coordinator.js +1 -1
  206. package/src/utils/soft-delete-dashboard-guard.js +1 -1
  207. package/src/utils/sql-table-extractor.js +1 -1
  208. package/src/utils/trusted-keys.js +1 -1
  209. package/src/utils/upload-handler.js +1 -1
  210. package/src/utils/upsert-builder.js +1 -1
  211. package/src/utils/workflow-hook-executor.js +1 -1
@@ -1,222 +1,223 @@
1
- 'use strict';
2
-
3
- /**
4
- * Contract: schema template
5
- *
6
- * Browse, preview, dan generate template schema dari koleksi RestForge Schema
7
- * Reference (85 template, 30 domain, 33 section). Verb ini bertindak sebagai
8
- * wrapper terhadap binary native `sdf-tools.exe` yang di-ship melalui folder
9
- * bin/. Semua filter dan display flag diteruskan ke binary; help text di sisi
10
- * Node mempertahankan kontrak CLI (contract validator + help generator).
11
- *
12
- * Binary lookup: <package-root>/bin/sdf-tools.exe relatif terhadap file ini
13
- * (resolusi sama untuk source workspace dan installation di node_modules).
14
- *
15
- * Platform: saat ini hanya Windows (sdf-tools.exe). Pemanggilan di non-Windows
16
- * akan return error eksplisit, bukan crash diam-diam.
17
- */
18
-
19
- const fs = require('fs');
20
- const os = require('os');
21
- const path = require('path');
22
- const { spawnSync } = require('child_process');
23
-
24
- const VALUE_FLAGS = ['domain', 'table', 'category', 'pattern', 'section', 'lang', 'path', 'format'];
25
- const BOOLEAN_FLAGS = [
26
- 'has-sdf',
27
- 'no-sdf',
28
- 'show',
29
- 'example',
30
- 'generate',
31
- 'force',
32
- 'list-domains',
33
- 'list-categories',
34
- 'list-sections',
35
- 'stats'
36
- ];
37
-
38
- function resolveBinaryPath() {
39
- if (os.platform() !== 'win32') return null;
40
- return path.resolve(__dirname, '..', '..', '..', 'bin', 'sdf-tools.exe');
41
- }
42
-
43
- function buildBinaryArgs(args) {
44
- const out = [];
45
- for (const name of VALUE_FLAGS) {
46
- const value = args[name];
47
- if (value === undefined || value === null || value === '') continue;
48
- out.push(`--${name}=${value}`);
49
- }
50
- for (const name of BOOLEAN_FLAGS) {
51
- if (args[name] === true) {
52
- out.push(`--${name}`);
53
- }
54
- }
55
- return out;
56
- }
57
-
58
- module.exports = {
59
- resource: 'schema',
60
- verb: 'template',
61
- description: 'Browse, preview, dan generate template schema dari koleksi RestForge Schema Reference',
62
- category: 'utility',
63
- flags: {
64
- domain: {
65
- type: 'string',
66
- required: false,
67
- default: null,
68
- description: 'Filter berdasarkan domain (csv, mis. erp atau erp,finance)'
69
- },
70
- table: {
71
- type: 'string',
72
- required: false,
73
- default: null,
74
- description: 'Filter nama tabel (wildcard glob: sales*, *_invoice)'
75
- },
76
- category: {
77
- type: 'string',
78
- required: false,
79
- default: null,
80
- description: 'Filter category: master-data atau transactional'
81
- },
82
- pattern: {
83
- type: 'string',
84
- required: false,
85
- default: null,
86
- description: 'Filter pattern: single-table atau master-detail'
87
- },
88
- section: {
89
- type: 'string',
90
- required: false,
91
- default: null,
92
- description: 'Filter section code (lihat --list-sections)'
93
- },
94
- 'has-sdf': {
95
- type: 'boolean',
96
- required: false,
97
- default: false,
98
- description: 'Filter hanya template yang sudah punya versi SDF'
99
- },
100
- 'no-sdf': {
101
- type: 'boolean',
102
- required: false,
103
- default: false,
104
- description: 'Filter hanya template yang belum punya SDF (gap analysis)'
105
- },
106
- show: {
107
- type: 'boolean',
108
- required: false,
109
- default: false,
110
- description: 'Cetak schema template (perlu --table=<nama_spesifik>)'
111
- },
112
- example: {
113
- type: 'boolean',
114
- required: false,
115
- default: false,
116
- description: 'Sertakan section CONTOH DATA (kombinasi dengan --show)'
117
- },
118
- lang: {
119
- type: 'string',
120
- required: false,
121
- default: null,
122
- description: 'Format schema: sdf (default) atau sql'
123
- },
124
- generate: {
125
- type: 'boolean',
126
- required: false,
127
- default: false,
128
- description: 'Generate template ke filesystem (perlu --table dan --path)'
129
- },
130
- path: {
131
- type: 'string',
132
- required: false,
133
- default: null,
134
- description: 'Path destination untuk --generate (direktori atau file)'
135
- },
136
- force: {
137
- type: 'boolean',
138
- required: false,
139
- default: false,
140
- description: 'Overwrite file destination existing saat --generate'
141
- },
142
- 'list-domains': {
143
- type: 'boolean',
144
- required: false,
145
- default: false,
146
- description: 'List semua domain aplikasi yang tersedia'
147
- },
148
- 'list-categories': {
149
- type: 'boolean',
150
- required: false,
151
- default: false,
152
- description: 'List semua category template'
153
- },
154
- 'list-sections': {
155
- type: 'boolean',
156
- required: false,
157
- default: false,
158
- description: 'List semua section beserta category-nya'
159
- },
160
- stats: {
161
- type: 'boolean',
162
- required: false,
163
- default: false,
164
- description: 'Tampilkan statistik koleksi (per category, pattern, domain, section)'
165
- },
166
- format: {
167
- type: 'string',
168
- required: false,
169
- default: null,
170
- description: 'Format output: table (default), plain, atau json'
171
- }
172
- },
173
- examples: [
174
- 'npx restforge schema template',
175
- 'npx restforge schema template --domain=erp',
176
- 'npx restforge schema template --domain=erp,inventory --category=master-data',
177
- 'npx restforge schema template --table=sales_order --show',
178
- 'npx restforge schema template --table=sales_order --show --lang=sql',
179
- 'npx restforge schema template --table=sales_order --generate --path=./schema --lang=sdf',
180
- 'npx restforge schema template --stats',
181
- 'npx restforge schema template --list-domains'
182
- ],
183
- async handler(args) {
184
- const binaryPath = resolveBinaryPath();
185
- if (!binaryPath) {
186
- const err = new Error(
187
- `schema template hanya tersedia di Windows (sdf-tools.exe). Platform saat ini: ${os.platform()}`
188
- );
189
- err.exitCode = 3;
190
- throw err;
191
- }
192
-
193
- if (!fs.existsSync(binaryPath)) {
194
- const err = new Error(
195
- `sdf-tools.exe tidak ditemukan di ${binaryPath}. ` +
196
- 'Pastikan binary sudah di-build dan tersedia di folder bin/ package.'
197
- );
198
- err.exitCode = 3;
199
- throw err;
200
- }
201
-
202
- const binaryArgs = buildBinaryArgs(args);
203
- const result = spawnSync(binaryPath, binaryArgs, {
204
- stdio: 'inherit',
205
- windowsHide: true
206
- });
207
-
208
- if (result.error) {
209
- const err = new Error(`Gagal menjalankan sdf-tools.exe: ${result.error.message}`);
210
- err.exitCode = 1;
211
- throw err;
212
- }
213
-
214
- const status = typeof result.status === 'number' ? result.status : 1;
215
- if (status !== 0) {
216
- const err = new Error(`sdf-tools.exe exit code ${status}`);
217
- err.exitCode = status;
218
- err.silent = true;
219
- throw err;
220
- }
221
- }
222
- };
1
+ 'use strict';
2
+
3
+ /**
4
+ * Contract: schema template
5
+ *
6
+ * Browse, preview, dan generate template schema dari koleksi RestForge Schema
7
+ * Reference (85 template, 30 domain, 33 section). Verb ini bertindak sebagai
8
+ * wrapper terhadap binary native `sdf-tools.exe` yang di-ship melalui folder
9
+ * bin/. Semua filter dan display flag diteruskan ke binary; help text di sisi
10
+ * Node mempertahankan kontrak CLI (contract validator + help generator).
11
+ *
12
+ * Binary lookup: <package-root>/bin/sdf-tools.exe relatif terhadap file ini
13
+ * (resolusi sama untuk source workspace dan installation di node_modules).
14
+ *
15
+ * Platform: saat ini hanya Windows (sdf-tools.exe). Pemanggilan di non-Windows
16
+ * akan return error eksplisit, bukan crash diam-diam.
17
+ */
18
+
19
+ const fs = require('fs');
20
+ const os = require('os');
21
+ const path = require('path');
22
+ const { spawnSync } = require('child_process');
23
+
24
+ const VALUE_FLAGS = ['domain', 'table', 'category', 'pattern', 'section', 'lang', 'format'];
25
+ const BOOLEAN_FLAGS = [
26
+ 'has-sdf',
27
+ 'no-sdf',
28
+ 'show',
29
+ 'example',
30
+ 'generate',
31
+ 'force',
32
+ 'list-domains',
33
+ 'list-categories',
34
+ 'list-sections',
35
+ 'stats'
36
+ ];
37
+
38
+ function resolveBinaryPath() {
39
+ if (os.platform() !== 'win32') return null;
40
+ return path.resolve(__dirname, '..', '..', '..', 'bin', 'sdf-tools.exe');
41
+ }
42
+
43
+ function buildBinaryArgs(args) {
44
+ const out = [];
45
+ for (const name of VALUE_FLAGS) {
46
+ const value = args[name];
47
+ if (value === undefined || value === null || value === '') continue;
48
+ out.push(`--${name}=${value}`);
49
+ }
50
+ if (args['schema-path']) out.push(`--path=${args['schema-path']}`);
51
+ for (const name of BOOLEAN_FLAGS) {
52
+ if (args[name] === true) {
53
+ out.push(`--${name}`);
54
+ }
55
+ }
56
+ return out;
57
+ }
58
+
59
+ module.exports = {
60
+ resource: 'schema',
61
+ verb: 'template',
62
+ description: 'Browse, preview, and generate schema templates from the RestForge Schema Reference collection',
63
+ category: 'utility',
64
+ flags: {
65
+ domain: {
66
+ type: 'string',
67
+ required: false,
68
+ default: null,
69
+ description: 'Filter by domain (csv, e.g., erp or erp,finance)'
70
+ },
71
+ table: {
72
+ type: 'string',
73
+ required: false,
74
+ default: null,
75
+ description: 'Filter by table name (wildcard glob: sales*, *_invoice)'
76
+ },
77
+ category: {
78
+ type: 'string',
79
+ required: false,
80
+ default: null,
81
+ description: 'Filter by category: master-data or transactional'
82
+ },
83
+ pattern: {
84
+ type: 'string',
85
+ required: false,
86
+ default: null,
87
+ description: 'Filter by pattern: single-table or master-detail'
88
+ },
89
+ section: {
90
+ type: 'string',
91
+ required: false,
92
+ default: null,
93
+ description: 'Filter by section code (see --list-sections)'
94
+ },
95
+ 'has-sdf': {
96
+ type: 'boolean',
97
+ required: false,
98
+ default: false,
99
+ description: 'Filter only templates that have an SDF version'
100
+ },
101
+ 'no-sdf': {
102
+ type: 'boolean',
103
+ required: false,
104
+ default: false,
105
+ description: 'Filter only templates that do not have an SDF version (gap analysis)'
106
+ },
107
+ show: {
108
+ type: 'boolean',
109
+ required: false,
110
+ default: false,
111
+ description: 'Print schema template (requires --table=<specific_name>)'
112
+ },
113
+ example: {
114
+ type: 'boolean',
115
+ required: false,
116
+ default: false,
117
+ description: 'Include sample data section (use with --show)'
118
+ },
119
+ lang: {
120
+ type: 'string',
121
+ required: false,
122
+ default: null,
123
+ description: 'Schema format: sdf (default) or sql'
124
+ },
125
+ generate: {
126
+ type: 'boolean',
127
+ required: false,
128
+ default: false,
129
+ description: 'Generate template to filesystem (requires --table and --schema-path)'
130
+ },
131
+ 'schema-path': {
132
+ type: 'string',
133
+ required: false,
134
+ default: null,
135
+ description: 'Destination path for --generate (directory or file)'
136
+ },
137
+ force: {
138
+ type: 'boolean',
139
+ required: false,
140
+ default: false,
141
+ description: 'Overwrite existing destination file when using --generate'
142
+ },
143
+ 'list-domains': {
144
+ type: 'boolean',
145
+ required: false,
146
+ default: false,
147
+ description: 'List all available application domains'
148
+ },
149
+ 'list-categories': {
150
+ type: 'boolean',
151
+ required: false,
152
+ default: false,
153
+ description: 'List all template categories'
154
+ },
155
+ 'list-sections': {
156
+ type: 'boolean',
157
+ required: false,
158
+ default: false,
159
+ description: 'List all sections with their categories'
160
+ },
161
+ stats: {
162
+ type: 'boolean',
163
+ required: false,
164
+ default: false,
165
+ description: 'Show collection statistics (per category, pattern, domain, section)'
166
+ },
167
+ format: {
168
+ type: 'string',
169
+ required: false,
170
+ default: null,
171
+ description: 'Output format: table (default), plain, or json'
172
+ }
173
+ },
174
+ examples: [
175
+ 'npx restforge schema template',
176
+ 'npx restforge schema template --domain=erp',
177
+ 'npx restforge schema template --domain=erp,inventory --category=master-data',
178
+ 'npx restforge schema template --table=sales_order --show',
179
+ 'npx restforge schema template --table=sales_order --show --lang=sql',
180
+ 'npx restforge schema template --table=sales_order --generate --schema-path=./schema --lang=sdf',
181
+ 'npx restforge schema template --stats',
182
+ 'npx restforge schema template --list-domains'
183
+ ],
184
+ async handler(args) {
185
+ const binaryPath = resolveBinaryPath();
186
+ if (!binaryPath) {
187
+ const err = new Error(
188
+ `schema template hanya tersedia di Windows (sdf-tools.exe). Platform saat ini: ${os.platform()}`
189
+ );
190
+ err.exitCode = 3;
191
+ throw err;
192
+ }
193
+
194
+ if (!fs.existsSync(binaryPath)) {
195
+ const err = new Error(
196
+ `sdf-tools.exe tidak ditemukan di ${binaryPath}. ` +
197
+ 'Pastikan binary sudah di-build dan tersedia di folder bin/ package.'
198
+ );
199
+ err.exitCode = 3;
200
+ throw err;
201
+ }
202
+
203
+ const binaryArgs = buildBinaryArgs(args);
204
+ const result = spawnSync(binaryPath, binaryArgs, {
205
+ stdio: 'inherit',
206
+ windowsHide: true
207
+ });
208
+
209
+ if (result.error) {
210
+ const err = new Error(`Gagal menjalankan sdf-tools.exe: ${result.error.message}`);
211
+ err.exitCode = 1;
212
+ throw err;
213
+ }
214
+
215
+ const status = typeof result.status === 'number' ? result.status : 1;
216
+ if (status !== 0) {
217
+ const err = new Error(`sdf-tools.exe exit code ${status}`);
218
+ err.exitCode = status;
219
+ err.silent = true;
220
+ throw err;
221
+ }
222
+ }
223
+ };
@@ -63,21 +63,21 @@ function printSuccessLines(absPath, models) {
63
63
  module.exports = {
64
64
  resource: 'schema',
65
65
  verb: 'validate',
66
- description: 'Memvalidasi file schema definition (single-model dan cross-model)',
66
+ description: 'Validate schema definition files (single-model and cross-model)',
67
67
  category: 'introspection',
68
68
  flags: {
69
- path: {
69
+ 'schema-path': {
70
70
  type: 'string',
71
71
  required: true,
72
- description: 'Path file atau folder schema (mis. ./schema atau ./schema/users.js)'
72
+ description: 'Path to schema file or directory (e.g., ./schema or ./schema/users.js)'
73
73
  }
74
74
  },
75
75
  examples: [
76
- 'npx restforge schema validate --path=./schema',
77
- 'npx restforge schema validate --path=./my-schema'
76
+ 'npx restforge schema validate --schema-path=./schema',
77
+ 'npx restforge schema validate --schema-path=./my-schema'
78
78
  ],
79
79
  async handler(args) {
80
- const schemaPath = args.path;
80
+ const schemaPath = args['schema-path'];
81
81
  const absPath = path.resolve(process.cwd(), schemaPath);
82
82
 
83
83
  let models;
@@ -145,36 +145,36 @@ function handleInit(args) {
145
145
  module.exports = {
146
146
  resource: 'test',
147
147
  verb: 'generate',
148
- description: 'Generate integration test file (Jest + Supertest) untuk endpoint',
148
+ description: 'Generate an integration test file (Jest + Supertest) for an endpoint',
149
149
  category: 'generation',
150
150
  flags: {
151
151
  project: {
152
152
  type: 'string',
153
153
  required: true,
154
- description: 'Nama project target'
154
+ description: 'Target project name'
155
155
  },
156
156
  endpoint: {
157
157
  type: 'string',
158
158
  required: true,
159
- description: 'Nama endpoint yang akan di-test'
159
+ description: 'Endpoint name to test'
160
160
  },
161
161
  port: {
162
162
  type: 'number',
163
163
  required: false,
164
164
  default: 3000,
165
- description: 'Port server saat test dijalankan'
165
+ description: 'Server port when running tests'
166
166
  },
167
167
  init: {
168
168
  type: 'boolean',
169
169
  required: false,
170
170
  default: false,
171
- description: 'Inisialisasi konfigurasi test-data.json (global + per-endpoint jika endpoint diisi)'
171
+ description: 'Initialize test-data.json configuration (global + per-endpoint if endpoint is provided)'
172
172
  },
173
173
  force: {
174
174
  type: 'boolean',
175
175
  required: false,
176
176
  default: false,
177
- description: 'Timpa file test existing'
177
+ description: 'Overwrite existing test files'
178
178
  }
179
179
  },
180
180
  examples: [
@@ -599,6 +599,26 @@ function parseCheckExpression(rawExpr) {
599
599
  }
600
600
  }
601
601
 
602
+ // PostgreSQL normalises IN-list CHECKs to: (col)::type = ANY ((ARRAY['a'::type, ...]::type[]))
603
+ // This form appears verbatim in pg_get_constraintdef output and is semantically identical to IN (...).
604
+ const pgAnyRe = /^\(?([A-Za-z_][A-Za-z0-9_]*)\)?(?:::\w+(?:\s+\w+)*)?\s*=\s*ANY\s*\((.+)\)\s*$/i;
605
+ const pgAnyM = e.match(pgAnyRe);
606
+ if (pgAnyM) {
607
+ const field = pgAnyM[1].toLowerCase();
608
+ const anyArg = pgAnyM[2];
609
+ const arrOpen = anyArg.toUpperCase().indexOf('ARRAY[');
610
+ if (arrOpen !== -1) {
611
+ const arrClose = anyArg.indexOf(']', arrOpen + 6);
612
+ if (arrClose !== -1) {
613
+ const raw = anyArg.slice(arrOpen + 6, arrClose);
614
+ // strip per-element type casts like ::character varying before parsing
615
+ const stripped = raw.replace(/::\w+(?:\s+\w+)*/g, '');
616
+ const values = parseValueList(stripped);
617
+ if (values) return { field, op: 'in', value: values };
618
+ }
619
+ }
620
+ }
621
+
602
622
  return { _unparsable: true, expression: rawExpr };
603
623
  }
604
624