@revoengine/cli 1.0.10 → 1.0.11
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/README.md +312 -33
- package/dist/src/cli.js +58 -7
- package/dist/src/client.d.ts +356 -5
- package/dist/src/client.js +803 -19
- package/dist/src/commands/auth.js +4 -2
- package/dist/src/commands/component.js +260 -141
- package/dist/src/commands/database-schemas.d.ts +2 -0
- package/dist/src/commands/database-schemas.js +188 -0
- package/dist/src/commands/database-views.d.ts +2 -0
- package/dist/src/commands/database-views.js +123 -0
- package/dist/src/commands/endpoints.js +114 -0
- package/dist/src/commands/env.js +44 -24
- package/dist/src/commands/events.d.ts +2 -0
- package/dist/src/commands/events.js +146 -0
- package/dist/src/commands/groups.d.ts +2 -0
- package/dist/src/commands/groups.js +169 -0
- package/dist/src/commands/index.d.ts +8 -0
- package/dist/src/commands/index.js +8 -0
- package/dist/src/commands/job-templates.d.ts +2 -0
- package/dist/src/commands/job-templates.js +101 -0
- package/dist/src/commands/metadata.js +29 -7
- package/dist/src/commands/project.js +10 -3
- package/dist/src/commands/role-groups.d.ts +2 -0
- package/dist/src/commands/role-groups.js +152 -0
- package/dist/src/commands/schedules.d.ts +2 -0
- package/dist/src/commands/schedules.js +141 -0
- package/dist/src/commands/terminal-service.d.ts +38 -0
- package/dist/src/commands/terminal-service.js +210 -0
- package/dist/src/commands/terminal.d.ts +22 -0
- package/dist/src/commands/terminal.js +511 -0
- package/dist/src/component-lock.d.ts +100 -2
- package/dist/src/component-lock.js +304 -15
- package/dist/src/config.d.ts +10 -2
- package/dist/src/config.js +49 -14
- package/dist/src/database-schema-artifacts.d.ts +7 -0
- package/dist/src/database-schema-artifacts.js +8 -0
- package/dist/src/env-sync.d.ts +0 -3
- package/dist/src/env-sync.js +3 -19
- package/dist/src/metadata-backfill.d.ts +16 -6
- package/dist/src/metadata-backfill.js +1069 -18
- package/dist/src/project.d.ts +2 -0
- package/dist/src/project.js +4 -17
- package/dist/src/prompt.js +10 -18
- package/dist/src/resource-metadata.d.ts +1 -0
- package/dist/src/resource-metadata.js +3 -0
- package/dist/src/resource-syncs/database-schema-sync.d.ts +117 -0
- package/dist/src/resource-syncs/database-schema-sync.js +2289 -0
- package/dist/src/resource-syncs/database-view-sync.d.ts +124 -0
- package/dist/src/resource-syncs/database-view-sync.js +1317 -0
- package/dist/src/resource-syncs/endpoint-sync.d.ts +96 -0
- package/dist/src/resource-syncs/endpoint-sync.js +1283 -0
- package/dist/src/resource-syncs/event-sync.d.ts +99 -0
- package/dist/src/resource-syncs/event-sync.js +949 -0
- package/dist/src/resource-syncs/group-sync.d.ts +86 -0
- package/dist/src/resource-syncs/group-sync.js +882 -0
- package/dist/src/resource-syncs/job-template-sync.d.ts +85 -0
- package/dist/src/resource-syncs/job-template-sync.js +782 -0
- package/dist/src/resource-syncs/role-group-sync.d.ts +83 -0
- package/dist/src/resource-syncs/role-group-sync.js +597 -0
- package/dist/src/resource-syncs/schedule-sync.d.ts +111 -0
- package/dist/src/resource-syncs/schedule-sync.js +1302 -0
- package/dist/src/resource-syncs/util.d.ts +19 -0
- package/dist/src/resource-syncs/util.js +116 -0
- package/dist/src/runtime-view.d.ts +1 -0
- package/dist/src/runtime-view.js +6 -1
- package/dist/src/sync-output.d.ts +38 -0
- package/dist/src/sync-output.js +131 -0
- package/dist/src/tracked-resources.d.ts +1 -1
- package/dist/src/tracked-resources.js +26 -2
- package/dist/src/types.d.ts +224 -0
- package/dist/src/ui.d.ts +3 -0
- package/dist/src/ui.js +67 -18
- package/dist/src/utils.d.ts +2 -0
- package/dist/src/utils.js +64 -0
- package/dist/src/workspace-component.d.ts +2 -0
- package/dist/src/workspace-component.js +34 -0
- package/dist/src/workspace-resource.d.ts +2 -0
- package/dist/src/workspace-resource.js +52 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -21,13 +21,21 @@ Inspect the local runtime and config path:
|
|
|
21
21
|
revo -i
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Add a project connection. The new project becomes active immediately:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
revo projects add local --url http://localhost:3000
|
|
28
|
+
revo projects list
|
|
29
|
+
revo auth status
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
To use the original `default` connection instead, save its credentials:
|
|
25
33
|
|
|
26
34
|
```bash
|
|
27
35
|
revo auth login
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
`revo auth login` opens
|
|
38
|
+
`revo auth login` opens a masked interactive terminal prompt for your API key and saves the `default` login. If you are already logged in, the CLI warns and asks you to `revo auth logout` first. For named connections, use `revo projects add <name>`.
|
|
31
39
|
|
|
32
40
|
The CLI validates the API key against `/api/v1/me` and infers the RevoEngine instance from the authenticated profile for tenant-scoped operations such as component push.
|
|
33
41
|
|
|
@@ -37,6 +45,25 @@ Check the active session:
|
|
|
37
45
|
revo auth status
|
|
38
46
|
```
|
|
39
47
|
|
|
48
|
+
Connect this computer as an Agent Gateway terminal with the same CLI installation and login:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
revo terminal connect --workspace "$HOME/projects/my-project" --name "Work Mac"
|
|
52
|
+
revo terminal status
|
|
53
|
+
revo --version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Pairing appears in AI Agents → Terminals for approval and access configuration; personal Vault settings also shows the grant. `revo terminal connect` runs in the foreground; stop it with Ctrl+C after approval if you want to move it into the background. Install a per-user background service for the approved terminal: LaunchAgent on macOS or `systemd --user` on Linux.
|
|
57
|
+
|
|
58
|
+
Each registration has a stable `agentTerminalId` and a model reference token `[AGENT_TERMINAL/<agentTerminalId>](Name)`. Existing local `runner.json` entries with `deviceId` are read with the same ID, so they do not need to be paired again. Access defaults to `restricted: true`; the owner can explicitly grant access to users, groups, or the entire instance.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
revo terminal service install --workspace "$HOME/projects/my-project"
|
|
62
|
+
revo terminal service uninstall --workspace "$HOME/projects/my-project"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The service starts at login, reconnects automatically, and pins the environment active at installation (or an explicit `--project <name>`). Install one service per workspace/profile; pass the same `--project` to uninstall after switching environments. Uninstall stops the service but keeps the terminal grant and local registration. `revo terminal disconnect --workspace <path>` revokes the grant and removes its local credential; uninstall the service first. On macOS, service logs are in `~/Library/Logs/RevoEngine/`. On Linux, inspect them with `journalctl --user -u <unit-name>`; `install` prints the unit name. Linux user services normally stop after logout unless an administrator enables user lingering. The runner uses your OS permissions; the workspace controls the starting directory, not OS sandbox access. A personal API key is required.
|
|
66
|
+
|
|
40
67
|
Remove stored credentials:
|
|
41
68
|
|
|
42
69
|
```bash
|
|
@@ -52,7 +79,7 @@ revo --help
|
|
|
52
79
|
Initialize a project for ambient low-code editor globals:
|
|
53
80
|
|
|
54
81
|
```bash
|
|
55
|
-
revo project
|
|
82
|
+
revo project init
|
|
56
83
|
revo project init ./app
|
|
57
84
|
revo project init ./app --identity-mode stableKey --stable-key-name resourceKey --resources component
|
|
58
85
|
revo project init ./app --identity-mode componentId
|
|
@@ -76,22 +103,245 @@ When compiler options are missing, project initialization sets `target: ES2022`,
|
|
|
76
103
|
|
|
77
104
|
Stable-key mode manages only components that contain the configured metadata property. Component UUIDs remain in API requests and lock diagnostics, but they are not used as durable identity. Duplicate stable-key values block plan, pull, and push. Use `--identity-mode componentId` only for a workspace that intentionally remains bound to one RevoEngine instance.
|
|
78
105
|
|
|
79
|
-
During interactive init, the CLI asks for the stable key metadata name and which resource families it should track. Press Enter to use `stableKey` and track `all` resources. For non-interactive runs, `--resources <list>` accepts `all` or comma-separated resource names such as `component`; when omitted it defaults to `all`. Project initialization
|
|
106
|
+
During interactive init, the CLI asks for the stable key metadata name and which resource families it should track. Press Enter to use `stableKey` and track `all` resources. For non-interactive runs, `--resources <list>` accepts `all` or comma-separated resource names such as `component`, `endpoint`, `group`, `role-group`, `job-template`, `schedule`, `event`, `database-schema`, or `database-view`; when omitted it defaults to `all`. Project initialization backfills missing stable-key metadata for the established resource families while preserving existing keys. Database Schema and Database View backfill are deliberately excluded from automatic initialization because large catalogs and metadata-only database updates require an explicit operator review. Init prints the exact follow-up plan command. Pass `--no-metadata-backfill` when initialization must not write any remote metadata.
|
|
80
107
|
|
|
81
108
|
Backfill stable-key metadata for tracked resources with an explicit plan/apply flow:
|
|
82
109
|
|
|
83
110
|
```bash
|
|
84
|
-
revo metadata plan --
|
|
85
|
-
revo metadata apply --
|
|
111
|
+
revo metadata plan --project test
|
|
112
|
+
revo metadata apply --project test --yes
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Backfill only writes resources missing the configured stable-key metadata unless `--force` is passed. Generated resource keys use `category/name#<random-hex>`. Database Schema and Database View keys are immutable once present, even with `--force`. Database View backfill reads the current view and uses the deployed full `PUT` API with the same definition, type, version, and ACL, changing only user metadata to add the Stable Key. Because this is a full view update, run it in a reviewed maintenance window. Database Schema backfill also plans column keys in `definition[].metadata.<stable-key-name>` for root tables only, using `category/table/column#<random-hex>`; existing, malformed, or duplicate column keys are never overwritten, including with `--force`. Partition definitions inherit their root table's columns and never receive independent column keys.
|
|
116
|
+
|
|
117
|
+
### Database Schemas
|
|
118
|
+
|
|
119
|
+
Database Schemas use an explicit SOURCE bootstrap followed by a portable pull:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
revo metadata plan --project test --resources database-schema
|
|
123
|
+
revo metadata apply --project test --resources database-schema --yes
|
|
124
|
+
# Generate Stable Keys only for root schemas and leave partitions unmanaged:
|
|
125
|
+
revo metadata plan --project test --resources database-schema --skip-partitions
|
|
126
|
+
revo metadata apply --project test --resources database-schema --skip-partitions --yes
|
|
127
|
+
revo database-schemas pull --all --project test
|
|
128
|
+
# Fail when any active schema or partition remains unmanaged:
|
|
129
|
+
revo database-schemas pull --all --project test --strict
|
|
130
|
+
# Compare desired manifests, the selected lock baseline, and live E2E without writes:
|
|
131
|
+
revo database-schemas plan --all --project e2e
|
|
132
|
+
revo database-schemas plan --all --project e2e --json
|
|
133
|
+
# Review only root schemas; partitions are excluded from the API catalog, workspace comparison, and strict coverage:
|
|
134
|
+
revo database-schemas plan --all --project e2e --skip-partitions
|
|
135
|
+
# Add one cached bulk size request for table/index/audit risk context:
|
|
136
|
+
revo database-schemas plan --all --project e2e --with-stats
|
|
137
|
+
# CI convergence and Stable Key coverage gate:
|
|
138
|
+
revo database-schemas plan --all --project e2e --strict
|
|
139
|
+
# Create, safely update, and verify managed root schemas and their partitions:
|
|
140
|
+
revo database-schemas push --all --project e2e --yes
|
|
141
|
+
# Or create one reviewed graph node by Stable Key:
|
|
142
|
+
revo database-schemas push 'Sales/Orders#1234abcd' --project e2e --yes
|
|
143
|
+
# Only after reviewing safe remote content drift; --force never bypasses manual DDL migration:
|
|
144
|
+
revo database-schemas push --all --project e2e --yes --force
|
|
145
|
+
# Destructive prune of previously managed partitions only:
|
|
146
|
+
revo database-schemas push --all --project e2e --yes --force --prune-partitions
|
|
147
|
+
# Destructive removal of reviewed target-only root schemas (no active partitions or Database View dependencies):
|
|
148
|
+
revo database-schemas push --all --project e2e --yes --force --prune-orphans
|
|
149
|
+
# After a reviewed deletion on the source, remove stale local desired manifests and locks only:
|
|
150
|
+
revo database-schemas pull --all --project test --yes --force --prune-orphans
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The catalog is read in deterministic pages of 200 records. Pass `--skip-partitions` to `metadata plan` and `metadata apply` when only root Database Schemas should receive generated table Stable Keys; the CLI adds a server-side `parent isNull` filter and defensively excludes any partition returned by the API. Without this flag, root schemas and partitions remain in scope for table keys, while column-key backfill always remains root-only. Root manifests are written below `<workspace>/DatabaseSchemas/<category>/`; every managed partition has its own nested manifest under its parent and carries its own Stable Key plus `parentStableKey`. Partition manifests do not duplicate the inherited column definition.
|
|
154
|
+
|
|
155
|
+
Manifests retain the complete non-reserved user metadata and portable column/partition configuration. Instance UUIDs, column definition IDs, versions, timestamps, records, details, users, ACL, audit settings, and tags are excluded. ACL, audit, and tags are returned only as pull diagnostics and are outside the portable hash; the lock retains only a root's source `restricted` boolean so first creation can safely reject a restricted source without storing target principals. Foreign references remain visible in the column definition with `migration.foreignReferences: "manual"` because they require operator migration. Missing Stable Keys are reported as unmanaged and skipped; duplicates, invalid keys, parent cycles, missing parents, and path collisions stop the pull before files change. A locally edited manifest is preserved unless `--force` is supplied. A normal pull never deletes local manifests. After reviewing source deletions, `pull --prune-orphans --yes --force` removes only local manifests and lock entries that no longer exist on the selected source; it never deletes any target table.
|
|
156
|
+
|
|
157
|
+
`database-schemas plan` is fileless and read-only. It reports three-way states plus root/partition orphans, previously managed partition removals, unmanaged WIP resources, collisions, reconciled manual work, and `manual-schema-migration-required`. Pass `--skip-partitions` for a root-schema-only view: partitions are excluded server-side with `parent isNull`, local partition manifests are excluded too, and they do not contribute to `--strict` coverage. This view intentionally cannot report partition drift, lifecycle work, or unmanaged partitions. Table names, parent relationships, partition bounds, column removals, unsafe keyless column additions, and structural changes without exact column identity remain manual. Changes to an existing column are operational when desired and target definitions share one unique column Stable Key; this includes rename, type, default, nullability, array, primary-key, unique, and index fields. A required, defaulted, indexed, unique, or primary-key new column is also operational when its desired definition carries one unique Stable Key that is absent from the target. A rename is still blocked as manual when the table has an active Database View or foreign-reference declaration. Column presentation order, column metadata, and adding an explicitly nullable column without a default, primary key, unique constraint, index, or foreign reference remain safe definition changes. Every reported change includes an operational hint covering the relevant lock, scan, rewrite, index, validation, conversion, or data-loss risk. `--with-stats` performs exactly one cached bulk `/api/v1/databases/stats` request; the default plan avoids that database-size query. `--strict` accepts only converged resources and informational target-only orphans, and fails for drift, collisions, manual migrations, deletions, missing baselines, or incomplete Stable Key coverage.
|
|
158
|
+
|
|
159
|
+
`database-schemas push` creates missing schemas and applies reviewed safe or controlled operational updates. It re-plans live state, then resolves an exact Stable Key match and fetches its current version immediately before every write; it never sends source UUIDs, rows, ACLs, audit or tags. Existing target column IDs are reattached first by a unique shared column Stable Key and otherwise by exact column name. With a unique shared key, the CLI imports changes to type, default, nullability, array, primary-key, unique, index, name, description, and metadata while preserving the target column identity. It also creates a required, defaulted, indexed, unique, or primary-key column when the new desired definition has one unique Stable Key absent from the target; no instance-local definition ID is sent for that new column. These structural writes can still fail when live data is incompatible and should be run in a reviewed maintenance window; every write is followed by an exact GET and portable-hash verification before the selected environment baseline is recorded. The write is still refused if an active Database View appears after planning a rename. Column drops, unsafe additions without a unique key, structural changes without a unique shared key, malformed or duplicate column keys, and foreign-reference deployment remain manual; `--force` can overwrite reviewed portable content drift but never bypasses those blockers. If an environment lock baseline was lost, `--force` first adopts an exactly matching target through GET-and-hash verification only; it sends no PUT. A reviewed safe difference without that baseline can also be aligned with `--force`. When a manually aligned target already matches the manifest, push verifies the live hash and advances only the selected lock baseline. Audited targets show an audit-trigger-rebuild warning, serialize writes, and retry one audit-lock conflict only after fresh validation. Root tables are created `restricted=false` and `audit=false`; a root pulled as restricted is reported as `access-policy-required` and skipped. Partitions follow root → child → nested-child order, reference the resolved target parent by name, and inherit definition, audit and ACL from that target parent. A failed or unavailable parent skips only its dependent branch, while unrelated creates continue. Removing a previously managed partition manifest produces `delete-partition`; deletion requires all of `--prune-partitions --yes --force`, is processed leaf-to-root, rechecks the live parent and active Database View dependencies, then records an environment tombstone after readback. A target-only root marked `orphan-root` can be deleted only with `--prune-orphans --yes --force`; it is revalidated by Stable Key and hash, and deletion is blocked when it has an active partition or Database View dependency. Unmanaged target-only partitions are never deleted. A tombstoned Stable Key is never recreated automatically, and overlapping replacement bounds require two separate pushes: prune the old partition first, then create the new partition with a new Stable Key.
|
|
160
|
+
|
|
161
|
+
### Database Views
|
|
162
|
+
|
|
163
|
+
Database Views are migrated only after their Database Schemas and column Stable Keys converge on the target:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
revo metadata plan --project test --resources database-view
|
|
167
|
+
revo metadata apply --project test --resources database-view --yes
|
|
168
|
+
revo database-views pull --all --project test
|
|
169
|
+
revo database-views plan --all --project e2e --strict
|
|
170
|
+
revo database-views push --all --project e2e --yes
|
|
171
|
+
# Or deploy one reviewed ordinary view by Stable Key:
|
|
172
|
+
revo database-views push 'Reporting/high_value_customers#f00dbabe' --project e2e --yes
|
|
173
|
+
# Materialized writes need their own explicit operational gate:
|
|
174
|
+
revo database-views push --all --project e2e --yes --allow-materialized
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The workspace contains `STRUCTURED` and `RAW_SQL` `VIEW` and `MATERIALIZED_VIEW` manifests below `<workspace>/DatabaseViews/`. A `RAW_SQL` manifest retains the SQL text and source schema Stable Keys, while a `STRUCTURED` manifest additionally retains referenced-column Stable Keys; neither retains instance IDs, generated lineage, versions, or source ACL principals. RAW_SQL preview and writes require the target's `databaseViewsRawSql` feature flag and `RESOURCE_ADMIN` permission. A materialized manifest retains the ordered `uniqueKey` and index columns but drops server-generated index names; independent index definitions are normalized deterministically. A plan is fileless: it resolves every source on the target, runs a bounded `take: 0` preview, reports materialization/quota risk and active refresh schedules, and blocks collisions, missing baselines, incompatible output, and any rename or type/mode transition. Materialized creates and updates require `--allow-materialized`; an active refresh schedule blocks an update and must be coordinated manually. Create re-plans live, previews again immediately before POST, and creates a private target view with empty users and groups. Updates fetch the exact live record, then send the full desired definition in a PUT with the current optimistic version while preserving its target-local ACL; preview and post-write hash verification are repeated before advancing the baseline. `--force` may overwrite reviewed portable content drift, but never identity, source-readiness, preview, ACL, rename, type, mode, schedule, or materialized-write-gate blockers. An identical target with a missing baseline is adopted by GET-and-hash verification without a PUT. A matching private view with an empty target-local ACL is `clean`; source ACLs are never copied, and access can be configured independently on the target. For the TEST → E2E operating procedure, including stable-key bootstrap, plan artifacts, target-local ACL work, materialized-view maintenance windows, and strict verification, see [the Database Views runbook](docs/runbooks/database-views-test-to-e2e.md).
|
|
178
|
+
|
|
179
|
+
Job templates use the same metadata bootstrap and workspace boundary. Generate keys on the source environment, then pull portable manifests into `<workspace>/JobTemplates`:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
revo metadata plan --project test --resources job-template
|
|
183
|
+
revo metadata apply --project test --resources job-template --yes
|
|
184
|
+
revo job-templates pull --all --project test
|
|
185
|
+
revo job-templates plan --all --project e2e
|
|
186
|
+
revo job-templates plan --all --project e2e --json
|
|
187
|
+
revo job-templates push --all --project e2e --yes
|
|
188
|
+
# Only after reviewing remote-changed, conflict, or missing-lock:
|
|
189
|
+
revo job-templates push --all --project e2e --yes --force
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Endpoints
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Establish Stable Key identity on SOURCE, then pull portable endpoint configuration to
|
|
196
|
+
# <workspace>/Endpoints and extend .revoengine/revo.lock.json.
|
|
197
|
+
revo metadata plan --project test --resources endpoint
|
|
198
|
+
revo metadata apply --project test --resources endpoint --yes
|
|
199
|
+
revo endpoints pull --all --project test
|
|
200
|
+
revo endpoints plan --all --project e2e
|
|
201
|
+
revo endpoints plan --all --project e2e --json
|
|
202
|
+
revo endpoints push --all --project e2e --yes
|
|
203
|
+
revo endpoints plan --all --project e2e --strict
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Endpoint plan is fileless and read-only. It compares portable workspace manifests, the selected target-environment baseline in `.revoengine/revo.lock.json`, and the live target. Component dependencies are resolved only by exact stable key. Latest bindings require identical portable Component content in the workspace and target; pinned bindings require the pulled digest, workspace digest, and target digest to all match. Dependency mismatches block every Endpoint write and instruct the operator to align Components before Endpoints.
|
|
207
|
+
|
|
208
|
+
Push recomputes the live plan, resolves target Component UUIDs and versions only in memory, and rejects all hard blockers before the first write. Creates, updates, and exact Stable Key restores converge configuration first and then the desired active state. Every write is fetched again and compared by the full portable hash before the target lock baseline is updated. `--force` can accept reviewed three-way content drift, but cannot bypass identity, route, dependency, restore-safety, or concurrency checks. Target-only and unmanaged Endpoints remain untouched, and `--prune` is rejected.
|
|
209
|
+
|
|
210
|
+
For the complete **SOURCE** → **TARGET** operator flow, Component dependency gate,
|
|
211
|
+
GitLab CI plan artifact, manual PROD approval, strict verification, and rollback,
|
|
212
|
+
see [the Endpoint runbook](https://gitlab.com/revoengine/cli/-/blob/master/docs/runbooks/endpoint-source-to-target.md).
|
|
213
|
+
|
|
214
|
+
Job-template manifests keep portable `options` and legacy `inputs`, reference their component by component stable key, and exclude UUIDs, versions, audit data, pinned component versions, and `triggerUser`. When `triggerUser` is present, pull prints a warning because the execution principal must be configured independently per environment.
|
|
215
|
+
|
|
216
|
+
Schedules support source bootstrap, portable pull, planning, and deployment for user-managed `JOB_TEMPLATE` targets and Materialized View refresh targets:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Establish stable-key identity for the source schedules.
|
|
220
|
+
revo metadata plan --project test --resources schedule
|
|
221
|
+
revo metadata apply --project test --resources schedule --yes
|
|
222
|
+
|
|
223
|
+
# Event bootstrap currently covers only JOB_TEMPLATE targets.
|
|
224
|
+
revo metadata plan --project test --resources event
|
|
225
|
+
revo metadata apply --project test --resources event --yes
|
|
226
|
+
|
|
227
|
+
# Pull source Schedule definitions and their lock baselines.
|
|
228
|
+
revo schedules pull --all --project test
|
|
229
|
+
|
|
230
|
+
# Compare the local definitions, the E2E lock baseline, and live E2E schedules.
|
|
231
|
+
revo schedules plan --all --project e2e
|
|
232
|
+
revo schedules plan --all --project e2e --json
|
|
233
|
+
revo schedules plan --all --project e2e --strict
|
|
234
|
+
|
|
235
|
+
# Create disabled Schedules and safely update existing definitions.
|
|
236
|
+
revo schedules push --all --project e2e --yes
|
|
237
|
+
# Materialized View refresh definitions require an additional operational gate.
|
|
238
|
+
revo schedules push --all --project e2e --yes --allow-materialized
|
|
239
|
+
# Only after reviewing remote-changed, conflict, or missing-lock:
|
|
240
|
+
revo schedules push --all --project e2e --yes --force --allow-materialized
|
|
241
|
+
|
|
242
|
+
# Deliberately activate only candidates created or updated by this push.
|
|
243
|
+
revo schedules push --all --project e2e --yes --allow-materialized --activate
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Each manifest references either a Job Template by Stable Key or a Materialized View by Database View Stable Key plus `CONCURRENT` or `BLOCKING` refresh mode. It excludes Schedule UUIDs, dependency UUIDs, versions, source `active`, and `targetVersion`. Source `active` becomes an editable `activationCandidate`; Job Template `sourceTargetConfig` is retained for operator context only. Before a Schedule can be created or updated, its dependency must resolve to exactly one compatible live target by exact Stable Key. A target-kind transition is reported as a warning and conflict, and can be applied only after review with `--force`. Missing or ambiguous dependencies, ordinary Views, `AGENT`, unrelated `PLATFORM_OPERATION`, system-managed, deleted, and unmanaged Schedules remain blocking or explicit exclusions. `--strict` fails for drift, blockers, or exclusions; target-only orphans remain informational.
|
|
247
|
+
|
|
248
|
+
Schedule push repeats its live preflight immediately before each write. Creates always send `active: false`; ordinary updates do not change the target activation state. Every create or update re-resolves the target Schedule and dependency, uses the live Schedule version for updates, re-fetches the result, verifies its portable hash, and then advances the selected environment baseline. Materialized View writes require `--allow-materialized`; that gate cannot be bypassed with `--force`. Deploy Database Views before their refresh Schedules. `remote-changed`, `conflict` (including target-kind transitions), and `missing-lock` require explicit `--force`. An exactly matching `missing-lock` target is re-read and adopted into the selected environment baseline without a PUT. There is no Schedule prune: target-only orphans remain untouched.
|
|
249
|
+
|
|
250
|
+
`schedules push --activate` is the optional final activation phase. It activates only candidates created or updated and verified in that same push, and never disables an already active target. Interactive use asks for a second confirmation; non-interactive use requires both `--yes` and `--activate`. Activation failures are isolated per Schedule.
|
|
251
|
+
|
|
252
|
+
Events currently support the source pull step for `JOB_TEMPLATE` targets. After assigning Stable Keys to Events and their Job Templates, pull the portable source manifests and lock baselines:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
revo metadata plan --project test --resources event
|
|
256
|
+
revo metadata apply --project test --resources event --yes
|
|
257
|
+
revo events pull --all --project test
|
|
258
|
+
revo events plan --all --project e2e
|
|
259
|
+
revo events plan --all --project e2e --json
|
|
260
|
+
revo events plan --all --project e2e --strict
|
|
261
|
+
|
|
262
|
+
# Create disabled Events and safely update their configuration.
|
|
263
|
+
revo events push --all --project e2e --yes
|
|
264
|
+
# Only after reviewing remote-changed, conflict, or missing-lock states:
|
|
265
|
+
revo events push --all --project e2e --yes --force
|
|
266
|
+
|
|
267
|
+
# After the configuration phase completes, align active state with source.
|
|
268
|
+
revo events push --all --project e2e --yes --activate
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The resulting `<workspace>/Events/**/event.json` manifests retain the Event name, category, description, type, filter, metadata, activation declaration, and API configuration fields that are portable. They replace `targetId` with the Job Template Stable Key and exclude instance UUIDs, target version/configuration, Event version, audits, execution history, and deletion fields. Events targeting `AGENT`, deleted Events, and Events whose target Job Template has no Stable Key are reported as exclusions and are not written. Pull preserves a locally changed Event manifest unless it is repeated with `--force`.
|
|
272
|
+
|
|
273
|
+
`events plan` is read-only. It compares each local Event with the selected environment's lock baseline and live target, then reports `clean`, `create`, `safe-update`, `remote-changed`, `conflict`, `missing-lock`, `activation-drift`, `orphan`, `collision`, and `skipped`. A difference only in `active` is always `activation-drift`, never a skip. Each Job Template Stable Key must resolve exactly once on the target; missing or ambiguous dependencies block the plan. Orphans and exclusions are reported but are not changed. `--strict` accepts only `clean`, informational `orphan`, and `skipped` states.
|
|
274
|
+
|
|
275
|
+
`events push` repeats the live preflight for every write and resolves `target.jobTemplateStableKey` to one exact target UUID and fresh version. Creates run before updates in Stable Key order and always send `active: false`; ordinary updates never change target activation. Each write is read back and verified against the full portable Event configuration before its environment baseline advances. The current Event API has no write contract for unknown `extensions`; they are retained by pull for visibility but block plan/push rather than risking a partial migration. `remote-changed`, `conflict`, and `missing-lock` require `--force`; invalid identity, unresolved dependencies, unmanaged targets, and API errors never become forceable. Orphans and skipped Events remain untouched.
|
|
276
|
+
|
|
277
|
+
`events push --activate` is the optional second phase. It starts only after all configuration writes have verified successfully, then activates or disables verified Events to match source `active`. Interactive use asks for a second confirmation; non-interactive use requires `--yes --activate`. Activation results, including partial failures, are present in both terminal and JSON output.
|
|
278
|
+
|
|
279
|
+
For the complete **SOURCE** → **TARGET** operator and CI sequence, including the required Component gate, plan artifact, and rollback procedure, see [the Job Template runbook](https://gitlab.com/revoengine/cli/-/blob/master/docs/runbooks/job-template-test-to-e2e.md). The commands in that runbook use TEST → E2E as a concrete example.
|
|
280
|
+
|
|
281
|
+
### Group migration
|
|
282
|
+
|
|
283
|
+
Groups use the same configured workspace and shared `.revoengine/revo.lock.json` as the other resource families. A Group manifest is stored below `<workspace>/Groups/` and contains only the portable name, category, description, user-owned metadata, and Stable Key. UUIDs, versions, members, user identifiers, member counts, leader, avatar, and access type are not persisted. The shared lock stores a `GROUP` owner only as another Group Stable Key. A source `USER` owner is recorded only as a manual-owner policy, never as a user UUID.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Establish Stable Keys on the source environment. Existing keys are preserved.
|
|
287
|
+
revo metadata plan --project test --resources group
|
|
288
|
+
revo metadata apply --project test --resources group --yes
|
|
289
|
+
|
|
290
|
+
# Pull portable source configuration and the TEST baseline.
|
|
291
|
+
revo groups pull --all --project test
|
|
292
|
+
|
|
293
|
+
# Compare the local desired state, E2E baseline, and live E2E Groups.
|
|
294
|
+
revo groups plan --all --project e2e
|
|
295
|
+
revo groups plan --all --project e2e --json
|
|
296
|
+
revo groups plan --all --project e2e --strict
|
|
297
|
+
|
|
298
|
+
# Apply after review. Push recomputes the live plan and never consumes plan JSON.
|
|
299
|
+
revo groups push --all --project e2e --yes
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`plan` reports missing `GROUP`-owned structures as `create` when the owner can be resolved on the target or created earlier in the same acyclic dependency graph. Missing source `USER`-owned structures are `manual-owner`: create them in the target UI with a target-local user owner and the exact source Stable Key, then run plan again. A same category/name target Group with a missing or different Stable Key is a blocking `collision`; the CLI never infers identity from its name.
|
|
303
|
+
|
|
304
|
+
`push` resolves every source `GROUP` owner by Stable Key to its target UUID immediately before POST or PUT. Create sends `members: []`. Updates synchronize a source `GROUP` owner relationship, but preserve a target-local owner when the source policy is `USER`. Member data is never hashed, compared, or sent. Target-only Groups remain `orphan` and are never deleted. Cyclic owner graphs cannot be created through the current single-Group API when the target has no bootstrap Group, so plan blocks them before any write. After an explicitly reviewed manual bootstrap creates both cycle members with temporary target-local owners and exact Stable Keys, plan reports owner drift and push safely closes the cycle with target Group UUIDs. An atomic/deferred-owner backend contract remains the preferred fully automatic solution.
|
|
305
|
+
|
|
306
|
+
For the complete **SOURCE** → **TARGET** operator flow, GitLab CI artifact
|
|
307
|
+
template, bootstrap procedure, and rollback, see [the Group runbook](https://gitlab.com/revoengine/cli/-/blob/master/docs/runbooks/group-source-to-target.md).
|
|
308
|
+
|
|
309
|
+
### Role-group migration
|
|
310
|
+
|
|
311
|
+
Role groups use the same lock-based `pull -> plan -> push` workflow as components. Generate stable keys on TEST first. Before deploying to another environment, copy the exact TEST `metadata.stableKey` to any matching role group that already exists there. Members and user UUIDs are always excluded.
|
|
312
|
+
|
|
313
|
+
Role-group manifests are committed below `RoleGroups/` in the workspace configured by `revo project init`. For a project configured with `workspace: "backend"`, the files live below `backend/RoleGroups/`. Sync baselines live in the shared `.revoengine/revo.lock.json`; TEST, E2E and PROD hashes are isolated by environment name. Role-group lock entries contain no UUID or version.
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Bootstrap missing role-group stable keys on the source environment.
|
|
317
|
+
revo metadata plan --project test --resources role-group
|
|
318
|
+
revo metadata apply --project test --resources role-group --yes
|
|
319
|
+
|
|
320
|
+
# Pull the portable desired state into the configured workspace.
|
|
321
|
+
revo role-groups pull --all --project test
|
|
322
|
+
|
|
323
|
+
# Preview E2E without changing files, lock, or the environment.
|
|
324
|
+
revo role-groups plan --all --project e2e
|
|
325
|
+
revo role-groups plan --all --project e2e --json
|
|
326
|
+
|
|
327
|
+
# Apply after review. Push recomputes the live plan and resolves target UUID/version.
|
|
328
|
+
revo role-groups push --all --project e2e --yes
|
|
329
|
+
|
|
330
|
+
# Verify convergence. Orphans and unrelated unmanaged groups remain untouched.
|
|
331
|
+
revo role-groups plan --all --project e2e --strict
|
|
86
332
|
```
|
|
87
333
|
|
|
88
|
-
|
|
334
|
+
`plan` performs a three-way comparison between the local manifest, the selected environment baseline in `revo.lock.json`, and the live target. It reports `clean`, `create`, `safe-update`, `remote-changed`, `conflict`, `missing-lock`, `orphan`, `collision`, and `skipped`. JSON output may be retained as a CI review artifact, but it is never accepted as push input.
|
|
335
|
+
|
|
336
|
+
`push` resolves the current target UUID by stableKey and reads the current target version immediately before mutation. A matching resource is updated in place even when its UUID differs from TEST. Base fields use the optimistic-version `PUT`; role relationships are synchronized separately through the backend `roleAdd` and `roleDelete` operations. `--force` may adopt or overwrite reviewed content drift, but never bypasses missing/duplicate stable keys, unknown system roles, or ambiguous identity. Prune is disabled until the backend soft-delete contract is confirmed. To roll back an update, restore the previous manifest commit, run plan again, and push that desired state.
|
|
337
|
+
|
|
338
|
+
Artifacts from the earlier experimental `resource` workflow under `.revoengine/resources`, `.revoengine/plans`, and `.revoengine/resources.lock.json` are ignored with a warning and are not removed automatically. The old `revo resource ...` command is no longer part of the CLI surface.
|
|
89
339
|
|
|
90
340
|
## Common commands
|
|
91
341
|
|
|
92
342
|
```bash
|
|
93
343
|
revo endpoints
|
|
94
|
-
revo project ./app
|
|
344
|
+
revo project init ./app
|
|
95
345
|
revo search CODE button
|
|
96
346
|
revo search SIMPLE customer
|
|
97
347
|
revo request GET /api/component/list
|
|
@@ -139,6 +389,22 @@ revo component push --all --yes
|
|
|
139
389
|
revo component push --all --force
|
|
140
390
|
```
|
|
141
391
|
|
|
392
|
+
For a migration from a saved source profile to another instance, use the same workspace workflow as Job Templates and Role Groups. Without `--project`, component commands use the active project. With `--project <name>`, they use that saved profile for one invocation and record a separate baseline under `components.<stableKey>.environments.<name>` in `.revoengine/revo.lock.json`. This profile-based workflow requires `componentIdentity.mode: "stableKey"` in `.revoengine/revo.json`; it refuses UUID-only identity so different instance UUIDs cannot be mistaken for missing components.
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# Pull TEST into the workspace and record the TEST baseline.
|
|
396
|
+
revo component pull --all --yes --project test
|
|
397
|
+
|
|
398
|
+
# Compare local source with live E2E and the E2E baseline.
|
|
399
|
+
revo component plan --all --project e2e
|
|
400
|
+
revo component plan --all --project e2e --json
|
|
401
|
+
|
|
402
|
+
# Create missing target components or safely update managed target components.
|
|
403
|
+
revo component push --all --yes --project e2e
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
The profile mode matches components by the configured stable key. It adopts an already identical target as the E2E baseline, creates a component missing from E2E, and blocks target drift without an E2E baseline. Commands targeting `default` retain their legacy lock behavior.
|
|
407
|
+
|
|
142
408
|
Debug one local component in sandbox:
|
|
143
409
|
|
|
144
410
|
```bash
|
|
@@ -148,6 +414,8 @@ revo component debug 6dfb536a-1111-4222-8333-123456789abc --timeout 30 --memory
|
|
|
148
414
|
revo component debug 6dfb536a-1111-4222-8333-123456789abc --stream
|
|
149
415
|
```
|
|
150
416
|
|
|
417
|
+
`--raw-debug` saves the full request and source map as a private file under the CLI config directory and prints only its path to stderr. Delete that file when the investigation is finished.
|
|
418
|
+
|
|
151
419
|
Pulled components are stored as a tree:
|
|
152
420
|
|
|
153
421
|
```text
|
|
@@ -187,20 +455,27 @@ Bulk sync behavior:
|
|
|
187
455
|
- Sync logs show direction explicitly: `RevoEngine -> path` for pull and `RevoEngine <- path` for push.
|
|
188
456
|
- Bulk runs print a summary such as `Deployed 54/67, Skipped 13/67 in 13s`.
|
|
189
457
|
|
|
190
|
-
##
|
|
458
|
+
## Projects
|
|
191
459
|
|
|
192
|
-
Save named
|
|
460
|
+
Save named project connections and switch the active one for ordinary CLI commands. `revo project init` configures the local workspace:
|
|
193
461
|
|
|
194
462
|
```bash
|
|
195
|
-
revo
|
|
196
|
-
revo
|
|
197
|
-
revo
|
|
198
|
-
revo
|
|
463
|
+
revo projects add develop --url https://api.dev.revong.com
|
|
464
|
+
revo projects add e2e --url https://api.e2e.revong.com
|
|
465
|
+
revo projects add prod --url https://app.revo.com
|
|
466
|
+
revo projects list
|
|
467
|
+
revo projects set develop
|
|
468
|
+
revo auth status
|
|
469
|
+
revo endpoints
|
|
470
|
+
revo projects set default
|
|
471
|
+
revo projects remove e2e
|
|
199
472
|
```
|
|
200
473
|
|
|
201
|
-
`revo
|
|
474
|
+
`revo projects add` prompts for the API key, validates it against `/api/v1/me`, asks whether it is production, saves it, and makes it active. Use `--offline` to skip validation. `revo projects list` marks the active connection with `*`; `revo -i` and `revo auth status` show its name and API URL. `revo projects set <name>` switches the persistent default for subsequent commands. `revo projects set default` selects the original `revo auth login` credentials. An explicit `--project <name>` selects one profile for a single invocation without changing the active project. `--env` and `revo env` remain supported as compatibility aliases. Named profiles keep their own URL, key, and instance even when `REVO_URL`, `REVO_TOKEN`, or `REVO_INSTANCE` is set. Removing the active profile returns to `default`.
|
|
202
475
|
|
|
203
|
-
|
|
476
|
+
`revo auth logout` clears only the original default login and keeps named project profiles and the active selection. Resource sync commands use the active named profile when `--project` is omitted; their existing requirement for a named profile remains. A production profile (stored as `"production": true` in `config.json`) requires an interactive confirmation before the first POST, PUT, PATCH, or DELETE in every CLI invocation. This protection cannot be bypassed with `--yes`, `--force`, or non-interactive CI.
|
|
477
|
+
|
|
478
|
+
Cross-environment component operations remain available as advanced commands:
|
|
204
479
|
|
|
205
480
|
```bash
|
|
206
481
|
revo env diff --from develop --to e2e
|
|
@@ -256,35 +531,35 @@ This writes `.revoengine/revo.json` with:
|
|
|
256
531
|
2. Save environment profiles:
|
|
257
532
|
|
|
258
533
|
```bash
|
|
259
|
-
revo
|
|
260
|
-
revo
|
|
261
|
-
revo
|
|
534
|
+
revo projects add test --url https://api.test.revong.com
|
|
535
|
+
revo projects add dev --url https://api.dev.revong.com
|
|
536
|
+
revo projects list
|
|
262
537
|
```
|
|
263
538
|
|
|
264
539
|
For one-off commands without a saved profile, use `default` plus environment variables:
|
|
265
540
|
|
|
266
541
|
```bash
|
|
267
|
-
REVO_URL="https://api.dev.revong.com" REVO_TOKEN="$REVO_DEV_TOKEN" revo metadata plan --
|
|
542
|
+
REVO_URL="https://api.dev.revong.com" REVO_TOKEN="$REVO_DEV_TOKEN" revo metadata plan --project default
|
|
268
543
|
```
|
|
269
544
|
|
|
270
545
|
3. Plan metadata backfill before writing anything:
|
|
271
546
|
|
|
272
547
|
```bash
|
|
273
|
-
revo metadata plan --
|
|
274
|
-
revo metadata plan --
|
|
548
|
+
revo metadata plan --project test
|
|
549
|
+
revo metadata plan --project dev
|
|
275
550
|
```
|
|
276
551
|
|
|
277
552
|
Use JSON when reviewing exact resources:
|
|
278
553
|
|
|
279
554
|
```bash
|
|
280
|
-
revo metadata plan --
|
|
555
|
+
revo metadata plan --project test --json
|
|
281
556
|
```
|
|
282
557
|
|
|
283
558
|
4. Apply metadata backfill:
|
|
284
559
|
|
|
285
560
|
```bash
|
|
286
|
-
revo metadata apply --
|
|
287
|
-
revo metadata apply --
|
|
561
|
+
revo metadata apply --project test --yes
|
|
562
|
+
revo metadata apply --project dev --yes
|
|
288
563
|
```
|
|
289
564
|
|
|
290
565
|
Important: if the same resources already exist in multiple environments, do not treat independently generated random suffixes as interchangeable. `category/name#aaaa1111` and `category/name#bbbb2222` are different stable keys, even when the readable prefix matches. Pick a source of truth and make the target environment use the exact same metadata value, including casing, before running destructive sync.
|
|
@@ -292,14 +567,14 @@ Important: if the same resources already exist in multiple environments, do not
|
|
|
292
567
|
5. Verify metadata backfill:
|
|
293
568
|
|
|
294
569
|
```bash
|
|
295
|
-
revo metadata plan --
|
|
296
|
-
revo metadata plan --
|
|
570
|
+
revo metadata plan --project test
|
|
571
|
+
revo metadata plan --project dev
|
|
297
572
|
```
|
|
298
573
|
|
|
299
574
|
Expected after a successful backfill:
|
|
300
575
|
|
|
301
576
|
```text
|
|
302
|
-
Plan: 0 to update, N already populated.
|
|
577
|
+
Plan: 0 to update, N already populated, 0 blocked.
|
|
303
578
|
```
|
|
304
579
|
|
|
305
580
|
6. Preview environment drift:
|
|
@@ -336,14 +611,15 @@ Only use `--prune --force` after reviewing the plan. It deletes target resources
|
|
|
336
611
|
|
|
337
612
|
## Configuration
|
|
338
613
|
|
|
339
|
-
The CLI
|
|
614
|
+
The CLI selects a project from `--project <name>` or the active project. For a named project, it uses that project's URL, key, and instance; explicit `--url`, `--token`, and `--instance` flags can override individual values. Named projects do not inherit values from environment variables or the `default` login.
|
|
615
|
+
|
|
616
|
+
For `default`, the CLI reads configuration in this order:
|
|
340
617
|
|
|
341
618
|
1. CLI flags such as `--url` and `--token`
|
|
342
|
-
2.
|
|
343
|
-
3.
|
|
344
|
-
4. Stored config in the OS config directory
|
|
619
|
+
2. Environment variables such as `REVO_URL` and `REVO_TOKEN`
|
|
620
|
+
3. Stored config in the OS config directory
|
|
345
621
|
|
|
346
|
-
This means environment variables override the locally stored config, which
|
|
622
|
+
This means environment variables override the locally stored `default` config, which supports CI and non-interactive automation.
|
|
347
623
|
|
|
348
624
|
Use `--url` for one-off local or dedicated API targets:
|
|
349
625
|
|
|
@@ -372,9 +648,12 @@ Supported environment variables:
|
|
|
372
648
|
- `REVO_URL` or `REVO_BASE_URL`
|
|
373
649
|
- `REVO_TOKEN` or `REVO_API_KEY`
|
|
374
650
|
- `REVO_NO_UPDATE_NOTIFIER`
|
|
651
|
+
- `REVO_TRUSTED_SERVICE_ORIGINS` (comma-separated exact HTTPS origins for custom sandbox services)
|
|
375
652
|
- `REVOENGINE_URL` or `REVOENGINE_BASE_URL`
|
|
376
653
|
- `REVOENGINE_TOKEN` or `REVOENGINE_API_KEY`
|
|
377
654
|
|
|
655
|
+
Authenticated API requests reject cross-origin pagination links and redirects. The sandbox service advertised by the authenticated profile may use a different origin: matching first-party API/sandbox hosts and `localhost` services are trusted automatically. For a custom sandbox, set `REVO_TRUSTED_SERVICE_ORIGINS` to its exact origin before running editor-type update or component debug. Do not include a path or credentials in this setting.
|
|
656
|
+
|
|
378
657
|
Example for CI:
|
|
379
658
|
|
|
380
659
|
```bash
|
package/dist/src/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { realpathSync } from 'node:fs';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
3
|
import { RevoClient } from "./client.js";
|
|
4
|
-
import {
|
|
5
|
-
import { handleAuthCommand, handleComponentCommand, handleEndpointsCommand, handleEnvCommand, handleInfoCommand, handleMetadataCommand, handleProjectCommand, handleRequestCommand, handleSearchCommand, } from "./commands/index.js";
|
|
4
|
+
import { getActiveEnvironmentName } from "./config.js";
|
|
5
|
+
import { handleAuthCommand, handleComponentCommand, handleDatabaseSchemasCommand, handleDatabaseViewsCommand, handleEndpointsCommand, handleEnvCommand, handleEventsCommand, handleGroupsCommand, handleInfoCommand, handleJobTemplatesCommand, handleMetadataCommand, handleProjectCommand, handleRequestCommand, handleRoleGroupsCommand, handleSearchCommand, handleSchedulesCommand, handleTerminalCommand, } from "./commands/index.js";
|
|
6
6
|
import { buildRuntimeViewModel } from "./runtime-view.js";
|
|
7
7
|
import { renderHelp, renderOverview } from "./ui.js";
|
|
8
8
|
import { maybeNotifyUpdateAvailable } from "./update-notifier.js";
|
|
@@ -136,23 +136,36 @@ function printError(error) {
|
|
|
136
136
|
process.stderr.write(`${danger('Error:')} ${message}\n`);
|
|
137
137
|
}
|
|
138
138
|
function resolveClient(args) {
|
|
139
|
-
|
|
139
|
+
return new RevoClient({
|
|
140
140
|
baseUrl: typeof args.url === 'string' ? args.url : typeof args.baseUrl === 'string' ? args.baseUrl : undefined,
|
|
141
141
|
instance: typeof args.instance === 'string' ? args.instance : typeof args.i === 'string' ? args.i : undefined,
|
|
142
142
|
token: typeof args.token === 'string' ? args.token : typeof args.t === 'string' ? args.t : undefined,
|
|
143
|
+
envName: typeof args.env === 'string' ? args.env : undefined,
|
|
143
144
|
});
|
|
144
|
-
return new RevoClient(runtime);
|
|
145
145
|
}
|
|
146
146
|
function createContext(args) {
|
|
147
|
-
|
|
147
|
+
if (args.project !== undefined && args.env !== undefined) {
|
|
148
|
+
throw new Error('Use either --project or --env, not both.');
|
|
149
|
+
}
|
|
150
|
+
if (args.project !== undefined && (typeof args.project !== 'string' || !args.project.trim())) {
|
|
151
|
+
throw new Error('--project requires a saved project name.');
|
|
152
|
+
}
|
|
153
|
+
const active = getActiveEnvironmentName();
|
|
154
|
+
const selectedProject = args.project === undefined ? args.env : args.project;
|
|
155
|
+
const effectiveArgs = selectedProject === undefined && active !== 'default'
|
|
156
|
+
? { ...args, env: active }
|
|
157
|
+
: args.project !== undefined ? { ...args, env: selectedProject } : args;
|
|
158
|
+
const client = resolveClient(effectiveArgs);
|
|
148
159
|
return {
|
|
149
|
-
args,
|
|
160
|
+
args: effectiveArgs,
|
|
150
161
|
client,
|
|
162
|
+
componentEnvironment: typeof effectiveArgs.env === 'string' ? effectiveArgs.env : undefined,
|
|
151
163
|
cwd: process.cwd(),
|
|
152
164
|
packageVersion,
|
|
153
165
|
print,
|
|
154
166
|
println,
|
|
155
167
|
error: (message) => printError(new Error(message)),
|
|
168
|
+
warn: (message) => process.stderr.write(`Warning: ${message}\n`),
|
|
156
169
|
};
|
|
157
170
|
}
|
|
158
171
|
function printHelp() {
|
|
@@ -188,22 +201,48 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
188
201
|
await handleAuthCommand(context);
|
|
189
202
|
return;
|
|
190
203
|
}
|
|
204
|
+
if (command === 'terminal') {
|
|
205
|
+
const terminalIndex = argv.indexOf('terminal');
|
|
206
|
+
const terminalArgs = argv.slice(terminalIndex + 1);
|
|
207
|
+
const action = args._[1] || 'help';
|
|
208
|
+
const actionIndex = terminalArgs.indexOf(action);
|
|
209
|
+
if (actionIndex >= 0)
|
|
210
|
+
terminalArgs.splice(actionIndex, 1);
|
|
211
|
+
await handleTerminalCommand([action, ...argv.slice(0, terminalIndex), ...terminalArgs]);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
191
214
|
if (command === 'component') {
|
|
192
215
|
await handleComponentCommand(context);
|
|
193
216
|
return;
|
|
194
217
|
}
|
|
218
|
+
if (command === 'database-schemas') {
|
|
219
|
+
await handleDatabaseSchemasCommand(context);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (command === 'database-views') {
|
|
223
|
+
await handleDatabaseViewsCommand(context);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
195
226
|
if (command === 'endpoints') {
|
|
196
227
|
await handleEndpointsCommand(context);
|
|
197
228
|
return;
|
|
198
229
|
}
|
|
199
|
-
if (command === 'env') {
|
|
230
|
+
if (command === 'projects' || command === 'env') {
|
|
200
231
|
await handleEnvCommand(context);
|
|
201
232
|
return;
|
|
202
233
|
}
|
|
234
|
+
if (command === 'events') {
|
|
235
|
+
await handleEventsCommand(context);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
203
238
|
if (command === 'metadata') {
|
|
204
239
|
await handleMetadataCommand(context);
|
|
205
240
|
return;
|
|
206
241
|
}
|
|
242
|
+
if (command === 'job-templates') {
|
|
243
|
+
await handleJobTemplatesCommand(context);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
207
246
|
if (command === 'project') {
|
|
208
247
|
await handleProjectCommand(context);
|
|
209
248
|
return;
|
|
@@ -216,6 +255,18 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
216
255
|
await handleRequestCommand(context);
|
|
217
256
|
return;
|
|
218
257
|
}
|
|
258
|
+
if (command === 'role-groups') {
|
|
259
|
+
await handleRoleGroupsCommand(context);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (command === 'groups') {
|
|
263
|
+
await handleGroupsCommand(context);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (command === 'schedules') {
|
|
267
|
+
await handleSchedulesCommand(context);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
219
270
|
throw new Error(`Unknown command: ${command}`);
|
|
220
271
|
}
|
|
221
272
|
if (isDirectExecution()) {
|