@superblocksteam/cli 1.0.2 → 1.1.1

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 CHANGED
@@ -12,7 +12,7 @@ $ npm install -g @superblocksteam/cli
12
12
  $ superblocks COMMAND
13
13
  running command...
14
14
  $ superblocks (--version)
15
- @superblocksteam/cli/1.0.2 linux-x64 node-v18.18.0
15
+ @superblocksteam/cli/1.1.1 linux-x64 node-v18.18.2
16
16
  $ superblocks --help [COMMAND]
17
17
  USAGE
18
18
  $ superblocks COMMAND
@@ -27,11 +27,12 @@ USAGE
27
27
  * [`superblocks components watch`](#superblocks-components-watch)
28
28
  * [`superblocks config set PROPERTY VALUE`](#superblocks-config-set-property-value)
29
29
  * [`superblocks help [COMMANDS]`](#superblocks-help-commands)
30
- * [`superblocks init [RESOURCEURL]`](#superblocks-init-resourceurl)
30
+ * [`superblocks init [RESOURCE_URL]`](#superblocks-init-resource_url)
31
31
  * [`superblocks login`](#superblocks-login)
32
32
  * [`superblocks migrate`](#superblocks-migrate)
33
- * [`superblocks pull [ONLY]`](#superblocks-pull-only)
34
- * [`superblocks rm [RESOURCELOCATION]`](#superblocks-rm-resourcelocation)
33
+ * [`superblocks pull [RESOURCE_PATH]`](#superblocks-pull-resource_path)
34
+ * [`superblocks push [RESOURCE_PATH]`](#superblocks-push-resource_path)
35
+ * [`superblocks rm [RESOURCE_PATH]`](#superblocks-rm-resource_path)
35
36
 
36
37
  ## `superblocks components create`
37
38
 
@@ -69,13 +70,18 @@ Upload creates a production-ready bundle and saves the files for use outside of
69
70
 
70
71
  ```
71
72
  USAGE
72
- $ superblocks components upload
73
+ $ superblocks components upload [-b <value>]
74
+
75
+ FLAGS
76
+ -b, --branch=<value> Superblocks branch to push to, the current (local) git branch will be used by default
73
77
 
74
78
  DESCRIPTION
75
79
  Upload creates a production-ready bundle and saves the files for use outside of Local Development mode.
76
80
 
77
81
  EXAMPLES
78
82
  $ superblocks components upload
83
+
84
+ $ superblocks components upload -b feature-branch
79
85
  ```
80
86
 
81
87
  ## `superblocks components watch`
@@ -132,16 +138,17 @@ DESCRIPTION
132
138
 
133
139
  _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.16/src/commands/help.ts)_
134
140
 
135
- ## `superblocks init [RESOURCEURL]`
141
+ ## `superblocks init [RESOURCE_URL]`
136
142
 
137
143
  Interactively configure the current directory as a Superblocks project or initialize new services in an already configured Superblocks project directory
138
144
 
139
145
  ```
140
146
  USAGE
141
- $ superblocks init [RESOURCEURL] [-m latest-edits|most-recent-commit|deployed]
147
+ $ superblocks init [RESOURCE_URL] [-m latest-edits|most-recent-commit|deployed]
142
148
 
143
149
  ARGUMENTS
144
- RESOURCEURL Superblocks resource URL (i.e. https://app.superblocks.com/applications/<application_id>/pages/<page_id>)
150
+ RESOURCE_URL Superblocks resource URL (i.e.
151
+ https://app.superblocks.com/applications/<application_id>/pages/<page_id>)
145
152
 
146
153
  FLAGS
147
154
  -m, --mode=<option> Pull mode
@@ -187,20 +194,21 @@ EXAMPLES
187
194
  $ superblocks migrate
188
195
  ```
189
196
 
190
- ## `superblocks pull [ONLY]`
197
+ ## `superblocks pull [RESOURCE_PATH]`
191
198
 
192
199
  Download objects from Superblocks and save them locally
193
200
 
194
201
  ```
195
202
  USAGE
196
- $ superblocks pull [ONLY] [-m latest-edits|most-recent-commit|deployed]
203
+ $ superblocks pull [RESOURCE_PATH] [-m latest-edits|most-recent-commit|deployed] [-b <value>]
197
204
 
198
205
  ARGUMENTS
199
- ONLY Superblocks resource location to pull (i.e. apps/my-app or backends/my-workflow)
206
+ RESOURCE_PATH Superblocks resource location to pull (i.e. apps/my-app)
200
207
 
201
208
  FLAGS
202
- -m, --mode=<option> [default: latest-edits] Pull mode
203
- <options: latest-edits|most-recent-commit|deployed>
209
+ -b, --branch=<value> Superblocks branch to pull from, the current git branch will be used by default
210
+ -m, --mode=<option> [default: latest-edits] Pull mode
211
+ <options: latest-edits|most-recent-commit|deployed>
204
212
 
205
213
  DESCRIPTION
206
214
  Download objects from Superblocks and save them locally
@@ -210,21 +218,44 @@ EXAMPLES
210
218
 
211
219
  $ superblocks pull apps/my-app
212
220
 
213
- $ superblocks pull backends/my-workflow
221
+ $ superblocks pull apps/my-app -b feature-branch
222
+ ```
223
+
224
+ ## `superblocks push [RESOURCE_PATH]`
225
+
226
+ Import objects from local filesystem to Superblocks
227
+
228
+ ```
229
+ USAGE
230
+ $ superblocks push [RESOURCE_PATH] [-b <value>]
231
+
232
+ ARGUMENTS
233
+ RESOURCE_PATH Superblocks resource location to push (e.g. apps/my-app)
234
+
235
+ FLAGS
236
+ -b, --branch=<value> Superblocks branch to push to, the current git branch will be used by default
237
+
238
+ DESCRIPTION
239
+ Import objects from local filesystem to Superblocks
240
+
241
+ EXAMPLES
242
+ $ superblocks push
243
+
244
+ $ superblocks push apps/my-app
214
245
 
215
- $ superblocks pull backends/my-scheduled-job
246
+ $ superblocks push apps/my-app -b feature-branch
216
247
  ```
217
248
 
218
- ## `superblocks rm [RESOURCELOCATION]`
249
+ ## `superblocks rm [RESOURCE_PATH]`
219
250
 
220
251
  Remove a Superblocks resource from the local Superblocks project and delete the resource folder directory locally (if it exists)
221
252
 
222
253
  ```
223
254
  USAGE
224
- $ superblocks rm [RESOURCELOCATION]
255
+ $ superblocks rm [RESOURCE_PATH]
225
256
 
226
257
  ARGUMENTS
227
- RESOURCELOCATION Superblocks resource location (i.e. apps/my-spectacular-app)
258
+ RESOURCE_PATH Superblocks resource location (i.e. apps/my-spectacular-app)
228
259
 
229
260
  DESCRIPTION
230
261
  Remove a Superblocks resource from the local Superblocks project and delete the resource folder directory locally (if
@@ -7,7 +7,7 @@
7
7
  "lint:fix": "npx eslint . --fix"
8
8
  },
9
9
  "dependencies": {
10
- "@superblocksteam/custom-components": "1.0.2",
10
+ "@superblocksteam/custom-components": "1.1.1",
11
11
  "react": "^18",
12
12
  "react-dom": "^18"
13
13
  },
@@ -2,5 +2,8 @@ import { AuthenticatedApplicationCommand } from "../../common/authenticated-comm
2
2
  export default class Upload extends AuthenticatedApplicationCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ };
5
8
  run(): Promise<void>;
6
9
  }
@@ -7,11 +7,14 @@ const css_plugin_1 = require("@superblocksteam/css-plugin");
7
7
  const react_shim_1 = require("@superblocksteam/react-shim");
8
8
  const util_1 = require("@superblocksteam/util");
9
9
  const plugin_react_1 = tslib_1.__importDefault(require("@vitejs/plugin-react"));
10
+ const colorette_1 = require("colorette");
10
11
  const fs = tslib_1.__importStar(require("fs-extra"));
11
12
  const vite_1 = require("vite");
12
13
  const authenticated_command_1 = require("../../common/authenticated-command");
14
+ const version_control_1 = require("../../common/version-control");
13
15
  class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
14
16
  async run() {
17
+ const { flags } = await this.parse(Upload);
15
18
  core_1.ux.action.start("Scanning for Superblocks components...");
16
19
  const exists = await fs.pathExists(util_1.CUSTOM_COMPONENTS_PATH);
17
20
  if (!exists) {
@@ -20,6 +23,7 @@ class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
20
23
  exit: 1,
21
24
  });
22
25
  }
26
+ const branch = flags.branch || (await (0, version_control_1.getCurrentGitBranchIfGit)());
23
27
  const headers = {
24
28
  [util_1.COMPONENT_EVENT_HEADER]: util_1.ComponentEvent.REGISTER,
25
29
  };
@@ -89,7 +93,7 @@ class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
89
93
  ];
90
94
  await walkThroughDirectory(".", fileRelativePaths, excluded);
91
95
  this.log(fileRelativePaths.join("\n"));
92
- await this.getSdk().uploadComponents(this.applicationConfig.id, configs, fileRelativePaths);
96
+ await this.getSdk().uploadComponents(this.applicationConfig.id, configs, fileRelativePaths, branch);
93
97
  core_1.ux.action.stop();
94
98
  }
95
99
  catch (e) {
@@ -97,10 +101,20 @@ class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
97
101
  this.error(`Failed to upload components - ${e.message}`, { exit: 1 });
98
102
  }
99
103
  this.log("You can now disable local dev mode and test your production assets");
104
+ this.log((0, colorette_1.bold)((0, colorette_1.green)("Once you are done developing please remember to commit your changes in the Superblocks UI.")));
100
105
  }
101
106
  }
102
107
  Upload.description = "Upload creates a production-ready bundle and saves the files for use outside of Local Development mode.";
103
- Upload.examples = ["<%= config.bin %> components upload"];
108
+ Upload.examples = [
109
+ "<%= config.bin %> components upload",
110
+ "<%= config.bin %> components upload -b feature-branch",
111
+ ];
112
+ Upload.flags = {
113
+ branch: core_1.Flags.string({
114
+ char: "b",
115
+ description: "Superblocks branch to push to, the current (local) git branch will be used by default",
116
+ }),
117
+ };
104
118
  exports.default = Upload;
105
119
  async function walkThroughDirectory(directory, mutableFiles, excluded) {
106
120
  const files = await fs.readdir(directory);
@@ -9,17 +9,29 @@ const plugin_react_1 = tslib_1.__importDefault(require("@vitejs/plugin-react"));
9
9
  const colorette_1 = require("colorette");
10
10
  const vite_1 = require("vite");
11
11
  const authenticated_command_1 = require("../../common/authenticated-command");
12
+ const version_control_1 = require("../../common/version-control");
12
13
  function healthEndpointMiddleware() {
13
14
  return {
14
15
  name: "health-endpoint-middleware",
15
16
  configureServer: (server) => {
16
- server.middlewares.use("/health", (req, res) => {
17
+ server.middlewares.use("/health", async (req, res) => {
18
+ let branch;
19
+ try {
20
+ branch = await (0, version_control_1.getCurrentGitBranchIfGit)();
21
+ }
22
+ catch (e) {
23
+ branch = null;
24
+ }
25
+ const gitState = branch
26
+ ? { active: true, branch }
27
+ : { active: false };
17
28
  res.setHeader("Cache-Control", "no-cache");
18
29
  res.setHeader("Content-Type", "application/json");
19
30
  res.setHeader("Access-Control-Allow-Origin", "*");
20
31
  const response = {
21
32
  status: "up",
22
33
  uptime: Math.floor(process.uptime()),
34
+ git: gitState,
23
35
  };
24
36
  res.write(JSON.stringify(response) + "\n");
25
37
  res.end();
@@ -36,8 +48,13 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
36
48
  await this.registerComponents(headers);
37
49
  this.log((0, colorette_1.yellow)("Remember to refresh your application to see any newly registered components."));
38
50
  this.log();
51
+ const editModeUrl = new URL(await this.getEditModeUrl());
52
+ editModeUrl.searchParams.set("devMode", "true");
53
+ const branch = await (0, version_control_1.getCurrentGitBranchIfGit)();
54
+ if (branch) {
55
+ editModeUrl.searchParams.set("branch", branch);
56
+ }
39
57
  const port = 3002;
40
- const editModeUrl = await this.getEditModeUrl();
41
58
  const viteLogger = (0, vite_1.createLogger)();
42
59
  viteLogger.info = (message) => {
43
60
  this.log(message);
@@ -67,7 +84,7 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
67
84
  plugins: [
68
85
  healthEndpointMiddleware(),
69
86
  (0, plugin_react_1.default)(),
70
- (0, vite_custom_component_reload_plugin_1.appendHotReloadEventPlugin)(),
87
+ (0, vite_custom_component_reload_plugin_1.appendHotReloadEventPlugin)(version_control_1.getCurrentGitBranchIfGit),
71
88
  (0, react_shim_1.injectReactVersionsPlugin)(),
72
89
  ],
73
90
  });
@@ -75,7 +92,7 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
75
92
  this.log((0, colorette_1.green)(`Local server started at port ${port}`));
76
93
  this.log((0, colorette_1.green)(`Visit your application at:`));
77
94
  this.log();
78
- this.log((0, colorette_1.bold)((0, colorette_1.magenta)(`${editModeUrl}?devMode=true`)));
95
+ this.log((0, colorette_1.bold)((0, colorette_1.magenta)(editModeUrl.href)));
79
96
  this.log();
80
97
  this.log((0, colorette_1.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: ${(0, colorette_1.magenta)("https://docs.superblocks.com/applications/custom-components/development-lifecycle#local-development-mode")}`));
81
98
  })();
@@ -6,7 +6,7 @@ export default class Initialize extends AuthenticatedCommand {
6
6
  mode: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
7
  };
8
8
  static args: {
9
- resourceUrl: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
9
+ resource_url: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
10
10
  };
11
11
  run(): Promise<void>;
12
12
  private createTasks;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ const path_1 = tslib_1.__importDefault(require("path"));
4
5
  const core_1 = require("@oclif/core");
5
6
  const util_1 = require("@superblocksteam/util");
6
7
  const fs = tslib_1.__importStar(require("fs-extra"));
@@ -27,7 +28,10 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
27
28
  ctx.fetchedResources = {};
28
29
  ctx.writtenResources = {};
29
30
  try {
30
- ctx.existingSuperblocksConfig = (await (0, util_1.getSuperblocksMonorepoConfigJson)(true))[0];
31
+ [
32
+ ctx.existingSuperblocksRootConfig,
33
+ ctx.superblocksRootConfigPath,
34
+ ] = await (0, util_1.getSuperblocksMonorepoConfigJson)(true);
31
35
  }
32
36
  catch {
33
37
  // no existing superblocks config
@@ -39,7 +43,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
39
43
  task: (ctx, task) => task.newListr([
40
44
  {
41
45
  title: "Fetching applications...",
42
- enabled: () => !args.resourceUrl,
46
+ enabled: () => !args.resource_url,
43
47
  task: async (ctx, task) => {
44
48
  // applications choices
45
49
  const applications = await this.getSdk().fetchApplications();
@@ -56,15 +60,16 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
56
60
  },
57
61
  {
58
62
  title: "Fetching resource by resourceUrl...",
59
- enabled: () => args.resourceUrl,
63
+ enabled: () => !(0, lodash_1.isEmpty)(args.resource_url),
60
64
  task: async (ctx, task) => {
61
- const [resourceId, resourceType] = getResourceIdFromUrl(args.resourceUrl);
65
+ const [resourceId, resourceType] = getResourceIdFromUrl(args.resource_url);
62
66
  if (resourceType === "APPLICATION") {
63
67
  const headers = {
64
68
  [util_1.COMPONENT_EVENT_HEADER]: util_1.ComponentEvent.INIT,
65
69
  };
66
70
  const application = await this.getSdk().fetchApplicationWithComponents({
67
71
  applicationId: resourceId,
72
+ branch: version_control_1.DEFAULT_BRANCH,
68
73
  headers,
69
74
  });
70
75
  if (!application) {
@@ -100,6 +105,11 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
100
105
  title: "Writing resources to a disk...",
101
106
  task: async (ctx, task) => {
102
107
  const subtasks = [];
108
+ // if ctx.superblocksRootConfigPath is defined, we are initializing a new resource in an existing Superblocks project
109
+ // otherwise, we are initializing a new Superblocks project
110
+ const superblocksRootPath = ctx.superblocksRootConfigPath
111
+ ? path_1.default.resolve(path_1.default.dirname(ctx.superblocksRootConfigPath), "..")
112
+ : undefined;
103
113
  for (const resourceId of ctx.resourceIdsToInitialize) {
104
114
  const resource = ctx.fetchedResources[resourceId];
105
115
  if (!resource) {
@@ -115,12 +125,13 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
115
125
  };
116
126
  const application = await this.getSdk().fetchApplicationWithComponents({
117
127
  applicationId: resourceId,
128
+ branch: version_control_1.DEFAULT_BRANCH,
118
129
  viewMode: ctx.viewMode,
119
130
  headers,
120
131
  });
121
132
  task.title += `: fetched`;
122
133
  ctx.writtenResources[resourceId] =
123
- await (0, version_control_1.writeResourceToDisk)("APPLICATION", resourceId, application, process.cwd());
134
+ await (0, version_control_1.writeResourceToDisk)("APPLICATION", resourceId, application, superblocksRootPath !== null && superblocksRootPath !== void 0 ? superblocksRootPath : process.cwd());
124
135
  task.title += `: done`;
125
136
  },
126
137
  });
@@ -152,7 +163,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
152
163
  {
153
164
  title: "Updating Superblocks project file...",
154
165
  task: async (ctx) => {
155
- var _a, _b;
166
+ var _a, _b, _c;
156
167
  const superblocksConfig = {
157
168
  configType: "ROOT",
158
169
  resources: {},
@@ -165,14 +176,14 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
165
176
  superblocksConfig.resources[resourceId] = resource;
166
177
  }
167
178
  // existing resources
168
- for (const [resourceId, resource] of Object.entries((_b = (_a = ctx.existingSuperblocksConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {})) {
179
+ for (const [resourceId, resource] of Object.entries((_b = (_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {})) {
169
180
  superblocksConfig.resources[resourceId] = resource;
170
181
  }
171
182
  if (!(await fs.exists(util_1.SUPERBLOCKS_HOME_FOLDER_NAME))) {
172
183
  await fs.mkdir(util_1.SUPERBLOCKS_HOME_FOLDER_NAME);
173
184
  }
174
185
  // create superblocks.json file
175
- await fs.writeFile(util_1.RESOURCE_CONFIG_PATH, JSON.stringify((0, version_control_1.sortByKey)(superblocksConfig), null, 2));
186
+ await fs.writeFile((_c = ctx.superblocksRootConfigPath) !== null && _c !== void 0 ? _c : util_1.RESOURCE_CONFIG_PATH, JSON.stringify((0, version_control_1.sortByKey)(superblocksConfig), null, 2));
176
187
  },
177
188
  },
178
189
  ], {
@@ -182,13 +193,13 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
182
193
  }
183
194
  async getResourcesToInitialize(ctx, task, args) {
184
195
  var _a, _b;
185
- if (args.resourceUrl) {
196
+ if (args.resource_url) {
186
197
  try {
187
- const [resourceId] = getResourceIdFromUrl(args.resourceUrl);
198
+ const [resourceId] = getResourceIdFromUrl(args.resource_url);
188
199
  return [resourceId];
189
200
  }
190
201
  catch {
191
- throw new Error(`Invalid resource URL: ${args.resourceUrl}`);
202
+ throw new Error(`Invalid resource URL: ${args.resource_url}`);
192
203
  }
193
204
  }
194
205
  else {
@@ -199,9 +210,9 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
199
210
  choices.push({
200
211
  name: resourceId,
201
212
  message: `${resource.name} (${resource.resourceType})`,
202
- disabled: (_a = ctx.existingSuperblocksConfig) === null || _a === void 0 ? void 0 : _a.resources[resourceId],
213
+ disabled: (_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources[resourceId],
203
214
  });
204
- if ((_b = ctx.existingSuperblocksConfig) === null || _b === void 0 ? void 0 : _b.resources[resourceId]) {
215
+ if ((_b = ctx.existingSuperblocksRootConfig) === null || _b === void 0 ? void 0 : _b.resources[resourceId]) {
205
216
  initialSelections.push(counter);
206
217
  }
207
218
  counter++;
@@ -229,7 +240,7 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
229
240
  .join(", ")}. Please make sure to select unique resources or rename them so that they have unique names.`);
230
241
  }
231
242
  // filter out disabled resources
232
- return resourceIdsToInitialize.filter((resourceId) => { var _a; return !((_a = ctx.existingSuperblocksConfig) === null || _a === void 0 ? void 0 : _a.resources[resourceId]); });
243
+ return resourceIdsToInitialize.filter((resourceId) => { var _a; return !((_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources[resourceId]); });
233
244
  }
234
245
  }
235
246
  async findDuplicates(selectedResourcesIds, resources) {
@@ -266,7 +277,7 @@ Initialize.flags = {
266
277
  }),
267
278
  };
268
279
  Initialize.args = {
269
- resourceUrl: core_1.Args.string({
280
+ resource_url: core_1.Args.string({
270
281
  description: "Superblocks resource URL (i.e. https://app.superblocks.com/applications/<application_id>/pages/<page_id>)",
271
282
  required: false,
272
283
  }),
@@ -15,15 +15,13 @@ class Login extends core_1.Command {
15
15
  var _a;
16
16
  const { flags } = await this.parse(Login);
17
17
  let token = flags.token;
18
- let superblocksBaseUrl = "";
18
+ const result = await (0, util_1.getLocalTokenWithUrlIfExists)();
19
+ const superblocksBaseUrl = (_a = result === null || result === void 0 ? void 0 : result.superblocksBaseUrl) !== null && _a !== void 0 ? _a : this.DEFAULT_BASE_URL;
19
20
  if (!token) {
20
- const result = await (0, util_1.getLocalTokenWithUrlIfExists)();
21
21
  if (result && "token" in result) {
22
- ({ token, superblocksBaseUrl } = result);
22
+ token = result.token;
23
23
  }
24
24
  else {
25
- superblocksBaseUrl =
26
- (_a = result === null || result === void 0 ? void 0 : result.superblocksBaseUrl) !== null && _a !== void 0 ? _a : this.DEFAULT_BASE_URL;
27
25
  const tokenPageUrl = new URL("personal-settings#apiKey", superblocksBaseUrl).href;
28
26
  token = (await (0, enquirer_1.prompt)({
29
27
  type: "password",
@@ -4,9 +4,10 @@ export default class Pull extends AuthenticatedCommand {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  mode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
8
  };
8
9
  static args: {
9
- only: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
10
+ resource_path: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
10
11
  };
11
12
  run(): Promise<void>;
12
13
  private createTasks;
@@ -11,10 +11,10 @@ const version_control_1 = require("../common/version-control");
11
11
  class Pull extends authenticated_command_1.AuthenticatedCommand {
12
12
  async run() {
13
13
  const { flags, args } = await this.parse(Pull);
14
- const tasks = this.createTasks(args.only, flags.mode);
14
+ const tasks = this.createTasks(args.resource_path, flags.mode, flags.branch);
15
15
  await tasks.run();
16
16
  }
17
- createTasks(only, mode) {
17
+ createTasks(resourcePath, mode, branch) {
18
18
  const tasks = new listr2_1.Listr([
19
19
  {
20
20
  title: "Checking for existing Superblocks project...",
@@ -35,6 +35,18 @@ class Pull extends authenticated_command_1.AuthenticatedCommand {
35
35
  }
36
36
  },
37
37
  },
38
+ {
39
+ title: "Checking for existing git repository...",
40
+ task: async (ctx) => {
41
+ try {
42
+ ctx.pullFromBranchName =
43
+ branch || (await (0, version_control_1.getCurrentGitBranchIfGit)()) || version_control_1.DEFAULT_BRANCH;
44
+ }
45
+ catch (e) {
46
+ this.error(`Failed to check for existing git repository: ${e.message}. Please make sure to clone or initialize a git repository.`);
47
+ }
48
+ },
49
+ },
38
50
  {
39
51
  title: "Checking for deleted Superblocks resources...",
40
52
  task: async (ctx, task) => {
@@ -46,6 +58,8 @@ class Pull extends authenticated_command_1.AuthenticatedCommand {
46
58
  try {
47
59
  await this.getSdk().fetchApplication({
48
60
  applicationId: resourceId,
61
+ //NOTE(alex): using default branch since we assume that the resource is deleted if it's deleted from the default branch
62
+ branch: version_control_1.DEFAULT_BRANCH,
49
63
  });
50
64
  }
51
65
  catch (error) {
@@ -108,11 +122,11 @@ Would you like to also delete these resources from your filesystem?`,
108
122
  },
109
123
  },
110
124
  {
111
- title: "Pulling resources...",
112
125
  task: async (ctx, task) => {
113
126
  var _a;
127
+ task.title = `Pulling resources from branch ${ctx.pullFromBranchName}...`;
114
128
  const viewMode = await (0, version_control_1.getMode)(task, mode);
115
- const resourceIdsToPull = await this.getResourceIdsToPull(ctx, task, only);
129
+ const resourceIdsToPull = await this.getResourceIdsToPull(ctx, task, resourcePath);
116
130
  const subtasks = [];
117
131
  const superblocksRootPath = node_path_1.default.resolve(node_path_1.default.dirname(ctx.superblocksRootConfigPath), "..");
118
132
  for (const resourceId of resourceIdsToPull) {
@@ -120,20 +134,33 @@ Would you like to also delete these resources from your filesystem?`,
120
134
  switch (resource === null || resource === void 0 ? void 0 : resource.resourceType) {
121
135
  case "APPLICATION": {
122
136
  subtasks.push({
123
- title: `Pulling application ${resource.location}...`,
137
+ title: `Pulling application ${resource.location} from branch ${ctx.pullFromBranchName}...`,
124
138
  task: async (_ctx, task) => {
125
139
  const headers = {
126
140
  [util_1.COMPONENT_EVENT_HEADER]: util_1.ComponentEvent.PULL,
127
141
  };
128
- const application = await this.getSdk().fetchApplicationWithComponents({
129
- applicationId: resourceId,
130
- viewMode,
131
- headers,
132
- });
133
- task.title += `: fetched`;
134
- ctx.writtenResources[resourceId] =
135
- await (0, version_control_1.writeResourceToDisk)("APPLICATION", resourceId, application, superblocksRootPath, resource.location);
136
- task.title += `: done`;
142
+ try {
143
+ const application = await this.getSdk().fetchApplicationWithComponents({
144
+ applicationId: resourceId,
145
+ branch: ctx.pullFromBranchName,
146
+ viewMode,
147
+ headers,
148
+ });
149
+ task.title += `: fetched`;
150
+ ctx.writtenResources[resourceId] =
151
+ await (0, version_control_1.writeResourceToDisk)("APPLICATION", resourceId, application, superblocksRootPath, resource.location);
152
+ task.title += `: done`;
153
+ }
154
+ catch (e) {
155
+ if (e instanceof util_1.NotFoundError) {
156
+ //NOTE(alex): today, branches are not shared between applications, so we can't pull from a branch that doesn't exist in the current application
157
+ //once we have shared branches, we can remove this catch block
158
+ task.title += `: not found in this branch. skipped`;
159
+ }
160
+ else {
161
+ throw e;
162
+ }
163
+ }
137
164
  },
138
165
  });
139
166
  break;
@@ -178,19 +205,19 @@ Would you like to also delete these resources from your filesystem?`,
178
205
  });
179
206
  return tasks;
180
207
  }
181
- async getResourceIdsToPull(ctx, task, only) {
208
+ async getResourceIdsToPull(ctx, task, resourcePath) {
182
209
  var _a, _b, _c, _d, _e, _f, _g;
183
- if (only) {
210
+ if (resourcePath) {
184
211
  for (const [resourceId, resource] of Object.entries((_b = (_a = ctx.existingSuperblocksRootConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {})) {
185
- if (resource.location === only) {
212
+ if (resource.location === resourcePath) {
186
213
  return [resourceId];
187
214
  }
188
215
  }
189
- const resource = Object.entries((_d = (_c = ctx.existingSuperblocksRootConfig) === null || _c === void 0 ? void 0 : _c.resources) !== null && _d !== void 0 ? _d : {}).find(([, resource]) => resource.location === only);
216
+ const resource = Object.entries((_d = (_c = ctx.existingSuperblocksRootConfig) === null || _c === void 0 ? void 0 : _c.resources) !== null && _d !== void 0 ? _d : {}).find(([, resource]) => resource.location === resourcePath);
190
217
  if (resource) {
191
218
  return [resource[0]];
192
219
  }
193
- throw new Error(`No resource found with the given location: ${only}`);
220
+ throw new Error(`No resource found with the given location: ${resourcePath}`);
194
221
  }
195
222
  const choices = [];
196
223
  const initialSelections = [];
@@ -229,8 +256,7 @@ Pull.description = "Download objects from Superblocks and save them locally";
229
256
  Pull.examples = [
230
257
  "<%= config.bin %> <%= command.id %>",
231
258
  "<%= config.bin %> <%= command.id %> apps/my-app",
232
- "<%= config.bin %> <%= command.id %> backends/my-workflow",
233
- "<%= config.bin %> <%= command.id %> backends/my-scheduled-job",
259
+ "<%= config.bin %> <%= command.id %> apps/my-app -b feature-branch",
234
260
  ];
235
261
  Pull.flags = {
236
262
  mode: core_1.Flags.string({
@@ -239,10 +265,14 @@ Pull.flags = {
239
265
  options: Object.keys(version_control_1.modeFlagValuesMap),
240
266
  default: version_control_1.LATEST_EDITS_MODE,
241
267
  }),
268
+ branch: core_1.Flags.string({
269
+ char: "b",
270
+ description: "Superblocks branch to pull from, the current git branch will be used by default",
271
+ }),
242
272
  };
243
273
  Pull.args = {
244
- only: core_1.Args.string({
245
- description: "Superblocks resource location to pull (i.e. apps/my-app or backends/my-workflow)",
274
+ resource_path: core_1.Args.string({
275
+ description: "Superblocks resource location to pull (i.e. apps/my-app)",
246
276
  required: false,
247
277
  }),
248
278
  };
@@ -0,0 +1,14 @@
1
+ import { AuthenticatedCommand } from "../common/authenticated-command";
2
+ export default class Push extends AuthenticatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ };
8
+ static args: {
9
+ resource_path: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
10
+ };
11
+ run(): Promise<void>;
12
+ private createTasks;
13
+ private getResourceIdsToPush;
14
+ }