@superblocksteam/cli 1.10.0 → 1.13.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/bin/dev +5 -7
- package/bin/run +1 -3
- 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} +58 -64
- 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} +34 -42
- package/dist/commands/pull.d.mts +17 -0
- package/dist/commands/{pull.js → pull.mjs} +72 -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} +1 -1
- package/dist/common/{version-control.js → version-control.mjs} +170 -202
- package/dist/index.js +1 -5
- package/dist/{productionCssPlugin.js → productionCssPlugin.mjs} +4 -10
- package/dist/{reactShimPlugin.js → reactShimPlugin.mjs} +17 -24
- package/dist/util/migrationWarningsForApplications.mjs +47 -0
- package/dist/util/{migrationsForDotfiles.js → migrationsForDotfiles.mjs} +10 -17
- package/oclif.manifest.json +284 -171
- package/package.json +43 -41
- package/dist/appendHotReloadEventPlugin.js +0 -48
- 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/util/migrationWarningsForApplications.js +0 -52
- /package/dist/{appendHotReloadEventPlugin.d.ts → appendHotReloadEventPlugin.d.mts} +0 -0
- /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/{productionCssPlugin.d.ts → productionCssPlugin.d.mts} +0 -0
- /package/dist/{reactShimPlugin.d.ts → reactShimPlugin.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,16 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const authenticated_command_1 = require("../../common/authenticated-command");
|
|
11
|
-
const version_control_1 = require("../../common/version-control");
|
|
12
|
-
const reactShimPlugin_1 = require("../../reactShimPlugin");
|
|
13
|
-
function healthEndpointMiddleware(getBranch) {
|
|
1
|
+
import { COMPONENT_EVENT_HEADER, ComponentEvent } from "@superblocksteam/util";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import { bold, green, yellow, red, magenta } from "colorette";
|
|
4
|
+
import { createLogger, createServer } from "vite";
|
|
5
|
+
import { appendHotReloadEventPlugin } from "../../appendHotReloadEventPlugin.mjs";
|
|
6
|
+
import { AuthenticatedApplicationCommand } from "../../common/authenticated-command.mjs";
|
|
7
|
+
import { getCurrentGitBranchIfGit } from "../../common/version-control.mjs";
|
|
8
|
+
import { injectReactVersionsPlugin } from "../../reactShimPlugin.mjs";
|
|
9
|
+
export function healthEndpointMiddleware(getBranch) {
|
|
14
10
|
return {
|
|
15
11
|
name: "health-endpoint-middleware",
|
|
16
12
|
configureServer: (server) => {
|
|
@@ -33,18 +29,18 @@ function healthEndpointMiddleware(getBranch) {
|
|
|
33
29
|
},
|
|
34
30
|
};
|
|
35
31
|
}
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
export default class Watch extends AuthenticatedApplicationCommand {
|
|
33
|
+
static description = "watch for changes to your custom components";
|
|
38
34
|
async run() {
|
|
39
35
|
const headers = {
|
|
40
|
-
[
|
|
36
|
+
[COMPONENT_EVENT_HEADER]: ComponentEvent.REGISTER,
|
|
41
37
|
};
|
|
42
38
|
await this.registerComponents(headers);
|
|
43
|
-
this.log(
|
|
39
|
+
this.log(yellow("Remember to refresh your application to see any newly registered components."));
|
|
44
40
|
this.log();
|
|
45
41
|
const editModeUrl = new URL(await this.getEditModeUrl());
|
|
46
42
|
editModeUrl.searchParams.set("devMode", "true");
|
|
47
|
-
const { branchName, localBranchName } = await this.validateApplicationGitSetup(
|
|
43
|
+
const { branchName, localBranchName } = await this.validateApplicationGitSetup(ComponentEvent.REGISTER);
|
|
48
44
|
if (branchName) {
|
|
49
45
|
editModeUrl.searchParams.set("branch", branchName);
|
|
50
46
|
}
|
|
@@ -54,9 +50,9 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
|
|
|
54
50
|
const getBranch = async () => {
|
|
55
51
|
let curLocalBranchName;
|
|
56
52
|
try {
|
|
57
|
-
curLocalBranchName = await
|
|
53
|
+
curLocalBranchName = await getCurrentGitBranchIfGit();
|
|
58
54
|
}
|
|
59
|
-
catch
|
|
55
|
+
catch {
|
|
60
56
|
curLocalBranchName = null;
|
|
61
57
|
}
|
|
62
58
|
if (curLocalBranchName === lastLocalBranchName) {
|
|
@@ -65,30 +61,29 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
|
|
|
65
61
|
}
|
|
66
62
|
else {
|
|
67
63
|
// the quick check indicates that the branch has changed, so we need to make an API call to validate the new branch
|
|
68
|
-
const { branchName, localBranchName } = await this.validateApplicationGitSetup(
|
|
64
|
+
const { branchName, localBranchName } = await this.validateApplicationGitSetup(ComponentEvent.REGISTER);
|
|
69
65
|
lastBranchName = branchName;
|
|
70
66
|
lastLocalBranchName = localBranchName;
|
|
71
67
|
return branchName;
|
|
72
68
|
}
|
|
73
69
|
};
|
|
74
70
|
const port = 3002;
|
|
75
|
-
const viteLogger =
|
|
71
|
+
const viteLogger = createLogger();
|
|
76
72
|
viteLogger.info = (message) => {
|
|
77
73
|
this.log(message);
|
|
78
74
|
};
|
|
79
75
|
viteLogger.warn = (msg) => {
|
|
80
|
-
this.log(
|
|
76
|
+
this.log(yellow(msg));
|
|
81
77
|
};
|
|
82
78
|
viteLogger.warnOnce = (msg) => {
|
|
83
|
-
this.log(
|
|
79
|
+
this.log(yellow(msg));
|
|
84
80
|
};
|
|
85
81
|
viteLogger.error = (msg) => {
|
|
86
|
-
this.log(
|
|
82
|
+
this.log(red(msg));
|
|
87
83
|
};
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
89
84
|
viteLogger.clearScreen = () => { };
|
|
90
85
|
await (async () => {
|
|
91
|
-
const server = await
|
|
86
|
+
const server = await createServer({
|
|
92
87
|
configFile: false,
|
|
93
88
|
base: `http://localhost:${port}`,
|
|
94
89
|
server: {
|
|
@@ -101,20 +96,18 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
|
|
|
101
96
|
customLogger: viteLogger,
|
|
102
97
|
plugins: [
|
|
103
98
|
healthEndpointMiddleware(getBranch),
|
|
104
|
-
(
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
react(),
|
|
100
|
+
appendHotReloadEventPlugin(getBranch),
|
|
101
|
+
injectReactVersionsPlugin(),
|
|
107
102
|
],
|
|
108
103
|
});
|
|
109
104
|
await server.listen();
|
|
110
|
-
this.log(
|
|
111
|
-
this.log(
|
|
105
|
+
this.log(green(`Local server started at port ${port}`));
|
|
106
|
+
this.log(green(`Visit your application at:`));
|
|
112
107
|
this.log();
|
|
113
|
-
this.log(
|
|
108
|
+
this.log(bold(magenta(editModeUrl.href)));
|
|
114
109
|
this.log();
|
|
115
|
-
this.log(
|
|
110
|
+
this.log(yellow(`Please ensure that Local Dev Mode is enabled in your Application so that the component is fetched from your local dev server. Learn more about Local Dev Mode here: ${magenta("https://docs.superblocks.com/applications/custom-components/development-lifecycle#local-development-mode")}`));
|
|
116
111
|
})();
|
|
117
112
|
}
|
|
118
113
|
}
|
|
119
|
-
Watch.description = "watch for changes to your custom components";
|
|
120
|
-
exports.default = Watch;
|
|
@@ -3,8 +3,8 @@ export default class SetSuperblocksConfig extends Command {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
6
|
-
property: import("@oclif/core/
|
|
7
|
-
value: import("@oclif/core/
|
|
6
|
+
property: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
8
|
};
|
|
9
9
|
run(): Promise<void>;
|
|
10
10
|
validateDomain(domain: string): Promise<void>;
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import dns from "dns";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import { Args, Command } from "@oclif/core";
|
|
4
|
+
import { getLocalTokenWithUrlIfExists, saveApiToken, } from "@superblocksteam/util";
|
|
5
|
+
export default class SetSuperblocksConfig extends Command {
|
|
6
|
+
static description = "Sets the specified property in your Superblocks configuration. A property governs the behavior of the Superblocks CLI, such as Superblocks region to interact with";
|
|
7
|
+
static examples = [
|
|
8
|
+
"<%= config.bin %> <%= command.id %> domain eu.superblocks.com",
|
|
9
|
+
"<%= config.bin %> <%= command.id %> domain app.superblocks.com",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
property: Args.string({
|
|
13
|
+
description: "Superblocks config name, e.g. domain",
|
|
14
|
+
options: ["domain"],
|
|
15
|
+
required: true,
|
|
16
|
+
}),
|
|
17
|
+
value: Args.string({
|
|
18
|
+
description: "Superblocks config value",
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
9
22
|
async run() {
|
|
10
23
|
const { args } = await this.parse(SetSuperblocksConfig);
|
|
11
24
|
try {
|
|
@@ -14,26 +27,26 @@ class SetSuperblocksConfig extends core_1.Command {
|
|
|
14
27
|
const newDomain = args.value;
|
|
15
28
|
const newSuperblocksBaseUrl = `https://${newDomain}/`;
|
|
16
29
|
await this.validateDomain(newDomain);
|
|
17
|
-
const result = await
|
|
30
|
+
const result = await getLocalTokenWithUrlIfExists();
|
|
18
31
|
if (result) {
|
|
19
32
|
if (!("token" in result)) {
|
|
20
33
|
// domain only, no token
|
|
21
|
-
await
|
|
34
|
+
await saveApiToken(newSuperblocksBaseUrl);
|
|
22
35
|
break;
|
|
23
36
|
}
|
|
24
37
|
// existing token with domain
|
|
25
38
|
const { token, superblocksBaseUrl } = result;
|
|
26
39
|
const tokenToSave = newSuperblocksBaseUrl === superblocksBaseUrl ? token : undefined;
|
|
27
40
|
if (tokenToSave) {
|
|
28
|
-
await
|
|
41
|
+
await saveApiToken(newSuperblocksBaseUrl, tokenToSave);
|
|
29
42
|
}
|
|
30
43
|
else {
|
|
31
|
-
await
|
|
44
|
+
await saveApiToken(newSuperblocksBaseUrl);
|
|
32
45
|
}
|
|
33
46
|
}
|
|
34
47
|
else {
|
|
35
48
|
// no existing token
|
|
36
|
-
await
|
|
49
|
+
await saveApiToken(newSuperblocksBaseUrl);
|
|
37
50
|
}
|
|
38
51
|
break;
|
|
39
52
|
}
|
|
@@ -51,29 +64,12 @@ class SetSuperblocksConfig extends core_1.Command {
|
|
|
51
64
|
if (!domainRegex.test(domain)) {
|
|
52
65
|
throw new Error(errorMessage);
|
|
53
66
|
}
|
|
54
|
-
const lookup =
|
|
67
|
+
const lookup = promisify(dns.lookup);
|
|
55
68
|
try {
|
|
56
69
|
await lookup(domain);
|
|
57
70
|
}
|
|
58
|
-
catch
|
|
71
|
+
catch {
|
|
59
72
|
throw new Error(errorMessage);
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
|
-
SetSuperblocksConfig.description = "Sets the specified property in your Superblocks configuration. A property governs the behavior of the Superblocks CLI, such as Superblocks region to interact with";
|
|
64
|
-
SetSuperblocksConfig.examples = [
|
|
65
|
-
"<%= config.bin %> <%= command.id %> domain eu.superblocks.com",
|
|
66
|
-
"<%= config.bin %> <%= command.id %> domain app.superblocks.com",
|
|
67
|
-
];
|
|
68
|
-
SetSuperblocksConfig.args = {
|
|
69
|
-
property: core_1.Args.string({
|
|
70
|
-
description: "Superblocks config name, e.g. domain",
|
|
71
|
-
options: ["domain"],
|
|
72
|
-
required: true,
|
|
73
|
-
}),
|
|
74
|
-
value: core_1.Args.string({
|
|
75
|
-
description: "Superblocks config value",
|
|
76
|
-
required: true,
|
|
77
|
-
}),
|
|
78
|
-
};
|
|
79
|
-
exports.default = SetSuperblocksConfig;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { AuthenticatedCommand } from "../common/authenticated-command";
|
|
1
|
+
import { AuthenticatedCommand } from "../common/authenticated-command.mjs";
|
|
2
2
|
export default class Initialize extends AuthenticatedCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
-
mode: import("@oclif/core/
|
|
7
|
-
"skip-signing-verification": import("@oclif/core/
|
|
6
|
+
mode: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"skip-signing-verification": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
8
|
};
|
|
9
9
|
static args: {
|
|
10
|
-
resource_url: import("@oclif/core/
|
|
10
|
+
resource_url: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
11
|
};
|
|
12
12
|
run(): Promise<void>;
|
|
13
13
|
private createTasks;
|
|
@@ -1,15 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { Args, Flags } from "@oclif/core";
|
|
3
|
+
import { COMPONENT_EVENT_HEADER, getSuperblocksMonorepoConfigJson, SUPERBLOCKS_HOME_FOLDER_NAME, RESOURCE_CONFIG_PATH, ComponentEvent, NotFoundError, } 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, DEFAULT_BRANCH, extractApiName, getMode, modeFlagValuesMap, MULTI_SELECT_PROMPT_HELP, sortByKey, writeMultiPageApplicationToDisk, writeResourceToDisk, } from "../common/version-control.mjs";
|
|
9
|
+
export default class Initialize extends AuthenticatedCommand {
|
|
10
|
+
static description = "Interactively configure the current directory as a Superblocks project or initialize new services in an already configured Superblocks project directory";
|
|
11
|
+
static examples = [
|
|
12
|
+
"<%= config.bin %> <%= command.id %>",
|
|
13
|
+
"<%= config.bin %> <%= command.id %> https://app.superblocks.com/applications/11111111-1111-1111-1111-111111111111/pages/22222222-2222-2222-2222-222222222222",
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
mode: Flags.string({
|
|
17
|
+
char: "m",
|
|
18
|
+
description: "Pull mode",
|
|
19
|
+
options: Object.keys(modeFlagValuesMap),
|
|
20
|
+
}),
|
|
21
|
+
"skip-signing-verification": Flags.boolean({
|
|
22
|
+
char: "s",
|
|
23
|
+
description: "If true, signature verification for signing enabled organizations will be skipped.",
|
|
24
|
+
default: false,
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
static args = {
|
|
28
|
+
resource_url: Args.string({
|
|
29
|
+
description: "Superblocks resource URL (i.e. https://app.superblocks.com/applications/<application_id> or https://app.superblocks.com/applications/edit/<application_id>)",
|
|
30
|
+
required: false,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
13
33
|
async run() {
|
|
14
34
|
const { flags, args } = await this.parse(Initialize);
|
|
15
35
|
const tasks = this.createTasks(flags, args);
|
|
@@ -22,7 +42,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
22
42
|
}
|
|
23
43
|
createTasks(flags, args) {
|
|
24
44
|
const skipSigningVerification = flags["skip-signing-verification"];
|
|
25
|
-
const tasks = new
|
|
45
|
+
const tasks = new Listr([
|
|
26
46
|
{
|
|
27
47
|
title: "Checking for existing Superblocks project...",
|
|
28
48
|
task: async (ctx) => {
|
|
@@ -34,7 +54,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
34
54
|
[
|
|
35
55
|
ctx.existingSuperblocksRootConfig,
|
|
36
56
|
ctx.superblocksRootConfigPath,
|
|
37
|
-
] = await
|
|
57
|
+
] = await getSuperblocksMonorepoConfigJson(true);
|
|
38
58
|
}
|
|
39
59
|
catch {
|
|
40
60
|
// no existing superblocks config
|
|
@@ -70,7 +90,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
70
90
|
for (const api of apis) {
|
|
71
91
|
ctx.fetchedResources[api.id] = {
|
|
72
92
|
resourceType: "BACKEND",
|
|
73
|
-
name:
|
|
93
|
+
name: extractApiName(api),
|
|
74
94
|
};
|
|
75
95
|
}
|
|
76
96
|
task.title += `: completed`;
|
|
@@ -78,21 +98,21 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
78
98
|
},
|
|
79
99
|
{
|
|
80
100
|
title: "Fetching resource by resourceUrl...",
|
|
81
|
-
enabled: () => !
|
|
101
|
+
enabled: () => !isEmpty(args.resource_url),
|
|
82
102
|
task: async (ctx, task) => {
|
|
83
103
|
const [resourceId, resourceType] = getResourceIdFromUrl(args.resource_url);
|
|
84
104
|
if (resourceType === "APPLICATION") {
|
|
85
105
|
const headers = {
|
|
86
|
-
[
|
|
106
|
+
[COMPONENT_EVENT_HEADER]: ComponentEvent.INIT,
|
|
87
107
|
};
|
|
88
108
|
const application = await this.getSdk().fetchApplicationWithComponents({
|
|
89
109
|
applicationId: resourceId,
|
|
90
|
-
branch:
|
|
110
|
+
branch: DEFAULT_BRANCH,
|
|
91
111
|
headers,
|
|
92
112
|
skipSigningVerification,
|
|
93
113
|
});
|
|
94
114
|
if (!application) {
|
|
95
|
-
throw new
|
|
115
|
+
throw new NotFoundError(`Application ${resourceId} was not found`);
|
|
96
116
|
}
|
|
97
117
|
ctx.fetchedResources[application.application.id] = {
|
|
98
118
|
resourceType,
|
|
@@ -106,7 +126,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
106
126
|
});
|
|
107
127
|
ctx.fetchedResources[api.id] = {
|
|
108
128
|
resourceType,
|
|
109
|
-
name:
|
|
129
|
+
name: extractApiName(api),
|
|
110
130
|
};
|
|
111
131
|
}
|
|
112
132
|
task.title += `: completed`;
|
|
@@ -119,7 +139,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
119
139
|
task: async (ctx, task) => {
|
|
120
140
|
const resourceIdsToInitialize = await this.getResourcesToInitialize(ctx, task, args);
|
|
121
141
|
ctx.resourceIdsToInitialize = resourceIdsToInitialize;
|
|
122
|
-
const viewMode = await
|
|
142
|
+
const viewMode = await getMode(task, flags.mode);
|
|
123
143
|
ctx.viewMode = viewMode;
|
|
124
144
|
},
|
|
125
145
|
},
|
|
@@ -130,7 +150,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
130
150
|
// if ctx.superblocksRootConfigPath is defined, we are initializing a new resource in an existing Superblocks project
|
|
131
151
|
// otherwise, we are initializing a new Superblocks project
|
|
132
152
|
const superblocksRootPath = ctx.superblocksRootConfigPath
|
|
133
|
-
?
|
|
153
|
+
? path.resolve(path.dirname(ctx.superblocksRootConfigPath), "..")
|
|
134
154
|
: undefined;
|
|
135
155
|
for (const resourceId of ctx.resourceIdsToInitialize) {
|
|
136
156
|
const resource = ctx.fetchedResources[resourceId];
|
|
@@ -143,11 +163,11 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
143
163
|
title: `Fetching application ${resource.name}...`,
|
|
144
164
|
task: async (_ctx, task) => {
|
|
145
165
|
const headers = {
|
|
146
|
-
[
|
|
166
|
+
[COMPONENT_EVENT_HEADER]: ComponentEvent.INIT,
|
|
147
167
|
};
|
|
148
168
|
const application = (await this.getSdk().fetchApplicationWithComponents({
|
|
149
169
|
applicationId: resourceId,
|
|
150
|
-
branch:
|
|
170
|
+
branch: DEFAULT_BRANCH,
|
|
151
171
|
viewMode: ctx.viewMode,
|
|
152
172
|
headers,
|
|
153
173
|
skipSigningVerification,
|
|
@@ -155,7 +175,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
155
175
|
task.title += `: fetched`;
|
|
156
176
|
if (application) {
|
|
157
177
|
ctx.writtenResources[resourceId] =
|
|
158
|
-
await
|
|
178
|
+
await writeMultiPageApplicationToDisk(application, superblocksRootPath ?? process.cwd(), ctx.featureFlags);
|
|
159
179
|
}
|
|
160
180
|
task.title += `: done`;
|
|
161
181
|
},
|
|
@@ -169,13 +189,13 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
169
189
|
const backend = await this.getSdk().fetchApi({
|
|
170
190
|
apiId: resourceId,
|
|
171
191
|
viewMode: ctx.viewMode,
|
|
172
|
-
branch:
|
|
192
|
+
branch: DEFAULT_BRANCH,
|
|
173
193
|
skipSigningVerification,
|
|
174
194
|
});
|
|
175
195
|
task.title += `: fetched`;
|
|
176
196
|
if (backend) {
|
|
177
197
|
ctx.writtenResources[resourceId] =
|
|
178
|
-
await
|
|
198
|
+
await writeResourceToDisk("BACKEND", resourceId, backend, superblocksRootPath ?? process.cwd(), ctx.featureFlags);
|
|
179
199
|
}
|
|
180
200
|
task.title += `: done`;
|
|
181
201
|
},
|
|
@@ -195,7 +215,6 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
195
215
|
{
|
|
196
216
|
title: "Updating Superblocks project file...",
|
|
197
217
|
task: async (ctx) => {
|
|
198
|
-
var _a, _b, _c;
|
|
199
218
|
const superblocksConfig = {
|
|
200
219
|
configType: "ROOT",
|
|
201
220
|
resources: {},
|
|
@@ -208,14 +227,14 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
208
227
|
superblocksConfig.resources[resourceId] = resource;
|
|
209
228
|
}
|
|
210
229
|
// existing resources
|
|
211
|
-
for (const [resourceId, resource] of Object.entries(
|
|
230
|
+
for (const [resourceId, resource] of Object.entries(ctx.existingSuperblocksRootConfig?.resources ?? {})) {
|
|
212
231
|
superblocksConfig.resources[resourceId] = resource;
|
|
213
232
|
}
|
|
214
|
-
if (!(await fs.exists(
|
|
215
|
-
await fs.mkdir(
|
|
233
|
+
if (!(await fs.exists(SUPERBLOCKS_HOME_FOLDER_NAME))) {
|
|
234
|
+
await fs.mkdir(SUPERBLOCKS_HOME_FOLDER_NAME);
|
|
216
235
|
}
|
|
217
236
|
// create superblocks.json file
|
|
218
|
-
await fs.writeFile(
|
|
237
|
+
await fs.writeFile(ctx.superblocksRootConfigPath ?? RESOURCE_CONFIG_PATH, JSON.stringify(sortByKey(superblocksConfig), null, 2));
|
|
219
238
|
},
|
|
220
239
|
},
|
|
221
240
|
], {
|
|
@@ -224,7 +243,6 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
224
243
|
return tasks;
|
|
225
244
|
}
|
|
226
245
|
async getResourcesToInitialize(ctx, task, args) {
|
|
227
|
-
var _a, _b;
|
|
228
246
|
if (args.resource_url) {
|
|
229
247
|
try {
|
|
230
248
|
const [resourceId] = getResourceIdFromUrl(args.resource_url);
|
|
@@ -242,37 +260,37 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
242
260
|
choices.push({
|
|
243
261
|
name: resourceId,
|
|
244
262
|
message: `${resource.name} (${resource.resourceType})`,
|
|
245
|
-
disabled:
|
|
263
|
+
disabled: ctx.existingSuperblocksRootConfig?.resources[resourceId],
|
|
246
264
|
});
|
|
247
|
-
if (
|
|
265
|
+
if (ctx.existingSuperblocksRootConfig?.resources[resourceId]) {
|
|
248
266
|
initialSelections.push(counter);
|
|
249
267
|
}
|
|
250
268
|
counter++;
|
|
251
269
|
}
|
|
252
|
-
if (
|
|
270
|
+
if (isEmpty(choices)) {
|
|
253
271
|
this.error(`No resources found in your account. Please make sure you have access to at least one application, workflow or scheduled job.`);
|
|
254
272
|
}
|
|
255
273
|
const resourceIdsToInitialize = await task.prompt([
|
|
256
274
|
{
|
|
257
275
|
type: "AutoComplete",
|
|
258
276
|
name: "resourceIdsToInitialize",
|
|
259
|
-
message: `Select resources to initialize (${
|
|
277
|
+
message: `Select resources to initialize (${MULTI_SELECT_PROMPT_HELP})`,
|
|
260
278
|
choices: choices,
|
|
261
279
|
initial: initialSelections,
|
|
262
280
|
multiple: true,
|
|
263
|
-
validate:
|
|
281
|
+
validate: atLeastOneSelection,
|
|
264
282
|
prefix: "▸",
|
|
265
283
|
indicator: "◉",
|
|
266
284
|
},
|
|
267
285
|
]);
|
|
268
286
|
const duplicates = await this.findDuplicates(resourceIdsToInitialize, ctx.fetchedResources);
|
|
269
|
-
if (!
|
|
287
|
+
if (!isEmpty(duplicates)) {
|
|
270
288
|
this.error(`Duplicate resources selected: ${duplicates
|
|
271
289
|
.map((duplicate) => `${duplicate.name} (${duplicate.resourceType}) id: ${duplicate.id}`)
|
|
272
290
|
.join(", ")}. Please make sure to select unique resources or rename them so that they have unique names.`);
|
|
273
291
|
}
|
|
274
292
|
// filter out disabled resources
|
|
275
|
-
return resourceIdsToInitialize.filter((resourceId) =>
|
|
293
|
+
return resourceIdsToInitialize.filter((resourceId) => !ctx.existingSuperblocksRootConfig?.resources[resourceId]);
|
|
276
294
|
}
|
|
277
295
|
}
|
|
278
296
|
async findDuplicates(selectedResourcesIds, resources) {
|
|
@@ -296,30 +314,6 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
|
|
|
296
314
|
return selectedResources.filter((resource) => countResourceNamesByType[resource.resourceType][resource.name] > 1);
|
|
297
315
|
}
|
|
298
316
|
}
|
|
299
|
-
Initialize.description = "Interactively configure the current directory as a Superblocks project or initialize new services in an already configured Superblocks project directory";
|
|
300
|
-
Initialize.examples = [
|
|
301
|
-
"<%= config.bin %> <%= command.id %>",
|
|
302
|
-
"<%= config.bin %> <%= command.id %> https://app.superblocks.com/applications/11111111-1111-1111-1111-111111111111/pages/22222222-2222-2222-2222-222222222222",
|
|
303
|
-
];
|
|
304
|
-
Initialize.flags = {
|
|
305
|
-
mode: core_1.Flags.string({
|
|
306
|
-
char: "m",
|
|
307
|
-
description: "Pull mode",
|
|
308
|
-
options: Object.keys(version_control_1.modeFlagValuesMap),
|
|
309
|
-
}),
|
|
310
|
-
"skip-signing-verification": core_1.Flags.boolean({
|
|
311
|
-
char: "s",
|
|
312
|
-
description: "If true, signature verification for signing enabled organizations will be skipped.",
|
|
313
|
-
default: false,
|
|
314
|
-
}),
|
|
315
|
-
};
|
|
316
|
-
Initialize.args = {
|
|
317
|
-
resource_url: core_1.Args.string({
|
|
318
|
-
description: "Superblocks resource URL (i.e. https://app.superblocks.com/applications/<application_id> or https://app.superblocks.com/applications/edit/<application_id>)",
|
|
319
|
-
required: false,
|
|
320
|
-
}),
|
|
321
|
-
};
|
|
322
|
-
exports.default = Initialize;
|
|
323
317
|
function getResourceIdFromUrl(resourceUrl) {
|
|
324
318
|
const url = new URL(resourceUrl);
|
|
325
319
|
if (url.pathname.startsWith("/applications")) {
|
|
@@ -2,7 +2,7 @@ import { Command } from "@oclif/core";
|
|
|
2
2
|
export default class Login extends Command {
|
|
3
3
|
static description: string;
|
|
4
4
|
static flags: {
|
|
5
|
-
token: import("@oclif/core/
|
|
5
|
+
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
6
|
};
|
|
7
7
|
DEFAULT_BASE_URL: string;
|
|
8
8
|
run(): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import { SuperblocksSdk } from "@superblocksteam/sdk";
|
|
3
|
+
import { FileAccessError, getLocalTokenWithUrlIfExists, saveApiToken, } from "@superblocksteam/util";
|
|
4
|
+
import { green, red } from "colorette";
|
|
5
|
+
import enquirer from "enquirer";
|
|
6
|
+
import { isEmpty } from "lodash-es";
|
|
7
|
+
const { prompt } = enquirer;
|
|
8
|
+
export default class Login extends Command {
|
|
9
|
+
static description = "Authenticate with Superblocks cloud";
|
|
10
|
+
static flags = {
|
|
11
|
+
// flag with a value (-t, --token=VALUE)
|
|
12
|
+
token: Flags.string({
|
|
13
|
+
char: "t",
|
|
14
|
+
description: "Superblocks user API key",
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
DEFAULT_BASE_URL = "https://app.superblocks.com/";
|
|
18
|
+
async run() {
|
|
19
|
+
const { flags } = await this.parse(Login);
|
|
20
|
+
let token = flags.token;
|
|
21
|
+
const result = await getLocalTokenWithUrlIfExists();
|
|
22
|
+
const superblocksBaseUrl = result?.superblocksBaseUrl ?? this.DEFAULT_BASE_URL;
|
|
23
|
+
if (!token) {
|
|
24
|
+
if (result && "token" in result) {
|
|
25
|
+
token = result.token;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const tokenPageUrl = new URL("personal-settings#apiKey", superblocksBaseUrl).href;
|
|
29
|
+
token = (await prompt({
|
|
30
|
+
type: "password",
|
|
31
|
+
name: "token",
|
|
32
|
+
message: `Enter your Superblocks API key (then press Enter) which can be found at ${tokenPageUrl}`,
|
|
33
|
+
validate: (response) => !isEmpty(response.trim()),
|
|
34
|
+
})).token;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
this.log();
|
|
38
|
+
try {
|
|
39
|
+
const sdk = new SuperblocksSdk(token, superblocksBaseUrl, this.config.version);
|
|
40
|
+
const user = await sdk.fetchCurrentUser();
|
|
41
|
+
await saveApiToken(superblocksBaseUrl, token);
|
|
42
|
+
this.log(green(`Welcome to the Superblocks 🐨 CLI ${user.user.name}!`));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof FileAccessError) {
|
|
46
|
+
this.log(red("Could not save token, ensure the Superblocks CLI has access to create folders in your home directory."));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (error.message) {
|
|
50
|
+
this.log(red(error.message));
|
|
51
|
+
}
|
|
52
|
+
this.log(red(`Login failed. Ensure you've copied the correct token from ${superblocksBaseUrl}. If using a different domain, run "superblocks help config set" for configuration options.`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|