@swell/cli 2.0.7 → 2.0.9

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.
@@ -3,6 +3,7 @@ export default class AppThemeDev extends PushAppCommand {
3
3
  static examples: string[];
4
4
  static flags: {
5
5
  bundle: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
6
+ force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
6
7
  local: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
7
8
  'no-push': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
8
9
  'storefront-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
@@ -21,6 +21,10 @@ export default class AppThemeDev extends PushAppCommand {
21
21
  bundle: Flags.boolean({
22
22
  description: 'bundle assets',
23
23
  }),
24
+ force: Flags.boolean({
25
+ default: false,
26
+ description: 'force push all configurations',
27
+ }),
24
28
  local: Flags.boolean({
25
29
  description: 'connect to a running local storefront app dev server',
26
30
  }),
@@ -45,13 +49,18 @@ export default class AppThemeDev extends PushAppCommand {
45
49
  }
46
50
  async run() {
47
51
  const { flags } = await this.parse(AppThemeDev);
48
- const { local } = flags;
52
+ const { force, local } = flags;
49
53
  const noPush = flags['no-push'];
50
54
  if (!(await this.ensureAppExists(undefined, false))) {
51
55
  return;
52
56
  }
57
+ if (local) {
58
+ const currentStore = localConfig.getDefaultStore();
59
+ const sessionId = localConfig.getSessionId(currentStore);
60
+ this.storefrontLocalUrl = this.localFrontendUrl(currentStore, sessionId);
61
+ }
53
62
  if (!noPush) {
54
- await this.pushAppConfigs();
63
+ await this.pushAppConfigs(force);
55
64
  }
56
65
  await this.getStorefrontToPush(flags);
57
66
  this.logStorefrontConnected();
@@ -136,7 +145,7 @@ export default class AppThemeDev extends PushAppCommand {
136
145
  const freePort = (await getPort({ port: portNumbers(3000, 3100) })) || FALLBACK_PORT;
137
146
  spinner.start(`Starting theme dev server on port ${freePort}...`);
138
147
  const storefrontUrl = local
139
- ? this.localFrontendUrl(currentStore, sessionId)
148
+ ? this.storefrontLocalUrl
140
149
  : this.storefrontFrontendUrl(currentStore, this.storefront, undefined, true);
141
150
  const bs = BrowserSync.create();
142
151
  bs.init({
@@ -80,7 +80,7 @@ class AppConfig {
80
80
  this.appPath = path.join(appPath, filePath);
81
81
  }
82
82
  if (filePathExists(this.appPath)) {
83
- this.fileHash = hashFile(this.appPath);
83
+ this.fileHash = hashFile(this.appPath, undefined, filePath);
84
84
  this.hash = this.hash || this.fileHash;
85
85
  this.fileData = fs.readFileSync(this.appPath);
86
86
  this.fileContent = this.fileData.toString('utf8');
@@ -131,7 +131,7 @@ declare function filePathExists(filePath: string): boolean;
131
131
  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
- declare function hashFile(filePath: string, fileContents?: Buffer): string;
134
+ declare function hashFile(filePath: string, fileContents?: Buffer, relativePath?: string): string;
135
135
  declare function hashString(contents: 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;
@@ -184,11 +184,12 @@ async function writeJsonFile(file, data = {}) {
184
184
  return writeFile(file, `${JSON.stringify(data, null, 2)}\n`);
185
185
  }
186
186
  // Hash method adapted from wrangler-sdk
187
- function hashFile(filePath, fileContents) {
187
+ function hashFile(filePath, fileContents, relativePath) {
188
188
  const contents = fileContents ?? fs.readFileSync(filePath);
189
189
  const base64Contents = contents.toString('base64');
190
- const extension = path.extname(filePath).slice(1);
191
- return hashString(base64Contents + extension);
190
+ // Include relative file path because we typically cache by hash including file metadata
191
+ // This allows de-duplication of cache entries for the same file contents
192
+ return hashString(base64Contents + relativePath);
192
193
  }
193
194
  function hashString(contents) {
194
195
  return blake3hash(contents).toString('hex').slice(0, 32);
@@ -110,7 +110,8 @@ export class PushAppCommand extends RemoteAppCommand {
110
110
  if (this.app.type === 'theme') {
111
111
  themeAppId = this.app.id;
112
112
  const storefrontApps = await this.handleRequestErrors(async () => this.api.get({
113
- adminPath: `/apps?type=storefront&kind=shop`,
113
+ // TODO: improve this filter query
114
+ adminPath: `/apps?type=storefront&$or[0][kind]=shop&$or[1][kind]=`,
114
115
  }));
115
116
  const compatibleStorefrontApps = storefrontApps.results.filter((app) => app.installed &&
116
117
  app.storefront?.theme?.provider === 'app' &&
@@ -11,6 +11,7 @@ export declare abstract class RemoteAppCommand extends AppCommand {
11
11
  appCreated: boolean;
12
12
  appType: string;
13
13
  storefront?: any;
14
+ storefrontLocalUrl?: string;
14
15
  themeSyncApp?: boolean;
15
16
  appFrontendUrl(storeId: string, installedAppId: string): string;
16
17
  cleanRemoteConfigs(remoteConfigs: AppConfig[], deleteDeprecated?: boolean): Promise<AppConfig[]>;
@@ -26,6 +26,8 @@ export class RemoteAppCommand extends AppCommand {
26
26
  appType = 'any';
27
27
  // API instance of the target storefront, if applicable
28
28
  storefront = null;
29
+ // Indicates we are syncing with a local app frontend via proxy
30
+ storefrontLocalUrl = '';
29
31
  // Indicates app configs are being synced along with theme configs
30
32
  themeSyncApp = false;
31
33
  appFrontendUrl(storeId, installedAppId) {
@@ -334,6 +336,9 @@ export class RemoteAppCommand extends AppCommand {
334
336
  ...configJson,
335
337
  ...(themeId ? { theme_id: themeId } : undefined),
336
338
  ...(this.themeSyncApp ? { $sync_app: true } : undefined),
339
+ ...(this.storefrontLocalUrl
340
+ ? { $storefront_local_url: this.storefrontLocalUrl }
341
+ : undefined),
337
342
  },
338
343
  });
339
344
  }
@@ -352,7 +357,7 @@ export class RemoteAppCommand extends AppCommand {
352
357
  try {
353
358
  const localConfig = localBatchConfigs.find((config) => config.filePath === batchConfig.filePath);
354
359
  if (localConfig) {
355
- const hash = hashFile(batchConfig.appPath);
360
+ const hash = hashFile(batchConfig.appPath, undefined, batchConfig.filePath);
356
361
  if (hash === batchConfig.hash) {
357
362
  return false;
358
363
  }
@@ -1473,6 +1473,12 @@
1473
1473
  "allowNo": false,
1474
1474
  "type": "boolean"
1475
1475
  },
1476
+ "force": {
1477
+ "description": "force push all configurations",
1478
+ "name": "force",
1479
+ "allowNo": false,
1480
+ "type": "boolean"
1481
+ },
1476
1482
  "local": {
1477
1483
  "description": "connect to a running local storefront app dev server",
1478
1484
  "name": "local",
@@ -1835,5 +1841,5 @@
1835
1841
  ]
1836
1842
  }
1837
1843
  },
1838
- "version": "2.0.7"
1844
+ "version": "2.0.9"
1839
1845
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [