@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.
- package/build-info.json +2 -2
- package/cli/consumer-deploy.js +1 -1
- package/cli/consumer.js +1 -1
- package/generators/cli/data/pull.js +95 -0
- package/generators/cli/data/push.js +85 -0
- package/generators/cli/fast-track.js +12 -25
- package/generators/cli/schema/introspect.js +10 -10
- package/generators/lib/data/db-executor.js +440 -0
- package/generators/lib/data/dialect-kit.js +56 -0
- package/generators/lib/data/envelope.js +220 -0
- package/generators/lib/data/pull-runner.js +407 -0
- package/generators/lib/data/push-runner.js +382 -0
- package/generators/lib/data/sdf-reader.js +132 -0
- package/generators/lib/data/table-order.js +126 -0
- package/generators/lib/data/value-codec.js +188 -0
- package/generators/lib/templates/dashboard-catalog.js +1 -1
- package/generators/lib/templates/db-connection-env.js +1 -1
- package/generators/lib/templates/dbschema-catalog.js +1 -1
- package/generators/lib/templates/field-validation-catalog.js +1 -1
- package/generators/lib/templates/mysql-template.js +1 -1
- package/generators/lib/templates/oracle-template.js +1 -1
- package/generators/lib/templates/postgres-template.js +1 -1
- package/generators/lib/templates/query-declarative-catalog.js +1 -1
- package/generators/lib/templates/sqlite-template.js +1 -1
- package/integrity-manifest.json +18 -18
- package/package.json +1 -1
- package/scripts/verify-integrity.js +1 -1
- package/server.js +1 -1
- package/src/components/handlers/adjust_handler.js +1 -1
- package/src/components/handlers/audit_handler.js +1 -1
- package/src/components/handlers/delete_handler.js +1 -1
- package/src/components/handlers/export_handler.js +1 -1
- package/src/components/handlers/import_handler.js +1 -1
- package/src/components/handlers/insert_handler.js +1 -1
- package/src/components/handlers/update_handler.js +1 -1
- package/src/components/handlers/upload_handler.js +1 -1
- package/src/components/handlers/workflow_handler.js +1 -1
- package/src/components/integrations/webhook.js +1 -1
- package/src/consumers/baseConsumer.js +1 -1
- package/src/consumers/declarativeMapper.js +1 -1
- package/src/consumers/handlers/apiHandler.js +1 -1
- package/src/consumers/handlers/consoleHandler.js +1 -1
- package/src/consumers/handlers/databaseHandler.js +1 -1
- package/src/consumers/handlers/index.js +1 -1
- package/src/consumers/handlers/kafkaHandler.js +1 -1
- package/src/consumers/index.js +1 -1
- package/src/consumers/messageTransformer.js +1 -1
- package/src/consumers/validator.js +1 -1
- package/src/core/db/dialect/base-dialect.js +1 -1
- package/src/core/db/dialect/index.js +1 -1
- package/src/core/db/dialect/mysql-dialect.js +1 -1
- package/src/core/db/dialect/oracle-dialect.js +1 -1
- package/src/core/db/dialect/postgres-dialect.js +1 -1
- package/src/core/db/dialect/sqlite-dialect.js +1 -1
- package/src/core/db/flatten-helper.js +1 -1
- package/src/core/db/query-builder-error.js +1 -1
- package/src/core/db/query-builder.js +1 -1
- package/src/core/db/relation-helper.js +1 -1
- package/src/core/handlers/delete_handler.js +1 -1
- package/src/core/handlers/insert_handler.js +1 -1
- package/src/core/handlers/update_handler.js +1 -1
- package/src/core/models/base-model.js +1 -1
- package/src/core/utils/cache-manager.js +1 -1
- package/src/core/utils/component-engine.js +1 -1
- package/src/core/utils/context-builder.js +1 -1
- package/src/core/utils/datetime-formatter.js +1 -1
- package/src/core/utils/datetime-parser.js +1 -1
- package/src/core/utils/db.js +1 -1
- package/src/core/utils/logger.js +1 -1
- package/src/core/utils/payload-loader.js +1 -1
- package/src/core/utils/security-checks.js +1 -1
- package/src/middleware/body-options.js +1 -1
- package/src/middleware/cors.js +1 -1
- package/src/middleware/idempotency.js +1 -1
- package/src/middleware/rate-limiter.js +1 -1
- package/src/middleware/request-logger.js +1 -1
- package/src/middleware/security-headers.js +1 -1
- package/src/models/base-model-mysql.js +1 -1
- package/src/models/base-model-oracle.js +1 -1
- package/src/models/base-model-sqlite.js +1 -1
- package/src/models/base-model.js +1 -1
- package/src/pro/caching/redis-client.js +1 -1
- package/src/pro/caching/redis-helper.js +1 -1
- package/src/pro/consumers/baseConsumer.js +1 -1
- package/src/pro/consumers/declarativeMapper.js +1 -1
- package/src/pro/consumers/handlers/apiHandler.js +1 -1
- package/src/pro/consumers/handlers/consoleHandler.js +1 -1
- package/src/pro/consumers/handlers/databaseHandler.js +1 -1
- package/src/pro/consumers/handlers/index.js +1 -1
- package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
- package/src/pro/consumers/index.js +1 -1
- package/src/pro/consumers/messageTransformer.js +1 -1
- package/src/pro/consumers/validator.js +1 -1
- package/src/pro/database/base-model-mysql.js +1 -1
- package/src/pro/database/base-model-oracle.js +1 -1
- package/src/pro/database/base-model-sqlite.js +1 -1
- package/src/pro/database/db-mysql.js +1 -1
- package/src/pro/database/db-oracle.js +1 -1
- package/src/pro/database/db-sqlite.js +1 -1
- package/src/pro/excel/excel-generator.js +1 -1
- package/src/pro/excel/excel-parser.js +1 -1
- package/src/pro/excel/export-service.js +1 -1
- package/src/pro/excel/export_handler.js +1 -1
- package/src/pro/excel/import-service.js +1 -1
- package/src/pro/excel/import-validator.js +1 -1
- package/src/pro/excel/import_handler.js +1 -1
- package/src/pro/excel/upsert-builder.js +1 -1
- package/src/pro/idgen/idgen-routes.js +1 -1
- package/src/pro/integrations/lookup-resolver.js +1 -1
- package/src/pro/integrations/upload-handler-v2.js +1 -1
- package/src/pro/integrations/upload-handler.js +1 -1
- package/src/pro/integrations/webhook.js +1 -1
- package/src/pro/locking/lock-routes.js +1 -1
- package/src/pro/locking/resource-lock-manager.js +1 -1
- package/src/pro/messaging/kafkaConsumerService.js +1 -1
- package/src/pro/messaging/kafkaService.js +1 -1
- package/src/pro/messaging/messagehubService.js +1 -1
- package/src/pro/messaging/rabbitmqService.js +1 -1
- package/src/pro/scheduler/job-manager.js +1 -1
- package/src/pro/scheduler/job-routes.js +1 -1
- package/src/pro/scheduler/job-validator.js +1 -1
- package/src/pro/storage/base-storage-provider.js +1 -1
- package/src/pro/storage/file-metadata-helper.js +1 -1
- package/src/pro/storage/index.js +1 -1
- package/src/pro/storage/local-storage-provider.js +1 -1
- package/src/pro/storage/s3-storage-provider.js +1 -1
- package/src/pro/storage/upload-cleanup-job.js +1 -1
- package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
- package/src/pro/storage/upload-pending-tracker.js +1 -1
- package/src/pro/websocket/broadcast-helper.js +1 -1
- package/src/pro/websocket/index.js +1 -1
- package/src/pro/websocket/livesync-server.js +1 -1
- package/src/pro/websocket/ws-broadcaster.js +1 -1
- package/src/services/export-service.js +1 -1
- package/src/services/import-service.js +1 -1
- package/src/services/kafkaConsumerService.js +1 -1
- package/src/services/kafkaService.js +1 -1
- package/src/services/messagehubService.js +1 -1
- package/src/services/rabbitmqService.js +1 -1
- package/src/utils/cache-invalidation-registry.js +1 -1
- package/src/utils/cache-manager.js +1 -1
- package/src/utils/component-engine.js +1 -1
- package/src/utils/config-extractor.js +1 -1
- package/src/utils/consumerLogger.js +1 -1
- package/src/utils/context-builder.js +1 -1
- package/src/utils/dashboard-helpers.js +1 -1
- package/src/utils/dateHelper.js +1 -1
- package/src/utils/datetime-formatter.js +1 -1
- package/src/utils/datetime-parser.js +1 -1
- package/src/utils/db-bootstrap.js +1 -1
- package/src/utils/db-mysql.js +1 -1
- package/src/utils/db-oracle.js +1 -1
- package/src/utils/db-sqlite.js +1 -1
- package/src/utils/db.js +1 -1
- package/src/utils/demo-generator.js +1 -1
- package/src/utils/excel-generator.js +1 -1
- package/src/utils/excel-parser.js +1 -1
- package/src/utils/file-watcher.js +1 -1
- package/src/utils/id-generator.js +1 -1
- package/src/utils/idempotency-manager.js +1 -1
- package/src/utils/import-validator.js +1 -1
- package/src/utils/license-client.js +1 -1
- package/src/utils/lock-manager.js +1 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/lookup-resolver.js +1 -1
- package/src/utils/payload-loader.js +1 -1
- package/src/utils/processor-response.js +1 -1
- package/src/utils/rabbitmq.js +1 -1
- package/src/utils/redis-client.js +1 -1
- package/src/utils/redis-helper.js +1 -1
- package/src/utils/request-scope.js +1 -1
- package/src/utils/security-checks.js +1 -1
- package/src/utils/service-resolver.js +1 -1
- package/src/utils/shutdown-coordinator.js +1 -1
- package/src/utils/trusted-keys.js +1 -1
- package/src/utils/upload-handler.js +1 -1
- package/src/utils/upsert-builder.js +1 -1
- 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(
|
|
246
|
+
function checkDesigner() {
|
|
250
247
|
console.log('');
|
|
251
248
|
console.log('[Preflight]');
|
|
252
249
|
|
|
253
|
-
// Probe nyata: jalankan `restforge-designer --version`.
|
|
254
|
-
|
|
255
|
-
|
|
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 (
|
|
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
|
|
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(
|
|
878
|
+
checkDesigner();
|
|
892
879
|
}
|
|
893
880
|
|
|
894
881
|
const ctx = {
|
|
895
882
|
cwd,
|
|
896
883
|
project: args.project,
|
|
897
|
-
schemaFlag: args
|
|
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
|
|
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 --
|
|
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 --
|
|
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
|
-
|
|
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 --
|
|
283
|
-
'npx restforge schema introspect --config=db.env --
|
|
284
|
-
'npx restforge schema introspect --config=db.env --
|
|
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
|
|
295
|
-
console.error('Error: --
|
|
296
|
-
throw new Error('--
|
|
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') {
|