@superblocksteam/cli 1.9.3 → 1.12.0
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/LICENSE.txt +87 -0
- package/README.md +6 -6
- package/assets/custom-components/setup/package.json +1 -1
- package/assets/custom-components/setup/tsconfig.json +0 -1
- package/assets/injectedReactShim17.jsx +15 -0
- package/assets/injectedReactShim18.jsx +16 -0
- package/assets/injectedReactShimShared.jsx +140 -0
- package/bin/dev +5 -7
- package/bin/run +1 -3
- package/dist/appendHotReloadEventPlugin.d.mts +2 -0
- package/dist/appendHotReloadEventPlugin.mjs +43 -0
- package/dist/commands/commits.d.mts +18 -0
- package/dist/commands/{commits.js → commits.mjs} +59 -67
- package/dist/commands/components/{create.d.ts → create.d.mts} +2 -2
- package/dist/commands/components/{create.js → create.mjs} +84 -93
- package/dist/commands/components/{register.d.ts → register.d.mts} +1 -1
- package/dist/commands/components/register.mjs +12 -0
- package/dist/commands/components/{upload.d.ts → upload.d.mts} +2 -2
- package/dist/commands/components/{upload.js → upload.mjs} +39 -43
- package/dist/commands/components/{watch.d.ts → watch.d.mts} +1 -1
- package/dist/commands/components/{watch.js → watch.mjs} +29 -36
- package/dist/commands/config/{set.d.ts → set.d.mts} +2 -2
- package/dist/commands/config/{set.js → set.mjs} +28 -32
- package/dist/commands/{init.d.ts → init.d.mts} +4 -4
- package/dist/commands/{init.js → init.mjs} +63 -65
- package/dist/commands/{login.d.ts → login.d.mts} +1 -1
- package/dist/commands/login.mjs +55 -0
- package/dist/commands/{migrate.d.ts → migrate.d.mts} +1 -1
- package/dist/commands/{migrate.js → migrate.mjs} +38 -46
- package/dist/commands/pull.d.mts +17 -0
- package/dist/commands/{pull.js → pull.mjs} +74 -80
- package/dist/commands/push.d.mts +15 -0
- package/dist/commands/{push.js → push.mjs} +81 -90
- package/dist/commands/{rm.d.ts → rm.d.mts} +2 -2
- package/dist/commands/{rm.js → rm.mjs} +34 -40
- package/dist/common/{authenticated-command.js → authenticated-command.mjs} +65 -75
- package/dist/common/defaults/{create-component-defaults.js → create-component-defaults.mjs} +2 -7
- package/dist/common/{version-control.d.ts → version-control.d.mts} +13 -6
- package/dist/common/version-control.mjs +1064 -0
- package/dist/index.js +1 -5
- package/dist/productionCssPlugin.d.mts +2 -0
- package/dist/productionCssPlugin.mjs +50 -0
- package/dist/reactShimPlugin.d.mts +2 -0
- package/dist/reactShimPlugin.mjs +127 -0
- package/dist/util/migrationWarningsForApplications.mjs +47 -0
- package/dist/util/{migrationsForDotfiles.js → migrationsForDotfiles.mjs} +10 -17
- package/oclif.manifest.json +274 -161
- package/package.json +45 -45
- package/dist/commands/commits.d.ts +0 -18
- package/dist/commands/components/register.js +0 -15
- package/dist/commands/login.js +0 -61
- package/dist/commands/pull.d.ts +0 -17
- package/dist/commands/push.d.ts +0 -15
- package/dist/common/version-control.js +0 -716
- package/dist/util/migrationWarningsForApplications.js +0 -52
- /package/dist/common/{authenticated-command.d.ts → authenticated-command.d.mts} +0 -0
- /package/dist/common/defaults/{create-component-defaults.d.ts → create-component-defaults.d.mts} +0 -0
- /package/dist/util/{migrationWarningsForApplications.d.ts → migrationWarningsForApplications.d.mts} +0 -0
- /package/dist/util/{migrationsForDotfiles.d.ts → migrationsForDotfiles.d.mts} +0 -0
|
@@ -1,22 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { Args, Flags } from "@oclif/core";
|
|
3
|
+
import { BranchNotCheckedOutError, CommitAlreadyExistsError, ValidateGitSetupError, } from "@superblocksteam/sdk";
|
|
4
|
+
import { getSuperblocksMonorepoConfigJson, getSuperblocksResourceConfigIfExists, NotFoundError, ComponentEvent, } from "@superblocksteam/util";
|
|
5
|
+
import { Listr } from "listr2";
|
|
6
|
+
import { isEmpty } from "lodash-es";
|
|
7
|
+
import { AuthenticatedCommand } from "../common/authenticated-command.mjs";
|
|
8
|
+
import { DEFAULT_BRANCH, FileStructureType, MULTI_SELECT_PROMPT_HELP, atLeastOneSelection, deleteResourcesAndUpdateRootConfig, extractApiName, getCurrentGitBranchIfGit, getFileStructureType, getHeadCommit, isCI, getLocalGitRepoState, isGitRepoDirty, readApiFromDisk, readMultiPageApplicationFromDisk, validateLocalResource, } from "../common/version-control.mjs";
|
|
9
|
+
export default class Push extends AuthenticatedCommand {
|
|
10
|
+
static description = "Import objects from local filesystem to Superblocks";
|
|
11
|
+
static examples = [
|
|
12
|
+
"<%= config.bin %> <%= command.id %>",
|
|
13
|
+
"<%= config.bin %> <%= command.id %> apps/my-app",
|
|
14
|
+
"<%= config.bin %> <%= command.id %> apps/my-app -b feature-branch",
|
|
15
|
+
"<%= config.bin %> <%= command.id %> apps/my-app --skip-commit",
|
|
16
|
+
];
|
|
17
|
+
static flags = {
|
|
18
|
+
branch: Flags.string({
|
|
19
|
+
char: "b",
|
|
20
|
+
description: "Superblocks branch to push to, the current git branch will be used by default",
|
|
21
|
+
}),
|
|
22
|
+
"skip-commit": Flags.boolean({
|
|
23
|
+
char: "s",
|
|
24
|
+
default: false,
|
|
25
|
+
description: "If true, push command will only update live edit state along with signature without creating a commit.",
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static args = {
|
|
29
|
+
resource_path: Args.string({
|
|
30
|
+
description: "Superblocks resource location to push (e.g. apps/my-app)",
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
13
33
|
async run() {
|
|
14
34
|
const { flags, args } = await this.parse(Push);
|
|
15
35
|
const tasks = this.createTasks(args.resource_path, flags.branch, flags["skip-commit"]);
|
|
16
36
|
await tasks.run();
|
|
17
37
|
}
|
|
18
38
|
createTasks(resourceName, branch, skipCommit) {
|
|
19
|
-
const tasks = new
|
|
39
|
+
const tasks = new Listr([
|
|
20
40
|
{
|
|
21
41
|
title: "Checking for existing Superblocks project...",
|
|
22
42
|
task: async (ctx) => {
|
|
@@ -26,10 +46,10 @@ class Push extends authenticated_command_1.AuthenticatedCommand {
|
|
|
26
46
|
[
|
|
27
47
|
ctx.existingSuperblocksRootConfig,
|
|
28
48
|
ctx.superblocksRootConfigPath,
|
|
29
|
-
] = await
|
|
49
|
+
] = await getSuperblocksMonorepoConfigJson(true);
|
|
30
50
|
ctx.existingSuperblocksResourceConfig =
|
|
31
|
-
await
|
|
32
|
-
ctx.superblocksRootPath =
|
|
51
|
+
await getSuperblocksResourceConfigIfExists();
|
|
52
|
+
ctx.superblocksRootPath = path.resolve(path.dirname(ctx.superblocksRootConfigPath), "..");
|
|
33
53
|
}
|
|
34
54
|
catch {
|
|
35
55
|
// no existing superblocks config
|
|
@@ -42,27 +62,27 @@ class Push extends authenticated_command_1.AuthenticatedCommand {
|
|
|
42
62
|
task: async (ctx) => {
|
|
43
63
|
ctx.branchToPushTo = new Map();
|
|
44
64
|
if (skipCommit) {
|
|
45
|
-
const repoState = await
|
|
65
|
+
const repoState = await getLocalGitRepoState();
|
|
46
66
|
if (repoState.status === "NO_GIT") {
|
|
47
67
|
if (!branch) {
|
|
48
68
|
this.error(`No git repository found in the current folder hierarchy. Please make sure to pass branch name. E.g. superblocks push --branch feature-branch.
|
|
49
69
|
If resource is not connected to git repository, pass "main" as branch name.`);
|
|
50
70
|
}
|
|
51
|
-
ctx.localBranchName = branch ||
|
|
71
|
+
ctx.localBranchName = branch || DEFAULT_BRANCH;
|
|
52
72
|
return;
|
|
53
73
|
}
|
|
54
74
|
}
|
|
55
75
|
try {
|
|
56
76
|
ctx.localBranchName =
|
|
57
|
-
branch || (await
|
|
77
|
+
branch || (await getCurrentGitBranchIfGit()) || DEFAULT_BRANCH;
|
|
58
78
|
if (!skipCommit) {
|
|
59
|
-
[ctx.headCommitId, ctx.headCommitMessage] = await
|
|
79
|
+
[ctx.headCommitId, ctx.headCommitMessage] = await getHeadCommit(ctx.localBranchName);
|
|
60
80
|
}
|
|
61
81
|
}
|
|
62
82
|
catch (e) {
|
|
63
83
|
this.error(`Failed to check for existing git repository: ${e.message}. Please make sure to clone or initialize a git repository.`);
|
|
64
84
|
}
|
|
65
|
-
const isDirtyRepo = await
|
|
85
|
+
const isDirtyRepo = await isGitRepoDirty();
|
|
66
86
|
if (isDirtyRepo && !skipCommit) {
|
|
67
87
|
this.error(`Your git repository is dirty. Please commit or stash your changes before pushing to Superblocks.`);
|
|
68
88
|
}
|
|
@@ -71,14 +91,13 @@ If resource is not connected to git repository, pass "main" as branch name.`);
|
|
|
71
91
|
{
|
|
72
92
|
title: "Checking for deleted Superblocks resources...",
|
|
73
93
|
task: async (ctx, task) => {
|
|
74
|
-
|
|
75
|
-
if ((0, version_control_1.isCI)()) {
|
|
94
|
+
if (isCI()) {
|
|
76
95
|
this.log("Skipping check for deleted Superblocks resources in CI environment.");
|
|
77
96
|
return;
|
|
78
97
|
}
|
|
79
98
|
try {
|
|
80
|
-
for (const [resourceId, resource] of Object.entries(
|
|
81
|
-
switch (resource
|
|
99
|
+
for (const [resourceId, resource] of Object.entries(ctx.existingSuperblocksRootConfig?.resources ?? {})) {
|
|
100
|
+
switch (resource?.resourceType) {
|
|
82
101
|
case "APPLICATION": {
|
|
83
102
|
try {
|
|
84
103
|
await this.getSdk().fetchApplication({
|
|
@@ -88,7 +107,7 @@ If resource is not connected to git repository, pass "main" as branch name.`);
|
|
|
88
107
|
});
|
|
89
108
|
}
|
|
90
109
|
catch (error) {
|
|
91
|
-
if (error instanceof
|
|
110
|
+
if (error instanceof NotFoundError) {
|
|
92
111
|
ctx.removedResourceIds.push(resourceId);
|
|
93
112
|
}
|
|
94
113
|
else {
|
|
@@ -106,7 +125,7 @@ If resource is not connected to git repository, pass "main" as branch name.`);
|
|
|
106
125
|
});
|
|
107
126
|
}
|
|
108
127
|
catch (error) {
|
|
109
|
-
if (error instanceof
|
|
128
|
+
if (error instanceof NotFoundError) {
|
|
110
129
|
ctx.removedResourceIds.push(resourceId);
|
|
111
130
|
}
|
|
112
131
|
else {
|
|
@@ -139,7 +158,7 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
139
158
|
},
|
|
140
159
|
]);
|
|
141
160
|
if (removeResourcesFromDisk) {
|
|
142
|
-
await
|
|
161
|
+
await deleteResourcesAndUpdateRootConfig(ctx.removedResourceIds, ctx.existingSuperblocksRootConfig, ctx.superblocksRootPath, ctx.superblocksRootConfigPath);
|
|
143
162
|
}
|
|
144
163
|
}
|
|
145
164
|
catch (e) {
|
|
@@ -155,7 +174,6 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
155
174
|
},
|
|
156
175
|
{
|
|
157
176
|
task: async (ctx, task) => {
|
|
158
|
-
var _a, _b;
|
|
159
177
|
if (skipCommit) {
|
|
160
178
|
this.log("Skipping git validation as --skip-commit flag is set");
|
|
161
179
|
return;
|
|
@@ -164,18 +182,18 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
164
182
|
const subtasks = [];
|
|
165
183
|
ctx.resourceIdsToSkip = new Set();
|
|
166
184
|
for (const resourceId of ctx.resourceIdsToPush) {
|
|
167
|
-
const resource =
|
|
185
|
+
const resource = ctx.existingSuperblocksRootConfig?.resources[resourceId];
|
|
168
186
|
// for user messages:
|
|
169
|
-
const resourceTitle = `${(
|
|
187
|
+
const resourceTitle = `${(resource.resourceType ?? "").toLowerCase()} ${resourceId}`;
|
|
170
188
|
subtasks.push({
|
|
171
189
|
title: `Checking ${resourceTitle}...`,
|
|
172
190
|
task: async () => {
|
|
173
191
|
try {
|
|
174
|
-
const { branchName } = await this.validateGitSetup(resource
|
|
192
|
+
const { branchName } = await this.validateGitSetup(resource?.resourceType, resourceId, ComponentEvent.PUSH, ctx.localBranchName);
|
|
175
193
|
ctx.branchToPushTo.set(resourceId, branchName);
|
|
176
194
|
}
|
|
177
195
|
catch (error) {
|
|
178
|
-
if (
|
|
196
|
+
if (isCI() && error instanceof ValidateGitSetupError) {
|
|
179
197
|
this.log(`WARN: Failed to validate git setup for ${resourceTitle}. Skipping push.\n\n${error.message}.`);
|
|
180
198
|
ctx.resourceIdsToSkip.add(resourceId);
|
|
181
199
|
}
|
|
@@ -210,17 +228,16 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
210
228
|
},
|
|
211
229
|
{
|
|
212
230
|
task: async (ctx, task) => {
|
|
213
|
-
var _a, _b;
|
|
214
231
|
task.title = `Validating project structure...`;
|
|
215
232
|
const subtasks = [];
|
|
216
|
-
const superblocksRootPath =
|
|
233
|
+
const superblocksRootPath = path.resolve(path.dirname(ctx.superblocksRootConfigPath), "..");
|
|
217
234
|
for (const resourceId of ctx.resourceIdsToPush) {
|
|
218
|
-
const resource =
|
|
219
|
-
const resourceTitle = `${(
|
|
235
|
+
const resource = ctx.existingSuperblocksRootConfig?.resources[resourceId];
|
|
236
|
+
const resourceTitle = `${(resource.resourceType ?? "").toLowerCase()} at ${resource.location}`;
|
|
220
237
|
subtasks.push({
|
|
221
238
|
title: `Validating ${resourceTitle}...`,
|
|
222
239
|
task: async () => {
|
|
223
|
-
const validationError = await
|
|
240
|
+
const validationError = await validateLocalResource(superblocksRootPath, resource);
|
|
224
241
|
if (validationError) {
|
|
225
242
|
this.error(`Push failed for resource '${resource.location}' (id: ${resourceId}). ${validationError}`);
|
|
226
243
|
}
|
|
@@ -234,25 +251,23 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
234
251
|
},
|
|
235
252
|
{
|
|
236
253
|
task: async (ctx, task) => {
|
|
237
|
-
var _a;
|
|
238
254
|
task.title = `Pushing resources to branch ${ctx.localBranchName}...`;
|
|
239
255
|
const subtasks = [];
|
|
240
|
-
const superblocksRootPath =
|
|
256
|
+
const superblocksRootPath = path.resolve(path.dirname(ctx.superblocksRootConfigPath), "..");
|
|
241
257
|
for (const resourceId of ctx.resourceIdsToPush) {
|
|
242
|
-
const resource =
|
|
243
|
-
switch (resource
|
|
258
|
+
const resource = ctx.existingSuperblocksRootConfig?.resources[resourceId];
|
|
259
|
+
switch (resource?.resourceType) {
|
|
244
260
|
case "APPLICATION": {
|
|
245
261
|
subtasks.push({
|
|
246
262
|
title: `Pushing application ${resource.location}...`,
|
|
247
263
|
task: async (_ctx, task) => {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (fileStructureType === version_control_1.FileStructureType.SINGLE_PAGE) {
|
|
264
|
+
const fileStructureType = await getFileStructureType(superblocksRootPath, resource.location);
|
|
265
|
+
if (fileStructureType === FileStructureType.SINGLE_PAGE) {
|
|
251
266
|
this.error(`Application files at ${resource.location} are in single page format, but the multi-page feature is enabled for your account. To resolve this issue, you can make a commit to this branch from Superblocks to convert the file structure to multi-page format (See docs: https://docs.superblocks.com/applications/multi-page/converting-single-page-to-multi-page#handling-outstanding-branches-created-before-multi-page). Alternatively, you can run \`superblocks migrate\` to convert your file structure and commit the changes before pushing.`);
|
|
252
267
|
}
|
|
253
|
-
const localGitRepoState = await
|
|
268
|
+
const localGitRepoState = await getLocalGitRepoState(ctx.localBranchName);
|
|
254
269
|
const applicationConfig = {
|
|
255
|
-
...(await
|
|
270
|
+
...(await readMultiPageApplicationFromDisk(superblocksRootPath, resource.location)),
|
|
256
271
|
commitId: ctx.headCommitId,
|
|
257
272
|
commitMessage: ctx.headCommitMessage,
|
|
258
273
|
gitState: localGitRepoState,
|
|
@@ -260,7 +275,8 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
260
275
|
};
|
|
261
276
|
task.title += `: read from disk`;
|
|
262
277
|
try {
|
|
263
|
-
const branch =
|
|
278
|
+
const branch = ctx.branchToPushTo.get(resourceId) ??
|
|
279
|
+
ctx.localBranchName;
|
|
264
280
|
if (skipCommit) {
|
|
265
281
|
task.title += `: going to push update live edits on branch ${branch}`;
|
|
266
282
|
}
|
|
@@ -274,10 +290,10 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
274
290
|
});
|
|
275
291
|
}
|
|
276
292
|
catch (error) {
|
|
277
|
-
if (error instanceof
|
|
293
|
+
if (error instanceof BranchNotCheckedOutError) {
|
|
278
294
|
this.log(`WARN: Application ${applicationConfig.application.name} failed to push, please check branch out in the Superblocks UI first in order to check this branch out for this resource.`);
|
|
279
295
|
}
|
|
280
|
-
else if (error instanceof
|
|
296
|
+
else if (error instanceof CommitAlreadyExistsError) {
|
|
281
297
|
this.log(`WARN: Application ${applicationConfig.application.name} failed to push as the commit already exists in Superblocks.`);
|
|
282
298
|
}
|
|
283
299
|
else {
|
|
@@ -294,10 +310,9 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
294
310
|
subtasks.push({
|
|
295
311
|
title: `Pushing workflow/scheduled job ${resource.location}...`,
|
|
296
312
|
task: async (_ctx, task) => {
|
|
297
|
-
|
|
298
|
-
const localGitRepoState = await (0, version_control_1.getLocalGitRepoState)(ctx.localBranchName);
|
|
313
|
+
const localGitRepoState = await getLocalGitRepoState(ctx.localBranchName);
|
|
299
314
|
const apiConfig = {
|
|
300
|
-
...(await
|
|
315
|
+
...(await readApiFromDisk(superblocksRootPath, resource.location)),
|
|
301
316
|
commitId: ctx.headCommitId,
|
|
302
317
|
commitMessage: ctx.headCommitMessage,
|
|
303
318
|
gitState: localGitRepoState,
|
|
@@ -305,7 +320,8 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
305
320
|
};
|
|
306
321
|
task.title += `: read from disk`;
|
|
307
322
|
try {
|
|
308
|
-
const branch =
|
|
323
|
+
const branch = ctx.branchToPushTo.get(resourceId) ??
|
|
324
|
+
ctx.localBranchName;
|
|
309
325
|
if (skipCommit) {
|
|
310
326
|
task.title += `: going to push update live edits on branch ${branch}`;
|
|
311
327
|
}
|
|
@@ -319,11 +335,11 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
319
335
|
});
|
|
320
336
|
}
|
|
321
337
|
catch (error) {
|
|
322
|
-
if (error instanceof
|
|
323
|
-
this.log(`WARN: Workflow/Scheduled Job ${
|
|
338
|
+
if (error instanceof BranchNotCheckedOutError) {
|
|
339
|
+
this.log(`WARN: Workflow/Scheduled Job ${extractApiName(apiConfig)} failed to push, please check branch out in the Superblocks UI first in order to check this branch out for this resource.`);
|
|
324
340
|
}
|
|
325
|
-
else if (error instanceof
|
|
326
|
-
this.log(`WARN: Workflow/Scheduled Job ${
|
|
341
|
+
else if (error instanceof CommitAlreadyExistsError) {
|
|
342
|
+
this.log(`WARN: Workflow/Scheduled Job ${extractApiName(apiConfig)} failed to push as the commit already exists in Superblocks.`);
|
|
327
343
|
}
|
|
328
344
|
else {
|
|
329
345
|
throw error;
|
|
@@ -352,23 +368,22 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
352
368
|
return tasks;
|
|
353
369
|
}
|
|
354
370
|
async getResourceIdsToPush(ctx, task, resourcePath, supportedResourceTypes = ["APPLICATION", "BACKEND"]) {
|
|
355
|
-
|
|
356
|
-
const resources = Object.entries((_b = (_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {}).filter(([, resource]) => {
|
|
371
|
+
const resources = Object.entries(ctx.existingSuperblocksRootConfig?.resources ?? {}).filter(([, resource]) => {
|
|
357
372
|
return supportedResourceTypes.includes(resource.resourceType);
|
|
358
373
|
});
|
|
359
374
|
// If there are no resources, or if the user has specified a resource name
|
|
360
375
|
// that doesn't exist, we should throw an error.
|
|
361
|
-
if (
|
|
376
|
+
if (isEmpty(resources)) {
|
|
362
377
|
throw new Error("No resources found in the current project");
|
|
363
378
|
}
|
|
364
|
-
else if (!
|
|
379
|
+
else if (!isEmpty(resourcePath)) {
|
|
365
380
|
const resource = resources.find(([, resource]) => resource.location === resourcePath);
|
|
366
381
|
if (resource) {
|
|
367
382
|
return [resource[0]];
|
|
368
383
|
}
|
|
369
384
|
throw new Error(`No resource found with the given location: ${resourcePath}`);
|
|
370
385
|
}
|
|
371
|
-
const resourceConfig = await
|
|
386
|
+
const resourceConfig = await getSuperblocksResourceConfigIfExists();
|
|
372
387
|
if (resourceConfig) {
|
|
373
388
|
return [resourceConfig.id];
|
|
374
389
|
}
|
|
@@ -380,7 +395,7 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
380
395
|
name: resourceId,
|
|
381
396
|
message: resource.location,
|
|
382
397
|
});
|
|
383
|
-
if (
|
|
398
|
+
if (ctx.existingSuperblocksResourceConfig?.id === resourceId) {
|
|
384
399
|
initialSelections.push(counter);
|
|
385
400
|
}
|
|
386
401
|
counter++;
|
|
@@ -391,11 +406,11 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
391
406
|
{
|
|
392
407
|
type: "AutoComplete",
|
|
393
408
|
name: "resourceIdsToPush",
|
|
394
|
-
message: `Select resources to push (${
|
|
409
|
+
message: `Select resources to push (${MULTI_SELECT_PROMPT_HELP})`,
|
|
395
410
|
choices: choices,
|
|
396
411
|
initial: initialSelections,
|
|
397
412
|
multiple: true,
|
|
398
|
-
validate:
|
|
413
|
+
validate: atLeastOneSelection,
|
|
399
414
|
prefix: "▸",
|
|
400
415
|
indicator: "◉",
|
|
401
416
|
},
|
|
@@ -403,27 +418,3 @@ Would you like to also delete these resources from your filesystem?`,
|
|
|
403
418
|
return resourceIdsToPush;
|
|
404
419
|
}
|
|
405
420
|
}
|
|
406
|
-
Push.description = "Import objects from local filesystem to Superblocks";
|
|
407
|
-
Push.examples = [
|
|
408
|
-
"<%= config.bin %> <%= command.id %>",
|
|
409
|
-
"<%= config.bin %> <%= command.id %> apps/my-app",
|
|
410
|
-
"<%= config.bin %> <%= command.id %> apps/my-app -b feature-branch",
|
|
411
|
-
"<%= config.bin %> <%= command.id %> apps/my-app --skip-commit",
|
|
412
|
-
];
|
|
413
|
-
Push.flags = {
|
|
414
|
-
branch: core_1.Flags.string({
|
|
415
|
-
char: "b",
|
|
416
|
-
description: "Superblocks branch to push to, the current git branch will be used by default",
|
|
417
|
-
}),
|
|
418
|
-
"skip-commit": core_1.Flags.boolean({
|
|
419
|
-
char: "s",
|
|
420
|
-
default: false,
|
|
421
|
-
description: "If true, push command will only update live edit state along with signature without creating a commit.",
|
|
422
|
-
}),
|
|
423
|
-
};
|
|
424
|
-
Push.args = {
|
|
425
|
-
resource_path: core_1.Args.string({
|
|
426
|
-
description: "Superblocks resource location to push (e.g. apps/my-app)",
|
|
427
|
-
}),
|
|
428
|
-
};
|
|
429
|
-
exports.default = Push;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { AuthenticatedCommand } from "../common/authenticated-command";
|
|
1
|
+
import { AuthenticatedCommand } from "../common/authenticated-command.mjs";
|
|
2
2
|
export default class Remove extends AuthenticatedCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
6
|
-
resource_path: import("@oclif/core/
|
|
6
|
+
resource_path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
7
|
};
|
|
8
8
|
run(): Promise<void>;
|
|
9
9
|
private createTasks;
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { Args } from "@oclif/core";
|
|
3
|
+
import { getSuperblocksMonorepoConfigJson, } from "@superblocksteam/util";
|
|
4
|
+
import fs from "fs-extra";
|
|
5
|
+
import { Listr } from "listr2";
|
|
6
|
+
import { isEmpty } from "lodash-es";
|
|
7
|
+
import { AuthenticatedCommand } from "../common/authenticated-command.mjs";
|
|
8
|
+
import { atLeastOneSelection, extractApiName, MULTI_SELECT_PROMPT_HELP, removeResourceFromDisk, sortByKey, } from "../common/version-control.mjs";
|
|
9
|
+
export default class Remove extends AuthenticatedCommand {
|
|
10
|
+
static description = "Remove a Superblocks resource from the local Superblocks project and delete the resource folder directory locally (if it exists)";
|
|
11
|
+
static examples = [
|
|
12
|
+
"<%= config.bin %> <%= command.id %>",
|
|
13
|
+
"<%= config.bin %> <%= command.id %> apps/my-spectacular-app",
|
|
14
|
+
];
|
|
15
|
+
static args = {
|
|
16
|
+
resource_path: Args.string({
|
|
17
|
+
description: "Superblocks resource location (i.e. apps/my-spectacular-app)",
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
13
20
|
async run() {
|
|
14
21
|
const { args } = await this.parse(Remove);
|
|
15
22
|
const tasks = this.createTasks(args);
|
|
@@ -21,7 +28,7 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
createTasks(args) {
|
|
24
|
-
const tasks = new
|
|
31
|
+
const tasks = new Listr([
|
|
25
32
|
{
|
|
26
33
|
title: "Checking for existing Superblocks project...",
|
|
27
34
|
task: async (ctx) => {
|
|
@@ -31,8 +38,8 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
31
38
|
[
|
|
32
39
|
ctx.existingSuperblocksRootConfig,
|
|
33
40
|
ctx.superblocksRootConfigPath,
|
|
34
|
-
] = await
|
|
35
|
-
ctx.superblocksRootPath =
|
|
41
|
+
] = await getSuperblocksMonorepoConfigJson(true);
|
|
42
|
+
ctx.superblocksRootPath = path.resolve(path.dirname(ctx.superblocksRootConfigPath), "..");
|
|
36
43
|
}
|
|
37
44
|
catch {
|
|
38
45
|
// no existing superblocks config
|
|
@@ -67,7 +74,7 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
67
74
|
for (const api of apis) {
|
|
68
75
|
ctx.fetchedResources[api.id] = {
|
|
69
76
|
resourceType: "BACKEND",
|
|
70
|
-
name:
|
|
77
|
+
name: extractApiName(api),
|
|
71
78
|
};
|
|
72
79
|
}
|
|
73
80
|
task.title += `: completed`;
|
|
@@ -85,17 +92,17 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
85
92
|
{
|
|
86
93
|
title: "Removing resources...",
|
|
87
94
|
task: async (ctx, task) => {
|
|
88
|
-
var _a;
|
|
89
95
|
const subtasks = [];
|
|
90
96
|
for (const resourceId of ctx.resourceIdsToRemove) {
|
|
91
|
-
const resourceLocation =
|
|
97
|
+
const resourceLocation = ctx.existingSuperblocksRootConfig?.resources[resourceId]
|
|
98
|
+
.location;
|
|
92
99
|
if (!resourceLocation) {
|
|
93
100
|
this.error(`Resource location not found for resource with id ${resourceId}`);
|
|
94
101
|
}
|
|
95
102
|
subtasks.push({
|
|
96
103
|
title: `Removing ${resourceId} from ${resourceLocation}...`,
|
|
97
104
|
task: async (_ctx, task) => {
|
|
98
|
-
await
|
|
105
|
+
await removeResourceFromDisk(ctx.superblocksRootPath, resourceLocation);
|
|
99
106
|
ctx.removedResourceIds.push(resourceId);
|
|
100
107
|
task.title += `: done`;
|
|
101
108
|
},
|
|
@@ -109,12 +116,12 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
109
116
|
{
|
|
110
117
|
title: "Updating Superblocks project file...",
|
|
111
118
|
task: async (ctx) => {
|
|
112
|
-
const [superblocksRootConfig, rootConfigPath] = await
|
|
119
|
+
const [superblocksRootConfig, rootConfigPath] = await getSuperblocksMonorepoConfigJson(true);
|
|
113
120
|
for (const removedResourceId of ctx.removedResourceIds) {
|
|
114
121
|
delete superblocksRootConfig.resources[removedResourceId];
|
|
115
122
|
}
|
|
116
123
|
// update superblocks.json file
|
|
117
|
-
await fs.writeFile(rootConfigPath, JSON.stringify(
|
|
124
|
+
await fs.writeFile(rootConfigPath, JSON.stringify(sortByKey(superblocksRootConfig), null, 2));
|
|
118
125
|
},
|
|
119
126
|
},
|
|
120
127
|
], {
|
|
@@ -123,7 +130,6 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
123
130
|
return tasks;
|
|
124
131
|
}
|
|
125
132
|
async getResourcesToRemove(ctx, task, args) {
|
|
126
|
-
var _a;
|
|
127
133
|
if (args.resource_path) {
|
|
128
134
|
const [resourceId] = getResourceIdFromLocation(ctx, args.resource_path);
|
|
129
135
|
return [resourceId];
|
|
@@ -131,30 +137,30 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
131
137
|
else {
|
|
132
138
|
const choices = [];
|
|
133
139
|
for (const [resourceId, resource] of Object.entries(ctx.fetchedResources)) {
|
|
134
|
-
if (
|
|
140
|
+
if (ctx.existingSuperblocksRootConfig?.resources[resourceId]) {
|
|
135
141
|
choices.push({
|
|
136
142
|
name: resourceId,
|
|
137
143
|
message: `${resource.name} (${resource.resourceType})`,
|
|
138
144
|
});
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
|
-
if (
|
|
147
|
+
if (isEmpty(choices)) {
|
|
142
148
|
this.error(`No resources found in your project. Please make sure you have at least one application, workflow or scheduled job in your project.`);
|
|
143
149
|
}
|
|
144
150
|
const resourceIdsToRemove = await task.prompt([
|
|
145
151
|
{
|
|
146
152
|
type: "AutoComplete",
|
|
147
153
|
name: "resourceIdsToRemove",
|
|
148
|
-
message: `Select resources to remove (${
|
|
154
|
+
message: `Select resources to remove (${MULTI_SELECT_PROMPT_HELP})`,
|
|
149
155
|
choices: choices,
|
|
150
156
|
multiple: true,
|
|
151
|
-
validate:
|
|
157
|
+
validate: atLeastOneSelection,
|
|
152
158
|
prefix: "▸",
|
|
153
159
|
indicator: "◉",
|
|
154
160
|
},
|
|
155
161
|
]);
|
|
156
162
|
const duplicates = await this.findDuplicates(resourceIdsToRemove, ctx.fetchedResources);
|
|
157
|
-
if (!
|
|
163
|
+
if (!isEmpty(duplicates)) {
|
|
158
164
|
this.error(`Duplicate resources selected: ${duplicates
|
|
159
165
|
.map((duplicate) => `${duplicate.name} (${duplicate.resourceType}) id: ${duplicate.id}`)
|
|
160
166
|
.join(", ")}. Please make sure to select unique resources or rename them so that they have unique names.`);
|
|
@@ -183,20 +189,8 @@ class Remove extends authenticated_command_1.AuthenticatedCommand {
|
|
|
183
189
|
return selectedResources.filter((resource) => countResourceNamesByType[resource.resourceType][resource.name] > 1);
|
|
184
190
|
}
|
|
185
191
|
}
|
|
186
|
-
Remove.description = "Remove a Superblocks resource from the local Superblocks project and delete the resource folder directory locally (if it exists)";
|
|
187
|
-
Remove.examples = [
|
|
188
|
-
"<%= config.bin %> <%= command.id %>",
|
|
189
|
-
"<%= config.bin %> <%= command.id %> apps/my-spectacular-app",
|
|
190
|
-
];
|
|
191
|
-
Remove.args = {
|
|
192
|
-
resource_path: core_1.Args.string({
|
|
193
|
-
description: "Superblocks resource location (i.e. apps/my-spectacular-app)",
|
|
194
|
-
}),
|
|
195
|
-
};
|
|
196
|
-
exports.default = Remove;
|
|
197
192
|
function getResourceIdFromLocation(ctx, resourceLocation) {
|
|
198
|
-
|
|
199
|
-
for (const [resourceId, resource] of Object.entries((_b = (_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {})) {
|
|
193
|
+
for (const [resourceId, resource] of Object.entries(ctx.existingSuperblocksRootConfig?.resources ?? {})) {
|
|
200
194
|
if (resource.location === resourceLocation) {
|
|
201
195
|
return [resourceId, resource.resourceType];
|
|
202
196
|
}
|