@swell/cli 2.0.9 → 2.0.10

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.
@@ -132,17 +132,23 @@ declare function writeFile(file: string, data: string): Promise<void>;
132
132
  declare function deleteFile(file: string): Promise<void>;
133
133
  declare function writeJsonFile(file: string, data?: any): Promise<void>;
134
134
  declare function hashFile(filePath: string, fileContents?: Buffer, relativePath?: string): string;
135
- declare function hashString(contents: string): string;
135
+ declare function hashString(...contents: (Buffer | string)[]): string;
136
136
  declare function appAssetImage(appPath: string, fileName: string): string | undefined;
137
137
  declare function appConfigFromFile(filePath: string, configType: ConfigType, appPath: string): AppConfig;
138
138
  declare function findAppConfig(app: App, filePath: string, configType: ConfigType): AppConfig | undefined;
139
+ interface BatchAppFiles {
140
+ configs: AppConfig[];
141
+ type: ConfigType;
142
+ label: string;
143
+ concurrency: number;
144
+ }
139
145
  /**
140
146
  * Get files to push in batches prioritized by dependencies
141
147
  *
142
- * @param configs - List of app configs
143
- * @returns {Array} Batches of files to push
148
+ * @param {AppConfig[]} configs - List of app configs
149
+ * @returns {BatchAppFiles[]} Batches of files to push
144
150
  */
145
- declare function batchAppFilesByType(configs: AppConfig[]): Array<any>;
151
+ declare function batchAppFilesByType(configs: AppConfig[]): BatchAppFiles[];
146
152
  export { PUSH_CONCURRENCY, App, AppVersion, ConfigInputFields, ConfigPaths, ConfigPathsType, ConfigType, FrontendProjectType, FrontendProjectTypes, StorefrontConfigPaths, StorefrontConfigTypes, SwellJsonFields, ThemeConfigPaths, ThemeConfigTypes, appAssetImage, appConfigFromFile, batchAppFilesByType, deleteFile, filePathExists, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, hashFile, hashString, writeFile, writeJsonFile, };
147
153
  export { AppConfig, FunctionProcessingError, IgnoringFileError, } from './app-config.js';
148
154
  export { allBaseFilesInDir, allConfigDirsPaths, allConfigFilesInDir, allConfigFilesPaths, allConfigFilesPathsByType, getAllConfigPaths, globAllFilesByPath, isPathDirectory, } from './paths.js';
@@ -1,4 +1,4 @@
1
- import { hash as blake3hash } from 'blake3-wasm';
1
+ import { createHash as createBlake3Hash } from 'blake3-wasm';
2
2
  import { pluralize, titleize } from 'inflection';
3
3
  import * as fs from 'node:fs';
4
4
  import * as path from 'node:path';
@@ -186,13 +186,16 @@ async function writeJsonFile(file, data = {}) {
186
186
  // Hash method adapted from wrangler-sdk
187
187
  function hashFile(filePath, fileContents, relativePath) {
188
188
  const contents = fileContents ?? fs.readFileSync(filePath);
189
- const base64Contents = contents.toString('base64');
190
189
  // Include relative file path because we typically cache by hash including file metadata
191
190
  // This allows de-duplication of cache entries for the same file contents
192
- return hashString(base64Contents + relativePath);
191
+ return hashString(contents, relativePath || '');
193
192
  }
194
- function hashString(contents) {
195
- return blake3hash(contents).toString('hex').slice(0, 32);
193
+ function hashString(...contents) {
194
+ const hash = createBlake3Hash();
195
+ for (const content of contents) {
196
+ hash.update(content);
197
+ }
198
+ return hash.digest('hex', { length: 16 });
196
199
  }
197
200
  function appAssetImage(appPath, fileName) {
198
201
  const assetsDirPath = path.join(appPath, ConfigPaths['ASSET']);
@@ -228,28 +231,26 @@ function findAppConfig(app, filePath, configType) {
228
231
  /**
229
232
  * Get files to push in batches prioritized by dependencies
230
233
  *
231
- * @param configs - List of app configs
232
- * @returns {Array} Batches of files to push
234
+ * @param {AppConfig[]} configs - List of app configs
235
+ * @returns {BatchAppFiles[]} Batches of files to push
233
236
  */
234
237
  function batchAppFilesByType(configs) {
235
238
  const modelsWithExtends = configs.filter((config) => config.type === 'model' && config.values.extends);
236
239
  const modelsWithoutExtends = configs.filter((config) => config.type === 'model' && !config.values.extends);
237
240
  const contentTypesWithCollection = configs.filter((config) => config.type === 'content' && config.values.collection);
238
241
  const contentTypesWithoutCollection = configs.filter((config) => config.type === 'content' && !config.values.collection);
239
- const prioritized = [
242
+ const prioritized = new Set([
240
243
  ...modelsWithExtends,
241
244
  ...modelsWithoutExtends,
242
245
  ...contentTypesWithCollection,
243
246
  ...contentTypesWithoutCollection,
244
- ];
247
+ ]);
245
248
  const sorted = [
246
- ...prioritized,
247
- ...configs.filter((config) => !prioritized.includes(config)),
249
+ ...prioritized.values(),
250
+ ...configs.filter((config) => !prioritized.has(config)),
248
251
  ];
249
252
  const batches = [];
250
- // eslint-disable-next-line guard-for-in
251
- for (const type in ConfigTypeBatchOrder) {
252
- const configType = ConfigTypeBatchOrder[type];
253
+ for (const configType of ConfigTypeBatchOrder) {
253
254
  const configsByType = sorted.filter((config) => config.type === configType);
254
255
  const label = configType === ConfigType.FILE ? 'App files' : titleize(configType);
255
256
  const concurrency = configType === ConfigType.NOTIFICATION || configType === ConfigType.ASSET
@@ -375,7 +375,7 @@ export class PushAppCommand extends RemoteAppCommand {
375
375
  const packageHash = localConfigs.find((config) => config.filePath === 'package.json')?.hash;
376
376
  frontendHashes += `|${packageHash}`;
377
377
  }
378
- return frontendHashes?.length > 0 ? hashString(frontendHashes) : undefined;
378
+ return frontendHashes.length > 0 ? hashString(frontendHashes) : undefined;
379
379
  }
380
380
  getFrontendProjectType(required = true) {
381
381
  this.frontendPath = path.join(this.appPath, 'frontend');
@@ -379,9 +379,8 @@ export class RemoteAppCommand extends AppCommand {
379
379
  }
380
380
  if (pullFiles.length > 0) {
381
381
  while (pullFiles.length > 0) {
382
- await Promise.all(pullFiles
383
- .splice(0, PUSH_CONCURRENCY)
384
- .map(async (config) => {
382
+ // eslint-disable-next-line no-await-in-loop
383
+ await Promise.all(pullFiles.splice(0, PUSH_CONCURRENCY).map(async (config) => {
385
384
  await this.pullRemoteFile(config);
386
385
  pulled.push(config.id);
387
386
  }));
@@ -393,6 +392,7 @@ export class RemoteAppCommand extends AppCommand {
393
392
  const removeList = filesToRemove
394
393
  .map((config) => config.filePath)
395
394
  .join('\n');
395
+ // eslint-disable-next-line no-await-in-loop
396
396
  const confirmed = await confirm({
397
397
  default: false,
398
398
  message: `The following files are not in the remote app:\n\n${removeList}\n\nDo you want to delete these files locally?`,
@@ -402,6 +402,7 @@ export class RemoteAppCommand extends AppCommand {
402
402
  }
403
403
  }
404
404
  while (filesToRemove.length > 0) {
405
+ // eslint-disable-next-line no-await-in-loop
405
406
  await Promise.all(filesToRemove.splice(0, PUSH_CONCURRENCY).map(async (config) => {
406
407
  await this.removeLocalFile(config);
407
408
  removed.push(config.id);
@@ -479,10 +480,9 @@ export class RemoteAppCommand extends AppCommand {
479
480
  this.log(`${style.appConfigName(`${batch.label} ${updatedLog}`)}`);
480
481
  }
481
482
  if (pushFiles.length > 0) {
482
- while (pushFiles.length) {
483
- await Promise.all(pushFiles
484
- .splice(0, batch.concurrency)
485
- .map(async (config) => {
483
+ while (pushFiles.length > 0) {
484
+ // eslint-disable-next-line no-await-in-loop
485
+ await Promise.all(pushFiles.splice(0, batch.concurrency).map(async (config) => {
486
486
  const pushedConfig = await this.pushRemoteFile(config);
487
487
  if (pushedConfig) {
488
488
  pushed.push(pushedConfig.id);
@@ -495,7 +495,8 @@ export class RemoteAppCommand extends AppCommand {
495
495
  }
496
496
  // Remove any deleted files
497
497
  if (filesToRemove.length > 0) {
498
- while (filesToRemove.length) {
498
+ while (filesToRemove.length > 0) {
499
+ // eslint-disable-next-line no-await-in-loop
499
500
  await Promise.all(filesToRemove.splice(0, batch.concurrency).map(async (config) => {
500
501
  await this.removeRemoteFile(config);
501
502
  removed.push(config.id);
@@ -1841,5 +1841,5 @@
1841
1841
  ]
1842
1842
  }
1843
1843
  },
1844
- "version": "2.0.9"
1844
+ "version": "2.0.10"
1845
1845
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.0.9",
3
+ "version": "2.0.10",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [