@swell/cli 2.0.11 → 2.0.13

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 (39) hide show
  1. package/dist/commands/app/dev.d.ts +2 -2
  2. package/dist/commands/app/dev.js +2 -2
  3. package/dist/commands/app/install.js +1 -1
  4. package/dist/commands/app/pull.d.ts +4 -1
  5. package/dist/commands/app/pull.js +9 -6
  6. package/dist/commands/app/push.d.ts +4 -2
  7. package/dist/commands/app/push.js +2 -2
  8. package/dist/commands/app/release.d.ts +3 -0
  9. package/dist/commands/app/release.js +3 -0
  10. package/dist/commands/app/version.d.ts +3 -0
  11. package/dist/commands/app/version.js +3 -0
  12. package/dist/commands/create/app.d.ts +1 -1
  13. package/dist/commands/create/app.js +1 -1
  14. package/dist/commands/login.js +1 -1
  15. package/dist/commands/theme/dev.d.ts +2 -4
  16. package/dist/commands/theme/dev.js +13 -7
  17. package/dist/commands/theme/init.d.ts +1 -1
  18. package/dist/commands/theme/init.js +1 -1
  19. package/dist/commands/theme/pull.d.ts +3 -3
  20. package/dist/commands/theme/pull.js +6 -3
  21. package/dist/commands/theme/push.d.ts +2 -3
  22. package/dist/commands/theme/push.js +18 -5
  23. package/dist/lib/api.d.ts +5 -4
  24. package/dist/lib/api.js +16 -3
  25. package/dist/lib/apps/app-config.d.ts +6 -6
  26. package/dist/lib/apps/app-config.js +4 -5
  27. package/dist/lib/apps/index.d.ts +36 -35
  28. package/dist/lib/apps/index.js +60 -62
  29. package/dist/lib/apps/paths.d.ts +10 -9
  30. package/dist/lib/apps/paths.js +36 -32
  31. package/dist/lib/config.d.ts +5 -2
  32. package/dist/lib/config.js +11 -3
  33. package/dist/lib/stores.js +2 -2
  34. package/dist/push-app-command.d.ts +24 -9
  35. package/dist/push-app-command.js +114 -63
  36. package/dist/remote-app-command.d.ts +2 -2
  37. package/dist/remote-app-command.js +14 -8
  38. package/oclif.manifest.json +41 -7
  39. package/package.json +2 -2
@@ -5,20 +5,30 @@ import * as path from 'node:path';
5
5
  import Stream from 'node:stream';
6
6
  import ora from 'ora';
7
7
  import { default as swellConfig } from './lib/app-config.js';
8
- import { ConfigType, FrontendProjectTypes, allConfigFilesInDir, appConfigFromFile, filePathExists, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
8
+ import { ConfigType, FrontendProjectTypes, allConfigFilesInDir, appConfigFromFile, filePathExists, filePathExistsAsync, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
9
+ import { selectEnvironmentId } from './lib/stores.js';
10
+ import { getGlobIgnorePathsChecker } from './lib/apps/paths.js';
9
11
  import { default as localConfig } from './lib/config.js';
10
12
  import { toAppId } from './lib/create/index.js';
11
13
  import style from './lib/style.js';
12
14
  import { RemoteAppCommand } from './remote-app-command.js';
13
15
  const PUSH_CONCURRENCY = 3;
16
+ const WATCH_WINDOW_MS = 100;
14
17
  export class PushAppCommand extends RemoteAppCommand {
15
18
  frontendPath = '';
16
19
  logWatchChanges = true;
17
20
  onWatchChange;
18
- watchingChangeQueue = [];
19
- watchingChangeQueueRunning = false;
20
- watchingFiles = [];
21
+ watchingChangeQueue = new Map();
22
+ watchingFiles = new Set();
23
+ watchingIgnoreFilter = null;
24
+ watchingTimer = null;
21
25
  watchListener = async (eventType, filename) => {
26
+ if (!filename) {
27
+ return;
28
+ }
29
+ if (this.watchingIgnoreFilter && this.watchingIgnoreFilter(filename)) {
30
+ return;
31
+ }
22
32
  const configFile = filename;
23
33
  const pathParsed = path.parse(configFile);
24
34
  const fileDirs = pathParsed.dir.split(path.sep);
@@ -26,8 +36,6 @@ export class PushAppCommand extends RemoteAppCommand {
26
36
  const configDir = fileDirs[0];
27
37
  // we only want to watch files in the root of the app directory
28
38
  // and ignore build files etc
29
- this.setWatchingFiles();
30
- const isWatching = this.watchingFiles.includes(configFile);
31
39
  // TODO: renaming a folder doesn't seem to work
32
40
  // because isWatching = false for the new files
33
41
  if (!configDir) {
@@ -37,6 +45,7 @@ export class PushAppCommand extends RemoteAppCommand {
37
45
  if (!configType) {
38
46
  return;
39
47
  }
48
+ const isWatching = this.watchingFiles.has(configFile);
40
49
  let watchFileEvent;
41
50
  // per node docs:
42
51
  //
@@ -47,12 +56,14 @@ export class PushAppCommand extends RemoteAppCommand {
47
56
  // correct API request
48
57
  if (eventType === 'rename') {
49
58
  watchFileEvent = 'new';
50
- if (!filePathExists(path.join(this.appPath, configFile))) {
59
+ if (!(await filePathExistsAsync(path.join(this.appPath, configFile)))) {
51
60
  watchFileEvent = 'deleted';
61
+ this.watchingFiles.delete(configFile);
52
62
  }
53
63
  else if (!isWatching) {
54
64
  return;
55
65
  }
66
+ this.watchingFiles.add(configFile);
56
67
  }
57
68
  else if (isWatching) {
58
69
  watchFileEvent = 'change';
@@ -85,9 +96,7 @@ export class PushAppCommand extends RemoteAppCommand {
85
96
  const typeLabelPlural = this.appType === 'theme' ? 'themes' : 'apps';
86
97
  const typeLabelPrefixed = this.appType === 'theme' ? 'a theme' : 'an app';
87
98
  const typeQuery = this.appType === 'theme' ? { type: 'theme' } : { type: 'storefront' };
88
- const apps = await this.api.get({
89
- adminPath: `/apps`,
90
- }, { query: { limit: null, ...typeQuery, ...query } });
99
+ const apps = await this.api.get({ adminPath: '/apps' }, { query: { limit: null, ...typeQuery, ...query } });
91
100
  if (!apps.count) {
92
101
  const currentStore = localConfig.getDefaultStore();
93
102
  this.error(`There are no ${typeLabelPlural} associated with your store ${style.storeId(currentStore)}`);
@@ -220,12 +229,11 @@ export class PushAppCommand extends RemoteAppCommand {
220
229
  }
221
230
  }
222
231
  async ensureAppExists(file, shouldCreate = true) {
223
- let currentStore = localConfig.getDefaultStore();
224
- this.api.setStoreEnv(currentStore, 'test');
225
- const loggedIn = await this.ensureLoggedIn();
226
- if (loggedIn) {
227
- currentStore = localConfig.getDefaultStore();
228
- this.api.setStoreEnv(currentStore, 'test');
232
+ const klass = this.ctor;
233
+ const currentStore = localConfig.getDefaultStore();
234
+ await this.ensureLoggedIn();
235
+ if (klass.orientation?.env) {
236
+ await this.api.setStoreEnv(currentStore, klass.orientation?.env);
229
237
  }
230
238
  const app = await this.getAppWithConfig('').catch((_error) =>
231
239
  // Ignore so we can continue to create it
@@ -234,9 +242,12 @@ export class PushAppCommand extends RemoteAppCommand {
234
242
  if (app && !isTheme && this.appType === 'theme') {
235
243
  this.error(`App ${style.appConfigValue(app?.name)} is not a theme.`);
236
244
  }
237
- const confirmExistingApp = await this.confirmRemoveInstalledApp(app, currentStore);
238
- if (confirmExistingApp === false) {
239
- return false;
245
+ // Confirm development app unless theme without app syncing
246
+ if (!isTheme || this.themeSyncApp) {
247
+ const confirmExistingApp = await this.confirmRemoveInstalledApp(app, currentStore);
248
+ if (confirmExistingApp === false) {
249
+ return false;
250
+ }
240
251
  }
241
252
  // Do not create or update if app already exists and not forcing it
242
253
  if (!shouldCreate && app) {
@@ -326,8 +337,9 @@ export class PushAppCommand extends RemoteAppCommand {
326
337
  }
327
338
  async getAppToPull(args, shouldChoose = true) {
328
339
  const { appId, targetPath } = args;
340
+ const klass = this.ctor;
329
341
  const currentStore = localConfig.getDefaultStore();
330
- this.api.setStoreEnv(currentStore, 'test');
342
+ await this.api.setStoreEnv(currentStore, klass.orientation?.env);
331
343
  this.resolveAppPath(appId, targetPath);
332
344
  if (isPathDirectory(this.appPath)) {
333
345
  this.swellConfig = swellConfig(this.appPath);
@@ -393,15 +405,16 @@ export class PushAppCommand extends RemoteAppCommand {
393
405
  }
394
406
  async getStorefrontToPull(args = {}, flags = {}) {
395
407
  const { appId, targetPath } = args;
396
- const targetApp = await this.getAppToPull(args, false);
397
408
  const targetStorefront = flags['storefront-id'];
409
+ const targetApp = await this.getAppToPull(args, false);
398
410
  this.resolveAppPath(appId, targetPath);
399
411
  // Only use default if path exists
400
- let currentStorefront;
412
+ let defaultStorefront;
401
413
  if (isPathDirectory(this.appPath)) {
402
- currentStorefront = localConfig.getDefaultStorefront(this.appPath);
414
+ defaultStorefront = localConfig.getDefaultStorefront(this.appPath);
403
415
  }
404
- let storefrontId = targetStorefront || targetApp ? currentStorefront : undefined;
416
+ await this.setStorefrontEnv(flags, defaultStorefront);
417
+ let storefrontId = targetStorefront || targetApp ? defaultStorefront?.id : undefined;
405
418
  if (!storefrontId || flags['storefront-select']) {
406
419
  const storefronts = await this.getAllStorefronts(targetApp?.id
407
420
  ? this.appType === 'theme'
@@ -452,8 +465,12 @@ export class PushAppCommand extends RemoteAppCommand {
452
465
  }
453
466
  async getStorefrontToPush(flags = {}) {
454
467
  const targetStorefront = flags['storefront-id'];
455
- const currentStorefront = localConfig.getDefaultStorefront(this.appPath);
456
- let storefrontId = targetStorefront || currentStorefront;
468
+ const defaultStorefront = localConfig.getDefaultStorefront(this.appPath);
469
+ let storefrontId = targetStorefront || defaultStorefront?.id;
470
+ // Force storefront select if pushing app from default storefront in live environment
471
+ if (this.themeSyncApp && defaultStorefront?.id && !defaultStorefront.env) {
472
+ storefrontId = '';
473
+ }
457
474
  if (!storefrontId || flags['storefront-select']) {
458
475
  const storefronts = await this.getAllAppStorefronts({
459
476
  type: this.appType,
@@ -494,28 +511,64 @@ export class PushAppCommand extends RemoteAppCommand {
494
511
  this.app = await this.getApp(this.app.id);
495
512
  return this.storefront;
496
513
  }
514
+ async setStorefrontEnv(flags, defaultStorefront) {
515
+ const currentStore = localConfig.getDefaultStore();
516
+ const targetStorefront = flags['storefront-id'];
517
+ if (defaultStorefront &&
518
+ !targetStorefront &&
519
+ !flags['storefront-id'] &&
520
+ !flags['storefront-select']) {
521
+ const klass = this.ctor;
522
+ if (klass.orientation?.env === undefined) {
523
+ await this.api.setStoreEnv(currentStore, defaultStorefront?.env);
524
+ }
525
+ }
526
+ else if (flags['env']) {
527
+ await this.api.setStoreEnv(currentStore, flags['env']);
528
+ }
529
+ else {
530
+ const hasTestEnv = await this.api.isTestEnvEnabled();
531
+ if (hasTestEnv) {
532
+ const env = await selectEnvironmentId();
533
+ await this.api.setStoreEnv(currentStore, env);
534
+ }
535
+ }
536
+ }
497
537
  async handleWatchFileChange(configFile, configType, event) {
498
538
  let config;
499
- if (event === 'deleted') {
500
- config = findAppConfig(this.app, configFile, configType);
501
- if (!config) {
502
- return;
539
+ switch (event) {
540
+ case 'deleted': {
541
+ config = findAppConfig(this.app, configFile, configType);
542
+ if (!config) {
543
+ return;
544
+ }
545
+ this.watchingChangeQueue.set(configFile, {
546
+ action: 'remove',
547
+ appConfig: config,
548
+ configFile,
549
+ });
550
+ break;
551
+ }
552
+ default: {
553
+ config = appConfigFromFile(configFile, configType, this.appPath);
554
+ this.watchingChangeQueue.set(configFile, {
555
+ action: 'push',
556
+ appConfig: config,
557
+ configFile,
558
+ });
559
+ break;
503
560
  }
504
- this.watchingChangeQueue.push({
505
- action: 'remove',
506
- appConfig: config,
507
- configFile,
508
- });
509
561
  }
510
- else {
511
- config = appConfigFromFile(configFile, configType, this.appPath);
512
- this.watchingChangeQueue.push({
513
- action: 'push',
514
- appConfig: config,
515
- configFile,
516
- });
562
+ if (this.watchingTimer === null) {
563
+ this.watchingTimer = setTimeout(async () => {
564
+ try {
565
+ await this.runWatchChangeQueue();
566
+ }
567
+ finally {
568
+ this.watchingTimer = null;
569
+ }
570
+ }, WATCH_WINDOW_MS);
517
571
  }
518
- await this.runWatchChangeQueue();
519
572
  }
520
573
  logAppFrontendUrl() {
521
574
  const currentStore = localConfig.getDefaultStore();
@@ -533,11 +586,8 @@ export class PushAppCommand extends RemoteAppCommand {
533
586
  if (!this.storefront) {
534
587
  this.error('Storefront not connected');
535
588
  }
536
- const { name, theme_app } = this.storefront;
537
- const themeLog = theme_app && theme_app.name !== name
538
- ? ` [theme] ${style.appName(theme_app.name)} v${theme_app.version}`
539
- : '';
540
- this.log(`[storefront] ${style.appName(name)}${themeLog}\n`);
589
+ const { name } = this.storefront;
590
+ this.log(`[storefront] ${style.appName(name)}\n`);
541
591
  }
542
592
  logStorefrontFrontendUrl(storefront, branchId) {
543
593
  const currentStore = localConfig.getDefaultStore();
@@ -603,44 +653,44 @@ export class PushAppCommand extends RemoteAppCommand {
603
653
  isPathDirectory(path.resolve(process.cwd(), resolvedAppId))) {
604
654
  resolvedPath = resolvedAppId;
605
655
  }
606
- // Reset app config and path if appId is provided
607
- if (resolvedPath && this.appPath === '.') {
656
+ // Reset app path if appId is provided
657
+ if (resolvedPath && this.appPath === process.cwd()) {
608
658
  this.appPath = path.resolve(process.cwd(), resolvedPath);
609
659
  }
610
660
  return this.appPath;
611
661
  }
612
662
  async runWatchChangeQueue() {
613
- if (this.watchingChangeQueueRunning) {
663
+ if (this.watchingChangeQueue.size <= 0) {
614
664
  return;
615
665
  }
616
- while (this.watchingChangeQueue.length > 0) {
617
- this.watchingChangeQueueRunning = true;
666
+ const queue = [...this.watchingChangeQueue.values()];
667
+ this.watchingChangeQueue.clear();
668
+ while (queue.length > 0) {
618
669
  // eslint-disable-next-line no-await-in-loop
619
- await Promise.all(this.watchingChangeQueue
620
- .splice(0, PUSH_CONCURRENCY)
621
- .map(async ({ action, appConfig }) => {
670
+ await Promise.all(queue.splice(0, PUSH_CONCURRENCY).map(async ({ action, appConfig }) => {
622
671
  const result = await (action === 'remove'
623
672
  ? this.removeRemoteFile(appConfig, this.logWatchChanges)
624
673
  : this.pushRemoteFile(appConfig, this.logWatchChanges));
625
674
  this.onWatchChange?.(appConfig, result);
626
675
  }));
627
676
  }
628
- this.watchingChangeQueueRunning = false;
629
677
  // refetch app to get updated configs
630
678
  this.app = await this.getAppWithConfig(this.app.id);
679
+ // Process next accumulated changes
680
+ return this.runWatchChangeQueue();
631
681
  }
632
682
  saveCurrentStorefront() {
633
683
  const currentStorefront = localConfig.getDefaultStorefront(this.appPath);
634
684
  if (this.storefront && this.storefront.id !== currentStorefront) {
635
- localConfig.setDefaultStorefront(this.appPath, this.storefront.id);
685
+ localConfig.setDefaultStorefront(this.appPath, this.storefront.id, this.api.envId);
636
686
  }
637
687
  }
638
- setWatchingFiles() {
639
- this.watchingFiles = globAllFilesByPath(this.appPath);
688
+ async setWatchingFiles() {
689
+ this.watchingFiles = new Set(await globAllFilesByPath(this.appPath));
640
690
  }
641
691
  async updateFrontendDeployment(currentStore, projectType, deploymentUrl, deploymentHash) {
642
692
  const spinner = ora();
643
- spinner.start(`Updating frontend deployment...`);
693
+ spinner.start('Updating frontend deployment...');
644
694
  await this.handleRequestErrors(async () => this.api.put({ adminPath: `/apps/${this.app.id}` }, {
645
695
  body: {
646
696
  $client_id: currentStore,
@@ -656,14 +706,15 @@ export class PushAppCommand extends RemoteAppCommand {
656
706
  spinner.succeed('Updated frontend deployment.\n');
657
707
  }
658
708
  async watchForChanges({ logChanges, onChange, syncAll, } = {}) {
709
+ this.watchingIgnoreFilter = await getGlobIgnorePathsChecker(this.appPath);
659
710
  this.logWatchChanges = logChanges ?? true;
660
711
  this.onWatchChange = onChange;
661
- this.setWatchingFiles();
712
+ await this.setWatchingFiles();
662
713
  if (syncAll) {
663
714
  await this.pushAppConfigs();
664
715
  fs.watch(this.appPath, { recursive: true }, async (_eventType, _filename) => {
665
716
  await this.pushAppConfigs();
666
- this.setWatchingFiles();
717
+ await this.setWatchingFiles();
667
718
  });
668
719
  return;
669
720
  }
@@ -5,11 +5,11 @@ import { App, AppConfig, AppVersion } from './lib/apps/index.js';
5
5
  * configurations.
6
6
  */
7
7
  export declare abstract class RemoteAppCommand extends AppCommand {
8
+ appType: string;
8
9
  static delayOrientation: boolean;
9
10
  static orientation: AppCommandOrientation;
10
11
  app: App;
11
12
  appCreated: boolean;
12
- appType: string;
13
13
  storefront?: any;
14
14
  storefrontLocalUrl?: string;
15
15
  themeSyncApp?: boolean;
@@ -32,7 +32,7 @@ export declare abstract class RemoteAppCommand extends AppCommand {
32
32
  protected installApp(version: string, spinner?: any): Promise<any>;
33
33
  isConfigDeprecated(config: AppConfig): boolean;
34
34
  localFrontendUrl(storeId: string, sessionId: string): string;
35
- logOrientation(): Promise<void>;
35
+ logOrientation(orientation?: AppCommandOrientation): Promise<void>;
36
36
  postConfigData(configJson: any): Promise<any>;
37
37
  protected pullAppConfigs(force?: boolean, confirmRemove?: boolean): Promise<{
38
38
  pulled: string[];
@@ -15,6 +15,7 @@ import style from './lib/style.js';
15
15
  * configurations.
16
16
  */
17
17
  export class RemoteAppCommand extends AppCommand {
18
+ appType = 'any';
18
19
  // allows child commands to set orientation
19
20
  static delayOrientation = false;
20
21
  // most of the times this will be the target environment
@@ -23,7 +24,6 @@ export class RemoteAppCommand extends AppCommand {
23
24
  app = {};
24
25
  // Indicates the app was created during the command execution
25
26
  appCreated = false;
26
- appType = 'any';
27
27
  // API instance of the target storefront, if applicable
28
28
  storefront = null;
29
29
  // Indicates we are syncing with a local app frontend via proxy
@@ -322,11 +322,11 @@ export class RemoteAppCommand extends AppCommand {
322
322
  localFrontendUrl(storeId, sessionId) {
323
323
  return getLocalFrontendHost(storeId, sessionId);
324
324
  }
325
- async logOrientation() {
325
+ async logOrientation(orientation) {
326
326
  const klass = this.ctor;
327
327
  const { flags } = await this.parse(klass);
328
- if (klass.orientation) {
329
- this.showOrientation(klass.orientation, flags);
328
+ if (klass.orientation || orientation) {
329
+ this.showOrientation(klass.orientation || orientation, flags);
330
330
  }
331
331
  }
332
332
  async postConfigData(configJson) {
@@ -334,7 +334,9 @@ export class RemoteAppCommand extends AppCommand {
334
334
  return this.api.post({ adminPath: `/apps/${this.app.id}/configs` }, {
335
335
  body: {
336
336
  ...configJson,
337
- ...(themeId ? { theme_id: themeId } : undefined),
337
+ ...(themeId
338
+ ? { theme_id: themeId, $environment_id: this.api.envId }
339
+ : undefined),
338
340
  ...(this.themeSyncApp ? { $sync_app: true } : undefined),
339
341
  ...(this.storefrontLocalUrl
340
342
  ? { $storefront_local_url: this.storefrontLocalUrl }
@@ -629,9 +631,13 @@ export class RemoteAppCommand extends AppCommand {
629
631
  const orientationOutput = [];
630
632
  const currentStore = localConfig.getDefaultStore();
631
633
  const { env, store } = flags;
632
- orientationOutput.push(`[${this.app.type === 'theme' ? 'theme' : 'app'}] ${style.appName(this.app.name)}${this.app.version ? ` v${this.app.version}` : ''}${this.storefront && this.storefront.name !== this.app.name
633
- ? ` [storefront] ${style.appName(this.storefront.name)}`
634
- : ``}`);
634
+ if (this.app.name) {
635
+ // Show theme version if not syncing app
636
+ const version = !this.themeSyncApp && this.app.type === 'theme' && this.storefront?.theme_version
637
+ ? this.storefront?.theme_version
638
+ : this.app.version;
639
+ orientationOutput.push(`[${this.app.type === 'theme' ? 'theme' : 'app'}] ${style.appName(this.app.name)}${version ? ` v${version}` : ''}`);
640
+ }
635
641
  if (store) {
636
642
  orientationOutput.push(`[store] ${style.storeId(store)}`);
637
643
  }
@@ -623,6 +623,9 @@
623
623
  "pluginType": "core",
624
624
  "strict": true,
625
625
  "summary": "Pull app files from Swell to your local machine.",
626
+ "orientation": {
627
+ "env": "test"
628
+ },
626
629
  "isESM": true,
627
630
  "relativePath": [
628
631
  "dist",
@@ -758,6 +761,9 @@
758
761
  "pluginType": "core",
759
762
  "strict": true,
760
763
  "summary": "Release a new version of your an app for publishing to the App Store.",
764
+ "orientation": {
765
+ "env": "test"
766
+ },
761
767
  "isESM": true,
762
768
  "relativePath": [
763
769
  "dist",
@@ -825,6 +831,9 @@
825
831
  "pluginType": "core",
826
832
  "strict": true,
827
833
  "summary": "Increment the version of your Swell app.",
834
+ "orientation": {
835
+ "env": "test"
836
+ },
828
837
  "isESM": true,
829
838
  "relativePath": [
830
839
  "dist",
@@ -1519,6 +1528,14 @@
1519
1528
  "name": "storefront-select",
1520
1529
  "allowNo": false,
1521
1530
  "type": "boolean"
1531
+ },
1532
+ "env": {
1533
+ "char": "e",
1534
+ "description": "target environment to push to, defaults to live",
1535
+ "name": "env",
1536
+ "hasDynamicHelp": false,
1537
+ "multiple": false,
1538
+ "type": "option"
1522
1539
  }
1523
1540
  },
1524
1541
  "hasDynamicHelp": false,
@@ -1529,9 +1546,6 @@
1529
1546
  "pluginType": "core",
1530
1547
  "strict": true,
1531
1548
  "summary": "Run a theme in dev mode from your local machine.",
1532
- "orientation": {
1533
- "env": "test"
1534
- },
1535
1549
  "isESM": true,
1536
1550
  "relativePath": [
1537
1551
  "dist",
@@ -1646,6 +1660,14 @@
1646
1660
  "allowNo": false,
1647
1661
  "type": "boolean"
1648
1662
  },
1663
+ "env": {
1664
+ "char": "e",
1665
+ "description": "target environment to pull from, defaults to live",
1666
+ "name": "env",
1667
+ "hasDynamicHelp": false,
1668
+ "multiple": false,
1669
+ "type": "option"
1670
+ },
1649
1671
  "sync-app": {
1650
1672
  "description": "pull app files in addition to theme files to",
1651
1673
  "name": "sync-app",
@@ -1660,6 +1682,9 @@
1660
1682
  "pluginName": "@swell/cli",
1661
1683
  "pluginType": "core",
1662
1684
  "summary": "Pull theme files from Swell to your local machine.",
1685
+ "orientation": {
1686
+ "env": "test"
1687
+ },
1663
1688
  "isESM": true,
1664
1689
  "relativePath": [
1665
1690
  "dist",
@@ -1667,8 +1692,7 @@
1667
1692
  "theme",
1668
1693
  "pull.js"
1669
1694
  ],
1670
- "delayOrientation": true,
1671
- "orientation": {}
1695
+ "delayOrientation": true
1672
1696
  },
1673
1697
  "theme:push": {
1674
1698
  "aliases": [],
@@ -1708,6 +1732,14 @@
1708
1732
  "allowNo": false,
1709
1733
  "type": "boolean"
1710
1734
  },
1735
+ "env": {
1736
+ "char": "e",
1737
+ "description": "target environment to push to, defaults to live",
1738
+ "name": "env",
1739
+ "hasDynamicHelp": false,
1740
+ "multiple": false,
1741
+ "type": "option"
1742
+ },
1711
1743
  "sync-app": {
1712
1744
  "description": "push app files in addition to theme files",
1713
1745
  "name": "sync-app",
@@ -1723,7 +1755,9 @@
1723
1755
  "pluginType": "core",
1724
1756
  "summary": "Push local files to your Swell theme.",
1725
1757
  "delayOrientation": true,
1726
- "orientation": {},
1758
+ "orientation": {
1759
+ "env": "test"
1760
+ },
1727
1761
  "isESM": true,
1728
1762
  "relativePath": [
1729
1763
  "dist",
@@ -1857,5 +1891,5 @@
1857
1891
  ]
1858
1892
  }
1859
1893
  },
1860
- "version": "2.0.11"
1894
+ "version": "2.0.13"
1861
1895
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "execa": "8.0.1",
43
43
  "find-up": "7.0.0",
44
44
  "get-port": "7.0.0",
45
- "globby": "14.0.1",
45
+ "globby": "^14.1.0",
46
46
  "inflection": "3.0.0",
47
47
  "istextorbinary": "9.5.0",
48
48
  "lodash": "4.17.21",