@swell/cli 2.0.1-alpha.16 → 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 (86) hide show
  1. package/dist/app-command.d.ts +1 -1
  2. package/dist/app-command.js +9 -9
  3. package/dist/commands/app/dev.d.ts +16 -0
  4. package/dist/commands/app/dev.js +28 -0
  5. package/dist/commands/app/frontend/deploy.d.ts +15 -0
  6. package/dist/commands/app/frontend/deploy.js +41 -0
  7. package/dist/commands/app/frontend/dev.d.ts +19 -0
  8. package/dist/commands/app/frontend/dev.js +108 -0
  9. package/dist/commands/app/info.js +14 -9
  10. package/dist/commands/app/init.d.ts +12 -0
  11. package/dist/commands/app/init.js +34 -0
  12. package/dist/commands/app/install.d.ts +0 -3
  13. package/dist/commands/app/install.js +12 -21
  14. package/dist/commands/app/pull.d.ts +15 -0
  15. package/dist/commands/app/pull.js +50 -0
  16. package/dist/commands/app/push.d.ts +9 -12
  17. package/dist/commands/app/push.js +57 -131
  18. package/dist/commands/app/release.d.ts +13 -0
  19. package/dist/commands/app/release.js +148 -0
  20. package/dist/commands/app/version.d.ts +5 -4
  21. package/dist/commands/app/version.js +60 -39
  22. package/dist/commands/app/watch.d.ts +2 -4
  23. package/dist/commands/app/watch.js +3 -83
  24. package/dist/commands/create/app.d.ts +35 -11
  25. package/dist/commands/create/app.js +131 -128
  26. package/dist/commands/create/frontend.d.ts +12 -0
  27. package/dist/commands/create/frontend.js +38 -0
  28. package/dist/commands/create/function.d.ts +2 -2
  29. package/dist/commands/create/function.js +2 -2
  30. package/dist/commands/create/notification.d.ts +2 -2
  31. package/dist/commands/create/notification.js +2 -2
  32. package/dist/commands/env.d.ts +12 -0
  33. package/dist/commands/env.js +31 -0
  34. package/dist/commands/login.js +7 -7
  35. package/dist/commands/logs.js +0 -3
  36. package/dist/commands/theme/dev.d.ts +21 -0
  37. package/dist/commands/theme/dev.js +164 -0
  38. package/dist/commands/theme/init.d.ts +9 -0
  39. package/dist/commands/theme/init.js +15 -0
  40. package/dist/commands/theme/pull.d.ts +20 -0
  41. package/dist/commands/theme/pull.js +65 -0
  42. package/dist/commands/theme/push.d.ts +19 -0
  43. package/dist/commands/theme/push.js +89 -0
  44. package/dist/create-app-command.d.ts +20 -0
  45. package/dist/create-app-command.js +253 -0
  46. package/dist/create-collection-command.d.ts +3 -3
  47. package/dist/create-collection-command.js +4 -4
  48. package/dist/{create-command.d.ts → create-config-command.d.ts} +1 -1
  49. package/dist/{create-command.js → create-config-command.js} +3 -5
  50. package/dist/env/local.d.ts +8 -0
  51. package/dist/env/local.js +7 -0
  52. package/dist/env/production.d.ts +8 -0
  53. package/dist/env/production.js +7 -0
  54. package/dist/env/review.d.ts +8 -0
  55. package/dist/env/review.js +7 -0
  56. package/dist/env/staging.d.ts +8 -0
  57. package/dist/env/staging.js +7 -0
  58. package/dist/lib/api.d.ts +1 -0
  59. package/dist/lib/api.js +39 -13
  60. package/dist/lib/app-config.d.ts +12 -5
  61. package/dist/lib/app-config.js +57 -21
  62. package/dist/lib/apps/app-config.d.ts +17 -3
  63. package/dist/lib/apps/app-config.js +194 -66
  64. package/dist/lib/apps/index.d.ts +92 -12
  65. package/dist/lib/apps/index.js +145 -47
  66. package/dist/lib/apps/paths.d.ts +14 -7
  67. package/dist/lib/apps/paths.js +73 -28
  68. package/dist/lib/config.d.ts +9 -2
  69. package/dist/lib/config.js +49 -1
  70. package/dist/lib/constants.d.ts +5 -0
  71. package/dist/lib/constants.js +23 -4
  72. package/dist/lib/create/content.d.ts +1 -1
  73. package/dist/lib/create/index.js +5 -1
  74. package/dist/lib/info.js +2 -2
  75. package/dist/lib/stores.d.ts +5 -3
  76. package/dist/lib/stores.js +7 -5
  77. package/dist/lib/style.d.ts +2 -0
  78. package/dist/lib/style.js +2 -0
  79. package/dist/push-app-command.d.ts +73 -0
  80. package/dist/push-app-command.js +754 -0
  81. package/dist/remote-app-command.d.ts +35 -9
  82. package/dist/remote-app-command.js +417 -159
  83. package/oclif.manifest.json +817 -71
  84. package/package.json +13 -1
  85. package/dist/commands/app/_pull.d.ts +0 -8
  86. package/dist/commands/app/_pull.js +0 -45
@@ -1,43 +1,110 @@
1
+ /// <reference types="node" />
1
2
  import { AppConfig } from './app-config.js';
2
3
  /**
3
4
  * An app as defined by the Swell API. This is different than an app
4
5
  * configuration that developers define.
5
6
  */
6
7
  type App = {
8
+ categories?: Array<string>;
7
9
  client?: any;
8
10
  client_id?: string;
11
+ compatibilities?: {
12
+ [key: string]: string;
13
+ };
9
14
  configs?: AppConfig[];
10
15
  date_created?: string;
11
16
  date_updated?: string;
12
17
  description?: string;
18
+ extensions?: Array<any>;
19
+ features?: Array<string>;
20
+ frontend?: {
21
+ deployment?: null | object;
22
+ deployment_hash?: string;
23
+ deployment_id?: string;
24
+ framework?: string;
25
+ service?: string;
26
+ url?: string;
27
+ };
28
+ highlights?: Array<{
29
+ id: string;
30
+ image_src?: unknown;
31
+ title: string;
32
+ }>;
13
33
  id?: string;
14
- installed?: boolean;
34
+ installed?: {
35
+ date_created: string;
36
+ id: string;
37
+ };
38
+ kind?: string;
39
+ logo_icon?: unknown;
15
40
  name?: string;
41
+ preview_image?: unknown;
42
+ preview_mobile_image?: unknown;
16
43
  private_id?: string;
17
44
  public_id?: string;
18
45
  published?: boolean;
46
+ purchase_options?: Array<string>;
47
+ storefront?: {
48
+ [key: string]: any;
49
+ };
50
+ styles?: Array<{
51
+ color: string;
52
+ color_alt?: string;
53
+ id: string;
54
+ label: string;
55
+ preview_image?: unknown;
56
+ preview_mobile_image?: unknown;
57
+ }>;
58
+ theme?: {
59
+ [key: string]: any;
60
+ };
61
+ type?: string;
62
+ use_cases?: Array<string>;
19
63
  version?: string;
20
64
  };
65
+ declare enum SwellJsonFields {
66
+ DESCRIPTION = "description",
67
+ EXTENSIONS = "extensions",
68
+ ID = "id",
69
+ KIND = "kind",
70
+ NAME = "name",
71
+ PERMISSIONS = "permissions",
72
+ STOREFRONT = "storefront",
73
+ THEME = "theme",
74
+ TYPE = "type",
75
+ VERSION = "version"
76
+ }
21
77
  type AppVersion = {
22
78
  date_created: string;
79
+ description?: string;
23
80
  id: string;
24
81
  name: string;
25
- notes: string;
82
+ published?: boolean;
83
+ release_notes?: string;
84
+ released?: boolean;
85
+ supported?: boolean;
26
86
  version: string;
27
87
  };
28
88
  declare enum ConfigType {
29
89
  ASSET = "asset",
30
90
  CONTENT = "content",
91
+ FILE = "file",
92
+ FRONTEND = "frontend",
31
93
  FUNCTION = "function",
32
94
  MODEL = "model",
33
95
  NOTIFICATION = "notification",
34
96
  SETTING = "setting",
97
+ THEME = "theme",
35
98
  WEBHOOK = "webhook"
36
99
  }
100
+ declare const StorefrontConfigTypes: string[];
101
+ declare const ThemeConfigTypes: string[];
37
102
  type ConfigPathsType = {
38
103
  [key in ConfigType]: string;
39
104
  };
40
105
  declare const ConfigPaths: ConfigPathsType;
106
+ declare const StorefrontConfigPaths: ConfigPathsType;
107
+ declare const ThemeConfigPaths: ConfigPathsType;
41
108
  declare enum ConfigInputFields {
42
109
  FILE = "file",
43
110
  NAME = "name",
@@ -45,23 +112,36 @@ declare enum ConfigInputFields {
45
112
  VALUES = "values",
46
113
  VERSION = "version"
47
114
  }
48
- declare function hasAllowedFileExtension(file: string, configType?: ConfigType): boolean;
115
+ type FrontendProjectType = {
116
+ buildCommand: string;
117
+ configFileName: string;
118
+ deployPath: string;
119
+ devCommand: string;
120
+ installCommand: string;
121
+ name: string;
122
+ slug: string;
123
+ };
124
+ declare const FrontendProjectTypes: Array<FrontendProjectType>;
125
+ declare function getAppSlugId(app: App): string | undefined;
126
+ declare function getFrontendProjectType(appPath: string): FrontendProjectType | undefined;
49
127
  declare function getConfigTypeFromPath(path: string): ConfigType | undefined;
50
128
  declare function getConfigTypeKeyFromValue(value: string): string | undefined;
51
- declare function fileExists(filePath: string): boolean;
129
+ declare function filePathExists(filePath: string): boolean;
52
130
  declare function writeFile(file: string, data: string): Promise<void>;
131
+ declare function deleteFile(file: string): Promise<void>;
53
132
  declare function writeJsonFile(file: string, data?: any): Promise<void>;
54
- declare function appLogoIcon(appPath: string): string | undefined;
55
- declare function isAppLogoIcon(file: string): boolean;
56
- declare function appConfigFromFile(configFile: string, configType: ConfigType): AppConfig;
57
- declare function findAppConfig(app: App, file: string, configType: ConfigType): AppConfig | undefined;
133
+ declare function hashFile(filePath: string, fileContents?: Buffer): string;
134
+ declare function hashString(contents: string): string;
135
+ declare function appAssetImage(appPath: string, fileName: string): string | undefined;
136
+ declare function appConfigFromFile(filePath: string, configType: ConfigType, appPath: string): AppConfig;
137
+ declare function findAppConfig(app: App, filePath: string, configType: ConfigType): AppConfig | undefined;
58
138
  /**
59
139
  * Get files to push in batches prioritized by dependencies
60
140
  *
61
- * @param appConfigs - List of app configs
141
+ * @param configs - List of app configs
62
142
  * @returns {Array} Batches of files to push
63
143
  */
64
- declare function batchAppConfigsByType(appConfigs: AppConfig[]): Array<any>;
65
- export { App, AppVersion, ConfigInputFields, ConfigPaths, ConfigPathsType, ConfigType, appConfigFromFile, appLogoIcon, batchAppConfigsByType, fileExists, findAppConfig, getConfigTypeFromPath, getConfigTypeKeyFromValue, hasAllowedFileExtension, isAppLogoIcon, writeFile, writeJsonFile, };
144
+ declare function batchAppFilesByType(configs: AppConfig[]): Array<any>;
145
+ export { 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, };
66
146
  export { AppConfig, FunctionProcessingError, IgnoringFileError, } from './app-config.js';
67
- export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, configFilePath, getAllConfigPaths, } from './paths.js';
147
+ export { allBaseFilesInDir, allConfigDirsPaths, allConfigFilesInDir, allConfigFilesPaths, allConfigFilesPathsByType, getAllConfigPaths, globAllFilesByPath, isPathDirectory, } from './paths.js';
@@ -1,16 +1,33 @@
1
+ import { hash as blake3hash } from 'blake3-wasm';
1
2
  import { pluralize, titleize } from 'inflection';
2
3
  import * as fs from 'node:fs';
3
4
  import * as path from 'node:path';
4
- import { appConfigFileExists } from '../app-config.js';
5
+ import { toAppId } from '../create/index.js';
5
6
  import { AppConfig } from './app-config.js';
7
+ var SwellJsonFields;
8
+ (function (SwellJsonFields) {
9
+ SwellJsonFields["DESCRIPTION"] = "description";
10
+ SwellJsonFields["EXTENSIONS"] = "extensions";
11
+ SwellJsonFields["ID"] = "id";
12
+ SwellJsonFields["KIND"] = "kind";
13
+ SwellJsonFields["NAME"] = "name";
14
+ SwellJsonFields["PERMISSIONS"] = "permissions";
15
+ SwellJsonFields["STOREFRONT"] = "storefront";
16
+ SwellJsonFields["THEME"] = "theme";
17
+ SwellJsonFields["TYPE"] = "type";
18
+ SwellJsonFields["VERSION"] = "version";
19
+ })(SwellJsonFields || (SwellJsonFields = {}));
6
20
  var ConfigType;
7
21
  (function (ConfigType) {
8
22
  ConfigType["ASSET"] = "asset";
9
23
  ConfigType["CONTENT"] = "content";
24
+ ConfigType["FILE"] = "file";
25
+ ConfigType["FRONTEND"] = "frontend";
10
26
  ConfigType["FUNCTION"] = "function";
11
27
  ConfigType["MODEL"] = "model";
12
28
  ConfigType["NOTIFICATION"] = "notification";
13
29
  ConfigType["SETTING"] = "setting";
30
+ ConfigType["THEME"] = "theme";
14
31
  ConfigType["WEBHOOK"] = "webhook";
15
32
  })(ConfigType || (ConfigType = {}));
16
33
  // Models and content should come first in order
@@ -22,14 +39,44 @@ const ConfigTypeBatchOrder = [
22
39
  ConfigType.NOTIFICATION,
23
40
  ConfigType.SETTING,
24
41
  ConfigType.WEBHOOK,
42
+ ConfigType.THEME,
43
+ ConfigType.FRONTEND,
44
+ ConfigType.FILE,
25
45
  ];
26
- const ConfigPaths = {
27
- ...Object.fromEntries(Object.keys(ConfigType).map((type) => [
46
+ // Configs available for different app types
47
+ const StandardConfigTypes = [
48
+ 'MODEL',
49
+ 'CONTENT',
50
+ 'ASSET',
51
+ 'FUNCTION',
52
+ 'FRONTEND',
53
+ 'NOTIFICATION',
54
+ 'SETTING',
55
+ 'WEBHOOK',
56
+ 'THEME',
57
+ ];
58
+ const StorefrontConfigTypes = ['FRONTEND', 'ASSET', 'SETTING'];
59
+ const ThemeConfigTypes = ['THEME', 'ASSET'];
60
+ const getConfigPaths = (types) => ({
61
+ ...Object.fromEntries(Object.keys(ConfigType)
62
+ .filter((type) => !types || types.find((inType) => inType === type))
63
+ .map((type) => [
28
64
  type,
29
65
  // a bit of a hack to make the path singular for content configs
30
66
  // need to refactor this to a function if we add more exceptions
31
- type === 'CONTENT' ? 'content' : pluralize(type.toLowerCase()),
67
+ type === 'CONTENT' || type === 'FRONTEND' || type === 'THEME'
68
+ ? type.toLowerCase()
69
+ : pluralize(type.toLowerCase()),
32
70
  ])),
71
+ });
72
+ const ConfigPaths = {
73
+ ...getConfigPaths(StandardConfigTypes),
74
+ };
75
+ const StorefrontConfigPaths = {
76
+ ...getConfigPaths(StorefrontConfigTypes),
77
+ };
78
+ const ThemeConfigPaths = {
79
+ ...getConfigPaths(ThemeConfigTypes),
33
80
  };
34
81
  var ConfigInputFields;
35
82
  (function (ConfigInputFields) {
@@ -39,17 +86,39 @@ var ConfigInputFields;
39
86
  ConfigInputFields["VALUES"] = "values";
40
87
  ConfigInputFields["VERSION"] = "version";
41
88
  })(ConfigInputFields || (ConfigInputFields = {}));
42
- function hasAllowedFileExtension(file, configType) {
43
- let allowedFileExtensions = new Set([
44
- '.js',
45
- '.json',
46
- '.tpl',
47
- '.ts',
48
- ]);
49
- if (configType === ConfigType.NOTIFICATION) {
50
- allowedFileExtensions = new Set(['.json']);
89
+ const FrontendProjectTypes = [
90
+ {
91
+ buildCommand: 'npx @cloudflare/next-on-pages',
92
+ configFileName: 'next.config',
93
+ deployPath: '.vercel/output/static',
94
+ devCommand: 'npx next dev --port ${PORT}',
95
+ installCommand: 'npx create-next-app@latest frontend --typescript --use-npm --src-dir --app --eslint --import-alias "@/*" --tailwind',
96
+ name: 'Next.js',
97
+ slug: 'nextjs',
98
+ },
99
+ {
100
+ buildCommand: 'npx astro build',
101
+ configFileName: 'astro.config',
102
+ deployPath: 'dist',
103
+ devCommand: 'npx astro dev --port ${PORT}',
104
+ installCommand: 'npm create astro@latest frontend -- --install --no-git --yes --skip-houston --typescript strict',
105
+ name: 'Astro',
106
+ slug: 'astro',
107
+ },
108
+ ];
109
+ const frontendProjectConfigExtensions = ['.mjs', '.js'];
110
+ function getAppSlugId(app) {
111
+ return toAppId(app.private_id) || app.public_id || app.id;
112
+ }
113
+ function getFrontendProjectType(appPath) {
114
+ for (const projectType of FrontendProjectTypes) {
115
+ for (const extension of frontendProjectConfigExtensions) {
116
+ const configFile = path.join(appPath, 'frontend', `${projectType.configFileName}${extension}`);
117
+ if (filePathExists(configFile)) {
118
+ return projectType;
119
+ }
120
+ }
51
121
  }
52
- return allowedFileExtensions.has(path.parse(file).ext);
53
122
  }
54
123
  function getConfigTypeFromPath(path) {
55
124
  for (const type in ConfigPaths) {
@@ -63,7 +132,7 @@ function getConfigTypeFromPath(path) {
63
132
  function getConfigTypeKeyFromValue(value) {
64
133
  return Object.keys(ConfigType).find((key) => ConfigType[key] === value);
65
134
  }
66
- function fileExists(filePath) {
135
+ function filePathExists(filePath) {
67
136
  try {
68
137
  // eslint-disable-next-line no-bitwise
69
138
  fs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK);
@@ -76,13 +145,22 @@ function fileExists(filePath) {
76
145
  return false;
77
146
  }
78
147
  }
79
- function writeFile(file, data) {
148
+ async function writeFile(file, data) {
149
+ // Convert from base64 if needed
150
+ let contents;
151
+ try {
152
+ const isBase64 = Buffer.from(data, 'base64').toString('base64') === data;
153
+ contents = isBase64 ? Buffer.from(data, 'base64') : data;
154
+ }
155
+ catch {
156
+ contents = data;
157
+ }
80
158
  return new Promise((resolve, _reject) => {
81
159
  fs.mkdir(path.dirname(file), { recursive: true }, (error) => {
82
160
  if (error) {
83
161
  throw error;
84
162
  }
85
- fs.writeFile(file, data, (error) => {
163
+ fs.writeFile(file, contents || '', (error) => {
86
164
  if (error) {
87
165
  throw error;
88
166
  }
@@ -91,49 +169,71 @@ function writeFile(file, data) {
91
169
  });
92
170
  });
93
171
  }
172
+ function deleteFile(file) {
173
+ return new Promise((resolve, _reject) => {
174
+ fs.unlink(file, (error) => {
175
+ if (error) {
176
+ throw error;
177
+ }
178
+ resolve();
179
+ });
180
+ });
181
+ }
94
182
  async function writeJsonFile(file, data = {}) {
95
183
  return writeFile(file, `${JSON.stringify(data, null, 2)}\n`);
96
184
  }
97
- function appLogoIcon(appPath) {
185
+ // Hash method adapted from wrangler-sdk
186
+ function hashFile(filePath, fileContents) {
187
+ const contents = fileContents ?? fs.readFileSync(filePath);
188
+ const base64Contents = contents.toString('base64');
189
+ const extension = path.extname(filePath).slice(1);
190
+ return hashString(base64Contents + extension);
191
+ }
192
+ function hashString(contents) {
193
+ return blake3hash(contents).toString('hex').slice(0, 32);
194
+ }
195
+ function appAssetImage(appPath, fileName) {
98
196
  const assetsDirPath = path.join(appPath, ConfigPaths['ASSET']);
99
- if (!appConfigFileExists(assetsDirPath)) {
197
+ if (!filePathExists(assetsDirPath)) {
100
198
  return;
101
199
  }
102
200
  for (const configFile of fs.readdirSync(assetsDirPath)) {
103
- if (isAppLogoIcon(configFile)) {
201
+ if (path.parse(configFile).name === fileName) {
104
202
  return path.join(assetsDirPath, configFile);
105
203
  }
106
204
  }
107
205
  }
108
- function isAppLogoIcon(file) {
109
- return path.parse(file).name === 'icon';
110
- }
111
- function appConfigFromFile(configFile, configType) {
112
- const { name } = path.parse(configFile);
113
- const appConfig = AppConfig.create({
114
- localPath: configFile,
206
+ function appConfigFromFile(filePath, configType, appPath) {
207
+ const { name } = path.parse(filePath);
208
+ const config = AppConfig.create({
209
+ appPath,
210
+ file_path: filePath,
211
+ filePath,
115
212
  name,
116
- type: configType,
117
- values: {},
213
+ type: configType || 'file',
118
214
  });
119
- return appConfig;
215
+ // Do not allow files larger than 10MB
216
+ if (config.mbSize && config.mbSize > 10) {
217
+ throw new Error(`App file size too large: ${config.filePath} (${config.mbSize} MB)`);
218
+ }
219
+ return config;
120
220
  }
121
- function findAppConfig(app, file, configType) {
122
- const { name } = path.parse(file);
221
+ function findAppConfig(app, filePath, configType) {
222
+ const { name } = path.parse(filePath);
123
223
  const config = app?.configs?.find((c) => c && c.type === configType && c.name === name);
124
224
  return config;
125
225
  }
126
226
  /**
127
227
  * Get files to push in batches prioritized by dependencies
128
228
  *
129
- * @param appConfigs - List of app configs
229
+ * @param configs - List of app configs
130
230
  * @returns {Array} Batches of files to push
131
231
  */
132
- function batchAppConfigsByType(appConfigs) {
133
- const modelsWithExtends = appConfigs.filter((item) => item.type === 'model' && item.values.extends);
134
- const modelsWithoutExtends = appConfigs.filter((item) => item.type === 'model' && !item.values.extends);
135
- const contentTypesWithCollection = appConfigs.filter((item) => item.type === 'content' && item.values.collection);
136
- const contentTypesWithoutCollection = appConfigs.filter((item) => item.type === 'content' && !item.values.collection);
232
+ function batchAppFilesByType(configs) {
233
+ const modelsWithExtends = configs.filter((config) => config.type === 'model' && config.values.extends);
234
+ const modelsWithoutExtends = configs.filter((config) => config.type === 'model' && !config.values.extends);
235
+ const contentTypesWithCollection = configs.filter((config) => config.type === 'content' && config.values.collection);
236
+ const contentTypesWithoutCollection = configs.filter((config) => config.type === 'content' && !config.values.collection);
137
237
  const prioritized = [
138
238
  ...modelsWithExtends,
139
239
  ...modelsWithoutExtends,
@@ -142,26 +242,24 @@ function batchAppConfigsByType(appConfigs) {
142
242
  ];
143
243
  const sorted = [
144
244
  ...prioritized,
145
- ...appConfigs.filter((item) => !prioritized.includes(item)),
245
+ ...configs.filter((config) => !prioritized.includes(config)),
146
246
  ];
147
247
  const batches = [];
148
248
  // eslint-disable-next-line guard-for-in
149
249
  for (const key in ConfigTypeBatchOrder) {
150
250
  const configType = ConfigTypeBatchOrder[key];
151
- const configsByType = sorted.filter((item) => item.type === configType);
152
- if (configsByType.length === 0) {
153
- continue;
154
- }
251
+ const configsByType = sorted.filter((config) => config.type === configType);
155
252
  batches.push({
156
253
  configs: configsByType,
157
- label: titleize(configType),
254
+ label: configType === ConfigType.FILE ? 'App files' : titleize(configType),
158
255
  type: configType,
159
256
  });
160
257
  }
258
+ // Add base files if config types are not specified
161
259
  return batches;
162
260
  }
163
- export { ConfigInputFields, ConfigPaths, ConfigType,
261
+ export { ConfigInputFields, ConfigPaths, ConfigType, FrontendProjectTypes, StorefrontConfigPaths, StorefrontConfigTypes, SwellJsonFields, ThemeConfigPaths, ThemeConfigTypes, appAssetImage, appConfigFromFile, batchAppFilesByType, deleteFile, filePathExists, findAppConfig,
164
262
  // functions
165
- appConfigFromFile, appLogoIcon, batchAppConfigsByType, fileExists, findAppConfig, getConfigTypeFromPath, getConfigTypeKeyFromValue, hasAllowedFileExtension, isAppLogoIcon, writeFile, writeJsonFile, };
263
+ getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, hashFile, hashString, writeFile, writeJsonFile, };
166
264
  export { AppConfig, FunctionProcessingError, IgnoringFileError, } from './app-config.js';
167
- export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, configFilePath, getAllConfigPaths, } from './paths.js';
265
+ export { allBaseFilesInDir, allConfigDirsPaths, allConfigFilesInDir, allConfigFilesPaths, allConfigFilesPathsByType, getAllConfigPaths, globAllFilesByPath, isPathDirectory, } from './paths.js';
@@ -1,18 +1,25 @@
1
- import { AppConfig, ConfigType } from './index.js';
1
+ import { ConfigType } from './index.js';
2
+ declare function globAllFilesByPath(appPath: string, dirPath?: string): string[];
2
3
  declare function allConfigDirsPaths(appPath: string): Generator<{
3
- configDirPath: string;
4
+ configDir: string;
4
5
  configType: ConfigType;
5
6
  }>;
6
7
  declare function allConfigFilesPaths(appPath: string): Generator<{
7
- configDirPath: string;
8
+ configDir: string;
8
9
  configFile: string;
9
10
  configType: ConfigType;
10
11
  }, void, unknown>;
11
12
  declare function allConfigFilesPathsByType(appPath: string, configTypeKey: string): Generator<{
12
- configDirPath: string;
13
+ configDir: string;
13
14
  configFile: string;
14
15
  configType: ConfigType;
15
16
  }, void, unknown>;
16
- declare function configFilePath(appPath: string, config: AppConfig): string;
17
- declare function getAllConfigPaths(): Array<string>;
18
- export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, configFilePath, getAllConfigPaths, };
17
+ declare function allConfigFilesInDir(appPath: string, dirPath: string, configType: ConfigType): Generator<{
18
+ configDir: string;
19
+ configFile: string;
20
+ configType: ConfigType;
21
+ }, void, unknown>;
22
+ declare function allBaseFilesInDir(appPath: string): Generator<string, void, unknown>;
23
+ declare function getAllConfigPaths(appType: string): Array<string>;
24
+ declare function isPathDirectory(path: string): boolean;
25
+ export { allBaseFilesInDir, allConfigDirsPaths, allConfigFilesInDir, allConfigFilesPaths, allConfigFilesPathsByType, getAllConfigPaths, globAllFilesByPath, isPathDirectory, };
@@ -1,49 +1,84 @@
1
+ import { globbySync } from 'globby';
1
2
  import * as fs from 'node:fs';
2
3
  import * as path from 'node:path';
3
- import { appConfigFileExists } from '../app-config.js';
4
- import { ConfigPaths, ConfigType, hasAllowedFileExtension, } from './index.js';
5
- function* allConfigDirsPaths(appPath) {
4
+ import { ConfigPaths, ConfigType, StorefrontConfigPaths, ThemeConfigPaths, filePathExists, } from './index.js';
5
+ function globFiles(pattern, appPath, dirPath = '.', options = {}) {
6
+ const filePaths = globbySync(`${dirPath}${path.sep}${pattern}`, {
7
+ cwd: appPath,
8
+ dot: true,
9
+ gitignore: true,
10
+ ...options,
11
+ expandDirectories: true,
12
+ // Explicitly ignore node_modules and lock files just in case
13
+ ignore: [
14
+ '**/.swellrc',
15
+ '**/.git/**',
16
+ '**/node_modules/**',
17
+ '**/package-lock.json',
18
+ '**/yarn.lock',
19
+ ...(options?.ignore || []),
20
+ ],
21
+ });
22
+ return filePaths;
23
+ }
24
+ function globAllFilesByPath(appPath, dirPath) {
25
+ return globFiles('**', appPath, dirPath);
26
+ }
27
+ function getConfirDirsPaths(appPath) {
28
+ const configDirsPaths = [];
6
29
  for (const type in ConfigType) {
7
30
  if (Object.prototype.hasOwnProperty.call(ConfigType, type)) {
8
31
  const configType = ConfigType[type];
9
32
  const configPath = ConfigPaths[type];
10
- const configDirPath = path.join(appPath, configPath);
11
- if (appConfigFileExists(configDirPath)) {
12
- yield { configDirPath, configType };
33
+ if (!configPath) {
34
+ continue;
35
+ }
36
+ const configDir = path.join(appPath, configPath);
37
+ if (filePathExists(configDir)) {
38
+ configDirsPaths.push({ configDir: configPath, configType });
13
39
  }
14
40
  }
15
41
  }
42
+ return configDirsPaths;
43
+ }
44
+ function* allConfigDirsPaths(appPath) {
45
+ for (const { configDir, configType } of getConfirDirsPaths(appPath)) {
46
+ yield { configDir, configType };
47
+ }
16
48
  }
17
49
  function* allConfigFilesPaths(appPath) {
18
- for (const { configDirPath, configType } of allConfigDirsPaths(appPath)) {
19
- yield* allConfigFilesInDir(configDirPath, configType);
50
+ for (const { configDir, configType } of allConfigDirsPaths(appPath)) {
51
+ yield* allConfigFilesInDir(appPath, configDir, configType);
20
52
  }
21
53
  }
22
54
  function* allConfigFilesPathsByType(appPath, configTypeKey) {
23
55
  const configPath = ConfigPaths[configTypeKey];
24
- const configDirPath = path.join(appPath, configPath);
25
- yield* allConfigFilesInDir(configDirPath, ConfigType[configTypeKey]);
26
- }
27
- function* allConfigFilesInDir(configDirPath, configType) {
28
- for (const file of fs.readdirSync(configDirPath)) {
29
- const configFile = path.join(configDirPath, file);
30
- // ignore sub-directories, e.g. functions/lib
31
- // ignore files that don't have the allowed extensions
32
- if (fs.lstatSync(configFile).isDirectory() ||
33
- !hasAllowedFileExtension(configFile, configType)) {
34
- continue;
35
- }
36
- yield { configDirPath, configFile, configType };
56
+ yield* allConfigFilesInDir(appPath, configPath, ConfigType[configTypeKey]);
57
+ }
58
+ function* allConfigFilesInDir(appPath, dirPath, configType) {
59
+ const filePaths = globFiles('**', appPath, dirPath);
60
+ for (const configFile of filePaths) {
61
+ yield { configDir: dirPath, configFile, configType };
37
62
  }
38
63
  }
39
- function configFilePath(appPath, config) {
40
- const configPath = ConfigPaths[config.type.toLocaleUpperCase()];
41
- const fileExt = config.file?.ext || '.json';
42
- return path.join(appPath, configPath, [config.name, fileExt].join(''));
64
+ function* allBaseFilesInDir(appPath) {
65
+ // Only get base files excluding config directories
66
+ const configPaths = getConfirDirsPaths(appPath);
67
+ const baseFiles = globFiles('**', appPath, '.', {
68
+ ignore: configPaths.map((config) => `${config.configDir}/**`),
69
+ });
70
+ for (const path of baseFiles) {
71
+ yield path;
72
+ }
43
73
  }
44
- function getAllConfigPaths() {
74
+ function getAllConfigPaths(appType) {
45
75
  const configPaths = [];
46
- for (const type in ConfigPaths) {
76
+ const ConfigPathsByType = appType === 'storefront'
77
+ ? StorefrontConfigPaths
78
+ : appType === 'theme'
79
+ ? ThemeConfigPaths
80
+ : ConfigPaths;
81
+ for (const type in ConfigPathsByType) {
47
82
  if (Object.prototype.hasOwnProperty.call(ConfigPaths, type)) {
48
83
  const configPath = ConfigPaths[type];
49
84
  configPaths.push(configPath);
@@ -51,4 +86,14 @@ function getAllConfigPaths() {
51
86
  }
52
87
  return configPaths;
53
88
  }
54
- export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, configFilePath, getAllConfigPaths, };
89
+ function isPathDirectory(path) {
90
+ try {
91
+ const stat = fs.statSync(path);
92
+ return stat.isDirectory();
93
+ }
94
+ catch {
95
+ // Handle error (e.g., file not found)
96
+ return false;
97
+ }
98
+ }
99
+ export { allBaseFilesInDir, allConfigDirsPaths, allConfigFilesInDir, allConfigFilesPaths, allConfigFilesPathsByType, getAllConfigPaths, globAllFilesByPath, isPathDirectory, };
@@ -1,9 +1,14 @@
1
1
  declare const env: any;
2
+ declare function setEnv(name: string, reviewBranch?: string): {
3
+ [key: string]: string;
4
+ };
2
5
  declare function ensureLoggedIn(storeId: string): Promise<any>;
3
6
  declare function get(key: string): any;
4
7
  declare function getAll(): any;
5
- declare function getDefaultStore(): any;
8
+ declare function getDefaultStore(): string;
6
9
  declare function setDefaultStore(storeId: string): void;
10
+ declare function getDefaultStorefront(appPath: string): string;
11
+ declare function setDefaultStorefront(appPath: string, storefrontId: string): void;
7
12
  declare function getSessionId(storeId: string): any;
8
13
  /**
9
14
  * Set store data for later access.
@@ -28,10 +33,12 @@ declare const config: {
28
33
  get: typeof get;
29
34
  getAll: typeof getAll;
30
35
  getDefaultStore: typeof getDefaultStore;
36
+ getDefaultStorefront: typeof getDefaultStorefront;
31
37
  getSessionId: typeof getSessionId;
32
38
  getUser: typeof getUser;
33
39
  setDefaultStore: typeof setDefaultStore;
40
+ setDefaultStorefront: typeof setDefaultStorefront;
34
41
  setStore: typeof setStore;
35
42
  setUser: typeof setUser;
36
43
  };
37
- export { config as default, env };
44
+ export { config as default, env, setEnv };