@restforgejs/platform 5.1.0 → 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 (178) 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 +12 -25
  7. package/generators/cli/schema/introspect.js +10 -10
  8. package/generators/lib/data/db-executor.js +440 -0
  9. package/generators/lib/data/dialect-kit.js +56 -0
  10. package/generators/lib/data/envelope.js +220 -0
  11. package/generators/lib/data/pull-runner.js +407 -0
  12. package/generators/lib/data/push-runner.js +382 -0
  13. package/generators/lib/data/sdf-reader.js +132 -0
  14. package/generators/lib/data/table-order.js +126 -0
  15. package/generators/lib/data/value-codec.js +188 -0
  16. package/generators/lib/templates/dashboard-catalog.js +1 -1
  17. package/generators/lib/templates/db-connection-env.js +1 -1
  18. package/generators/lib/templates/dbschema-catalog.js +1 -1
  19. package/generators/lib/templates/field-validation-catalog.js +1 -1
  20. package/generators/lib/templates/mysql-template.js +1 -1
  21. package/generators/lib/templates/oracle-template.js +1 -1
  22. package/generators/lib/templates/postgres-template.js +1 -1
  23. package/generators/lib/templates/query-declarative-catalog.js +1 -1
  24. package/generators/lib/templates/sqlite-template.js +1 -1
  25. package/integrity-manifest.json +18 -18
  26. package/package.json +1 -1
  27. package/scripts/verify-integrity.js +1 -1
  28. package/server.js +1 -1
  29. package/src/components/handlers/adjust_handler.js +1 -1
  30. package/src/components/handlers/audit_handler.js +1 -1
  31. package/src/components/handlers/delete_handler.js +1 -1
  32. package/src/components/handlers/export_handler.js +1 -1
  33. package/src/components/handlers/import_handler.js +1 -1
  34. package/src/components/handlers/insert_handler.js +1 -1
  35. package/src/components/handlers/update_handler.js +1 -1
  36. package/src/components/handlers/upload_handler.js +1 -1
  37. package/src/components/handlers/workflow_handler.js +1 -1
  38. package/src/components/integrations/webhook.js +1 -1
  39. package/src/consumers/baseConsumer.js +1 -1
  40. package/src/consumers/declarativeMapper.js +1 -1
  41. package/src/consumers/handlers/apiHandler.js +1 -1
  42. package/src/consumers/handlers/consoleHandler.js +1 -1
  43. package/src/consumers/handlers/databaseHandler.js +1 -1
  44. package/src/consumers/handlers/index.js +1 -1
  45. package/src/consumers/handlers/kafkaHandler.js +1 -1
  46. package/src/consumers/index.js +1 -1
  47. package/src/consumers/messageTransformer.js +1 -1
  48. package/src/consumers/validator.js +1 -1
  49. package/src/core/db/dialect/base-dialect.js +1 -1
  50. package/src/core/db/dialect/index.js +1 -1
  51. package/src/core/db/dialect/mysql-dialect.js +1 -1
  52. package/src/core/db/dialect/oracle-dialect.js +1 -1
  53. package/src/core/db/dialect/postgres-dialect.js +1 -1
  54. package/src/core/db/dialect/sqlite-dialect.js +1 -1
  55. package/src/core/db/flatten-helper.js +1 -1
  56. package/src/core/db/query-builder-error.js +1 -1
  57. package/src/core/db/query-builder.js +1 -1
  58. package/src/core/db/relation-helper.js +1 -1
  59. package/src/core/handlers/delete_handler.js +1 -1
  60. package/src/core/handlers/insert_handler.js +1 -1
  61. package/src/core/handlers/update_handler.js +1 -1
  62. package/src/core/models/base-model.js +1 -1
  63. package/src/core/utils/cache-manager.js +1 -1
  64. package/src/core/utils/component-engine.js +1 -1
  65. package/src/core/utils/context-builder.js +1 -1
  66. package/src/core/utils/datetime-formatter.js +1 -1
  67. package/src/core/utils/datetime-parser.js +1 -1
  68. package/src/core/utils/db.js +1 -1
  69. package/src/core/utils/logger.js +1 -1
  70. package/src/core/utils/payload-loader.js +1 -1
  71. package/src/core/utils/security-checks.js +1 -1
  72. package/src/middleware/body-options.js +1 -1
  73. package/src/middleware/cors.js +1 -1
  74. package/src/middleware/idempotency.js +1 -1
  75. package/src/middleware/rate-limiter.js +1 -1
  76. package/src/middleware/request-logger.js +1 -1
  77. package/src/middleware/security-headers.js +1 -1
  78. package/src/models/base-model-mysql.js +1 -1
  79. package/src/models/base-model-oracle.js +1 -1
  80. package/src/models/base-model-sqlite.js +1 -1
  81. package/src/models/base-model.js +1 -1
  82. package/src/pro/caching/redis-client.js +1 -1
  83. package/src/pro/caching/redis-helper.js +1 -1
  84. package/src/pro/consumers/baseConsumer.js +1 -1
  85. package/src/pro/consumers/declarativeMapper.js +1 -1
  86. package/src/pro/consumers/handlers/apiHandler.js +1 -1
  87. package/src/pro/consumers/handlers/consoleHandler.js +1 -1
  88. package/src/pro/consumers/handlers/databaseHandler.js +1 -1
  89. package/src/pro/consumers/handlers/index.js +1 -1
  90. package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
  91. package/src/pro/consumers/index.js +1 -1
  92. package/src/pro/consumers/messageTransformer.js +1 -1
  93. package/src/pro/consumers/validator.js +1 -1
  94. package/src/pro/database/base-model-mysql.js +1 -1
  95. package/src/pro/database/base-model-oracle.js +1 -1
  96. package/src/pro/database/base-model-sqlite.js +1 -1
  97. package/src/pro/database/db-mysql.js +1 -1
  98. package/src/pro/database/db-oracle.js +1 -1
  99. package/src/pro/database/db-sqlite.js +1 -1
  100. package/src/pro/excel/excel-generator.js +1 -1
  101. package/src/pro/excel/excel-parser.js +1 -1
  102. package/src/pro/excel/export-service.js +1 -1
  103. package/src/pro/excel/export_handler.js +1 -1
  104. package/src/pro/excel/import-service.js +1 -1
  105. package/src/pro/excel/import-validator.js +1 -1
  106. package/src/pro/excel/import_handler.js +1 -1
  107. package/src/pro/excel/upsert-builder.js +1 -1
  108. package/src/pro/idgen/idgen-routes.js +1 -1
  109. package/src/pro/integrations/lookup-resolver.js +1 -1
  110. package/src/pro/integrations/upload-handler-v2.js +1 -1
  111. package/src/pro/integrations/upload-handler.js +1 -1
  112. package/src/pro/integrations/webhook.js +1 -1
  113. package/src/pro/locking/lock-routes.js +1 -1
  114. package/src/pro/locking/resource-lock-manager.js +1 -1
  115. package/src/pro/messaging/kafkaConsumerService.js +1 -1
  116. package/src/pro/messaging/kafkaService.js +1 -1
  117. package/src/pro/messaging/messagehubService.js +1 -1
  118. package/src/pro/messaging/rabbitmqService.js +1 -1
  119. package/src/pro/scheduler/job-manager.js +1 -1
  120. package/src/pro/scheduler/job-routes.js +1 -1
  121. package/src/pro/scheduler/job-validator.js +1 -1
  122. package/src/pro/storage/base-storage-provider.js +1 -1
  123. package/src/pro/storage/file-metadata-helper.js +1 -1
  124. package/src/pro/storage/index.js +1 -1
  125. package/src/pro/storage/local-storage-provider.js +1 -1
  126. package/src/pro/storage/s3-storage-provider.js +1 -1
  127. package/src/pro/storage/upload-cleanup-job.js +1 -1
  128. package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
  129. package/src/pro/storage/upload-pending-tracker.js +1 -1
  130. package/src/pro/websocket/broadcast-helper.js +1 -1
  131. package/src/pro/websocket/index.js +1 -1
  132. package/src/pro/websocket/livesync-server.js +1 -1
  133. package/src/pro/websocket/ws-broadcaster.js +1 -1
  134. package/src/services/export-service.js +1 -1
  135. package/src/services/import-service.js +1 -1
  136. package/src/services/kafkaConsumerService.js +1 -1
  137. package/src/services/kafkaService.js +1 -1
  138. package/src/services/messagehubService.js +1 -1
  139. package/src/services/rabbitmqService.js +1 -1
  140. package/src/utils/cache-invalidation-registry.js +1 -1
  141. package/src/utils/cache-manager.js +1 -1
  142. package/src/utils/component-engine.js +1 -1
  143. package/src/utils/config-extractor.js +1 -1
  144. package/src/utils/consumerLogger.js +1 -1
  145. package/src/utils/context-builder.js +1 -1
  146. package/src/utils/dashboard-helpers.js +1 -1
  147. package/src/utils/dateHelper.js +1 -1
  148. package/src/utils/datetime-formatter.js +1 -1
  149. package/src/utils/datetime-parser.js +1 -1
  150. package/src/utils/db-bootstrap.js +1 -1
  151. package/src/utils/db-mysql.js +1 -1
  152. package/src/utils/db-oracle.js +1 -1
  153. package/src/utils/db-sqlite.js +1 -1
  154. package/src/utils/db.js +1 -1
  155. package/src/utils/demo-generator.js +1 -1
  156. package/src/utils/excel-generator.js +1 -1
  157. package/src/utils/excel-parser.js +1 -1
  158. package/src/utils/file-watcher.js +1 -1
  159. package/src/utils/id-generator.js +1 -1
  160. package/src/utils/idempotency-manager.js +1 -1
  161. package/src/utils/import-validator.js +1 -1
  162. package/src/utils/license-client.js +1 -1
  163. package/src/utils/lock-manager.js +1 -1
  164. package/src/utils/logger.js +1 -1
  165. package/src/utils/lookup-resolver.js +1 -1
  166. package/src/utils/payload-loader.js +1 -1
  167. package/src/utils/processor-response.js +1 -1
  168. package/src/utils/rabbitmq.js +1 -1
  169. package/src/utils/redis-client.js +1 -1
  170. package/src/utils/redis-helper.js +1 -1
  171. package/src/utils/request-scope.js +1 -1
  172. package/src/utils/security-checks.js +1 -1
  173. package/src/utils/service-resolver.js +1 -1
  174. package/src/utils/shutdown-coordinator.js +1 -1
  175. package/src/utils/trusted-keys.js +1 -1
  176. package/src/utils/upload-handler.js +1 -1
  177. package/src/utils/upsert-builder.js +1 -1
  178. package/src/utils/workflow-hook-executor.js +1 -1
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Contract: data pull
5
+ *
6
+ * Export isi sebuah tabel database ke file envelope JSON
7
+ * (`{cwd}/data-storage/<table>.json`) dengan whitelist kolom dan metadata
8
+ * bersumber MURNI dari SDF (Schema Definition File), bukan introspeksi DB.
9
+ *
10
+ * Eksekusi via jalur CLI generator (cli-entry.js) tanpa gerbang license/integrity
11
+ * (amandemen arah B, lihat docs/plan/data-pull-push/data-pull-push-09-amendments.md).
12
+ * Handler tetap tipis: seluruh logika berada di lib/data/pull-runner.js.
13
+ *
14
+ * Catatan: flag `--schema` (namespace) TIDAK dideklarasikan — namespace tabel
15
+ * diambil dari SDF IR (amandemen A4). Lokasi SDF ditentukan `--schema-path`.
16
+ */
17
+
18
+ module.exports = {
19
+ resource: 'data',
20
+ verb: 'pull',
21
+ description: 'Export isi tabel database ke file envelope JSON (data-storage/<table>.json) berdasarkan metadata SDF',
22
+ category: 'introspection',
23
+ flags: {
24
+ table: {
25
+ type: 'string',
26
+ required: false,
27
+ default: null,
28
+ description: 'Nama tabel sumber yang akan di-pull (harus terdaftar di SDF)'
29
+ },
30
+ 'all-tables': {
31
+ type: 'boolean',
32
+ required: false,
33
+ default: false,
34
+ description: 'Pull seluruh tabel yang terdaftar di --schema-path (mutual-exclusive dengan --table)'
35
+ },
36
+ config: {
37
+ type: 'string',
38
+ required: false,
39
+ default: null,
40
+ description: 'File config database (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
41
+ },
42
+ 'schema-path': {
43
+ type: 'string',
44
+ required: false,
45
+ default: 'schema',
46
+ description: 'Lokasi SDF (file atau folder) sumber metadata tabel'
47
+ },
48
+ format: {
49
+ type: 'string',
50
+ required: false,
51
+ default: 'json',
52
+ description: "Format penyimpanan nilai; saat ini hanya menerima 'json'"
53
+ },
54
+ limit: {
55
+ type: 'number',
56
+ required: false,
57
+ default: null,
58
+ description: 'Batas maksimum total rows yang di-export (null = seluruh tabel)'
59
+ },
60
+ 'batch-size': {
61
+ type: 'number',
62
+ required: false,
63
+ default: 1000,
64
+ description: 'Ukuran batch baca internal dari database'
65
+ },
66
+ 'storage-path': {
67
+ type: 'string',
68
+ required: false,
69
+ default: 'data-storage',
70
+ description: 'Folder output relatif terhadap working directory'
71
+ },
72
+ force: {
73
+ type: 'boolean',
74
+ required: false,
75
+ default: false,
76
+ description: 'Overwrite file output bila sudah ada'
77
+ },
78
+ json: {
79
+ type: 'boolean',
80
+ required: false,
81
+ default: false,
82
+ description: 'Output ringkasan dalam format JSON (untuk konsumsi CI/CD)'
83
+ }
84
+ },
85
+ examples: [
86
+ 'npx restforge data pull --table=visitors',
87
+ 'npx restforge data pull --all-tables --config=db.env',
88
+ 'npx restforge data pull --all-tables --config=db.env --json',
89
+ 'npx restforge data pull --table=visitors --config=db.env --limit=500',
90
+ 'npx restforge data pull --table=visitors --config=db.env --json'
91
+ ],
92
+ async handler(args) {
93
+ return require('../../lib/data/pull-runner').run(args);
94
+ }
95
+ };
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Contract: data push
5
+ *
6
+ * Muat isi file envelope JSON (`{cwd}/data-storage/<qualifiedName>.json`) ke tabel
7
+ * tujuan via INSERT batch dengan commit per batch. Nama file diturunkan dari SDF
8
+ * (aturan IDENTIK `data pull`, bukan dari flag `--table` mentah). Metadata kolom +
9
+ * tipe canonical bersumber MURNI dari SDF; konversi nilai per dialect tujuan
10
+ * ditangani value-codec.
11
+ *
12
+ * Eksekusi via jalur CLI generator (cli-entry.js) tanpa gerbang license/integrity
13
+ * (amandemen arah B, lihat docs/plan/data-pull-push/data-pull-push-09-amendments.md).
14
+ * Handler tetap tipis: seluruh logika berada di lib/data/push-runner.js.
15
+ *
16
+ * Push bersifat append-only (amandemen A6, User konfirmasi 2026-06-03). Mode
17
+ * `upsert`/`replace` di-descope dari v1, sehingga flag `--mode` dan `--force`
18
+ * TIDAK dideklarasikan. Push selalu menjalankan jalur append (INSERT batch +
19
+ * commit per batch). `--mode=...`/`--force` kini menjadi unknown flag → ditolak
20
+ * arg-parser dengan exit 2 (perilaku standar).
21
+ *
22
+ * Catatan: flag `--schema` (namespace) TIDAK dideklarasikan — namespace tabel
23
+ * diambil dari SDF IR (amandemen A4). Lokasi SDF ditentukan `--schema-path`.
24
+ */
25
+
26
+ module.exports = {
27
+ resource: 'data',
28
+ verb: 'push',
29
+ description: 'Muat isi file envelope JSON (data-storage/<table>.json) ke tabel tujuan via INSERT batch berdasarkan metadata SDF',
30
+ category: 'management',
31
+ flags: {
32
+ table: {
33
+ type: 'string',
34
+ required: false,
35
+ default: null,
36
+ description: 'Nama tabel tujuan yang akan di-push (harus terdaftar di SDF)'
37
+ },
38
+ 'all-tables': {
39
+ type: 'boolean',
40
+ required: false,
41
+ default: false,
42
+ description: 'Push seluruh tabel yang punya file di --storage-path, urut topological FK parent→child (mutual-exclusive dengan --table)'
43
+ },
44
+ config: {
45
+ type: 'string',
46
+ required: false,
47
+ default: null,
48
+ description: 'File config database tujuan (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
49
+ },
50
+ 'schema-path': {
51
+ type: 'string',
52
+ required: false,
53
+ default: 'schema',
54
+ description: 'Lokasi SDF (file atau folder) sumber metadata tabel'
55
+ },
56
+ 'storage-path': {
57
+ type: 'string',
58
+ required: false,
59
+ default: 'data-storage',
60
+ description: 'Folder sumber file envelope relatif terhadap working directory'
61
+ },
62
+ 'batch-size': {
63
+ type: 'number',
64
+ required: false,
65
+ default: 1000,
66
+ description: 'Ukuran batch INSERT, sekaligus unit commit per batch'
67
+ },
68
+ json: {
69
+ type: 'boolean',
70
+ required: false,
71
+ default: false,
72
+ description: 'Output ringkasan dalam format JSON (untuk konsumsi CI/CD)'
73
+ }
74
+ },
75
+ examples: [
76
+ 'npx restforge data push --table=visitors',
77
+ 'npx restforge data push --all-tables --config=db.env',
78
+ 'npx restforge data push --all-tables --config=db.env --json',
79
+ 'npx restforge data push --table=visitors --config=db.env --batch-size=500',
80
+ 'npx restforge data push --table=visitors --config=db.env --json'
81
+ ],
82
+ async handler(args) {
83
+ return require('../../lib/data/push-runner').run(args);
84
+ }
85
+ };
@@ -18,9 +18,6 @@
18
18
  * Scope Frontend (dan bagian frontend pada ALL) juga dieksekusi NYATA: payload
19
19
  * migrate (RDF -> UDF) per tabel -> restforge-designer activate -> generate.
20
20
  *
21
- * Flag `--sim-no-designer` memaksa cabang dialog "designer NOT FOUND" untuk
22
- * keperluan uji (mem-bypass probe `restforge-designer --version`).
23
- *
24
21
  * Catatan: contract ini global verb (snapshot key = `fast-track`), file berada
25
22
  * di root `generators/cli/` sehingga ter-discover otomatis sejajar dengan `init`.
26
23
  */
@@ -246,19 +243,15 @@ function collectTables(schemaDir) {
246
243
  // Preflight: cek dependency restforge-designer (sebelum input konfigurasi)
247
244
  // ---------------------------------------------------------------------------
248
245
 
249
- function checkDesigner(args) {
246
+ function checkDesigner() {
250
247
  console.log('');
251
248
  console.log('[Preflight]');
252
249
 
253
- // Probe nyata: jalankan `restforge-designer --version`. Flag --sim-no-designer
254
- // memaksa cabang NOT FOUND untuk keperluan uji dialog.
255
- let found = false;
250
+ // Probe nyata: jalankan `restforge-designer --version`.
251
+ const r = spawnSync('cmd', ['/S', '/C', 'restforge-designer --version'], { encoding: 'utf8' });
252
+ const found = !r.error && r.status === 0;
256
253
  let version = '';
257
- if (!args['sim-no-designer']) {
258
- const r = spawnSync('cmd', ['/S', '/C', 'restforge-designer --version'], { encoding: 'utf8' });
259
- found = !r.error && r.status === 0;
260
- if (found && r.stdout) version = r.stdout.trim().split(/\r?\n/)[0];
261
- }
254
+ if (found && r.stdout) version = r.stdout.trim().split(/\r?\n/)[0];
262
255
 
263
256
  if (!found) {
264
257
  console.log(leader(' > restforge-designer', 'NOT FOUND', 32));
@@ -838,7 +831,7 @@ module.exports = {
838
831
  required: true,
839
832
  description: 'Nama project/aplikasi (mis. visitors-app)'
840
833
  },
841
- schema: {
834
+ 'schema-path': {
842
835
  type: 'string',
843
836
  required: true,
844
837
  description: 'Folder berisi SDF aplikasi (relatif cwd)'
@@ -860,22 +853,16 @@ module.exports = {
860
853
  required: false,
861
854
  default: false,
862
855
  description: 'Mode destruktif: drop table & regenerate (perlu konfirmasi y/N)'
863
- },
864
- 'sim-no-designer': {
865
- type: 'boolean',
866
- required: false,
867
- default: false,
868
- description: '[preview] Paksa cabang dialog "restforge-designer NOT FOUND" (scope frontend)'
869
856
  }
870
857
  },
871
858
  examples: [
872
- 'npx restforge fast-track --project=visitors-app --schema=./schema',
873
- 'npx restforge fast-track --project=visitors-app --schema=./schema --config=db-connection.env',
874
- 'npx restforge fast-track --project=visitors-app --schema=./schema --overwrite'
859
+ 'npx restforge fast-track --project=visitors-app --schema-path=./schema',
860
+ 'npx restforge fast-track --project=visitors-app --schema-path=./schema --config=db-connection.env',
861
+ 'npx restforge fast-track --project=visitors-app --schema-path=./schema --overwrite'
875
862
  ],
876
863
  async handler(args) {
877
864
  const cwd = process.cwd();
878
- const schemaDir = path.resolve(cwd, args.schema);
865
+ const schemaDir = path.resolve(cwd, args['schema-path']);
879
866
  const { names: tables } = collectTables(schemaDir);
880
867
 
881
868
  const prompter = createPrompter();
@@ -888,13 +875,13 @@ module.exports = {
888
875
 
889
876
  // 3) Preflight designer hanya bila scope mencakup frontend.
890
877
  if (scope.frontend) {
891
- checkDesigner(args);
878
+ checkDesigner();
892
879
  }
893
880
 
894
881
  const ctx = {
895
882
  cwd,
896
883
  project: args.project,
897
- schemaFlag: args.schema,
884
+ schemaFlag: args['schema-path'],
898
885
  configFlag: args.config,
899
886
  tables,
900
887
  cfg,
@@ -180,7 +180,7 @@ function parseSchemaFlag(value) {
180
180
  }
181
181
 
182
182
  function resolveMode(args, schemaList, tableQualified) {
183
- const out = args.output;
183
+ const out = args['schema-path'];
184
184
  const isDry = args['dry-run'];
185
185
 
186
186
  if (isDry && !out) {
@@ -200,7 +200,7 @@ function resolveMode(args, schemaList, tableQualified) {
200
200
  if (expectedBase !== targetTableName) {
201
201
  return {
202
202
  error: `Single-mode output filename '${path.basename(out)}' does not match --table='${targetTableName}'. ` +
203
- `Use --output=<folder> or rename the file to '${targetTableName}.js'.`
203
+ `Use --schema-path=<folder> or rename the file to '${targetTableName}.js'.`
204
204
  };
205
205
  }
206
206
  return { kind: 'single-file', file: path.resolve(out), table: targetTableName };
@@ -209,7 +209,7 @@ function resolveMode(args, schemaList, tableQualified) {
209
209
  }
210
210
 
211
211
  if (looksLikeJs) {
212
- return { error: `Bulk mode requires a folder for --output, got file '${out}'. Specify a folder or add --table=<name>.` };
212
+ return { error: `Bulk mode requires a folder for --schema-path, got file '${out}'. Specify a folder or add --table=<name>.` };
213
213
  }
214
214
 
215
215
  const isMultiSchema = (args['all-schemas']) || (Array.isArray(schemaList) && schemaList.length > 1);
@@ -242,7 +242,7 @@ module.exports = {
242
242
  default: null,
243
243
  description: 'File config database (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
244
244
  },
245
- output: {
245
+ 'schema-path': {
246
246
  type: 'string',
247
247
  required: true,
248
248
  description: 'Folder atau file output schema'
@@ -279,9 +279,9 @@ module.exports = {
279
279
  }
280
280
  },
281
281
  examples: [
282
- 'npx restforge schema introspect --config=db.env --output=./schema',
283
- 'npx restforge schema introspect --config=db.env --output=./schema --table=users --dry-run',
284
- 'npx restforge schema introspect --config=db.env --output=./schema --all-schemas --force'
282
+ 'npx restforge schema introspect --config=db.env --schema-path=./schema',
283
+ 'npx restforge schema introspect --config=db.env --schema-path=./schema --table=users --dry-run',
284
+ 'npx restforge schema introspect --config=db.env --schema-path=./schema --all-schemas --force'
285
285
  ],
286
286
  async handler(args) {
287
287
  const resolvedConfigResult = resolveConfig(args.config, process.cwd());
@@ -291,9 +291,9 @@ module.exports = {
291
291
  throw new Error('--config=<file> is required');
292
292
  }
293
293
 
294
- if (!args['dry-run'] && !args.output) {
295
- console.error('Error: --output=<path> is required (or use --dry-run to preview to stdout).');
296
- throw new Error('--output=<path> is required');
294
+ if (!args['dry-run'] && !args['schema-path']) {
295
+ console.error('Error: --schema-path=<path> is required (or use --dry-run to preview to stdout).');
296
+ throw new Error('--schema-path=<path> is required');
297
297
  }
298
298
 
299
299
  if (resolvedConfigResult.source === 'default') {