@revoengine/cli 1.0.9 → 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 +464 -8
- package/dist/src/cli.js +65 -6
- package/dist/src/client.d.ts +366 -5
- package/dist/src/client.js +954 -13
- package/dist/src/commands/auth.js +4 -2
- package/dist/src/commands/component.js +839 -412
- 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.d.ts +2 -0
- package/dist/src/commands/env.js +380 -0
- 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 +10 -0
- package/dist/src/commands/index.js +10 -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.d.ts +2 -0
- package/dist/src/commands/metadata.js +159 -0
- package/dist/src/commands/project.js +82 -1
- 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 +126 -2
- package/dist/src/component-lock.js +378 -15
- package/dist/src/config.d.ts +20 -0
- package/dist/src/config.js +121 -6
- 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 +83 -0
- package/dist/src/env-sync.js +315 -0
- package/dist/src/metadata-backfill.d.ts +56 -0
- package/dist/src/metadata-backfill.js +1176 -0
- package/dist/src/project.d.ts +17 -9
- package/dist/src/project.js +87 -11
- package/dist/src/prompt.js +10 -18
- package/dist/src/resource-metadata.d.ts +25 -0
- package/dist/src/resource-metadata.js +132 -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 +7 -0
- package/dist/src/tracked-resources.js +61 -0
- package/dist/src/types.d.ts +227 -0
- package/dist/src/ui.d.ts +3 -0
- package/dist/src/ui.js +68 -10
- 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/dist/src/ui.js
CHANGED
|
@@ -94,28 +94,80 @@ function renderCommandCatalog() {
|
|
|
94
94
|
` ${formatCommand(`${CLI_NAME} <command> [arguments] [options]`)}`,
|
|
95
95
|
'',
|
|
96
96
|
paintHeader('Global Options'),
|
|
97
|
+
commandRow('--project <name>', 'Use one saved project for this command'),
|
|
97
98
|
commandRow('--url <url>', 'Override API base URL for TEST, prod, local, or dedicated tenants'),
|
|
98
99
|
commandRow('--token <apiKey>', 'Override API key for non-interactive runs'),
|
|
99
100
|
commandRow('--no-update-notifier', 'Disable npm version update checks for this run'),
|
|
100
101
|
'',
|
|
101
|
-
paintHeader('
|
|
102
|
+
paintHeader('Projects'),
|
|
102
103
|
commandRow('revo -i', 'Show runtime info, config path, and auth state'),
|
|
104
|
+
commandRow('revo projects add <name> [--url <url>] [--token <apiKey>]', 'Save and activate a project'),
|
|
105
|
+
commandRow('revo projects list [--json]', 'List projects and mark the active one'),
|
|
106
|
+
commandRow('revo projects set <name>', 'Switch the active project; use default for the original login'),
|
|
107
|
+
commandRow('revo projects remove <name>', 'Remove a saved project'),
|
|
108
|
+
'',
|
|
109
|
+
paintHeader('Authentication'),
|
|
103
110
|
commandRow('revo auth login', 'Paste API key in the terminal'),
|
|
104
111
|
commandRow('revo auth status', 'Show the current authentication status'),
|
|
105
112
|
commandRow('revo auth logout', 'Remove stored credentials'),
|
|
106
|
-
|
|
113
|
+
'',
|
|
114
|
+
paintHeader('Workspace'),
|
|
115
|
+
commandRow('revo project init [path] [--identity-mode <stableKey|componentId>] [--stable-key-name <name>] [--resources <list>]', 'Initialize local workspace config and editor types'),
|
|
107
116
|
commandRow('revo project update [path]', 'Refresh editor types and project metadata'),
|
|
108
|
-
|
|
117
|
+
'',
|
|
118
|
+
paintHeader('Terminal'),
|
|
119
|
+
commandRow('revo terminal connect --workspace <path> --name <name>', 'Pair and run a local terminal'),
|
|
120
|
+
commandRow('revo terminal service install --workspace <path>', 'Run an approved terminal in the background on macOS or Linux'),
|
|
121
|
+
commandRow('revo terminal service uninstall --workspace <path>', 'Stop and remove the background service'),
|
|
122
|
+
commandRow('revo terminal status', 'Show terminal grants'),
|
|
123
|
+
commandRow('revo terminal disconnect --workspace <path>', 'Revoke a local terminal grant'),
|
|
109
124
|
'',
|
|
110
125
|
paintHeader('Components'),
|
|
111
|
-
commandRow('revo component plan --all [--json] [--strict] [--changed --base <ref>]', 'Preview local/remote sync status'),
|
|
112
|
-
commandRow('revo component pull <
|
|
113
|
-
commandRow('revo component pull --all [--yes] [--force]', 'Pull every available component safely'),
|
|
114
|
-
commandRow('revo component push <
|
|
115
|
-
commandRow('revo component push --all [--yes] [--force] [--changed --base <ref>]', 'Push local components with lock checks'),
|
|
126
|
+
commandRow('revo component plan --all [--project <name>] [--json] [--strict] [--changed --base <ref>]', 'Preview local/remote sync status'),
|
|
127
|
+
commandRow('revo component pull <identity...> [--project <name>] [--force]', 'Pull by configured stable key or component ID'),
|
|
128
|
+
commandRow('revo component pull --all [--project <name>] [--yes] [--force]', 'Pull every available component safely'),
|
|
129
|
+
commandRow('revo component push <identity...> [--project <name>]', 'Push by configured stable key or component ID'),
|
|
130
|
+
commandRow('revo component push --all [--project <name>] [--yes] [--force] [--changed --base <ref>]', 'Push local components with lock checks'),
|
|
116
131
|
commandRow('revo component debug <componentId> [BODY] [--stream] [--raw-debug]', 'Debug one local component against sandbox'),
|
|
117
132
|
'',
|
|
118
|
-
paintHeader('
|
|
133
|
+
paintHeader('Databases'),
|
|
134
|
+
commandRow('revo database-schemas pull --all [--project <name>] [--force] [--strict]', 'Pull portable Database Schemas and partitions'),
|
|
135
|
+
commandRow('revo database-schemas plan --all [--project <name>] [--with-stats] [--json] [--strict]', 'Preview schema drift, DDL risks, partitions, and performance hints'),
|
|
136
|
+
commandRow('revo database-schemas push <stableKey>|--all [--project <name>] --yes [--force] [--prune-partitions]', 'Create, safely update, or explicitly prune managed partitions'),
|
|
137
|
+
commandRow('revo database-views pull --all [--project <name>] [--force] [--strict]', 'Pull portable STRUCTURED and RAW_SQL Database Views after Database Schema convergence'),
|
|
138
|
+
commandRow('revo database-views plan --all [--project <name>] [--json] [--strict]', 'Preview Database View drift, source readiness, and target compilation'),
|
|
139
|
+
commandRow('revo database-views push <stableKey>|--all [--project <name>] --yes [--force] [--allow-materialized]', 'Create or update Database Views after live preview'),
|
|
140
|
+
'',
|
|
141
|
+
paintHeader('Endpoints'),
|
|
142
|
+
commandRow('revo endpoints', 'List available API endpoints'),
|
|
143
|
+
commandRow('revo endpoints pull --all [--project <name>] [--force]', 'Pull managed endpoints into the configured workspace'),
|
|
144
|
+
commandRow('revo endpoints plan --all [--project <name>] [--json] [--strict]', 'Preview Endpoint state and Component compatibility'),
|
|
145
|
+
commandRow('revo endpoints push --all [--project <name>] [--yes] [--force]', 'Deploy and verify managed endpoints'),
|
|
146
|
+
'',
|
|
147
|
+
paintHeader('Access'),
|
|
148
|
+
commandRow('revo role-groups pull --all [--project <name>] [--force]', 'Pull managed role groups into the configured workspace'),
|
|
149
|
+
commandRow('revo role-groups plan --all [--project <name>] [--json] [--strict]', 'Preview workspace, lock, and live target state'),
|
|
150
|
+
commandRow('revo role-groups push --all [--project <name>] [--yes] [--force]', 'Push role groups with live stable-key and lock checks'),
|
|
151
|
+
commandRow('revo groups pull --all [--project <name>] [--force]', 'Pull managed groups into the configured workspace'),
|
|
152
|
+
commandRow('revo groups plan --all [--project <name>] [--json] [--strict]', 'Preview workspace, lock, and live target state'),
|
|
153
|
+
commandRow('revo groups push --all [--project <name>] [--yes] [--force]', 'Push portable group structures with live owner resolution'),
|
|
154
|
+
'',
|
|
155
|
+
paintHeader('Automation'),
|
|
156
|
+
commandRow('revo job-templates pull --all [--project <name>] [--force]', 'Pull portable job templates into the configured workspace'),
|
|
157
|
+
commandRow('revo job-templates plan --all [--project <name>] [--json] [--strict]', 'Preview workspace, lock, dependencies, and live target state'),
|
|
158
|
+
commandRow('revo job-templates push --all [--project <name>] --yes [--force] [--json]', 'Create or safely update job templates with live lock checks'),
|
|
159
|
+
commandRow('revo schedules pull --all [--project <name>] [--force]', 'Pull Job Template and Materialized View schedules into the configured workspace'),
|
|
160
|
+
commandRow('revo schedules plan --all [--project <name>] [--json] [--strict]', 'Preview workspace, lock, target schedules, and portable dependencies'),
|
|
161
|
+
commandRow('revo schedules push --all [--project <name>] --yes [--force] [--allow-materialized] [--activate] [--json]', 'Create or safely update disabled-by-default Schedule definitions'),
|
|
162
|
+
commandRow('revo events pull --all [--project <name>] [--force] [--json]', 'Pull portable Job Template Event definitions into the configured workspace'),
|
|
163
|
+
commandRow('revo events plan --all [--project <name>] [--json] [--strict]', 'Preview Event manifests, lock baselines, target state, and Job Template dependencies'),
|
|
164
|
+
commandRow('revo events push --all [--project <name>] --yes [--force] [--activate] [--json]', 'Create or safely update disabled-by-default Event definitions'),
|
|
165
|
+
'',
|
|
166
|
+
paintHeader('Advanced'),
|
|
167
|
+
commandRow('revo env diff --from <env> --to <env> [--prune] [--json] [--strict]', 'Compare components across two projects'),
|
|
168
|
+
commandRow('revo env apply --from <env> --to <env> [--yes] [--prune] [--force]', 'Mirror components from one project into another'),
|
|
169
|
+
commandRow('revo metadata plan [--project <name>] [--skip-partitions] [--json]', 'Preview stable-key metadata backfill'),
|
|
170
|
+
commandRow('revo metadata apply [--project <name>] --yes [--skip-partitions]', 'Populate missing stable-key metadata'),
|
|
119
171
|
commandRow('revo search <CODE|SIMPLE> <term>', 'Search code references or all platform content'),
|
|
120
172
|
commandRow('revo request <METHOD> <PATH> [BODY]', 'Make a raw API request with optional JSON body'),
|
|
121
173
|
].join('\n');
|
|
@@ -142,8 +194,11 @@ export function renderHelp(version) {
|
|
|
142
194
|
}
|
|
143
195
|
export function renderRuntimeInfo(input) {
|
|
144
196
|
const { auth, configDir, nodeVersion, packageVersion, runtime } = input;
|
|
197
|
+
const environmentName = input.environmentName || 'default';
|
|
145
198
|
const onboardingWarning = auth.status === 'not_authenticated'
|
|
146
|
-
? paintWarning(
|
|
199
|
+
? paintWarning(environmentName === 'default'
|
|
200
|
+
? `Warning: Start onboarding with ${CLI_NAME} auth login`
|
|
201
|
+
: `Warning: Check the API key for project "${environmentName}"`)
|
|
147
202
|
: '';
|
|
148
203
|
return [
|
|
149
204
|
renderBanner(packageVersion),
|
|
@@ -152,11 +207,13 @@ export function renderRuntimeInfo(input) {
|
|
|
152
207
|
paintHeader('Runtime'),
|
|
153
208
|
row('Node', nodeVersion),
|
|
154
209
|
row('Config', configDir),
|
|
210
|
+
row('Project', environmentName),
|
|
155
211
|
row('Base URL', runtime.baseUrl),
|
|
156
212
|
row('Status', formatStatusValue(auth)),
|
|
157
213
|
...(shouldRenderValidationRow(auth) ? [row('Validation', auth.validation || 'skipped')] : []),
|
|
158
214
|
'',
|
|
159
215
|
paintHeader('Tips'),
|
|
216
|
+
commandRow('revo projects list', 'See and switch projects'),
|
|
160
217
|
commandRow('revo auth login', 'Save credentials interactively'),
|
|
161
218
|
commandRow('revo --help', 'Show the command reference'),
|
|
162
219
|
].join('\n');
|
|
@@ -167,6 +224,7 @@ export function renderAuthStatus(input) {
|
|
|
167
224
|
paintHeader('Auth Status'),
|
|
168
225
|
row('Status', formatStatusValue(auth)),
|
|
169
226
|
row('Config', configDir),
|
|
227
|
+
row('Project', input.environmentName || 'default'),
|
|
170
228
|
row('Base URL', runtime.baseUrl),
|
|
171
229
|
row('API key', runtime.token ? 'configured' : 'missing'),
|
|
172
230
|
...(shouldRenderValidationRow(auth) ? [row('Validation', auth.validation || 'skipped')] : []),
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare function readBoolFlag(args: ParsedArgs, names: string[]): boolean
|
|
|
4
4
|
export declare function readValues(args: ParsedArgs, names: string[]): string[];
|
|
5
5
|
export declare function toArray(value: string | string[] | undefined): string[];
|
|
6
6
|
export declare function sanitizeSegment(value: string): string;
|
|
7
|
+
export declare function normalizeCron(value: string): string;
|
|
8
|
+
export declare function isValidNormalizedCron(value: string): boolean;
|
|
7
9
|
export declare function readJsonFile(filePath: string): any;
|
|
8
10
|
export declare function writeJsonFile(filePath: string, data: unknown): void;
|
|
9
11
|
export declare function deepClone<T>(value: T): T;
|
package/dist/src/utils.js
CHANGED
|
@@ -51,6 +51,70 @@ export function sanitizeSegment(value) {
|
|
|
51
51
|
.replace(/\s+/g, '_');
|
|
52
52
|
return normalized.length > 0 ? normalized : 'untitled';
|
|
53
53
|
}
|
|
54
|
+
const CRON_MONTH_ALIASES = {
|
|
55
|
+
JAN: 1,
|
|
56
|
+
FEB: 2,
|
|
57
|
+
MAR: 3,
|
|
58
|
+
APR: 4,
|
|
59
|
+
MAY: 5,
|
|
60
|
+
JUN: 6,
|
|
61
|
+
JUL: 7,
|
|
62
|
+
AUG: 8,
|
|
63
|
+
SEP: 9,
|
|
64
|
+
OCT: 10,
|
|
65
|
+
NOV: 11,
|
|
66
|
+
DEC: 12,
|
|
67
|
+
};
|
|
68
|
+
const CRON_DAY_ALIASES = {
|
|
69
|
+
SUN: 0,
|
|
70
|
+
MON: 1,
|
|
71
|
+
TUE: 2,
|
|
72
|
+
WED: 3,
|
|
73
|
+
THU: 4,
|
|
74
|
+
FRI: 5,
|
|
75
|
+
SAT: 6,
|
|
76
|
+
};
|
|
77
|
+
export function normalizeCron(value) {
|
|
78
|
+
return value.trim().replace(/\s+/g, ' ');
|
|
79
|
+
}
|
|
80
|
+
function cronFieldIsValid(field, min, max, aliases = {}) {
|
|
81
|
+
return field.split(',').every((part) => {
|
|
82
|
+
if (part === '*') {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
const [rangePart, step, ...extraStepParts] = part.split('/');
|
|
86
|
+
if (extraStepParts.length > 0 || !rangePart || (step !== undefined && (!/^\d+$/.test(step) || Number(step) <= 0))) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (rangePart === '*') {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
const rangeMatch = rangePart.match(/^([A-Z0-9]+)(-([A-Z0-9]+))?$/i);
|
|
93
|
+
if (!rangeMatch) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const startRaw = rangeMatch[1].toUpperCase();
|
|
97
|
+
const endRaw = rangeMatch[3] ? rangeMatch[3].toUpperCase() : startRaw;
|
|
98
|
+
const start = aliases[startRaw] ?? Number(startRaw);
|
|
99
|
+
const end = aliases[endRaw] ?? Number(endRaw);
|
|
100
|
+
return Number.isInteger(start) && Number.isInteger(end)
|
|
101
|
+
&& start >= min && end <= max && start <= end;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
export function isValidNormalizedCron(value) {
|
|
105
|
+
if (value !== normalizeCron(value)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const fields = value.split(' ');
|
|
109
|
+
if (fields.length !== 5) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return cronFieldIsValid(fields[0], 0, 59)
|
|
113
|
+
&& cronFieldIsValid(fields[1], 0, 23)
|
|
114
|
+
&& cronFieldIsValid(fields[2], 1, 31)
|
|
115
|
+
&& cronFieldIsValid(fields[3], 1, 12, CRON_MONTH_ALIASES)
|
|
116
|
+
&& cronFieldIsValid(fields[4], 0, 6, CRON_DAY_ALIASES);
|
|
117
|
+
}
|
|
54
118
|
export function readJsonFile(filePath) {
|
|
55
119
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
56
120
|
return raw.trim() ? JSON.parse(raw) : {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function hydrateWorkspaceComponentElementDetails(manifestPath, component, preferredExtension) {
|
|
4
|
+
const componentDirectory = path.dirname(manifestPath);
|
|
5
|
+
const detailDirectories = [
|
|
6
|
+
path.join(componentDirectory, 'elements'),
|
|
7
|
+
path.join(componentDirectory, 'details'),
|
|
8
|
+
];
|
|
9
|
+
return {
|
|
10
|
+
...component,
|
|
11
|
+
elements: (component.elements || []).map((element) => {
|
|
12
|
+
let details = typeof element.details === 'string' ? element.details : '';
|
|
13
|
+
for (const detailDirectory of detailDirectories) {
|
|
14
|
+
if (!fs.existsSync(detailDirectory)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const preferredPath = preferredExtension
|
|
18
|
+
? path.join(detailDirectory, `${element.order}_${element.key}.${preferredExtension}`)
|
|
19
|
+
: '';
|
|
20
|
+
if (preferredPath && fs.existsSync(preferredPath)) {
|
|
21
|
+
details = fs.readFileSync(preferredPath, 'utf8');
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
const prefix = `${element.order}_${element.key}.`;
|
|
25
|
+
const detailFile = fs.readdirSync(detailDirectory).sort().find((entry) => entry.startsWith(prefix));
|
|
26
|
+
if (detailFile) {
|
|
27
|
+
details = fs.readFileSync(path.join(detailDirectory, detailFile), 'utf8');
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { ...element, details };
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/** Replace one resource directory only after its replacement is fully written. */
|
|
4
|
+
export function replaceWorkspaceResourceDirectory(root, directory, populate) {
|
|
5
|
+
const resolvedRoot = path.resolve(root);
|
|
6
|
+
const resolvedDirectory = path.resolve(directory);
|
|
7
|
+
const relative = path.relative(resolvedRoot, resolvedDirectory);
|
|
8
|
+
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
9
|
+
throw new Error(`Resource directory must be inside workspace root: ${directory}`);
|
|
10
|
+
}
|
|
11
|
+
// Never replace a symlink or write through a symlink in the selected path.
|
|
12
|
+
for (let current = resolvedDirectory;; current = path.dirname(current)) {
|
|
13
|
+
if (fs.lstatSync(current, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
14
|
+
throw new Error(`Cannot replace a resource through a symbolic link: ${current}`);
|
|
15
|
+
}
|
|
16
|
+
if (current === resolvedRoot) {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const parent = path.dirname(resolvedDirectory);
|
|
21
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
22
|
+
const transaction = fs.mkdtempSync(path.join(parent, '.revo-pull-'));
|
|
23
|
+
const staged = path.join(transaction, 'new');
|
|
24
|
+
const backup = path.join(transaction, 'previous');
|
|
25
|
+
fs.mkdirSync(staged);
|
|
26
|
+
let backedUp = false;
|
|
27
|
+
let installed = false;
|
|
28
|
+
try {
|
|
29
|
+
populate(staged);
|
|
30
|
+
if (fs.existsSync(resolvedDirectory)) {
|
|
31
|
+
fs.renameSync(resolvedDirectory, backup);
|
|
32
|
+
backedUp = true;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
fs.renameSync(staged, resolvedDirectory);
|
|
36
|
+
installed = true;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (backedUp) {
|
|
40
|
+
fs.renameSync(backup, resolvedDirectory);
|
|
41
|
+
backedUp = false;
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
// Keep the backup if restoring the original directory itself failed.
|
|
48
|
+
if (installed || !backedUp) {
|
|
49
|
+
fs.rmSync(transaction, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revoengine/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "CLI package for the RevoEngine Platform API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"revoengine": "dist/bin/revo.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "tsc -p tsconfig.build.json",
|
|
13
|
-
"
|
|
12
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
13
|
+
"clean": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist', { recursive: true, force: true });\"",
|
|
14
|
+
"check": "node --input-type=module -e \"await import('./src/config.ts'); await import('./src/legacy.ts'); await import('./src/client.ts'); await import('./src/component-lock.ts'); await import('./src/resource-metadata.ts'); await import('./src/tracked-resources.ts'); await import('./src/metadata-backfill.ts'); await import('./src/workspace-component.ts'); await import('./src/workspace-resource.ts'); await import('./src/resource-syncs/database-schema-sync.ts'); await import('./src/resource-syncs/database-view-sync.ts'); await import('./src/resource-syncs/endpoint-sync.ts'); await import('./src/resource-syncs/group-sync.ts'); await import('./src/resource-syncs/role-group-sync.ts'); await import('./src/resource-syncs/job-template-sync.ts'); await import('./src/resource-syncs/schedule-sync.ts'); await import('./src/resource-syncs/event-sync.ts'); await import('./src/sync-output.ts'); await import('./src/ui.ts'); await import('./src/update-notifier.ts'); await import('./src/env-sync.ts'); await import('./src/commands/auth.ts'); await import('./src/commands/component.ts'); await import('./src/commands/database-schemas.ts'); await import('./src/commands/database-views.ts'); await import('./src/commands/endpoints.ts'); await import('./src/commands/env.ts'); await import('./src/commands/events.ts'); await import('./src/commands/groups.ts'); await import('./src/commands/info.ts'); await import('./src/commands/job-templates.ts'); await import('./src/commands/metadata.ts'); await import('./src/commands/request.ts'); await import('./src/commands/role-groups.ts'); await import('./src/commands/search.ts'); await import('./src/commands/schedules.ts'); await import('./src/commands/terminal-service.ts'); await import('./src/commands/terminal.ts'); await import('./src/cli.ts'); await import('./src/index.ts'); await import('./bin/revo.ts'); await import('./scripts/dev.ts')\"",
|
|
14
15
|
"dev": "node ./scripts/dev.ts",
|
|
15
16
|
"prepack": "npm run build",
|
|
16
17
|
"test": "node --test ./test/*.test.ts"
|
|
@@ -25,8 +26,12 @@
|
|
|
25
26
|
"node": ">=24"
|
|
26
27
|
},
|
|
27
28
|
"license": "MIT",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"ws": "^8.19.0"
|
|
31
|
+
},
|
|
28
32
|
"devDependencies": {
|
|
29
33
|
"@types/node": "^25.5.0",
|
|
34
|
+
"@types/ws": "^8.18.1",
|
|
30
35
|
"typescript": "^6.0.3"
|
|
31
36
|
}
|
|
32
37
|
}
|