@restforgejs/platform 5.1.21 → 5.2.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 +2 -2
- package/cli/consumer.js +2 -2
- package/generators/cli/catalog/dashboard.js +1 -1
- package/generators/cli/catalog/dbschema.js +3 -3
- package/generators/cli/catalog/field-validation.js +1 -1
- package/generators/cli/catalog/query-declarative.js +1 -1
- package/generators/cli/config/clear-default.js +1 -1
- package/generators/cli/config/get-default.js +1 -1
- package/generators/cli/config/list.js +1 -1
- package/generators/cli/config/schema.js +1 -1
- package/generators/cli/config/set-default.js +2 -2
- package/generators/cli/config/template.js +1 -1
- package/generators/cli/dashboard/create.js +7 -7
- package/generators/cli/data/pull.js +12 -12
- package/generators/cli/data/push.js +9 -9
- package/generators/cli/endpoint/create.js +11 -11
- package/generators/cli/endpoint/list.js +3 -3
- package/generators/cli/fast-track.js +65 -12
- package/generators/cli/init.js +2 -2
- package/generators/cli/kafka/consumer-create.js +5 -5
- package/generators/cli/key/generate.js +3 -3
- package/generators/cli/key/list.js +2 -2
- package/generators/cli/key/revoke.js +3 -3
- package/generators/cli/payload/diff.js +3 -3
- package/generators/cli/payload/generate.js +5 -5
- package/generators/cli/payload/sync.js +5 -5
- package/generators/cli/payload/validate.js +3 -3
- package/generators/cli/processor/create.js +7 -7
- package/generators/cli/processor/list.js +3 -3
- package/generators/cli/project/delete.js +2 -2
- package/generators/cli/project/list.js +1 -1
- package/generators/cli/query/validate.js +3 -3
- package/generators/cli/schema/apply.js +13 -13
- package/generators/cli/schema/describe.js +6 -6
- package/generators/cli/schema/diff.js +10 -10
- package/generators/cli/schema/generate-ddl.js +11 -11
- package/generators/cli/schema/init.js +95 -95
- package/generators/cli/schema/introspect.js +8 -8
- package/generators/cli/schema/list.js +6 -6
- package/generators/cli/schema/migrate.js +91 -13
- package/generators/cli/schema/models.js +6 -6
- package/generators/cli/schema/template.js +223 -222
- package/generators/cli/schema/validate.js +6 -6
- package/generators/cli/test/generate.js +6 -6
- package/generators/lib/dbschema-kit/introspect-mapper.js +20 -0
- package/generators/lib/migrate/migrate-runner.js +12 -2
- package/generators/lib/migrate/sql-parser.js +5 -3
- package/generators/lib/payload/payload-runner.js +31 -5
- 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 +2 -2
- 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/soft-delete-dashboard-guard.js +1 -1
- package/src/utils/sql-table-extractor.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
|
@@ -129,19 +129,19 @@ module.exports = {
|
|
|
129
129
|
type: 'string',
|
|
130
130
|
required: false,
|
|
131
131
|
default: null,
|
|
132
|
-
description: 'Filter
|
|
132
|
+
description: 'Filter by section (defineModelOptions, fieldTypes, constraints, relationTypes, referentialActions, checkOperations, auditColumns, softDelete, shorthandSyntax, namingRules, dialectSupport)'
|
|
133
133
|
},
|
|
134
134
|
name: {
|
|
135
135
|
type: 'string',
|
|
136
136
|
required: false,
|
|
137
137
|
default: null,
|
|
138
|
-
description: 'Filter
|
|
138
|
+
description: 'Filter by exact name (only valid with --section for array sections)'
|
|
139
139
|
},
|
|
140
140
|
kind: {
|
|
141
141
|
type: 'string',
|
|
142
142
|
required: false,
|
|
143
143
|
default: null,
|
|
144
|
-
description: 'Filter
|
|
144
|
+
description: 'Filter constraints by kind: standalone or value (only valid with --section=constraints)'
|
|
145
145
|
},
|
|
146
146
|
pretty: {
|
|
147
147
|
type: 'boolean',
|
|
@@ -18,7 +18,7 @@ const { FIELD_VALIDATION_CATALOG } = require('../../lib/templates/field-validati
|
|
|
18
18
|
module.exports = {
|
|
19
19
|
resource: 'catalog',
|
|
20
20
|
verb: 'field-validation',
|
|
21
|
-
description: 'Output JSON catalog
|
|
21
|
+
description: 'Output JSON catalog of supported field validation types, constraints, and format presets',
|
|
22
22
|
category: 'introspection',
|
|
23
23
|
flags: {
|
|
24
24
|
pretty: {
|
|
@@ -19,7 +19,7 @@ const { QUERY_DECLARATIVE_CATALOG } = require('../../lib/templates/query-declara
|
|
|
19
19
|
module.exports = {
|
|
20
20
|
resource: 'catalog',
|
|
21
21
|
verb: 'query-declarative',
|
|
22
|
-
description: 'Output JSON catalog query declarative properties, endpoint resolution,
|
|
22
|
+
description: 'Output JSON catalog of query declarative properties, endpoint resolution, and file reference conventions',
|
|
23
23
|
category: 'introspection',
|
|
24
24
|
flags: {
|
|
25
25
|
pretty: {
|
|
@@ -20,7 +20,7 @@ const {
|
|
|
20
20
|
module.exports = {
|
|
21
21
|
resource: 'config',
|
|
22
22
|
verb: 'clear-default',
|
|
23
|
-
description: '
|
|
23
|
+
description: 'Remove the default config for the current working directory',
|
|
24
24
|
category: 'management',
|
|
25
25
|
flags: {},
|
|
26
26
|
examples: [
|
|
@@ -23,7 +23,7 @@ const {
|
|
|
23
23
|
module.exports = {
|
|
24
24
|
resource: 'config',
|
|
25
25
|
verb: 'get-default',
|
|
26
|
-
description: '
|
|
26
|
+
description: 'Show the active default config file for the current working directory',
|
|
27
27
|
category: 'introspection',
|
|
28
28
|
flags: {
|
|
29
29
|
pretty: {
|
|
@@ -60,7 +60,7 @@ function isMatchingDefault(fileName, location, defaultName) {
|
|
|
60
60
|
module.exports = {
|
|
61
61
|
resource: 'config',
|
|
62
62
|
verb: 'list',
|
|
63
|
-
description: '
|
|
63
|
+
description: 'List available .env files in the working directory and config/ folder',
|
|
64
64
|
category: 'introspection',
|
|
65
65
|
flags: {
|
|
66
66
|
pretty: {
|
|
@@ -19,7 +19,7 @@ const {
|
|
|
19
19
|
module.exports = {
|
|
20
20
|
resource: 'config',
|
|
21
21
|
verb: 'schema',
|
|
22
|
-
description: 'Output JSON schema
|
|
22
|
+
description: 'Output JSON schema for db-connection.env parameters',
|
|
23
23
|
category: 'introspection',
|
|
24
24
|
flags: {
|
|
25
25
|
pretty: {
|
|
@@ -22,13 +22,13 @@ const {
|
|
|
22
22
|
module.exports = {
|
|
23
23
|
resource: 'config',
|
|
24
24
|
verb: 'set-default',
|
|
25
|
-
description: 'Set
|
|
25
|
+
description: 'Set a config file as default for the current working directory (stored in .restforge/defaults.json)',
|
|
26
26
|
category: 'management',
|
|
27
27
|
flags: {
|
|
28
28
|
config: {
|
|
29
29
|
type: 'string',
|
|
30
30
|
required: true,
|
|
31
|
-
description: '
|
|
31
|
+
description: 'Config file to set as default (lookup: cwd → config/ folder → +.env extension)'
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
examples: [
|
|
@@ -16,7 +16,7 @@ const { DB_CONNECTION_ENV_TEMPLATE } = require('../../lib/templates/db-connectio
|
|
|
16
16
|
module.exports = {
|
|
17
17
|
resource: 'config',
|
|
18
18
|
verb: 'template',
|
|
19
|
-
description: 'Output raw
|
|
19
|
+
description: 'Output the raw db-connection.env template (KEY=VALUE format)',
|
|
20
20
|
category: 'utility',
|
|
21
21
|
flags: {},
|
|
22
22
|
examples: [
|
|
@@ -27,41 +27,41 @@ const { validateSafeName } = require('../../lib/utils/path-validator');
|
|
|
27
27
|
module.exports = {
|
|
28
28
|
resource: 'dashboard',
|
|
29
29
|
verb: 'create',
|
|
30
|
-
description: 'Generate dashboard endpoint module
|
|
30
|
+
description: 'Generate dashboard endpoint module from payload (multi-widget aggregator)',
|
|
31
31
|
category: 'generation',
|
|
32
32
|
flags: {
|
|
33
33
|
project: {
|
|
34
34
|
type: 'string',
|
|
35
35
|
required: true,
|
|
36
|
-
description: '
|
|
36
|
+
description: 'Target project name'
|
|
37
37
|
},
|
|
38
38
|
name: {
|
|
39
39
|
type: 'string',
|
|
40
40
|
required: true,
|
|
41
|
-
description: '
|
|
41
|
+
description: 'Dashboard name (must start with "dash-", e.g., dash-sales)'
|
|
42
42
|
},
|
|
43
43
|
payload: {
|
|
44
44
|
type: 'string',
|
|
45
45
|
required: true,
|
|
46
|
-
description: 'Path
|
|
46
|
+
description: 'Path or filename of the dashboard JSON payload'
|
|
47
47
|
},
|
|
48
48
|
database: {
|
|
49
49
|
type: 'string',
|
|
50
50
|
required: false,
|
|
51
51
|
default: null,
|
|
52
|
-
description: '
|
|
52
|
+
description: 'Database type (postgres|mysql|oracle|sqlite). Default: postgres'
|
|
53
53
|
},
|
|
54
54
|
force: {
|
|
55
55
|
type: 'boolean',
|
|
56
56
|
required: false,
|
|
57
57
|
default: false,
|
|
58
|
-
description: '
|
|
58
|
+
description: 'Overwrite existing files in the output directory'
|
|
59
59
|
},
|
|
60
60
|
'skip-sql-validation': {
|
|
61
61
|
type: 'boolean',
|
|
62
62
|
required: false,
|
|
63
63
|
default: false,
|
|
64
|
-
description: '
|
|
64
|
+
description: 'Skip SQL keyword validation'
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
examples: [
|
|
@@ -21,74 +21,74 @@
|
|
|
21
21
|
module.exports = {
|
|
22
22
|
resource: 'data',
|
|
23
23
|
verb: 'pull',
|
|
24
|
-
description: 'Export
|
|
24
|
+
description: 'Export database table contents to JSON envelope files (data-storage/<schema>/<table>.json) based on SDF metadata',
|
|
25
25
|
category: 'introspection',
|
|
26
26
|
flags: {
|
|
27
27
|
table: {
|
|
28
28
|
type: 'string',
|
|
29
29
|
required: false,
|
|
30
30
|
default: null,
|
|
31
|
-
description: '
|
|
31
|
+
description: 'Source table name to pull (must be registered in SDF)'
|
|
32
32
|
},
|
|
33
33
|
schema: {
|
|
34
34
|
type: 'string',
|
|
35
35
|
required: false,
|
|
36
36
|
default: null,
|
|
37
|
-
description: 'Filter schema:
|
|
37
|
+
description: 'Filter by schema: single or comma-separated (mutually exclusive with --table/--all-schemas)'
|
|
38
38
|
},
|
|
39
39
|
'all-schemas': {
|
|
40
40
|
type: 'boolean',
|
|
41
41
|
required: false,
|
|
42
42
|
default: false,
|
|
43
|
-
description: 'Pull
|
|
43
|
+
description: 'Pull all tables across all schemas (mutually exclusive with --table/--schema)'
|
|
44
44
|
},
|
|
45
45
|
config: {
|
|
46
46
|
type: 'string',
|
|
47
47
|
required: false,
|
|
48
48
|
default: null,
|
|
49
|
-
description: '
|
|
49
|
+
description: 'Database config file (.env). Fallback to `.restforge/defaults.json` if not explicitly provided (set via `config set-default`)'
|
|
50
50
|
},
|
|
51
51
|
'schema-path': {
|
|
52
52
|
type: 'string',
|
|
53
53
|
required: false,
|
|
54
54
|
default: 'schema',
|
|
55
|
-
description: '
|
|
55
|
+
description: 'SDF location (file or folder) for table metadata'
|
|
56
56
|
},
|
|
57
57
|
format: {
|
|
58
58
|
type: 'string',
|
|
59
59
|
required: false,
|
|
60
60
|
default: 'json',
|
|
61
|
-
description: "
|
|
61
|
+
description: "Storage format for values; currently only accepts 'json'"
|
|
62
62
|
},
|
|
63
63
|
limit: {
|
|
64
64
|
type: 'number',
|
|
65
65
|
required: false,
|
|
66
66
|
default: null,
|
|
67
|
-
description: '
|
|
67
|
+
description: 'Maximum number of rows to export (null = entire table)'
|
|
68
68
|
},
|
|
69
69
|
'batch-size': {
|
|
70
70
|
type: 'number',
|
|
71
71
|
required: false,
|
|
72
72
|
default: 1000,
|
|
73
|
-
description: '
|
|
73
|
+
description: 'Internal read batch size from database'
|
|
74
74
|
},
|
|
75
75
|
'storage-path': {
|
|
76
76
|
type: 'string',
|
|
77
77
|
required: false,
|
|
78
78
|
default: 'data-storage',
|
|
79
|
-
description: '
|
|
79
|
+
description: 'Output folder relative to working directory'
|
|
80
80
|
},
|
|
81
81
|
force: {
|
|
82
82
|
type: 'boolean',
|
|
83
83
|
required: false,
|
|
84
84
|
default: false,
|
|
85
|
-
description: 'Overwrite file
|
|
85
|
+
description: 'Overwrite output file if it already exists'
|
|
86
86
|
},
|
|
87
87
|
json: {
|
|
88
88
|
type: 'boolean',
|
|
89
89
|
required: false,
|
|
90
90
|
default: false,
|
|
91
|
-
description: 'Output
|
|
91
|
+
description: 'Output summary in JSON format (for CI/CD consumption)'
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
examples: [
|
|
@@ -30,56 +30,56 @@
|
|
|
30
30
|
module.exports = {
|
|
31
31
|
resource: 'data',
|
|
32
32
|
verb: 'push',
|
|
33
|
-
description: '
|
|
33
|
+
description: 'Load JSON envelope files (data-storage/<schema>/<table>.json) into the target table via batch INSERT based on SDF metadata',
|
|
34
34
|
category: 'management',
|
|
35
35
|
flags: {
|
|
36
36
|
table: {
|
|
37
37
|
type: 'string',
|
|
38
38
|
required: false,
|
|
39
39
|
default: null,
|
|
40
|
-
description: '
|
|
40
|
+
description: 'Target table name to push (must be registered in SDF)'
|
|
41
41
|
},
|
|
42
42
|
schema: {
|
|
43
43
|
type: 'string',
|
|
44
44
|
required: false,
|
|
45
45
|
default: null,
|
|
46
|
-
description: 'Filter schema:
|
|
46
|
+
description: 'Filter by schema: single or comma-separated (mutually exclusive with --table/--all-schemas)'
|
|
47
47
|
},
|
|
48
48
|
'all-schemas': {
|
|
49
49
|
type: 'boolean',
|
|
50
50
|
required: false,
|
|
51
51
|
default: false,
|
|
52
|
-
description: 'Push
|
|
52
|
+
description: 'Push all tables across all schemas in topological FK order parent→child (mutually exclusive with --table/--schema)'
|
|
53
53
|
},
|
|
54
54
|
config: {
|
|
55
55
|
type: 'string',
|
|
56
56
|
required: false,
|
|
57
57
|
default: null,
|
|
58
|
-
description: '
|
|
58
|
+
description: 'Target database config file (.env). Fallback to `.restforge/defaults.json` if not explicitly provided (set via `config set-default`)'
|
|
59
59
|
},
|
|
60
60
|
'schema-path': {
|
|
61
61
|
type: 'string',
|
|
62
62
|
required: false,
|
|
63
63
|
default: 'schema',
|
|
64
|
-
description: '
|
|
64
|
+
description: 'SDF location (file or folder) for table metadata'
|
|
65
65
|
},
|
|
66
66
|
'storage-path': {
|
|
67
67
|
type: 'string',
|
|
68
68
|
required: false,
|
|
69
69
|
default: 'data-storage',
|
|
70
|
-
description: '
|
|
70
|
+
description: 'Source folder for envelope files relative to working directory'
|
|
71
71
|
},
|
|
72
72
|
'batch-size': {
|
|
73
73
|
type: 'number',
|
|
74
74
|
required: false,
|
|
75
75
|
default: 1000,
|
|
76
|
-
description: '
|
|
76
|
+
description: 'INSERT batch size, also the commit unit per batch'
|
|
77
77
|
},
|
|
78
78
|
json: {
|
|
79
79
|
type: 'boolean',
|
|
80
80
|
required: false,
|
|
81
81
|
default: false,
|
|
82
|
-
description: 'Output
|
|
82
|
+
description: 'Output summary in JSON format (for CI/CD consumption)'
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
examples: [
|
|
@@ -68,47 +68,47 @@ async function runAuditMigrationHook(payload, opts) {
|
|
|
68
68
|
module.exports = {
|
|
69
69
|
resource: 'endpoint',
|
|
70
70
|
verb: 'create',
|
|
71
|
-
description: 'Generate
|
|
71
|
+
description: 'Generate a new REST endpoint from a JSON payload',
|
|
72
72
|
category: 'generation',
|
|
73
73
|
flags: {
|
|
74
74
|
project: {
|
|
75
75
|
type: 'string',
|
|
76
76
|
required: true,
|
|
77
|
-
description: '
|
|
77
|
+
description: 'Target project name'
|
|
78
78
|
},
|
|
79
79
|
name: {
|
|
80
80
|
type: 'string',
|
|
81
81
|
required: true,
|
|
82
|
-
description: '
|
|
82
|
+
description: 'Endpoint name to create'
|
|
83
83
|
},
|
|
84
84
|
payload: {
|
|
85
85
|
type: 'string',
|
|
86
86
|
required: true,
|
|
87
|
-
description: 'Path
|
|
87
|
+
description: 'Path or filename of the JSON payload'
|
|
88
88
|
},
|
|
89
89
|
database: {
|
|
90
90
|
type: 'string',
|
|
91
91
|
required: false,
|
|
92
92
|
default: null,
|
|
93
|
-
description: '
|
|
93
|
+
description: 'Database type (postgres|mysql|oracle|sqlite). Default: postgres'
|
|
94
94
|
},
|
|
95
95
|
config: {
|
|
96
96
|
type: 'string',
|
|
97
97
|
required: false,
|
|
98
98
|
default: null,
|
|
99
|
-
description: '
|
|
99
|
+
description: 'Database config file (.env) for payload-vs-database schema validation. Required unless `--skip-schema-check` is active or a default config is set via `config set-default`. Fallback to `.restforge/defaults.json` if not explicitly provided'
|
|
100
100
|
},
|
|
101
101
|
'skip-schema-check': {
|
|
102
102
|
type: 'boolean',
|
|
103
103
|
required: false,
|
|
104
104
|
default: false,
|
|
105
|
-
description: '
|
|
105
|
+
description: 'Skip database schema validation (escape hatch for offline DB or maintenance). RDF shape is still validated'
|
|
106
106
|
},
|
|
107
107
|
force: {
|
|
108
108
|
type: 'boolean',
|
|
109
109
|
required: false,
|
|
110
110
|
default: false,
|
|
111
|
-
description: '
|
|
111
|
+
description: 'Overwrite existing files in the output directory'
|
|
112
112
|
},
|
|
113
113
|
'create-examples': {
|
|
114
114
|
type: 'boolean',
|
|
@@ -120,19 +120,19 @@ module.exports = {
|
|
|
120
120
|
type: 'boolean',
|
|
121
121
|
required: false,
|
|
122
122
|
default: false,
|
|
123
|
-
description: '
|
|
123
|
+
description: 'Skip SQL keyword validation'
|
|
124
124
|
},
|
|
125
125
|
'no-audit-migration': {
|
|
126
126
|
type: 'boolean',
|
|
127
127
|
required: false,
|
|
128
128
|
default: false,
|
|
129
|
-
description: 'Skip
|
|
129
|
+
description: 'Skip audit table migration execution when payload uses fieldPolicy strategies "audit" (SQL file is still written to migrations/audit/)'
|
|
130
130
|
},
|
|
131
131
|
verbose: {
|
|
132
132
|
type: 'boolean',
|
|
133
133
|
required: false,
|
|
134
134
|
default: false,
|
|
135
|
-
description: '
|
|
135
|
+
description: 'Show verbose output for debugging'
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
138
|
examples: [
|
|
@@ -202,20 +202,20 @@ function renderHumanTable(entries) {
|
|
|
202
202
|
module.exports = {
|
|
203
203
|
resource: 'endpoint',
|
|
204
204
|
verb: 'list',
|
|
205
|
-
description: '
|
|
205
|
+
description: 'List endpoints from project metadata in the working directory',
|
|
206
206
|
category: 'management',
|
|
207
207
|
flags: {
|
|
208
208
|
format: {
|
|
209
209
|
type: 'string',
|
|
210
210
|
required: false,
|
|
211
211
|
default: 'text',
|
|
212
|
-
description: '
|
|
212
|
+
description: 'Output format: `text` (human-readable table) or `json` (for AI agent / mcp-server)'
|
|
213
213
|
},
|
|
214
214
|
name: {
|
|
215
215
|
type: 'string',
|
|
216
216
|
required: false,
|
|
217
217
|
default: null,
|
|
218
|
-
description: 'Filter
|
|
218
|
+
description: 'Filter endpoint name, case-insensitive. Wildcard `*` matches any characters (e.g., `*product*`); without wildcard means exact match'
|
|
219
219
|
}
|
|
220
220
|
},
|
|
221
221
|
examples: [
|
|
@@ -856,19 +856,49 @@ function tableToKebab(table) {
|
|
|
856
856
|
* displayCols = kolom code/name di luar PK & kolom audit, dipakai sebagai kolom
|
|
857
857
|
* display saat tabel ini menjadi parent FK (untuk `payload sync --expand-fk`).
|
|
858
858
|
*/
|
|
859
|
+
// Postgres 'public' diperlakukan sebagai default implisit (selalu di search_path
|
|
860
|
+
// secara konvensi), SAMA seperti pengecualian di `qualifiedRefTable()`
|
|
861
|
+
// (generators/lib/payload/payload-runner.js). `schema introspect` SELALU menulis
|
|
862
|
+
// field `schema:` eksplisit di SDF hasil introspeksi, termasuk untuk tabel yang
|
|
863
|
+
// sebenarnya di schema default ('public') — tanpa pengecualian ini, SETIAP SDF
|
|
864
|
+
// hasil introspect Postgres default-schema akan ikut di-qualify ('public.visitors'),
|
|
865
|
+
// menghasilkan nama file RDF berprefix 'public-' yang tidak konsisten dengan JOIN
|
|
866
|
+
// SQL (qualifiedRefTable() di payload-runner.js TIDAK menulis prefix 'public.' pada
|
|
867
|
+
// klausa JOIN) — JOIN auto-discovery di `payload migrate` (migrate-runner.js) jadi
|
|
868
|
+
// gagal menemukan file RDF parent, dan page UDF parent tidak pernah dibuat.
|
|
869
|
+
const DEFAULT_SCHEMA_SENTINEL = 'public';
|
|
870
|
+
function isQualifyingSchema(schemaName) {
|
|
871
|
+
return !!schemaName && schemaName !== DEFAULT_SCHEMA_SENTINEL;
|
|
872
|
+
}
|
|
873
|
+
|
|
859
874
|
function loadModels(schemaDir) {
|
|
860
875
|
const models = loadSchemaPath(schemaDir);
|
|
861
876
|
const entries = [];
|
|
862
877
|
for (const model of models.values()) {
|
|
863
|
-
|
|
878
|
+
// qualifiedName (mis. 'myschema.guest_book') dipakai, bukan tableName
|
|
879
|
+
// bare, agar `--table=` yang dikirim ke `payload generate`/`payload sync`
|
|
880
|
+
// tetap menemukan tabel yang ada di custom schema (tanpa prefix, resolver
|
|
881
|
+
// koneksi default ke schema 'public'/setara dan tabel tidak ditemukan).
|
|
882
|
+
// Schema 'public' dikecualikan (lihat isQualifyingSchema) karena memang
|
|
883
|
+
// sudah default tanpa perlu di-qualify.
|
|
884
|
+
const schemaName = model.schemaName || null;
|
|
885
|
+
const table = isQualifyingSchema(schemaName) ? (model.qualifiedName || model.tableName) : model.tableName;
|
|
864
886
|
const primaryKey = Array.isArray(model.primaryKey) ? model.primaryKey : [];
|
|
865
887
|
|
|
866
888
|
const fks = [];
|
|
867
889
|
for (const rel of Object.values(model.relations || {})) {
|
|
868
890
|
if (rel.type !== 'belongsTo' || !rel.localKey || !rel.target) continue;
|
|
891
|
+
// Konvensi SDF (restforge-handbook/catalogs/sdf/multi-schema.md): target
|
|
892
|
+
// relasi ditulis bare bila parent di schema YANG SAMA dengan child, dan
|
|
893
|
+
// fully-qualified hanya bila cross-schema. Qualify bare target dengan
|
|
894
|
+
// schema child di sini supaya konsisten dengan `table` qualified di atas
|
|
895
|
+
// (byTable/parentTables dibangun dari nilai ini, lihat ctx.byTable).
|
|
896
|
+
const parentTable = rel.target.includes('.')
|
|
897
|
+
? rel.target
|
|
898
|
+
: (isQualifyingSchema(schemaName) ? `${schemaName}.${rel.target}` : rel.target);
|
|
869
899
|
fks.push({
|
|
870
900
|
childCol: rel.localKey,
|
|
871
|
-
parentTable
|
|
901
|
+
parentTable,
|
|
872
902
|
parentCol: rel.references || null
|
|
873
903
|
});
|
|
874
904
|
}
|
|
@@ -879,7 +909,17 @@ function loadModels(schemaDir) {
|
|
|
879
909
|
return !isPk && !AUDIT_COLS.has(name) && /(code|name)/i.test(name);
|
|
880
910
|
});
|
|
881
911
|
|
|
882
|
-
|
|
912
|
+
// `kebab` (qualified, mis. 'myschema-guest-book') HARUS dipakai untuk
|
|
913
|
+
// mencocokkan nama file RDF/UDF di disk (`payload generate` menulis
|
|
914
|
+
// baseFilename dari `--table=` literal, jadi ikut prefix schema).
|
|
915
|
+
// `resourceName` (bare, mis. 'guest-book') dipakai khusus untuk identitas
|
|
916
|
+
// REST endpoint (`endpoint create --name=`): endpoint TIDAK mengenal
|
|
917
|
+
// schema (itu murni konsep koneksi database), dan `payload migrate`
|
|
918
|
+
// (RDF -> UDF) sendiri sudah men-strip schema saat menurunkan apiPath/
|
|
919
|
+
// pageId (lihat backend-payload-migrator.js: cleanTable = tableName.split('.').pop()).
|
|
920
|
+
// Memakai `kebab` qualified untuk nama endpoint akan membuat route REST
|
|
921
|
+
// tidak sinkron dengan apiPath yang dipanggil frontend.
|
|
922
|
+
entries.push({ kebab: tableToKebab(table), resourceName: tableToKebab(model.tableName), table, fks, displayCols });
|
|
883
923
|
}
|
|
884
924
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
885
925
|
return entries;
|
|
@@ -894,13 +934,24 @@ function buildTableEntries(schemaDir) {
|
|
|
894
934
|
* Turunkan daftar `--fk-columns` untuk `payload sync --expand-fk` dari SDF:
|
|
895
935
|
* `<parentTable>.<displayCol>` untuk tiap kolom display (code/name) tiap parent.
|
|
896
936
|
* Kosong bila tidak ada kolom display terdeteksi (jatuh ke mode AUTO command).
|
|
937
|
+
*
|
|
938
|
+
* `parentTable` di sini WAJIB bare (tanpa prefix schema), berbeda dari
|
|
939
|
+
* `fk.parentTable` yang dipakai untuk lookup `byTable` (qualified). Alasannya:
|
|
940
|
+
* `payload-runner.js parseFkColumns()` mem-validasi setiap entri persis 2 segmen
|
|
941
|
+
* (`table.column`), dan nilainya dicocokkan terhadap `getForeignKeys().references.table`
|
|
942
|
+
* hasil introspeksi DB — yang SELALU bare (`pg_class.relname`, schema ada di field
|
|
943
|
+
* terpisah `references.schema`). Mengirim `sch02.company.company_name` (3 segmen)
|
|
944
|
+
* ditolak validator; mengirim bare `company.company_name` cocok dengan hasil introspeksi.
|
|
897
945
|
*/
|
|
898
946
|
function fkColumnsForEntry(entry, byTable) {
|
|
899
947
|
const cols = [];
|
|
900
948
|
for (const fk of entry.fks) {
|
|
901
949
|
const parent = byTable.get(fk.parentTable);
|
|
902
950
|
const disp = parent ? parent.displayCols : [];
|
|
903
|
-
|
|
951
|
+
const bareParentTable = fk.parentTable.includes('.')
|
|
952
|
+
? fk.parentTable.split('.').pop()
|
|
953
|
+
: fk.parentTable;
|
|
954
|
+
for (const dc of disp) cols.push(`${bareParentTable}.${dc}`);
|
|
904
955
|
}
|
|
905
956
|
return cols;
|
|
906
957
|
}
|
|
@@ -974,7 +1025,7 @@ function runBackendPipeline(ctx) {
|
|
|
974
1025
|
// Mode --overwrite: drop tabel lalu re-create (destruktif). Tanpa --overwrite:
|
|
975
1026
|
// CREATE TABLE IF NOT EXISTS (tabel existing dilewati).
|
|
976
1027
|
const dropFlag = ctx.overwrite ? ' --drop=true' : '';
|
|
977
|
-
run(`npx restforge schema migrate --path=${ctx.schemaFlag} ${cfgArg} --auto-create-db${dropFlag}`, ctx.cwd);
|
|
1028
|
+
run(`npx restforge schema migrate --schema-path=${ctx.schemaFlag} ${cfgArg} --auto-create-db${dropFlag}`, ctx.cwd);
|
|
978
1029
|
|
|
979
1030
|
phase('[3/4] Payload RDF (generate)');
|
|
980
1031
|
for (const t of ctx.tableEntries) {
|
|
@@ -998,7 +1049,9 @@ function runBackendPipeline(ctx) {
|
|
|
998
1049
|
|
|
999
1050
|
phase('[4/4] REST endpoints');
|
|
1000
1051
|
for (const t of ctx.tableEntries) {
|
|
1001
|
-
|
|
1052
|
+
// --name= = identitas REST endpoint (bare, lihat resourceName di loadModels).
|
|
1053
|
+
// --payload= = nama file RDF di disk (qualified/kebab, ikut prefix schema).
|
|
1054
|
+
run(`npx restforge endpoint create --project=${ctx.project} --name=${t.resourceName} --payload=${t.kebab}.json ${cfgArg} --database=${dbFlag} --force`, ctx.cwd);
|
|
1002
1055
|
}
|
|
1003
1056
|
}
|
|
1004
1057
|
|
|
@@ -1185,36 +1238,36 @@ async function maybeRunFrontend(ctx, ask) {
|
|
|
1185
1238
|
|
|
1186
1239
|
module.exports = {
|
|
1187
1240
|
verb: 'fast-track',
|
|
1188
|
-
description: 'Generate REST API + frontend app
|
|
1241
|
+
description: 'Generate REST API + frontend app from SDF (real execution) with optional runtime server',
|
|
1189
1242
|
category: 'generation',
|
|
1190
1243
|
flags: {
|
|
1191
1244
|
project: {
|
|
1192
1245
|
type: 'string',
|
|
1193
1246
|
required: true,
|
|
1194
|
-
description: '
|
|
1247
|
+
description: 'Project/application name (e.g., visitors-app)'
|
|
1195
1248
|
},
|
|
1196
1249
|
'schema-path': {
|
|
1197
1250
|
type: 'string',
|
|
1198
1251
|
required: true,
|
|
1199
|
-
description: 'Folder
|
|
1252
|
+
description: 'Folder containing the application SDF (relative to cwd)'
|
|
1200
1253
|
},
|
|
1201
1254
|
config: {
|
|
1202
1255
|
type: 'string',
|
|
1203
1256
|
required: false,
|
|
1204
1257
|
default: null,
|
|
1205
|
-
description: '
|
|
1258
|
+
description: 'Target env filename in config/ folder. If empty, fast-track uses the existing config file: 1 file is used directly, >1 files use config get-default'
|
|
1206
1259
|
},
|
|
1207
1260
|
license: {
|
|
1208
1261
|
type: 'string',
|
|
1209
1262
|
required: false,
|
|
1210
1263
|
default: null,
|
|
1211
|
-
description: 'License key (XXXX-XXXX-XXXX-XXXX).
|
|
1264
|
+
description: 'License key (XXXX-XXXX-XXXX-XXXX). If provided, used as the default for the LICENSE prompt'
|
|
1212
1265
|
},
|
|
1213
1266
|
overwrite: {
|
|
1214
1267
|
type: 'boolean',
|
|
1215
1268
|
required: false,
|
|
1216
1269
|
default: false,
|
|
1217
|
-
description: '
|
|
1270
|
+
description: 'Destructive mode: drop table & regenerate (requires y/N confirmation)'
|
|
1218
1271
|
}
|
|
1219
1272
|
},
|
|
1220
1273
|
examples: [
|
package/generators/cli/init.js
CHANGED
|
@@ -288,14 +288,14 @@ async function runInteractive(workingDir, prompter) {
|
|
|
288
288
|
|
|
289
289
|
module.exports = {
|
|
290
290
|
verb: 'init',
|
|
291
|
-
description: 'Generate starter config file (config/db-connection.env)
|
|
291
|
+
description: 'Generate a starter config file (config/db-connection.env) in the working directory. Interactive in terminal; non-interactive with --force',
|
|
292
292
|
category: 'utility',
|
|
293
293
|
flags: {
|
|
294
294
|
force: {
|
|
295
295
|
type: 'boolean',
|
|
296
296
|
required: false,
|
|
297
297
|
default: false,
|
|
298
|
-
description: '
|
|
298
|
+
description: 'Overwrite existing file without confirmation'
|
|
299
299
|
}
|
|
300
300
|
},
|
|
301
301
|
examples: [
|