@swell/cli 2.0.1-alpha.17 → 2.0.1-alpha.18

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.
Files changed (67) hide show
  1. package/dist/app-command.d.ts +1 -1
  2. package/dist/app-command.js +3 -3
  3. package/dist/commands/app/dev.d.ts +3 -5
  4. package/dist/commands/app/dev.js +3 -6
  5. package/dist/commands/app/frontend/deploy.d.ts +1 -3
  6. package/dist/commands/app/frontend/deploy.js +2 -5
  7. package/dist/commands/app/frontend/dev.d.ts +4 -6
  8. package/dist/commands/app/frontend/dev.js +12 -15
  9. package/dist/commands/app/info.js +1 -3
  10. package/dist/commands/app/init.js +2 -2
  11. package/dist/commands/app/install.js +0 -1
  12. package/dist/commands/app/pull.d.ts +3 -3
  13. package/dist/commands/app/pull.js +16 -16
  14. package/dist/commands/app/push.d.ts +4 -4
  15. package/dist/commands/app/push.js +28 -31
  16. package/dist/commands/app/release.d.ts +3 -3
  17. package/dist/commands/app/release.js +43 -45
  18. package/dist/commands/app/version.d.ts +4 -4
  19. package/dist/commands/app/version.js +28 -28
  20. package/dist/commands/create/app.d.ts +15 -15
  21. package/dist/commands/create/app.js +66 -66
  22. package/dist/commands/create/frontend.js +4 -7
  23. package/dist/commands/env.d.ts +12 -0
  24. package/dist/commands/env.js +31 -0
  25. package/dist/commands/login.js +1 -3
  26. package/dist/commands/logs.js +0 -2
  27. package/dist/commands/theme/dev.d.ts +6 -8
  28. package/dist/commands/theme/dev.js +30 -33
  29. package/dist/commands/theme/init.d.ts +1 -1
  30. package/dist/commands/theme/init.js +1 -1
  31. package/dist/commands/theme/pull.d.ts +7 -7
  32. package/dist/commands/theme/pull.js +21 -21
  33. package/dist/commands/theme/push.d.ts +7 -7
  34. package/dist/commands/theme/push.js +24 -27
  35. package/dist/create-app-command.d.ts +7 -7
  36. package/dist/create-app-command.js +146 -147
  37. package/dist/create-config-command.js +0 -2
  38. package/dist/env/local.d.ts +8 -0
  39. package/dist/env/local.js +7 -0
  40. package/dist/env/production.d.ts +8 -0
  41. package/dist/env/production.js +7 -0
  42. package/dist/env/review.d.ts +8 -0
  43. package/dist/env/review.js +7 -0
  44. package/dist/env/staging.d.ts +8 -0
  45. package/dist/env/staging.js +7 -0
  46. package/dist/lib/api.d.ts +3 -3
  47. package/dist/lib/api.js +35 -35
  48. package/dist/lib/app-config.d.ts +2 -2
  49. package/dist/lib/app-config.js +12 -11
  50. package/dist/lib/apps/app-config.d.ts +19 -19
  51. package/dist/lib/apps/app-config.js +59 -65
  52. package/dist/lib/apps/index.d.ts +56 -56
  53. package/dist/lib/apps/index.js +40 -42
  54. package/dist/lib/apps/paths.d.ts +1 -1
  55. package/dist/lib/apps/paths.js +4 -4
  56. package/dist/lib/config.d.ts +4 -1
  57. package/dist/lib/config.js +35 -1
  58. package/dist/lib/constants.js +7 -8
  59. package/dist/lib/create/index.js +2 -2
  60. package/dist/lib/stores.d.ts +4 -2
  61. package/dist/lib/stores.js +4 -2
  62. package/dist/push-app-command.d.ts +34 -34
  63. package/dist/push-app-command.js +391 -402
  64. package/dist/remote-app-command.d.ts +24 -24
  65. package/dist/remote-app-command.js +245 -259
  66. package/oclif.manifest.json +152 -119
  67. package/package.json +2 -1
package/dist/lib/api.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import fetch from 'node-fetch';
2
- import qs from 'qs';
2
+ import { stringify } from 'qs';
3
3
  import config from './config.js';
4
4
  import { API_BASE_URL, getAdminApiBaseUrl } from './constants.js';
5
5
  const defaultHeaders = (opts) => ({
@@ -51,10 +51,9 @@ export default class Api {
51
51
  ? `${getAdminApiBaseUrl(storeId)}/${this.truncatePath(pathOpts.adminPath)}`
52
52
  : `${API_BASE_URL}/${this.truncatePath(pathOpts.backendPath)}`;
53
53
  if (options.query) {
54
- path += `?${qs.stringify(options.query)}`;
54
+ path += `?${stringify(options.query)}`;
55
55
  }
56
56
  path = path
57
- // eslint-disable-next-line no-template-curly-in-string
58
57
  .replace('${STORE_ID}', storeId) // replace store id in template string
59
58
  .replaceAll(/([^:]\/)\/+/g, '$1'); // remove duplicate slashes
60
59
  if (!path)
@@ -85,29 +84,15 @@ export default class Api {
85
84
  return null;
86
85
  }
87
86
  }
88
- isAdmin() {
89
- return !this.secretKey;
90
- }
91
- async waitForAsyncResponse(response, pathOpts, options = {}) {
92
- const { onAsyncGetPath, spinner } = options;
93
- if (!response?.async_progressing || !onAsyncGetPath) {
94
- return response;
95
- }
96
- await new Promise((resolve) => setTimeout(resolve, 1000));
97
- const asyncResponse = await this.api(onAsyncGetPath(response), {
98
- method: 'GET',
99
- onAsyncGetPath,
87
+ async delete(pathOpts, options = {}) {
88
+ // ensure post body is stringified
89
+ if (options.body)
90
+ options.body = JSON.stringify(options.body);
91
+ const response = await this.api(pathOpts, {
92
+ method: 'DELETE',
93
+ ...options,
100
94
  });
101
- if (asyncResponse?.async_error) {
102
- throw new Error(asyncResponse.async_error);
103
- }
104
- if (!asyncResponse?.async_progressing && spinner) {
105
- spinner.suffixText = '';
106
- }
107
- else if (asyncResponse?.async_progress > 0 && spinner) {
108
- spinner.suffixText = `${asyncResponse.async_progress}%`;
109
- }
110
- return this.waitForAsyncResponse(asyncResponse, pathOpts, options);
95
+ return this.waitForAsyncResponse(response, pathOpts, options);
111
96
  }
112
97
  async get(pathOpts, options = {}) {
113
98
  return this.api(pathOpts, {
@@ -115,6 +100,9 @@ export default class Api {
115
100
  ...options,
116
101
  });
117
102
  }
103
+ isAdmin() {
104
+ return !this.secretKey;
105
+ }
118
106
  async post(pathOpts, options = {}) {
119
107
  // ensure post body is stringified
120
108
  if (options.body)
@@ -135,16 +123,6 @@ export default class Api {
135
123
  });
136
124
  return this.waitForAsyncResponse(response, pathOpts, options);
137
125
  }
138
- async delete(pathOpts, options = {}) {
139
- // ensure post body is stringified
140
- if (options.body)
141
- options.body = JSON.stringify(options.body);
142
- const response = await this.api(pathOpts, {
143
- method: 'DELETE',
144
- ...options,
145
- });
146
- return this.waitForAsyncResponse(response, pathOpts, options);
147
- }
148
126
  setStoreEnv(storeId, envId) {
149
127
  this.storeId = storeId;
150
128
  this.envId = envId;
@@ -152,4 +130,26 @@ export default class Api {
152
130
  truncatePath(path) {
153
131
  return path?.startsWith('/') ? path.slice(1) : path;
154
132
  }
133
+ async waitForAsyncResponse(response, pathOpts, options = {}) {
134
+ const { onAsyncGetPath, spinner } = options;
135
+ if (!response?.async_progressing || !onAsyncGetPath) {
136
+ return response;
137
+ }
138
+ /* eslint-disable-next-line no-promise-executor-return */
139
+ await new Promise((resolve) => setTimeout(resolve, 1000));
140
+ const asyncResponse = await this.api(onAsyncGetPath(response), {
141
+ method: 'GET',
142
+ onAsyncGetPath,
143
+ });
144
+ if (asyncResponse?.async_error) {
145
+ throw new Error(asyncResponse.async_error);
146
+ }
147
+ if (!asyncResponse?.async_progressing && spinner) {
148
+ spinner.suffixText = '';
149
+ }
150
+ else if (asyncResponse?.async_progress > 0 && spinner) {
151
+ spinner.suffixText = `${asyncResponse.async_progress}%`;
152
+ }
153
+ return this.waitForAsyncResponse(asyncResponse, pathOpts, options);
154
+ }
155
155
  }
@@ -30,8 +30,8 @@ declare function newConfig(path?: string): any;
30
30
  /**
31
31
  * Returns a new configuration instance at the specified path.
32
32
  *
33
- * @param path Path of the current working directory
33
+ * @param appPath Path of the current working directory
34
34
  * @returns Conf
35
35
  */
36
36
  declare function newConfigAtPath(appPath?: string): any;
37
- export { swellConfigFileExists, config as default, newConfig, newConfigAtPath, readRcFile, writeRcFile, };
37
+ export { config as default, newConfig, newConfigAtPath, readRcFile, swellConfigFileExists, writeRcFile, };
@@ -5,15 +5,16 @@ import Conf from 'conf';
5
5
  import * as fs from 'node:fs';
6
6
  import * as path from 'node:path';
7
7
  const schema = {
8
+ compatibilities: { type: 'object' },
9
+ description: { type: 'string' },
8
10
  id: { type: 'string' },
11
+ integrations: { type: 'array' },
9
12
  name: { type: 'string' },
10
- type: { type: 'string' },
11
- version: { type: 'string' },
12
- description: { type: 'string' },
13
+ permissions: { type: 'array' },
13
14
  storefront: { type: 'object' },
14
15
  theme: { type: 'object' },
15
- compatibilities: { type: 'object' },
16
- permissions: { type: 'array' },
16
+ type: { type: 'string' },
17
+ version: { type: 'string' },
17
18
  };
18
19
  const APP_FILE_NAME = 'swell';
19
20
  const APP_FILE_EXT = 'json';
@@ -114,14 +115,14 @@ function config(configDir = '') {
114
115
  let config;
115
116
  try {
116
117
  config = new Conf({
118
+ clearInvalidConfig: true,
117
119
  configName: APP_FILE_NAME,
118
120
  cwd: dirPath,
119
121
  schema,
120
- clearInvalidConfig: true,
121
122
  });
122
123
  }
123
- catch (err) {
124
- throw new Error(`Error parsing swell.json: ${err.toString()}`);
124
+ catch (error) {
125
+ throw new Error(`Error parsing swell.json: ${error.toString()}`);
125
126
  }
126
127
  // for convenience, we add custom properties to the Conf object
127
128
  // we prefix them with "sw" to avoid conflicts with Conf's properties
@@ -136,17 +137,17 @@ function config(configDir = '') {
136
137
  */
137
138
  function newConfig(path) {
138
139
  return new Conf({
140
+ clearInvalidConfig: true,
139
141
  configName: APP_FILE_NAME,
140
142
  cwd: `${process.cwd()}${path ? `/${path}` : ''}`,
141
143
  schema,
142
144
  serialize,
143
- clearInvalidConfig: true,
144
145
  });
145
146
  }
146
147
  /**
147
148
  * Returns a new configuration instance at the specified path.
148
149
  *
149
- * @param path Path of the current working directory
150
+ * @param appPath Path of the current working directory
150
151
  * @returns Conf
151
152
  */
152
153
  function newConfigAtPath(appPath) {
@@ -161,4 +162,4 @@ function newConfigAtPath(appPath) {
161
162
  function serialize(value) {
162
163
  return JSON.stringify(value, null, 2);
163
164
  }
164
- export { swellConfigFileExists, config as default, newConfig, newConfigAtPath, readRcFile, writeRcFile, };
165
+ export { config as default, newConfig, newConfigAtPath, readRcFile, swellConfigFileExists, writeRcFile, };
@@ -8,6 +8,7 @@ declare class FunctionProcessingError extends Error {
8
8
  constructor(message: string, error: Error);
9
9
  }
10
10
  type AppConfigFile = {
11
+ content_type?: string;
11
12
  data?: string;
12
13
  date_uploaded?: string;
13
14
  ext?: string;
@@ -15,42 +16,41 @@ type AppConfigFile = {
15
16
  length?: number;
16
17
  md5?: string;
17
18
  url?: string;
18
- content_type?: string;
19
19
  };
20
20
  /**
21
21
  * An app configuration as defined by the Swell API. This implies that the
22
22
  * app & the configuration are saved to the API.
23
23
  */
24
24
  declare abstract class AppConfig {
25
- id?: string;
26
- version?: string;
27
- hash?: string;
28
- fileHash?: string;
25
+ appConfigId?: string;
26
+ appPath: string;
27
+ byteSize?: number;
28
+ date_created?: string;
29
+ date_updated?: string;
29
30
  file?: AppConfigFile;
30
31
  file_path?: string;
32
+ fileContent?: string;
33
+ fileData?: Buffer;
34
+ fileHash?: string;
35
+ filePath: string;
36
+ hash?: string;
37
+ id?: string;
38
+ mbSize?: number;
31
39
  name?: string;
32
40
  parent_id?: string;
33
41
  slug?: string;
34
42
  values: {
35
43
  [key: string]: any;
36
44
  };
37
- date_created?: string;
38
- date_updated?: string;
39
- appConfigId?: string;
40
- filePath: string;
41
- appPath: string;
42
- fileData?: Buffer;
43
- fileContent?: string;
44
- byteSize?: number;
45
- mbSize?: number;
46
- /** build the JSON used when making requests (usually push) to the API */
47
- protected abstract preparePostData(postData: any): Promise<any>;
48
- abstract type: ConfigType;
49
- abstract hasValues: boolean;
45
+ version?: string;
50
46
  constructor(attrs?: Partial<AppConfig>);
51
47
  static create(attrs?: Partial<AppConfig>): AppConfig;
48
+ isRootConfig(configDir: string): boolean;
52
49
  postData(): Promise<any>;
53
50
  prepareFileData(): any;
54
- isRootConfig(configDir: string): boolean;
51
+ abstract hasValues: boolean;
52
+ /** build the JSON used when making requests (usually push) to the API */
53
+ protected abstract preparePostData(postData: any): Promise<any>;
54
+ abstract type: ConfigType;
55
55
  }
56
56
  export { AppConfig, FunctionProcessingError, IgnoringFileError };
@@ -1,11 +1,10 @@
1
- /* eslint-disable camelcase */
1
+ import { getEncoding } from 'istextorbinary';
2
2
  import isEmpty from 'lodash/isEmpty.js';
3
+ import { detectFilenameMime } from 'mime-detect';
3
4
  import * as fs from 'node:fs';
4
5
  import * as path from 'node:path';
5
- import { detectFilenameMime } from 'mime-detect';
6
- import { getEncoding } from 'istextorbinary';
7
6
  import { bundleFunction } from '../bundle.js';
8
- import { ConfigType, ConfigPaths, hashFile, filePathExists } from './index.js';
7
+ import { ConfigPaths, ConfigType, filePathExists, hashFile } from './index.js';
9
8
  class IgnoringFileError extends Error {
10
9
  constructor(message) {
11
10
  super(message);
@@ -25,38 +24,38 @@ class FunctionProcessingError extends Error {
25
24
  * app & the configuration are saved to the API.
26
25
  */
27
26
  class AppConfig {
28
- // Server-side props
29
- id;
30
- version;
31
- hash;
32
- fileHash;
33
- file;
34
- file_path;
35
- name;
36
- parent_id;
37
- slug;
38
- values = {};
39
- date_created;
40
- date_updated;
41
27
  // Used when pushing a theme and the app config is considered
42
28
  appConfigId;
43
- // Relative path of remote AppConfig, same as file_path if defined
44
- filePath;
45
29
  // Full local path of remote AppConfig
46
30
  appPath;
47
- // Buffer of local file data
48
- fileData;
49
- // UTF8 content of local file
50
- fileContent;
51
31
  // Size of local file in bytes and mb
52
32
  byteSize;
33
+ date_created;
34
+ date_updated;
35
+ file;
36
+ file_path;
37
+ // UTF8 content of local file
38
+ fileContent;
39
+ // Buffer of local file data
40
+ fileData;
41
+ fileHash;
42
+ // Relative path of remote AppConfig, same as file_path if defined
43
+ filePath;
44
+ hash;
45
+ // Server-side props
46
+ id;
53
47
  mbSize;
48
+ name;
49
+ parent_id;
50
+ slug;
51
+ values = {};
52
+ version;
54
53
  constructor(attrs = {}) {
55
54
  Object.assign(this, attrs);
56
- let { filePath, appPath } = attrs;
57
- this.filePath = filePath || '';
55
+ let { appPath, file_path, filePath, name, type } = attrs;
58
56
  this.appPath = appPath || '';
59
- if (!attrs.type || !attrs.name) {
57
+ this.filePath = filePath || '';
58
+ if (!type || !name) {
60
59
  throw new Error('Missing app config type or name.');
61
60
  }
62
61
  if (!appPath) {
@@ -64,15 +63,15 @@ class AppConfig {
64
63
  }
65
64
  // Make sure file path is set from server prop or type/name
66
65
  if (!filePath) {
67
- if (attrs.file_path) {
68
- filePath = attrs.file_path;
66
+ if (file_path) {
67
+ filePath = file_path;
69
68
  }
70
69
  else {
71
70
  // Note this shouldn't be necessary unless the config was created before file_path was added
72
- const typePath = ConfigPaths[String(attrs.type).toUpperCase()];
73
- filePath = `${typePath}/${attrs.name}`;
71
+ const typePath = ConfigPaths[String(type).toUpperCase()];
72
+ filePath = `${typePath}/${name}`;
74
73
  if (!typePath) {
75
- throw new Error(`Missing path for app config type: ${attrs.type}`);
74
+ throw new Error(`Missing path for app config type: ${type}`);
76
75
  }
77
76
  }
78
77
  this.filePath = filePath;
@@ -126,6 +125,11 @@ class AppConfig {
126
125
  }
127
126
  }
128
127
  }
128
+ isRootConfig(configDir) {
129
+ return !this.filePath
130
+ ?.replace(new RegExp(`^${configDir}/`), '')
131
+ .includes('/');
132
+ }
129
133
  async postData() {
130
134
  if (this.fileContent === undefined) {
131
135
  return;
@@ -142,24 +146,19 @@ class AppConfig {
142
146
  }
143
147
  }
144
148
  // Detect file content type
145
- let contentType = detectFilenameMime(this.filePath);
146
- if (this.filePath.endsWith('.liquid') ||
147
- this.filePath.endsWith('.liquidx')) {
148
- contentType = 'application/liquid';
149
- }
150
- else {
151
- contentType = detectFilenameMime(this.filePath);
152
- }
149
+ const contentType = this.filePath.endsWith('.liquid') || this.filePath.endsWith('.liquidx')
150
+ ? 'application/liquid'
151
+ : detectFilenameMime(this.filePath);
153
152
  const postData = {
154
- // Name is either configured or the last part of the path without extension
155
- name: this.values?.name || this.name,
156
- type: this.type,
157
- hash: this.hash,
158
- file_path: this.filePath,
159
153
  file: {
160
- data: this.prepareFileData(),
161
154
  content_type: contentType,
155
+ data: this.prepareFileData(),
162
156
  },
157
+ file_path: this.filePath,
158
+ hash: this.hash,
159
+ // Name is either configured or the last part of the path without extension
160
+ name: this.values?.name || this.name,
161
+ type: this.type,
163
162
  };
164
163
  if (this.hasValues) {
165
164
  postData.values = this.values || {};
@@ -174,22 +173,17 @@ class AppConfig {
174
173
  ? { $base64: this.fileData.toString('base64') }
175
174
  : this.fileData?.toString('utf8');
176
175
  }
177
- isRootConfig(configDir) {
178
- return !this.filePath
179
- ?.replace(new RegExp(`^${configDir}/`), '')
180
- .includes('/');
181
- }
182
176
  }
183
177
  class AppConfigDefault extends AppConfig {
184
- type = ConfigType.FILE;
185
178
  hasValues = false;
179
+ type = ConfigType.FILE;
186
180
  preparePostData(postData) {
187
181
  return postData;
188
182
  }
189
183
  }
190
184
  class AppConfigModel extends AppConfig {
191
- type = ConfigType.MODEL;
192
185
  hasValues = true;
186
+ type = ConfigType.MODEL;
193
187
  preparePostData(postData) {
194
188
  postData.values.collection =
195
189
  postData.values.collection || postData.values.model || this.name;
@@ -197,16 +191,16 @@ class AppConfigModel extends AppConfig {
197
191
  }
198
192
  }
199
193
  class AppConfigContent extends AppConfig {
200
- type = ConfigType.CONTENT;
201
194
  hasValues = true;
195
+ type = ConfigType.CONTENT;
202
196
  preparePostData(postData) {
203
197
  postData.values.collection = postData.values.collection || this.name;
204
198
  return postData;
205
199
  }
206
200
  }
207
201
  class AppConfigNotification extends AppConfig {
208
- type = ConfigType.NOTIFICATION;
209
202
  hasValues = true;
203
+ type = ConfigType.NOTIFICATION;
210
204
  preparePostData(postData) {
211
205
  const isTemplate = this.isRootConfig('notifications') &&
212
206
  (this.filePath.endsWith('.tpl') || this.filePath.endsWith('.liquid'));
@@ -220,34 +214,34 @@ class AppConfigNotification extends AppConfig {
220
214
  jsonData = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
221
215
  postData.values.collection = jsonData?.collection || jsonData?.model;
222
216
  }
223
- catch (err) {
217
+ catch {
224
218
  // noop
225
219
  }
226
220
  postData.file = {
227
- data: this.fileContent?.replaceAll('\r\n', '\n'),
228
221
  content_type: 'text/plain',
222
+ data: this.fileContent?.replaceAll('\r\n', '\n'),
229
223
  };
230
224
  }
231
225
  return postData;
232
226
  }
233
227
  }
234
228
  class AppConfigSetting extends AppConfig {
235
- type = ConfigType.SETTING;
236
229
  hasValues = true;
230
+ type = ConfigType.SETTING;
237
231
  preparePostData(postData) {
238
232
  return postData;
239
233
  }
240
234
  }
241
235
  class AppConfigWebhook extends AppConfig {
242
- type = ConfigType.WEBHOOK;
243
236
  hasValues = true;
237
+ type = ConfigType.WEBHOOK;
244
238
  preparePostData(postData) {
245
239
  return postData;
246
240
  }
247
241
  }
248
242
  class AppConfigFunction extends AppConfig {
249
- type = ConfigType.FUNCTION;
250
243
  hasValues = true;
244
+ type = ConfigType.FUNCTION;
251
245
  async preparePostData(postData) {
252
246
  const isFunction = this.isRootConfig('functions') &&
253
247
  (this.filePath.endsWith('.js') || this.filePath.endsWith('.ts'));
@@ -262,8 +256,8 @@ class AppConfigFunction extends AppConfig {
262
256
  data: this.prepareFileData(),
263
257
  };
264
258
  postData.build_file = {
265
- data: code,
266
259
  content_type: 'text/javascript',
260
+ data: code,
267
261
  };
268
262
  postData.values = config;
269
263
  }
@@ -276,25 +270,25 @@ class AppConfigFunction extends AppConfig {
276
270
  }
277
271
  // Assets do not get installed but saved as plain files
278
272
  class AppConfigAsset extends AppConfigDefault {
279
- type = ConfigType.ASSET;
280
273
  hasValues = false;
274
+ type = ConfigType.ASSET;
281
275
  }
282
276
  class AppConfigFrontend extends AppConfigDefault {
283
- type = ConfigType.FRONTEND;
284
277
  hasValues = false;
278
+ type = ConfigType.FRONTEND;
285
279
  }
286
280
  class AppConfigTheme extends AppConfigDefault {
287
- type = ConfigType.THEME;
288
281
  hasValues = false;
282
+ type = ConfigType.THEME;
289
283
  preparePostData(postData) {
290
- const isConfigJson = this.filePath?.match(/^theme\/config\/[^\.\/]+\.json$/);
284
+ const isConfigJson = this.filePath?.match(/^theme\/config\/[^./]+\.json$/);
291
285
  // Files in theme/config/*.json are treated as settings with values
292
286
  if (isConfigJson) {
293
287
  try {
294
288
  const jsonData = JSON.parse(fs.readFileSync(this.filePath, 'utf8'));
295
289
  postData.values = jsonData;
296
290
  }
297
- catch (err) {
291
+ catch {
298
292
  // noop
299
293
  }
300
294
  }