@superblocksteam/cli 0.0.19 → 0.0.21

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/0.0.19 linux-x64 node-v18.17.0
15
+ @superblocksteam/cli/0.0.21 linux-x64 node-v18.17.0
16
16
  $ superblocks --help [COMMAND]
17
17
  USAGE
18
18
  $ superblocks COMMAND
@@ -29,6 +29,7 @@ USAGE
29
29
  * [`superblocks help [COMMANDS]`](#superblocks-help-commands)
30
30
  * [`superblocks init [RESOURCEURL]`](#superblocks-init-resourceurl)
31
31
  * [`superblocks login`](#superblocks-login)
32
+ * [`superblocks migrate`](#superblocks-migrate)
32
33
  * [`superblocks pull [ONLY]`](#superblocks-pull-only)
33
34
 
34
35
  ## `superblocks components create`
@@ -125,7 +126,7 @@ DESCRIPTION
125
126
  Display help for superblocks.
126
127
  ```
127
128
 
128
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.10/src/commands/help.ts)_
129
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.16/src/commands/help.ts)_
129
130
 
130
131
  ## `superblocks init [RESOURCEURL]`
131
132
 
@@ -154,7 +155,7 @@ EXAMPLES
154
155
 
155
156
  ## `superblocks login`
156
157
 
157
- Authenticates with Superblocks cloud
158
+ Authenticate with Superblocks cloud
158
159
 
159
160
  ```
160
161
  USAGE
@@ -164,7 +165,22 @@ FLAGS
164
165
  -t, --token=<value> Superblocks user API key
165
166
 
166
167
  DESCRIPTION
167
- Authenticates with Superblocks cloud
168
+ Authenticate with Superblocks cloud
169
+ ```
170
+
171
+ ## `superblocks migrate`
172
+
173
+ Migrate files to use the current CLI version
174
+
175
+ ```
176
+ USAGE
177
+ $ superblocks migrate
178
+
179
+ DESCRIPTION
180
+ Migrate files to use the current CLI version
181
+
182
+ EXAMPLES
183
+ $ superblocks migrate
168
184
  ```
169
185
 
170
186
  ## `superblocks pull [ONLY]`
@@ -1,20 +1,23 @@
1
1
  import React, { useCallback, useState } from "react";
2
+ import { useSuperblocksContext } from "@superblocksteam/custom-components";
3
+ import { type Props, type EventTriggers } from "./types";
2
4
  import { Task, ErrorComponent, validateTasks } from "./validation";
3
- import { Props } from "./types";
4
5
  import "./main.scss";
5
6
 
6
- export default function Component({
7
- updateStatefulProperties,
8
- tasks,
9
- onTaskAdded,
10
- onTaskStatusChanged,
11
- }: Props) {
12
- const { validatedTasks, hasError } = validateTasks(tasks);
7
+ export default function Component({ tasks }: Props) {
8
+ const {
9
+ updateProperties,
10
+ events : {
11
+ onTaskAdded,
12
+ onTaskStatusChanged,
13
+ },
14
+ } = useSuperblocksContext<Props, EventTriggers>();
15
+ const { validatedTasks, hasError } = validateTasks(tasks ?? {});
13
16
  const [value, setValue] = useState("");
14
17
 
15
18
  const onTodoAdded = useCallback(() => {
16
19
  const id = Math.random().toString(36).substring(2, 8);
17
- updateStatefulProperties({
20
+ updateProperties({
18
21
  tasks: {
19
22
  ...validatedTasks,
20
23
  [id]: {
@@ -24,11 +27,11 @@ export default function Component({
24
27
  },
25
28
  });
26
29
  onTaskAdded();
27
- }, [updateStatefulProperties, validatedTasks, value, onTaskAdded]);
30
+ }, [updateProperties, validatedTasks, value, onTaskAdded]);
28
31
 
29
32
  const onTaskStatusChange = useCallback(
30
33
  (id: string, status: boolean) => {
31
- updateStatefulProperties({
34
+ updateProperties({
32
35
  tasks: {
33
36
  ...validatedTasks,
34
37
  [id]: {
@@ -39,7 +42,7 @@ export default function Component({
39
42
  });
40
43
  onTaskStatusChanged();
41
44
  },
42
- [updateStatefulProperties, validatedTasks, tasks, onTaskStatusChanged]
45
+ [updateProperties, validatedTasks, tasks, onTaskStatusChanged]
43
46
  );
44
47
 
45
48
  return hasError ? (
@@ -7,11 +7,11 @@
7
7
  "lint:fix": "npx eslint . --fix"
8
8
  },
9
9
  "dependencies": {
10
+ "@superblocksteam/custom-components": "0.0.21",
10
11
  "react": "^18",
11
12
  "react-dom": "^18"
12
13
  },
13
14
  "devDependencies": {
14
- "@superblocksteam/cli": "0.0.19",
15
15
  "@types/react": "^18",
16
16
  "@types/react-dom": "^18",
17
17
  "@typescript-eslint/eslint-plugin": "^5.62.0",
@@ -1,6 +1,7 @@
1
1
  import { AuthenticatedApplicationCommand } from "../../common/authenticated-command";
2
2
  export default class CreateComponent extends AuthenticatedApplicationCommand {
3
3
  static description: string;
4
+ private dataTypeToDefaultControlType;
4
5
  private initializeComponentByWizard;
5
6
  private initializeComponentByExample;
6
7
  run(): Promise<void>;
@@ -27,11 +27,26 @@ const tsStringify = (obj) => {
27
27
  return `{\n${stringifiedEntries.join(",\n")}\n},\n`;
28
28
  };
29
29
  class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCommand {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.dataTypeToDefaultControlType = (propertyType) => {
33
+ switch (propertyType) {
34
+ case "any":
35
+ return "js-expr";
36
+ case "boolean":
37
+ return "switch";
38
+ default:
39
+ return "text";
40
+ }
41
+ };
42
+ }
30
43
  async initializeComponentByWizard(isFirstTimeCreate) {
44
+ this.log(`${(0, colorette_1.cyanBright)("ℹ")} Follow this wizard to configure your Custom Component. You can always edit the generated config.ts file directly to modify your properties or events.`);
45
+ this.log();
31
46
  const displayName = (await (0, enquirer_1.prompt)({
32
47
  type: "input",
33
48
  name: "displayName",
34
- message: "What is the display name of the component you want to create? (e.g. Date Picker)",
49
+ message: "What is the display name of the component you want to create? (e.g. To-Do List)",
35
50
  validate: (response) => !(0, lodash_1.isEmpty)(response.trim()),
36
51
  })).displayName;
37
52
  const name = (await (0, enquirer_1.prompt)({
@@ -39,112 +54,121 @@ class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCo
39
54
  name: "name",
40
55
  message: "What is the machine readable name of the component you want to create?",
41
56
  validate: (response) => (0, identifiers_1.isValidIdentifier)(response) || "Invalid identifier",
42
- initial: (0, identifiers_1.suggestIdentifier)(displayName, true) || "DatePicker",
57
+ initial: (0, identifiers_1.suggestIdentifier)(displayName, true) || "ToDoList",
43
58
  })).name;
44
59
  this.log();
45
- this.log(`${(0, colorette_1.cyanBright)("ℹ")} A ${(0, colorette_1.bold)("stateful property")} determines what shows up in the properties panel of a custom component`);
60
+ this.log(`${(0, colorette_1.cyanBright)("ℹ")} Properties represent the state of the component. You will define how each property is made available to the rest of your App and whether each property is displayed in the Properties Panel. Read more about properties here: ${(0, colorette_1.magenta)("https://docs.superblocks.com/applications/custom-components/#properties--events")}`);
46
61
  this.log();
47
- const hasStatefulProps = (await (0, enquirer_1.prompt)({
62
+ const hasProperties = (await (0, enquirer_1.prompt)({
48
63
  type: "confirm",
49
- name: "hasStatefulProps",
50
- message: `Does this component have ${(0, colorette_1.bold)("stateful properties")}?`,
64
+ name: "hasProperties",
65
+ message: `Does this component have ${(0, colorette_1.bold)("properties")}?`,
51
66
  initial: false,
52
- })).hasStatefulProps;
53
- const statefulProps = [];
54
- if (hasStatefulProps) {
67
+ })).hasProperties;
68
+ const properties = [];
69
+ if (hasProperties) {
55
70
  for (;;) {
56
- const statefulPropName = (await (0, enquirer_1.prompt)({
57
- type: "input",
58
- name: "statefulPropName",
59
- message: "What is the label of the stateful prop? (e.g. Selected Date)",
60
- validate: (response) => !(0, lodash_1.isEmpty)(response.trim()),
61
- })).statefulPropName.trim();
62
- const statefulPropPath = (await (0, enquirer_1.prompt)({
71
+ const propertyPath = (await (0, enquirer_1.prompt)({
63
72
  type: "input",
64
73
  name: "path",
65
- initial: (0, identifiers_1.suggestIdentifier)(statefulPropName) || "selectedDate",
66
- message: "What is the machine readable name of the stateful prop?",
74
+ message: "What is the path of the property? This will be used to access the property in your code (e.g. currentTasks)",
67
75
  validate: (response) => {
68
76
  if (!(0, identifiers_1.isValidIdentifier)(response))
69
77
  return "Invalid identifier";
70
- if (statefulProps.some((v) => v.path === response))
78
+ if (properties.some((v) => v.path === response))
71
79
  return "Duplicate property name";
72
80
  return true;
73
81
  },
74
82
  })).path;
75
- const statefulPropType = (await (0, enquirer_1.prompt)({
83
+ const propertyType = (await (0, enquirer_1.prompt)({
76
84
  type: "select",
77
85
  name: "type",
78
- message: `What input type should ${statefulPropName} be?`,
79
- choices: Object.entries(util_1.inputTypeDefinions).map(([k, v]) => ({
86
+ message: `What is the type of ${propertyPath}?`,
87
+ choices: Object.entries(util_1.dataTypeDefinions).map(([k, v]) => ({
80
88
  name: k,
81
89
  message: v.prompt,
82
90
  value: k,
83
91
  })),
84
92
  initial: 0,
85
93
  })).type;
86
- const placeholderText = (await (0, enquirer_1.prompt)({
87
- type: "input",
94
+ const showInPropsPanel = (await (0, enquirer_1.prompt)({
88
95
  name: "value",
89
- message: `What placeholder text should ${statefulPropName} have, if any?`,
90
- required: false,
96
+ type: "confirm",
97
+ message: "Should this property be shown in the properties panel?",
98
+ initial: true,
91
99
  })).value;
92
- statefulProps.push({
93
- label: statefulPropName,
94
- path: statefulPropPath,
95
- inputType: statefulPropType,
96
- placeholder: placeholderText || undefined,
100
+ let propertiesPanelDisplay = undefined;
101
+ if (showInPropsPanel) {
102
+ this.log();
103
+ this.log((0, colorette_1.bold)("Properties Panel Display Configuration"));
104
+ const propertyLabel = (await (0, enquirer_1.prompt)({
105
+ type: "input",
106
+ name: "label",
107
+ message: "What is the label of the property? (e.g. Tasks)",
108
+ validate: (response) => !(0, lodash_1.isEmpty)(response.trim()),
109
+ })).label.trim();
110
+ propertiesPanelDisplay = {
111
+ label: propertyLabel,
112
+ controlType: this.dataTypeToDefaultControlType(propertyType),
113
+ };
114
+ }
115
+ properties.push({
116
+ path: propertyPath,
117
+ dataType: propertyType,
118
+ propertiesPanelDisplay,
97
119
  });
98
- const addAnotherStatefulProp = (await (0, enquirer_1.prompt)({
120
+ this.log(`You can configure the remaining display attributes (tooltip, placeholder, etc) in the config.ts file directly.`);
121
+ this.log();
122
+ const addAnotherProperty = (await (0, enquirer_1.prompt)({
99
123
  type: "confirm",
100
124
  name: "value",
101
- message: "Do you want to add another stateful prop?",
125
+ message: "Do you want to add another property?",
102
126
  initial: false,
103
127
  })).value;
104
- if (!addAnotherStatefulProp) {
128
+ if (!addAnotherProperty) {
105
129
  break;
106
130
  }
107
131
  }
108
132
  }
109
133
  this.log();
110
- this.log(`${(0, colorette_1.cyanBright)("ℹ")} ${(0, colorette_1.bold)("Event handlers")} represent the events your custom component can fire`);
134
+ this.log(`${(0, colorette_1.cyanBright)("ℹ")} ${(0, colorette_1.bold)("Events")} represent the types of events that the component can trigger in Superblocks. Learn more about events: ${(0, colorette_1.magenta)("https://docs.superblocks.com/applications/custom-components/#properties--events")}`);
111
135
  this.log();
112
136
  const hasEventHandlers = (await (0, enquirer_1.prompt)({
113
137
  type: "confirm",
114
138
  name: "value",
115
- message: `Does this component have ${(0, colorette_1.bold)("event handlers")}? (e.g. a date picker component that has a On Change event handler)`,
139
+ message: `Does this component have ${(0, colorette_1.bold)("events")}? (e.g. a date picker component that triggers an On Change event)`,
116
140
  initial: false,
117
141
  })).value;
118
- const eventHandlers = [];
142
+ const events = [];
119
143
  if (hasEventHandlers) {
120
144
  for (;;) {
121
145
  const eventHandlerName = (await (0, enquirer_1.prompt)({
122
146
  name: "value",
123
147
  type: "input",
124
- message: "What is the label of the event handler? (e.g. On Change)",
148
+ message: "What is the label of the event? (e.g. On Change)",
125
149
  validate: (response) => !(0, lodash_1.isEmpty)(response.trim()),
126
150
  })).value.trim();
127
151
  const eventHandlerPath = (await (0, enquirer_1.prompt)({
128
152
  name: "value",
129
- message: "What is the machine readable name of the event handler?",
153
+ message: "What is the path of the event? This will be used to trigger the event in your code (e.g. onChange)",
130
154
  type: "input",
131
155
  initial: (0, identifiers_1.suggestIdentifier)(eventHandlerName) || "onChange",
132
156
  validate: (response) => {
133
157
  if (!(0, identifiers_1.isValidIdentifier)(response))
134
158
  return "Invalid identifier";
135
- if (eventHandlers.some((v) => v.path === response))
159
+ if (events.some((v) => v.path === response))
136
160
  return "Duplicate property name";
137
161
  return true;
138
162
  },
139
163
  })).value;
140
- eventHandlers.push({
164
+ events.push({
141
165
  label: eventHandlerName,
142
166
  path: eventHandlerPath,
143
167
  });
144
168
  const addAnotherEventHandler = (await (0, enquirer_1.prompt)({
145
169
  name: "value",
146
170
  type: "confirm",
147
- message: "Do you want to add another event handler?",
171
+ message: "Do you want to add another event?",
148
172
  initial: false,
149
173
  })).value;
150
174
  if (!addAnotherEventHandler) {
@@ -156,14 +180,14 @@ class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCo
156
180
  id: (0, node_crypto_1.randomUUID)(),
157
181
  name,
158
182
  displayName,
159
- statefulPropsRendered: statefulProps
160
- .map((statefulProp) => tsStringify(statefulProp))
183
+ propertiesRendered: properties
184
+ .map((property) => tsStringify(property))
161
185
  .join(""),
162
- eventHandlersRendered: eventHandlers
186
+ eventHandlersRendered: events
163
187
  .map((eventHandler) => tsStringify(eventHandler))
164
188
  .join(""),
165
189
  });
166
- const componentTsx = (0, create_component_defaults_1.getDefaultComponentTsx)(statefulProps, eventHandlers.map((prop) => prop.path));
190
+ const componentTsx = (0, create_component_defaults_1.getDefaultComponentTsx)(properties, events.map((prop) => prop.path));
167
191
  if (isFirstTimeCreate) {
168
192
  await fs.copy(DEFAULT_PACKAGE_JSON_TEMPLATE_PATH, ".");
169
193
  }
@@ -173,23 +197,26 @@ class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCo
173
197
  return {
174
198
  name,
175
199
  displayName,
176
- statefulProps,
177
- eventHandlers,
200
+ properties,
201
+ events,
178
202
  };
179
203
  }
180
204
  async initializeComponentByExample() {
181
205
  const response = {
182
- displayName: "Example Component",
183
- name: "ExampleComponent",
184
- statefulProps: [
206
+ displayName: "To-Do List (Example)",
207
+ name: "ToDoList",
208
+ properties: [
185
209
  {
186
- label: "Default Tasks",
187
210
  path: "tasks",
188
- inputType: "js",
189
- placeholder: "{ taskId: { taskName: 'Task Name', taskStatus: 'complete' | 'todo' } }",
211
+ dataType: "any",
212
+ propertiesPanelDisplay: {
213
+ label: "Default Tasks",
214
+ placeholder: "{ taskId: { taskName: 'Task Name', taskStatus: 'complete' | 'todo' } }",
215
+ controlType: "js-expr",
216
+ },
190
217
  },
191
218
  ],
192
- eventHandlers: [
219
+ events: [
193
220
  {
194
221
  label: "On Task Added",
195
222
  path: "onTaskAdded",
@@ -204,10 +231,10 @@ class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCo
204
231
  id: (0, node_crypto_1.randomUUID)(),
205
232
  name: response.name,
206
233
  displayName: response.displayName,
207
- statefulPropsRendered: response.statefulProps
208
- .map((statefulProp) => tsStringify(statefulProp))
234
+ propertiesRendered: response.properties
235
+ .map((property) => tsStringify(property))
209
236
  .join(""),
210
- eventHandlersRendered: response.eventHandlers
237
+ eventHandlersRendered: response.events
211
238
  .map((eventHandler) => tsStringify(eventHandler))
212
239
  .join(""),
213
240
  });
@@ -218,31 +245,38 @@ class CreateComponent extends authenticated_command_1.AuthenticatedApplicationCo
218
245
  return response;
219
246
  }
220
247
  async run() {
248
+ this.log();
221
249
  const isFirstTimeCreate = !(await fs.exists("package.json"));
222
- const initExampleComponent = isFirstTimeCreate &&
223
- (await (0, enquirer_1.prompt)({
250
+ let response;
251
+ if (isFirstTimeCreate) {
252
+ this.log(`${(0, colorette_1.cyanBright)("ℹ")} Welcome to Custom Components! In order to help you get started, we’ve built an example To-Do List Component. You can use this component as a template as you build your own Custom Component. To work with this component, we recommend following along with our quickstart guide: ${(0, colorette_1.magenta)("https://docs.superblocks.com/applications/custom-components/quickstart")}`);
253
+ this.log();
254
+ this.log(`If you choose to generate the example component, you will not have to provide any additional inputs. You can re-run superblocks components create once you are ready to create your own component from scratch. `);
255
+ this.log();
256
+ const initExampleComponent = (await (0, enquirer_1.prompt)({
224
257
  name: "value",
225
258
  type: "confirm",
226
- message: "Would you like to use a pre-generated example custom component?",
259
+ message: "Would you like to generate an example custom component?",
227
260
  initial: false,
228
261
  })).value;
229
- let response;
230
- if (!initExampleComponent) {
231
- response = await this.initializeComponentByWizard(isFirstTimeCreate);
262
+ response = initExampleComponent
263
+ ? await this.initializeComponentByExample()
264
+ : await this.initializeComponentByWizard(isFirstTimeCreate);
232
265
  }
233
266
  else {
234
- response = await this.initializeComponentByExample();
267
+ response = await this.initializeComponentByWizard(isFirstTimeCreate);
235
268
  }
236
269
  this.log((0, colorette_1.green)("Successfully created component! Added the following files:"));
237
270
  this.log();
238
271
  const tree = core_1.ux.tree();
239
272
  tree.insert("components");
240
273
  tree.nodes.components.insert(response.name);
241
- tree.nodes.components.nodes[response.name].insert("config.ts # update this file to configure your component's properties panel");
274
+ tree.nodes.components.nodes[response.name].insert("config.ts # update this file to manage your component's properties and events");
275
+ tree.nodes.components.nodes[response.name].insert("types.ts # this file contains your react component type definitions and is automatically updated while you run 'superblocks components watch'");
242
276
  tree.nodes.components.nodes[response.name].insert("component.tsx # your component's react code");
243
277
  tree.display();
244
278
  this.log();
245
- this.log(`${(0, colorette_1.green)("Remember to run $ ")}${(0, colorette_1.cyan)("superblocks components watch")}${(0, colorette_1.green)(" to watch for changes to your component files")}`);
279
+ this.log(`${(0, colorette_1.green)("Remember to run $ ")}${(0, colorette_1.magenta)("superblocks components watch")}${(0, colorette_1.green)(" to watch for changes to your component files")}`);
246
280
  this.log();
247
281
  this.log(`Edit your component's react code here:
248
282
  ${(0, colorette_1.green)(`components/${response.name}/component.tsx`)}`);
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const node_http_1 = tslib_1.__importDefault(require("node:http"));
5
4
  const path_1 = tslib_1.__importDefault(require("path"));
6
5
  const core_1 = require("@oclif/core");
7
6
  const css_plugin_1 = require("@superblocksteam/css-plugin");
@@ -9,7 +8,6 @@ const react_shim_1 = require("@superblocksteam/react-shim");
9
8
  const util_1 = require("@superblocksteam/util");
10
9
  const plugin_react_1 = tslib_1.__importDefault(require("@vitejs/plugin-react"));
11
10
  const fs = tslib_1.__importStar(require("fs-extra"));
12
- const serve_handler_1 = tslib_1.__importDefault(require("serve-handler"));
13
11
  const vite_1 = require("vite");
14
12
  const authenticated_command_1 = require("../../common/authenticated-command");
15
13
  class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
@@ -82,36 +80,7 @@ class Upload extends authenticated_command_1.AuthenticatedApplicationCommand {
82
80
  this.log(e.message);
83
81
  this.error("Failed to upload components", { exit: 1 });
84
82
  }
85
- this.log("For testing purposes, the production assets will be served from this machine.");
86
- const server = node_http_1.default.createServer((request, response) => {
87
- // You pass two more arguments for config and middleware
88
- // More details here: https://github.com/vercel/serve-handler#options
89
- return (0, serve_handler_1.default)(request, response, {
90
- public: "./",
91
- headers: [
92
- {
93
- source: "**/*",
94
- headers: [
95
- {
96
- key: "Access-Control-Allow-Origin",
97
- value: "*",
98
- },
99
- {
100
- key: "Access-Control-Allow-Credentials",
101
- value: "true",
102
- },
103
- {
104
- key: "Access-Control-Allow-Private-Network",
105
- value: "true",
106
- },
107
- ],
108
- },
109
- ],
110
- });
111
- });
112
- server.listen(3030, () => {
113
- console.log("Running asset server at http://localhost:3030");
114
- });
83
+ this.log("You can now disable local dev mode and test your production assets");
115
84
  }
116
85
  }
117
86
  Upload.description = "Upload creates a production-ready bundle and saves the files for use outside of Local Development mode.";
@@ -32,7 +32,6 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
32
32
  await this.registerComponents();
33
33
  this.log((0, colorette_1.yellow)("Remember to refresh your application to see any newly registered components."));
34
34
  this.log();
35
- this.log((0, colorette_1.green)(`Visit ${await this.getBaseUrl()} and access your application in edit mode to see your components! 🐨`));
36
35
  const port = 3002;
37
36
  const editModeUrl = await this.getEditModeUrl();
38
37
  const viteLogger = (0, vite_1.createLogger)();
@@ -71,7 +70,7 @@ class Watch extends authenticated_command_1.AuthenticatedApplicationCommand {
71
70
  this.log();
72
71
  this.log((0, colorette_1.bold)((0, colorette_1.magenta)(`${editModeUrl}?devMode=true`)));
73
72
  this.log();
74
- this.log((0, colorette_1.yellow)("Remember to refresh your already open Application page and turn on local development in Superblocks to connect to your local server!"));
73
+ 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")}`));
75
74
  })();
76
75
  }
77
76
  }
@@ -139,23 +139,20 @@ class Initialize extends authenticated_command_1.AuthenticatedCommand {
139
139
  {
140
140
  title: "Updating Superblocks project file...",
141
141
  task: async (ctx) => {
142
- var _a, _b, _c, _d;
142
+ var _a, _b;
143
143
  const superblocksConfig = {
144
144
  configType: "ROOT",
145
145
  resources: {},
146
146
  metadata: {
147
147
  cliVersion: this.config.version,
148
- lastUpdated: ctx.now,
149
- created: (_b = (_a = ctx.existingSuperblocksConfig) === null || _a === void 0 ? void 0 : _a.metadata.created) !== null && _b !== void 0 ? _b : ctx.now,
150
148
  },
151
149
  };
152
- superblocksConfig.metadata.lastUpdated = ctx.now;
153
150
  // new resources
154
151
  for (const [resourceId, resource] of Object.entries(ctx.writtenResources)) {
155
152
  superblocksConfig.resources[resourceId] = resource;
156
153
  }
157
154
  // existing resources
158
- for (const [resourceId, resource] of Object.entries((_d = (_c = ctx.existingSuperblocksConfig) === null || _c === void 0 ? void 0 : _c.resources) !== null && _d !== void 0 ? _d : {})) {
155
+ for (const [resourceId, resource] of Object.entries((_b = (_a = ctx.existingSuperblocksConfig) === null || _a === void 0 ? void 0 : _a.resources) !== null && _b !== void 0 ? _b : {})) {
159
156
  superblocksConfig.resources[resourceId] = resource;
160
157
  }
161
158
  if (!(await fs.exists(util_1.SUPERBLOCKS_HOME_FOLDER_NAME))) {
@@ -268,7 +265,7 @@ function getResourceIdFromUrl(resourceUrl) {
268
265
  return [url.pathname.split("/")[2], "APPLICATION"];
269
266
  }
270
267
  else if (url.pathname.startsWith("/workflows") ||
271
- url.pathname.startsWith("/scheduled-jobs")) {
268
+ url.pathname.startsWith("/scheduled_jobs")) {
272
269
  return [url.pathname.split("/")[2], "BACKEND"];
273
270
  }
274
271
  throw new Error(`Failed to parse resource URL: ${resourceUrl}`);
@@ -49,7 +49,7 @@ class Login extends core_1.Command {
49
49
  }
50
50
  }
51
51
  }
52
- Login.description = "Authenticates with Superblocks cloud";
52
+ Login.description = "Authenticate with Superblocks cloud";
53
53
  Login.flags = {
54
54
  // flag with a value (-t, --token=VALUE)
55
55
  token: core_1.Flags.string({
@@ -0,0 +1,9 @@
1
+ import { AuthenticatedCommand } from "../common/authenticated-command";
2
+ export default class Migrate extends AuthenticatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ private createTasks;
7
+ private getResourceIdsToMigrate;
8
+ private migrateApplication;
9
+ }