@swell/cli 2.0.19 → 2.1.0

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.
@@ -1,26 +1,21 @@
1
1
  import { Flags } from '@oclif/core';
2
- import getPort, { portNumbers } from 'get-port';
3
- import ngrok from 'ngrok';
4
- import ora from 'ora';
5
2
  import { default as localConfig } from '../../../lib/config.js';
6
3
  import style from '../../../lib/style.js';
7
4
  import { PushAppCommand } from '../../../push-app-command.js';
8
- const FALLBACK_PORT = 3000;
5
+ import AppDev from '../dev.js';
9
6
  export default class AppFrontendDev extends PushAppCommand {
10
7
  static examples = [
11
8
  'swell app frontend dev',
12
9
  'swell app frontend dev --no-push',
13
- 'swell app frontend dev --port 3000',
10
+ 'swell app frontend dev --proxy-port 3000',
14
11
  'swell app frontend dev --storefront-select',
15
12
  'swell app frontend dev --storefront-id <id>',
16
13
  ];
17
14
  static flags = {
18
- 'no-push': Flags.boolean({
19
- description: 'skip pushing app files initially',
20
- }),
21
- port: Flags.integer({
22
- char: 'p',
23
- description: 'override the default port to run the app locally',
15
+ ...AppDev.flags,
16
+ 'proxy-port': Flags.integer({
17
+ description: 'specify the port for an existing frontend proxy',
18
+ default: 3001,
24
19
  }),
25
20
  'storefront-id': Flags.string({
26
21
  description: 'identify a storefront to preview with and push theme files to',
@@ -29,25 +24,23 @@ export default class AppFrontendDev extends PushAppCommand {
29
24
  default: false,
30
25
  description: 'prompt to select a storefront to preview with',
31
26
  }),
27
+ 'app-dev': Flags.boolean({
28
+ description: 'indicates frontend app is running in app dev mode',
29
+ default: true,
30
+ }),
32
31
  };
33
32
  static orientation = {
34
33
  env: 'test',
35
34
  };
36
35
  static summary = `Run a frontend app in dev mode from your local machine.`;
37
- logAppLocalUrl(storeId, sessionId) {
38
- const frontendAppRoute = this.app.type === 'storefront' && this.app.storefront?.external
39
- ? `/${this.app.private_id}`
40
- : '';
41
- this.log(`View it at ${style.link(`${this.localFrontendUrl(storeId, sessionId)}${frontendAppRoute}`)}\n`);
42
- }
43
36
  async run() {
44
37
  const { flags } = await this.parse(AppFrontendDev);
45
- const { port } = flags;
38
+ const { port, 'proxy-port': proxyPort, 'app-dev': isAppDev } = flags;
46
39
  const noPush = flags['no-push'];
47
40
  if (!(await this.ensureAppExists(undefined, false))) {
48
41
  return;
49
42
  }
50
- if (!noPush) {
43
+ if (!noPush && !isAppDev) {
51
44
  await this.pushAppConfigs();
52
45
  }
53
46
  if (this.app.type === 'storefront') {
@@ -55,54 +48,124 @@ export default class AppFrontendDev extends PushAppCommand {
55
48
  this.logStorefrontConnected();
56
49
  }
57
50
  this.saveCurrentStorefront();
58
- const projectType = this.getFrontendProjectType();
59
- await this.startDevServer(projectType, port);
51
+ if (!isAppDev) {
52
+ this.log(`Starting app dev server...\n`);
53
+ }
54
+ const serverPort = await this.startProxyServer(proxyPort || port);
55
+ await this.execFrontendProject(serverPort, isAppDev);
60
56
  }
61
- async startDevServer(projectType, port) {
57
+ async execFrontendProject(serverPort, isAppDev) {
58
+ const projectType = this.getFrontendProjectType(!isAppDev);
59
+ if (!projectType) {
60
+ return;
61
+ }
62
62
  const currentStore = localConfig.getDefaultStore();
63
- const spinner = ora();
64
- // Find an open port starting at 3000
65
- const freePort = port ||
66
- (await getPort({ port: portNumbers(3000, 3100) })) ||
67
- FALLBACK_PORT;
68
- this.log(`Starting ${projectType.name} dev server...\n`);
69
- // Start ngrok proxy
70
- const proxyUrl = await ngrok.connect({
71
- addr: freePort,
72
- region: 'us', // TODO: make it configurable
73
- });
74
- await this.updateLocalProxy(proxyUrl, spinner, this.storefront?.id);
75
- return this.exec(projectType.devCommand.replace('${PORT}', String(freePort)), (string) => {
76
- // Hide useless astro warning about image optimization
77
- if (string.includes('The current configuration does not support image optimization')) {
78
- return false;
63
+ let serverReadyDetected = false;
64
+ await this.execFrontend(projectType.devCommand.replace('${PORT}', String(serverPort)), (string) => {
65
+ // Framework-specific output handling and ready detection
66
+ if (projectType.slug === 'nextjs') {
67
+ // 1. NOISE FILTER: Hide unwanted output
68
+ if (string.includes('Using vars defined in .dev.vars')) {
69
+ return false;
70
+ }
71
+ // 2. URL FILTER: Hide localhost/network URLs (confusing - users should use Swell tunnel)
72
+ if (/- Local:\s+http:\/\//i.test(string) ||
73
+ /- Network:\s+http:\/\//i.test(string) ||
74
+ /Ready on http:\/\/localhost/i.test(string)) {
75
+ return false;
76
+ }
77
+ // 3. READY DETECTION: Detect server ready, show our message
78
+ if (!serverReadyDetected) {
79
+ if (/✓ Ready in \d+/i.test(string) ||
80
+ /✓ Starting/i.test(string)) {
81
+ serverReadyDetected = true;
82
+ this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
83
+ const sessionId = localConfig.getSessionId(currentStore);
84
+ setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
85
+ if (!isAppDev) {
86
+ this.watchForChanges();
87
+ }
88
+ }
89
+ }
79
90
  }
80
- // Hide useless astro warning about .dev.vars
81
- if (string.includes('There is no `.dev.vars` file')) {
82
- return false;
91
+ else if (projectType.slug === 'astro') {
92
+ // 2. URL FILTER: Hide localhost/network URLs (confusing - users should use Swell tunnel)
93
+ if (string.includes('┃ Local') ||
94
+ string.includes('┃ Network')) {
95
+ return false;
96
+ }
97
+ // 3. READY DETECTION: Detect server ready, show our message
98
+ if (!serverReadyDetected && /watching for file changes/i.test(string)) {
99
+ serverReadyDetected = true;
100
+ this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
101
+ const sessionId = localConfig.getSessionId(currentStore);
102
+ setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
103
+ if (!isAppDev) {
104
+ this.watchForChanges();
105
+ }
106
+ }
83
107
  }
84
- // Hide astro localhost URL/network as it can confuse the user
85
- if (string.includes('┃ Local') || string.includes('┃ Network')) {
86
- return false;
108
+ else if (projectType.slug === 'angular') {
109
+ // 1. NOISE FILTER: Hide unwanted output
110
+ if (string.includes('press h + enter to show help')) {
111
+ return false;
112
+ }
113
+ // 2. URL FILTER: Hide localhost/network URLs (confusing - users should use Swell tunnel)
114
+ if (/➜\s+Local:\s+http:\/\//i.test(string)) {
115
+ return false;
116
+ }
117
+ // 3. READY DETECTION: Detect server ready, show our message
118
+ if (!serverReadyDetected) {
119
+ if (/Application bundle generation complete/i.test(string) ||
120
+ /Watch mode enabled/i.test(string)) {
121
+ serverReadyDetected = true;
122
+ this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
123
+ const sessionId = localConfig.getSessionId(currentStore);
124
+ setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
125
+ if (!isAppDev) {
126
+ this.watchForChanges();
127
+ }
128
+ }
129
+ }
87
130
  }
88
- // Started, show app url (TODO for nextjs)
89
- if (string.includes('watching for file changes')) {
90
- spinner.succeed(`Started ${projectType.name} dev server on port ${freePort}.\n`);
91
- const sessionId = localConfig.getSessionId(currentStore);
92
- setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
93
- this.watchForChanges();
131
+ else if (projectType.slug === 'hono') {
132
+ // 2. URL FILTER: Hide localhost URLs (confusing - users should use Swell tunnel)
133
+ // Note: For Hono, the ready signal IS the URL line, so we handle both in section 3
134
+ // 3. READY DETECTION: Detect server ready, show our message, hide the URL
135
+ if (!serverReadyDetected && /Ready on http:\/\/localhost:\d+/i.test(string)) {
136
+ serverReadyDetected = true;
137
+ this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
138
+ const sessionId = localConfig.getSessionId(currentStore);
139
+ setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
140
+ if (!isAppDev) {
141
+ this.watchForChanges();
142
+ }
143
+ return false; // Hide the "Ready on localhost" line
144
+ }
145
+ }
146
+ else if (projectType.slug === 'nuxt') {
147
+ // 2. URL FILTER: Hide localhost/network URLs (confusing - users should use Swell tunnel)
148
+ if (/➜ Local:\s+http:\/\//i.test(string) ||
149
+ /➜ Network:/i.test(string)) {
150
+ return false;
151
+ }
152
+ // 3. READY DETECTION: Detect server ready, show our message
153
+ if (!serverReadyDetected && /Nuxt \d+\.\d+\.\d+/i.test(string)) {
154
+ serverReadyDetected = true;
155
+ this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
156
+ const sessionId = localConfig.getSessionId(currentStore);
157
+ setTimeout(() => this.logAppLocalUrl(currentStore, sessionId), 100);
158
+ if (!isAppDev) {
159
+ this.watchForChanges();
160
+ }
161
+ }
94
162
  }
95
163
  });
96
164
  }
97
- async updateLocalProxy(proxyUrl, spinner, storefrontId) {
98
- const storefront = this.app.type === 'storefront' &&
99
- (await this.getAppStorefront({ storefront_id: storefrontId }));
100
- await this.handleRequestErrors(async () => this.api.put({ adminPath: `/client/apps/${this.app.id}/local-proxy` }, {
101
- body: {
102
- proxy_url: proxyUrl,
103
- storefront_id: storefront?.id || null,
104
- storefront_slug: storefront?.slug || null,
105
- },
106
- }), () => spinner.fail('Error starting local proxy'));
165
+ logAppLocalUrl(storeId, sessionId) {
166
+ const frontendAppRoute = this.app.type === 'storefront' && this.app.storefront?.external
167
+ ? `/${this.app.private_id}`
168
+ : '';
169
+ this.log(`View it at ${style.link(`${this.localFrontendUrl(storeId, sessionId)}${frontendAppRoute}`)}\n`);
107
170
  }
108
171
  }
@@ -3,6 +3,7 @@ import { Flags } from '@oclif/core';
3
3
  import ora from 'ora';
4
4
  import * as semver from 'semver';
5
5
  import config from '../../lib/config.js';
6
+ import { readRcFile } from '../../lib/app-config.js';
6
7
  import { selectEnvironmentId, selectLoggedInStoreId, } from '../../lib/stores.js';
7
8
  import style from '../../lib/style.js';
8
9
  import { RemoteAppCommand } from '../../remote-app-command.js';
@@ -123,10 +124,20 @@ Without a store specified, install the app in the Live environment of the curren
123
124
  }
124
125
  }
125
126
  async confirmRemoveDevelopmentApp(storeToInstall) {
126
- const existingSourcedApps = await this.api.get({ adminPath: `/client/apps` }, {
127
- query: { source_id: this.app.id },
128
- });
129
- if (existingSourcedApps.results[0]?.id) {
127
+ let sourceAppId;
128
+ try {
129
+ const sourceApp = await readRcFile(this.swellRcPath());
130
+ sourceAppId = sourceApp?.id;
131
+ }
132
+ catch (error) {
133
+ // noop
134
+ }
135
+ const existingSourcedApps = sourceAppId
136
+ ? await this.api.get({ adminPath: `/client/apps` }, {
137
+ query: { source_id: sourceAppId },
138
+ })
139
+ : null;
140
+ if (existingSourcedApps?.results[0]?.id) {
130
141
  const continueInstall = await confirm({
131
142
  default: false,
132
143
  message: `${style.storeId(storeToInstall)} has a development version of ${style.appConfigValue(this.app.name)}. Do you want to replace it with an installed instance?`,
@@ -7,6 +7,10 @@ export declare abstract class CreateAppCommand extends SwellCommand {
7
7
  };
8
8
  private devApi;
9
9
  constructor(argv: string[], config: any);
10
+ addAllowedHostsToAstro(configPath: string): Promise<void>;
11
+ addAllowedHostsToAngular(configPath: string): Promise<void>;
12
+ addAllowedHostsToNuxt(configPath: string): Promise<void>;
13
+ private addFrontendAllowedHosts;
10
14
  createAppConfigFolders(swellConfig: any): Promise<void>;
11
15
  createFrontendApp(swellConfig: any, flags: any, directCreate?: boolean, kind?: string): Promise<boolean>;
12
16
  createStorefrontApp(swellConfig: any, flags: any, directCreate?: boolean): Promise<boolean>;
@@ -10,6 +10,7 @@ import Api from './lib/api.js';
10
10
  import { FrontendProjectTypes, getAllConfigPaths, writeFile, writeJsonFile, } from './lib/apps/index.js';
11
11
  import style from './lib/style.js';
12
12
  import { SwellCommand } from './swell-command.js';
13
+ import fs from 'node:fs/promises';
13
14
  const execAsync = promisify(exec);
14
15
  export class CreateAppCommand extends SwellCommand {
15
16
  static baseFlags = {
@@ -30,6 +31,134 @@ export class CreateAppCommand extends SwellCommand {
30
31
  super(argv, config);
31
32
  this.devApi = new Api(undefined, 'test');
32
33
  }
34
+ async addAllowedHostsToAstro(configPath) {
35
+ const astroConfigPath = path.join(configPath, 'frontend', 'astro.config.mjs');
36
+ let content;
37
+ try {
38
+ content = await fs.readFile(astroConfigPath, 'utf-8');
39
+ }
40
+ catch {
41
+ return;
42
+ }
43
+ if (content.includes('allowedHosts')) {
44
+ return;
45
+ }
46
+ const lines = content.split('\n');
47
+ let insertIndex = -1;
48
+ for (let i = 0; i < lines.length; i++) {
49
+ if (lines[i].includes('defineConfig({')) {
50
+ insertIndex = i + 1;
51
+ break;
52
+ }
53
+ }
54
+ if (insertIndex === -1) {
55
+ return;
56
+ }
57
+ // Detect indentation from next line or use default
58
+ const nextLine = lines[insertIndex];
59
+ const indentMatch = nextLine?.match(/^(\s+)/);
60
+ const baseIndent = indentMatch ? indentMatch[1] : ' ';
61
+ const viteConfig = [
62
+ `${baseIndent}vite: {`,
63
+ `${baseIndent} server: {`,
64
+ `${baseIndent} allowedHosts: ['.ngrok.app', '.loca.lt'],`,
65
+ `${baseIndent} },`,
66
+ `${baseIndent}},`,
67
+ ];
68
+ lines.splice(insertIndex, 0, ...viteConfig);
69
+ await fs.writeFile(astroConfigPath, lines.join('\n'), 'utf-8');
70
+ }
71
+ async addAllowedHostsToAngular(configPath) {
72
+ const angularJsonPath = path.join(configPath, 'frontend', 'angular.json');
73
+ let content;
74
+ try {
75
+ content = await fs.readFile(angularJsonPath, 'utf-8');
76
+ }
77
+ catch {
78
+ return;
79
+ }
80
+ let config;
81
+ try {
82
+ config = JSON.parse(content);
83
+ }
84
+ catch {
85
+ return;
86
+ }
87
+ const projects = config.projects;
88
+ if (!projects || typeof projects !== 'object') {
89
+ return;
90
+ }
91
+ const projectNames = Object.keys(projects);
92
+ if (projectNames.length === 0) {
93
+ return;
94
+ }
95
+ // Use first project (typically only one exists in new apps)
96
+ const projectName = projectNames[0];
97
+ const project = projects[projectName];
98
+ if (!project?.architect?.serve) {
99
+ return;
100
+ }
101
+ if (!project.architect.serve.options) {
102
+ project.architect.serve.options = {};
103
+ }
104
+ if (project.architect.serve.options.allowedHosts) {
105
+ return;
106
+ }
107
+ project.architect.serve.options.allowedHosts = ['.ngrok.app', '.loca.lt'];
108
+ await fs.writeFile(angularJsonPath, JSON.stringify(config, null, 2), 'utf-8');
109
+ }
110
+ async addAllowedHostsToNuxt(configPath) {
111
+ const nuxtConfigPath = path.join(configPath, 'frontend', 'nuxt.config.ts');
112
+ let content;
113
+ try {
114
+ content = await fs.readFile(nuxtConfigPath, 'utf-8');
115
+ }
116
+ catch {
117
+ return;
118
+ }
119
+ if (content.includes('allowedHosts')) {
120
+ return;
121
+ }
122
+ const lines = content.split('\n');
123
+ let insertIndex = -1;
124
+ for (let i = 0; i < lines.length; i++) {
125
+ if (lines[i].includes('defineNuxtConfig({')) {
126
+ insertIndex = i + 1;
127
+ break;
128
+ }
129
+ }
130
+ if (insertIndex === -1) {
131
+ return;
132
+ }
133
+ const nextLine = lines[insertIndex];
134
+ const indentMatch = nextLine?.match(/^(\s+)/);
135
+ const baseIndent = indentMatch ? indentMatch[1] : ' ';
136
+ const viteConfig = [
137
+ `${baseIndent}vite: {`,
138
+ `${baseIndent} server: {`,
139
+ `${baseIndent} allowedHosts: ['.ngrok.app', '.loca.lt'],`,
140
+ `${baseIndent} },`,
141
+ `${baseIndent}},`,
142
+ ];
143
+ lines.splice(insertIndex, 0, ...viteConfig);
144
+ await fs.writeFile(nuxtConfigPath, lines.join('\n'), 'utf-8');
145
+ }
146
+ async addFrontendAllowedHosts(projectType, configPath) {
147
+ // Configure allowedHosts for frameworks using Vite dev server
148
+ // This allows tunneling services (ngrok, localtunnel) to proxy requests to the local dev environment
149
+ switch (projectType.slug) {
150
+ case 'astro':
151
+ await this.addAllowedHostsToAstro(configPath);
152
+ break;
153
+ case 'angular':
154
+ await this.addAllowedHostsToAngular(configPath);
155
+ break;
156
+ case 'nuxt':
157
+ await this.addAllowedHostsToNuxt(configPath);
158
+ break;
159
+ // Other frameworks don't require allowedHosts configuration
160
+ }
161
+ }
33
162
  async createAppConfigFolders(swellConfig) {
34
163
  for (const type of getAllConfigPaths(swellConfig.get('type'))) {
35
164
  // Create a config folder
@@ -67,6 +196,9 @@ export class CreateAppCommand extends SwellCommand {
67
196
  if (!projectType) {
68
197
  this.error(`Could not find project type: ${frameworkType}`);
69
198
  }
199
+ if (!projectType.installCommand) {
200
+ this.error(`Project type ${projectType.name} cannot be installed (legacy type)`);
201
+ }
70
202
  this.log();
71
203
  spinner.start(`Creating ${projectType?.name} frontend app (this may take a while)...`);
72
204
  try {
@@ -88,6 +220,31 @@ export class CreateAppCommand extends SwellCommand {
88
220
  this.log();
89
221
  return false;
90
222
  }
223
+ // Ensure frontend package.json has correct name for workspace
224
+ const frontendPkgPath = path.join(configPath, 'frontend', 'package.json');
225
+ try {
226
+ const pkgContent = await fs.readFile(frontendPkgPath, 'utf-8');
227
+ const pkg = JSON.parse(pkgContent);
228
+ if (pkg.name !== 'frontend') {
229
+ pkg.name = 'frontend';
230
+ await fs.writeFile(frontendPkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
231
+ }
232
+ }
233
+ catch {
234
+ // Ignore if package.json doesn't exist or can't be read
235
+ }
236
+ await this.addFrontendAllowedHosts(projectType, configPath);
237
+ // Re-run npm install at root to properly initialize workspace structure
238
+ // (removes frontend/package-lock.json, hoists dependencies, creates root lock file)
239
+ spinner.start('Initializing workspace...');
240
+ try {
241
+ const execAsync = promisify(exec);
242
+ await execAsync('npm install', { cwd: configPath });
243
+ spinner.succeed('Workspace initialized');
244
+ }
245
+ catch (error) {
246
+ spinner.warn('Failed to initialize workspace');
247
+ }
91
248
  spinner.succeed(`${projectType?.name} initialized app in ${configPath}/frontend/`);
92
249
  if (directCreate) {
93
250
  this.log();
@@ -212,6 +369,9 @@ export class CreateAppCommand extends SwellCommand {
212
369
  const configPath = path.dirname(config.path);
213
370
  const packageJson = {
214
371
  description: config.get('description'),
372
+ // Include workspace even if frontend doesn't exist yet
373
+ // npm tolerates missing workspace directories without errors
374
+ workspaces: ['frontend'],
215
375
  devDependencies: {
216
376
  '@swell/app-types': '^1.0.5',
217
377
  },
@@ -226,7 +386,7 @@ export class CreateAppCommand extends SwellCommand {
226
386
  target: 'esnext',
227
387
  types: ['@swell/app-types'],
228
388
  },
229
- exclude: ['node_modules'],
389
+ exclude: ['node_modules', 'frontend'],
230
390
  include: ['**/*.ts'],
231
391
  };
232
392
  await writeJsonFile(path.join(configPath, 'package.json'), packageJson);
@@ -4,5 +4,6 @@ declare namespace _default {
4
4
  let LOGIN_HOST: string;
5
5
  let APP_PAGES_HOST: string;
6
6
  let STOREFRONT_FRONTEND_HOST: string;
7
+ let LOCAL_PROXY_PROVIDER: string;
7
8
  }
8
9
  export default _default;
package/dist/env/local.js CHANGED
@@ -4,4 +4,5 @@ export default {
4
4
  LOGIN_HOST: 'http://${STORE_ID}.swell.test:3000',
5
5
  APP_PAGES_HOST: 'http://${STORE_ID}--${APP_ID}--${ENV}.swell.test:4001',
6
6
  STOREFRONT_FRONTEND_HOST: 'http://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.test:4001',
7
+ LOCAL_PROXY_PROVIDER: '',
7
8
  };
@@ -4,5 +4,6 @@ declare namespace _default {
4
4
  let LOGIN_HOST: string;
5
5
  let APP_PAGES_HOST: string;
6
6
  let STOREFRONT_FRONTEND_HOST: string;
7
+ let LOCAL_PROXY_PROVIDER: string;
7
8
  }
8
9
  export default _default;
@@ -4,4 +4,5 @@ export default {
4
4
  LOGIN_HOST: 'https://${STORE_ID}.swell.store',
5
5
  APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.swell.store',
6
6
  STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.store',
7
+ LOCAL_PROXY_PROVIDER: '',
7
8
  };
@@ -4,5 +4,6 @@ declare namespace _default {
4
4
  let LOGIN_HOST: string;
5
5
  let APP_PAGES_HOST: string;
6
6
  let STOREFRONT_FRONTEND_HOST: string;
7
+ let LOCAL_PROXY_PROVIDER: string;
7
8
  }
8
9
  export default _default;
@@ -4,4 +4,5 @@ export default {
4
4
  LOGIN_HOST: 'https://${REVIEW_DOMAIN}.rav2.swell.store',
5
5
  APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.${REVIEW_DOMAIN}.rav2.swell.store',
6
6
  STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.${REVIEW_DOMAIN}.rav2.swell.store',
7
+ LOCAL_PROXY_PROVIDER: '',
7
8
  };
@@ -4,5 +4,6 @@ declare namespace _default {
4
4
  let LOGIN_HOST: string;
5
5
  let APP_PAGES_HOST: string;
6
6
  let STOREFRONT_FRONTEND_HOST: string;
7
+ let LOCAL_PROXY_PROVIDER: string;
7
8
  }
8
9
  export default _default;
@@ -4,4 +4,5 @@ export default {
4
4
  LOGIN_HOST: 'https://staging.swell.store',
5
5
  APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.staging.swell.store',
6
6
  STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.staging.swell.store',
7
+ LOCAL_PROXY_PROVIDER: '',
7
8
  };
@@ -53,4 +53,53 @@ export declare abstract class AppConfig {
53
53
  protected abstract preparePostData(postData: any): Promise<any>;
54
54
  abstract type: ConfigType;
55
55
  }
56
+ export declare class AppConfigDefault extends AppConfig {
57
+ hasValues: boolean;
58
+ type: ConfigType;
59
+ preparePostData(postData: any): Promise<any>;
60
+ }
61
+ export declare class AppConfigModel extends AppConfig {
62
+ hasValues: boolean;
63
+ type: ConfigType;
64
+ preparePostData(postData: any): Promise<any>;
65
+ }
66
+ export declare class AppConfigContent extends AppConfig {
67
+ hasValues: boolean;
68
+ type: ConfigType;
69
+ preparePostData(postData: any): Promise<any>;
70
+ }
71
+ export declare class AppConfigNotification extends AppConfig {
72
+ hasValues: boolean;
73
+ type: ConfigType;
74
+ preparePostData(postData: any): Promise<any>;
75
+ }
76
+ export declare class AppConfigSetting extends AppConfig {
77
+ hasValues: boolean;
78
+ type: ConfigType;
79
+ preparePostData(postData: any): Promise<any>;
80
+ }
81
+ export declare class AppConfigWebhook extends AppConfig {
82
+ hasValues: boolean;
83
+ type: ConfigType;
84
+ preparePostData(postData: any): Promise<any>;
85
+ }
86
+ export declare class AppConfigFunction extends AppConfig {
87
+ hasValues: boolean;
88
+ type: ConfigType;
89
+ isRootFunction(): boolean;
90
+ preparePostData(postData: any): Promise<any>;
91
+ }
92
+ export declare class AppConfigAsset extends AppConfigDefault {
93
+ hasValues: boolean;
94
+ type: ConfigType;
95
+ }
96
+ export declare class AppConfigFrontend extends AppConfigDefault {
97
+ hasValues: boolean;
98
+ type: ConfigType;
99
+ }
100
+ export declare class AppConfigTheme extends AppConfigDefault {
101
+ hasValues: boolean;
102
+ type: ConfigType;
103
+ preparePostData(postData: any): Promise<any>;
104
+ }
56
105
  export {};