@swell/cli 2.0.1-alpha.16 → 2.0.1-alpha.17
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.
- package/dist/app-command.d.ts +1 -1
- package/dist/app-command.js +8 -8
- package/dist/commands/app/dev.d.ts +18 -0
- package/dist/commands/app/dev.js +31 -0
- package/dist/commands/app/frontend/deploy.d.ts +17 -0
- package/dist/commands/app/frontend/deploy.js +44 -0
- package/dist/commands/app/frontend/dev.d.ts +21 -0
- package/dist/commands/app/frontend/dev.js +111 -0
- package/dist/commands/app/info.js +15 -8
- package/dist/commands/app/init.d.ts +12 -0
- package/dist/commands/app/init.js +34 -0
- package/dist/commands/app/install.d.ts +0 -3
- package/dist/commands/app/install.js +12 -20
- package/dist/commands/app/pull.d.ts +15 -0
- package/dist/commands/app/pull.js +50 -0
- package/dist/commands/app/push.d.ts +10 -13
- package/dist/commands/app/push.js +64 -135
- package/dist/commands/app/release.d.ts +13 -0
- package/dist/commands/app/release.js +150 -0
- package/dist/commands/app/version.d.ts +7 -6
- package/dist/commands/app/version.js +61 -40
- package/dist/commands/app/watch.d.ts +2 -4
- package/dist/commands/app/watch.js +3 -83
- package/dist/commands/create/app.d.ts +35 -11
- package/dist/commands/create/app.js +141 -138
- package/dist/commands/create/frontend.d.ts +12 -0
- package/dist/commands/create/frontend.js +41 -0
- package/dist/commands/create/function.d.ts +2 -2
- package/dist/commands/create/function.js +2 -2
- package/dist/commands/create/notification.d.ts +2 -2
- package/dist/commands/create/notification.js +2 -2
- package/dist/commands/login.js +6 -4
- package/dist/commands/logs.js +0 -1
- package/dist/commands/theme/dev.d.ts +23 -0
- package/dist/commands/theme/dev.js +167 -0
- package/dist/commands/theme/init.d.ts +9 -0
- package/dist/commands/theme/init.js +15 -0
- package/dist/commands/theme/pull.d.ts +20 -0
- package/dist/commands/theme/pull.js +65 -0
- package/dist/commands/theme/push.d.ts +19 -0
- package/dist/commands/theme/push.js +92 -0
- package/dist/create-app-command.d.ts +20 -0
- package/dist/create-app-command.js +254 -0
- package/dist/create-collection-command.d.ts +3 -3
- package/dist/create-collection-command.js +4 -4
- package/dist/{create-command.d.ts → create-config-command.d.ts} +1 -1
- package/dist/{create-command.js → create-config-command.js} +3 -3
- package/dist/lib/api.d.ts +3 -2
- package/dist/lib/api.js +47 -21
- package/dist/lib/app-config.d.ts +12 -5
- package/dist/lib/app-config.js +59 -24
- package/dist/lib/apps/app-config.d.ts +22 -8
- package/dist/lib/apps/app-config.js +202 -68
- package/dist/lib/apps/index.d.ts +93 -13
- package/dist/lib/apps/index.js +150 -50
- package/dist/lib/apps/paths.d.ts +14 -7
- package/dist/lib/apps/paths.js +73 -28
- package/dist/lib/config.d.ts +5 -1
- package/dist/lib/config.js +14 -0
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +20 -0
- package/dist/lib/create/content.d.ts +1 -1
- package/dist/lib/create/index.js +5 -1
- package/dist/lib/info.js +2 -2
- package/dist/lib/stores.d.ts +1 -1
- package/dist/lib/stores.js +3 -3
- package/dist/lib/style.d.ts +2 -0
- package/dist/lib/style.js +2 -0
- package/dist/push-app-command.d.ts +73 -0
- package/dist/push-app-command.js +765 -0
- package/dist/remote-app-command.d.ts +33 -7
- package/dist/remote-app-command.js +423 -151
- package/oclif.manifest.json +794 -81
- package/package.json +13 -2
- package/dist/commands/app/_pull.d.ts +0 -8
- package/dist/commands/app/_pull.js +0 -45
package/dist/lib/apps/index.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import { pluralize, titleize } from 'inflection';
|
|
2
1
|
import * as fs from 'node:fs';
|
|
3
2
|
import * as path from 'node:path';
|
|
4
|
-
import {
|
|
3
|
+
import { pluralize, titleize } from 'inflection';
|
|
4
|
+
import { hash as blake3hash } from 'blake3-wasm';
|
|
5
5
|
import { AppConfig } from './app-config.js';
|
|
6
|
+
import { toAppId } from '../create/index.js';
|
|
7
|
+
var SwellJsonFields;
|
|
8
|
+
(function (SwellJsonFields) {
|
|
9
|
+
SwellJsonFields["ID"] = "id";
|
|
10
|
+
SwellJsonFields["NAME"] = "name";
|
|
11
|
+
SwellJsonFields["TYPE"] = "type";
|
|
12
|
+
SwellJsonFields["KIND"] = "kind";
|
|
13
|
+
SwellJsonFields["VERSION"] = "version";
|
|
14
|
+
SwellJsonFields["DESCRIPTION"] = "description";
|
|
15
|
+
SwellJsonFields["STOREFRONT"] = "storefront";
|
|
16
|
+
SwellJsonFields["THEME"] = "theme";
|
|
17
|
+
SwellJsonFields["PERMISSIONS"] = "permissions";
|
|
18
|
+
SwellJsonFields["EXTENSIONS"] = "extensions";
|
|
19
|
+
})(SwellJsonFields || (SwellJsonFields = {}));
|
|
6
20
|
var ConfigType;
|
|
7
21
|
(function (ConfigType) {
|
|
8
22
|
ConfigType["ASSET"] = "asset";
|
|
@@ -12,6 +26,9 @@ var ConfigType;
|
|
|
12
26
|
ConfigType["NOTIFICATION"] = "notification";
|
|
13
27
|
ConfigType["SETTING"] = "setting";
|
|
14
28
|
ConfigType["WEBHOOK"] = "webhook";
|
|
29
|
+
ConfigType["FRONTEND"] = "frontend";
|
|
30
|
+
ConfigType["THEME"] = "theme";
|
|
31
|
+
ConfigType["FILE"] = "file";
|
|
15
32
|
})(ConfigType || (ConfigType = {}));
|
|
16
33
|
// Models and content should come first in order
|
|
17
34
|
const ConfigTypeBatchOrder = [
|
|
@@ -22,14 +39,46 @@ 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
|
];
|
|
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
|
+
return {
|
|
62
|
+
...Object.fromEntries(Object.keys(ConfigType)
|
|
63
|
+
.filter((type) => !types || types.find((inType) => inType === type))
|
|
64
|
+
.map((type) => [
|
|
65
|
+
type,
|
|
66
|
+
// a bit of a hack to make the path singular for content configs
|
|
67
|
+
// need to refactor this to a function if we add more exceptions
|
|
68
|
+
type === 'CONTENT' || type === 'FRONTEND' || type === 'THEME'
|
|
69
|
+
? type.toLowerCase()
|
|
70
|
+
: pluralize(type.toLowerCase()),
|
|
71
|
+
])),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
26
74
|
const ConfigPaths = {
|
|
27
|
-
...
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
75
|
+
...getConfigPaths(StandardConfigTypes),
|
|
76
|
+
};
|
|
77
|
+
const StorefrontConfigPaths = {
|
|
78
|
+
...getConfigPaths(StorefrontConfigTypes),
|
|
79
|
+
};
|
|
80
|
+
const ThemeConfigPaths = {
|
|
81
|
+
...getConfigPaths(ThemeConfigTypes),
|
|
33
82
|
};
|
|
34
83
|
var ConfigInputFields;
|
|
35
84
|
(function (ConfigInputFields) {
|
|
@@ -39,17 +88,39 @@ var ConfigInputFields;
|
|
|
39
88
|
ConfigInputFields["VALUES"] = "values";
|
|
40
89
|
ConfigInputFields["VERSION"] = "version";
|
|
41
90
|
})(ConfigInputFields || (ConfigInputFields = {}));
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'.js',
|
|
45
|
-
'
|
|
46
|
-
'.
|
|
47
|
-
'.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
91
|
+
const FrontendProjectTypes = [
|
|
92
|
+
{
|
|
93
|
+
name: 'Next.js',
|
|
94
|
+
slug: 'nextjs',
|
|
95
|
+
configFileName: 'next.config',
|
|
96
|
+
deployPath: '.vercel/output/static',
|
|
97
|
+
installCommand: 'npx create-next-app@latest frontend --typescript --use-npm --src-dir --app --eslint --import-alias "@/*" --tailwind',
|
|
98
|
+
buildCommand: 'npx @cloudflare/next-on-pages',
|
|
99
|
+
devCommand: 'npx next dev --port ${PORT}',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'Astro',
|
|
103
|
+
slug: 'astro',
|
|
104
|
+
configFileName: 'astro.config',
|
|
105
|
+
deployPath: 'dist',
|
|
106
|
+
installCommand: 'npm create astro@latest frontend -- --install --no-git --yes --skip-houston --typescript strict',
|
|
107
|
+
buildCommand: 'npx astro build',
|
|
108
|
+
devCommand: 'npx astro dev --port ${PORT}',
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
const frontendProjectConfigExtensions = ['.mjs', '.js'];
|
|
112
|
+
function getAppSlugId(app) {
|
|
113
|
+
return toAppId(app.private_id) || app.public_id || app.id;
|
|
114
|
+
}
|
|
115
|
+
function getFrontendProjectType(appPath) {
|
|
116
|
+
for (const projectType of FrontendProjectTypes) {
|
|
117
|
+
for (const extension of frontendProjectConfigExtensions) {
|
|
118
|
+
const configFile = path.join(appPath, 'frontend', `${projectType.configFileName}${extension}`);
|
|
119
|
+
if (filePathExists(configFile)) {
|
|
120
|
+
return projectType;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
51
123
|
}
|
|
52
|
-
return allowedFileExtensions.has(path.parse(file).ext);
|
|
53
124
|
}
|
|
54
125
|
function getConfigTypeFromPath(path) {
|
|
55
126
|
for (const type in ConfigPaths) {
|
|
@@ -63,7 +134,7 @@ function getConfigTypeFromPath(path) {
|
|
|
63
134
|
function getConfigTypeKeyFromValue(value) {
|
|
64
135
|
return Object.keys(ConfigType).find((key) => ConfigType[key] === value);
|
|
65
136
|
}
|
|
66
|
-
function
|
|
137
|
+
function filePathExists(filePath) {
|
|
67
138
|
try {
|
|
68
139
|
// eslint-disable-next-line no-bitwise
|
|
69
140
|
fs.accessSync(filePath, fs.constants.R_OK | fs.constants.W_OK);
|
|
@@ -76,13 +147,22 @@ function fileExists(filePath) {
|
|
|
76
147
|
return false;
|
|
77
148
|
}
|
|
78
149
|
}
|
|
79
|
-
function writeFile(file, data) {
|
|
150
|
+
async function writeFile(file, data) {
|
|
151
|
+
// Convert from base64 if needed
|
|
152
|
+
let contents;
|
|
153
|
+
try {
|
|
154
|
+
const isBase64 = Buffer.from(data, 'base64').toString('base64') === data;
|
|
155
|
+
contents = isBase64 ? Buffer.from(data, 'base64') : data;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
contents = data;
|
|
159
|
+
}
|
|
80
160
|
return new Promise((resolve, _reject) => {
|
|
81
161
|
fs.mkdir(path.dirname(file), { recursive: true }, (error) => {
|
|
82
162
|
if (error) {
|
|
83
163
|
throw error;
|
|
84
164
|
}
|
|
85
|
-
fs.writeFile(file,
|
|
165
|
+
fs.writeFile(file, contents || '', (error) => {
|
|
86
166
|
if (error) {
|
|
87
167
|
throw error;
|
|
88
168
|
}
|
|
@@ -91,35 +171,57 @@ function writeFile(file, data) {
|
|
|
91
171
|
});
|
|
92
172
|
});
|
|
93
173
|
}
|
|
174
|
+
function deleteFile(file) {
|
|
175
|
+
return new Promise((resolve, _reject) => {
|
|
176
|
+
fs.unlink(file, (error) => {
|
|
177
|
+
if (error) {
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
resolve();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
94
184
|
async function writeJsonFile(file, data = {}) {
|
|
95
185
|
return writeFile(file, `${JSON.stringify(data, null, 2)}\n`);
|
|
96
186
|
}
|
|
97
|
-
|
|
187
|
+
// Hash method adapted from wrangler-sdk
|
|
188
|
+
function hashFile(filePath, fileContents) {
|
|
189
|
+
const contents = fileContents ?? fs.readFileSync(filePath);
|
|
190
|
+
const base64Contents = contents.toString('base64');
|
|
191
|
+
const extension = path.extname(filePath).substring(1);
|
|
192
|
+
return hashString(base64Contents + extension);
|
|
193
|
+
}
|
|
194
|
+
function hashString(contents) {
|
|
195
|
+
return blake3hash(contents).toString('hex').slice(0, 32);
|
|
196
|
+
}
|
|
197
|
+
function appAssetImage(appPath, fileName) {
|
|
98
198
|
const assetsDirPath = path.join(appPath, ConfigPaths['ASSET']);
|
|
99
|
-
if (!
|
|
199
|
+
if (!filePathExists(assetsDirPath)) {
|
|
100
200
|
return;
|
|
101
201
|
}
|
|
102
202
|
for (const configFile of fs.readdirSync(assetsDirPath)) {
|
|
103
|
-
if (
|
|
203
|
+
if (path.parse(configFile).name === fileName) {
|
|
104
204
|
return path.join(assetsDirPath, configFile);
|
|
105
205
|
}
|
|
106
206
|
}
|
|
107
207
|
}
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function appConfigFromFile(configFile, configType) {
|
|
112
|
-
const { name } = path.parse(configFile);
|
|
113
|
-
const appConfig = AppConfig.create({
|
|
114
|
-
localPath: configFile,
|
|
208
|
+
function appConfigFromFile(filePath, configType, appPath) {
|
|
209
|
+
const { name } = path.parse(filePath);
|
|
210
|
+
const config = AppConfig.create({
|
|
115
211
|
name,
|
|
116
|
-
|
|
117
|
-
|
|
212
|
+
filePath,
|
|
213
|
+
appPath,
|
|
214
|
+
type: configType || 'file',
|
|
215
|
+
file_path: filePath,
|
|
118
216
|
});
|
|
119
|
-
|
|
217
|
+
// Do not allow files larger than 10MB
|
|
218
|
+
if (config.mbSize && config.mbSize > 10) {
|
|
219
|
+
throw new Error(`App file size too large: ${config.filePath} (${config.mbSize} MB)`);
|
|
220
|
+
}
|
|
221
|
+
return config;
|
|
120
222
|
}
|
|
121
|
-
function findAppConfig(app,
|
|
122
|
-
const { name } = path.parse(
|
|
223
|
+
function findAppConfig(app, filePath, configType) {
|
|
224
|
+
const { name } = path.parse(filePath);
|
|
123
225
|
const config = app?.configs?.find((c) => c && c.type === configType && c.name === name);
|
|
124
226
|
return config;
|
|
125
227
|
}
|
|
@@ -129,11 +231,11 @@ function findAppConfig(app, file, configType) {
|
|
|
129
231
|
* @param appConfigs - List of app configs
|
|
130
232
|
* @returns {Array} Batches of files to push
|
|
131
233
|
*/
|
|
132
|
-
function
|
|
133
|
-
const modelsWithExtends =
|
|
134
|
-
const modelsWithoutExtends =
|
|
135
|
-
const contentTypesWithCollection =
|
|
136
|
-
const contentTypesWithoutCollection =
|
|
234
|
+
function batchAppFilesByType(configs) {
|
|
235
|
+
const modelsWithExtends = configs.filter((config) => config.type === 'model' && config.values.extends);
|
|
236
|
+
const modelsWithoutExtends = configs.filter((config) => config.type === 'model' && !config.values.extends);
|
|
237
|
+
const contentTypesWithCollection = configs.filter((config) => config.type === 'content' && config.values.collection);
|
|
238
|
+
const contentTypesWithoutCollection = configs.filter((config) => config.type === 'content' && !config.values.collection);
|
|
137
239
|
const prioritized = [
|
|
138
240
|
...modelsWithExtends,
|
|
139
241
|
...modelsWithoutExtends,
|
|
@@ -142,26 +244,24 @@ function batchAppConfigsByType(appConfigs) {
|
|
|
142
244
|
];
|
|
143
245
|
const sorted = [
|
|
144
246
|
...prioritized,
|
|
145
|
-
...
|
|
247
|
+
...configs.filter((config) => !prioritized.includes(config)),
|
|
146
248
|
];
|
|
147
249
|
const batches = [];
|
|
148
250
|
// eslint-disable-next-line guard-for-in
|
|
149
251
|
for (const key in ConfigTypeBatchOrder) {
|
|
150
252
|
const configType = ConfigTypeBatchOrder[key];
|
|
151
|
-
const configsByType = sorted.filter((
|
|
152
|
-
if (configsByType.length === 0) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
253
|
+
const configsByType = sorted.filter((config) => config.type === configType);
|
|
155
254
|
batches.push({
|
|
156
255
|
configs: configsByType,
|
|
157
|
-
label: titleize(configType),
|
|
256
|
+
label: configType === ConfigType.FILE ? 'App files' : titleize(configType),
|
|
158
257
|
type: configType,
|
|
159
258
|
});
|
|
160
259
|
}
|
|
260
|
+
// Add base files if config types are not specified
|
|
161
261
|
return batches;
|
|
162
262
|
}
|
|
163
|
-
export { ConfigInputFields, ConfigPaths, ConfigType,
|
|
263
|
+
export { SwellJsonFields, ConfigInputFields, ConfigPaths, StorefrontConfigPaths, StorefrontConfigTypes, ThemeConfigTypes, ThemeConfigPaths, ConfigType, FrontendProjectTypes,
|
|
164
264
|
// functions
|
|
165
|
-
appConfigFromFile,
|
|
265
|
+
getAppSlugId, appConfigFromFile, appAssetImage, batchAppFilesByType, filePathExists, findAppConfig, getConfigTypeFromPath, getConfigTypeKeyFromValue, writeFile, writeJsonFile, deleteFile, hashFile, hashString, getFrontendProjectType, };
|
|
166
266
|
export { AppConfig, FunctionProcessingError, IgnoringFileError, } from './app-config.js';
|
|
167
|
-
export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType,
|
|
267
|
+
export { globAllFilesByPath, allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, allConfigFilesInDir, allBaseFilesInDir, isPathDirectory, getAllConfigPaths, } from './paths.js';
|
package/dist/lib/apps/paths.d.ts
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigType } from './index.js';
|
|
2
|
+
declare function globAllFilesByPath(appPath: string, dirPath?: string): string[];
|
|
2
3
|
declare function allConfigDirsPaths(appPath: string): Generator<{
|
|
3
|
-
|
|
4
|
+
configDir: string;
|
|
4
5
|
configType: ConfigType;
|
|
5
6
|
}>;
|
|
6
7
|
declare function allConfigFilesPaths(appPath: string): Generator<{
|
|
7
|
-
|
|
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
|
-
|
|
13
|
+
configDir: string;
|
|
13
14
|
configFile: string;
|
|
14
15
|
configType: ConfigType;
|
|
15
16
|
}, void, unknown>;
|
|
16
|
-
declare function
|
|
17
|
-
|
|
18
|
-
|
|
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 { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, allConfigFilesInDir, allBaseFilesInDir, globAllFilesByPath, isPathDirectory, getAllConfigPaths, };
|
package/dist/lib/apps/paths.js
CHANGED
|
@@ -1,49 +1,84 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import { ConfigPaths, ConfigType,
|
|
5
|
-
function
|
|
3
|
+
import { globbySync } from 'globby';
|
|
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
|
+
// Explicitly ignore node_modules and lock files just in case
|
|
12
|
+
ignore: [
|
|
13
|
+
'**/.swellrc',
|
|
14
|
+
'**/.git/**',
|
|
15
|
+
'**/node_modules/**',
|
|
16
|
+
'**/package-lock.json',
|
|
17
|
+
'**/yarn.lock',
|
|
18
|
+
...(options?.ignore || []),
|
|
19
|
+
],
|
|
20
|
+
expandDirectories: true,
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 {
|
|
19
|
-
yield* allConfigFilesInDir(
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (const
|
|
29
|
-
|
|
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
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
+
function isPathDirectory(path) {
|
|
90
|
+
try {
|
|
91
|
+
const stat = fs.statSync(path);
|
|
92
|
+
return stat.isDirectory();
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// Handle error (e.g., file not found)
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export { allConfigDirsPaths, allConfigFilesPaths, allConfigFilesPathsByType, allConfigFilesInDir, allBaseFilesInDir, globAllFilesByPath, isPathDirectory, getAllConfigPaths, };
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ declare const env: any;
|
|
|
2
2
|
declare function ensureLoggedIn(storeId: string): Promise<any>;
|
|
3
3
|
declare function get(key: string): any;
|
|
4
4
|
declare function getAll(): any;
|
|
5
|
-
declare function getDefaultStore():
|
|
5
|
+
declare function getDefaultStore(): string;
|
|
6
6
|
declare function setDefaultStore(storeId: string): void;
|
|
7
|
+
declare function getDefaultStorefront(appPath: string): string;
|
|
8
|
+
declare function setDefaultStorefront(appPath: string, storefrontId: string): void;
|
|
7
9
|
declare function getSessionId(storeId: string): any;
|
|
8
10
|
/**
|
|
9
11
|
* Set store data for later access.
|
|
@@ -28,9 +30,11 @@ declare const config: {
|
|
|
28
30
|
get: typeof get;
|
|
29
31
|
getAll: typeof getAll;
|
|
30
32
|
getDefaultStore: typeof getDefaultStore;
|
|
33
|
+
getDefaultStorefront: typeof getDefaultStorefront;
|
|
31
34
|
getSessionId: typeof getSessionId;
|
|
32
35
|
getUser: typeof getUser;
|
|
33
36
|
setDefaultStore: typeof setDefaultStore;
|
|
37
|
+
setDefaultStorefront: typeof setDefaultStorefront;
|
|
34
38
|
setStore: typeof setStore;
|
|
35
39
|
setUser: typeof setUser;
|
|
36
40
|
};
|
package/dist/lib/config.js
CHANGED
|
@@ -68,6 +68,18 @@ function getDefaultStore() {
|
|
|
68
68
|
function setDefaultStore(storeId) {
|
|
69
69
|
return configStore.set('defaultStore', storeId);
|
|
70
70
|
}
|
|
71
|
+
function getDefaultStorefront(appPath) {
|
|
72
|
+
const storeId = getDefaultStore();
|
|
73
|
+
const defaultStorefronts = configStore.get('defaultStorefronts') || {};
|
|
74
|
+
return defaultStorefronts[storeId]?.[appPath];
|
|
75
|
+
}
|
|
76
|
+
function setDefaultStorefront(appPath, storefrontId) {
|
|
77
|
+
const storeId = getDefaultStore();
|
|
78
|
+
const defaultStorefronts = configStore.get('defaultStorefronts') || {};
|
|
79
|
+
defaultStorefronts[storeId] = defaultStorefronts[storeId] || {};
|
|
80
|
+
defaultStorefronts[storeId][appPath] = storefrontId;
|
|
81
|
+
return configStore.set('defaultStorefronts', defaultStorefronts);
|
|
82
|
+
}
|
|
71
83
|
function getSessionId(storeId) {
|
|
72
84
|
if (!configStore.has('stores'))
|
|
73
85
|
return;
|
|
@@ -122,9 +134,11 @@ const config = {
|
|
|
122
134
|
get,
|
|
123
135
|
getAll,
|
|
124
136
|
getDefaultStore,
|
|
137
|
+
getDefaultStorefront,
|
|
125
138
|
getSessionId,
|
|
126
139
|
getUser,
|
|
127
140
|
setDefaultStore,
|
|
141
|
+
setDefaultStorefront,
|
|
128
142
|
setStore,
|
|
129
143
|
setUser,
|
|
130
144
|
};
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export declare const API_BASE_URL: any;
|
|
2
2
|
export declare const ADMIN_API_BASE_URL: any;
|
|
3
3
|
export declare const LOGIN_HOST: any;
|
|
4
|
+
export declare const APP_PAGES_HOST: any;
|
|
5
|
+
export declare const STOREFRONT_FRONTEND_HOST: any;
|
|
4
6
|
export declare function getAdminApiBaseUrl(storeId: string): any;
|
|
5
7
|
export declare function getLoginHost(storeId?: string): any;
|
|
8
|
+
export declare function getAppFrontendHost(storeId: string, installedAppId: string): any;
|
|
9
|
+
export declare function getStorefrontFrontendHost(storefrontSlug: string, branchId?: string): any;
|
|
10
|
+
export declare function getLocalFrontendHost(storeId: string, sessionId: string): any;
|
package/dist/lib/constants.js
CHANGED
|
@@ -7,6 +7,13 @@ export const API_BASE_URL = env.get('API_BASE_URL') || 'https://api.swell.store'
|
|
|
7
7
|
export const ADMIN_API_BASE_URL = env.get('ADMIN_API_BASE_URL') || 'https://${STORE_ID}.swell.store/admin/api';
|
|
8
8
|
// url host for admin login
|
|
9
9
|
export const LOGIN_HOST = env.get('LOGIN_HOST') || 'https://${STORE_ID}.swell.store';
|
|
10
|
+
// url host for app frontend
|
|
11
|
+
export const APP_PAGES_HOST = env.get('APP_PAGES_HOST') ||
|
|
12
|
+
'https://${STORE_ID}--${APP_ID}--${ENV}.swell.store';
|
|
13
|
+
// url host for storefront app frontend
|
|
14
|
+
export const STOREFRONT_FRONTEND_HOST = env.get('STOREFRONT_FRONTEND_HOST') ||
|
|
15
|
+
env.get('STOREFRONT_PAGES_HOST') ||
|
|
16
|
+
'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.store';
|
|
10
17
|
// helpers to get constants with replacements
|
|
11
18
|
export function getAdminApiBaseUrl(storeId) {
|
|
12
19
|
return ADMIN_API_BASE_URL.replace('${STORE_ID}', storeId);
|
|
@@ -14,3 +21,16 @@ export function getAdminApiBaseUrl(storeId) {
|
|
|
14
21
|
export function getLoginHost(storeId) {
|
|
15
22
|
return LOGIN_HOST.replace('${STORE_ID}', storeId || 'login');
|
|
16
23
|
}
|
|
24
|
+
export function getAppFrontendHost(storeId, installedAppId) {
|
|
25
|
+
return APP_PAGES_HOST.replace('${STORE_ID}', storeId)
|
|
26
|
+
.replace('${APP_ID}', installedAppId)
|
|
27
|
+
.replace('${ENV}', 'app');
|
|
28
|
+
}
|
|
29
|
+
export function getStorefrontFrontendHost(storefrontSlug, branchId) {
|
|
30
|
+
return STOREFRONT_FRONTEND_HOST.replace('${STOREFRONT_SLUG}', storefrontSlug).replace('${BRANCH_PREFIX}', branchId ? `${branchId}.` : '');
|
|
31
|
+
}
|
|
32
|
+
export function getLocalFrontendHost(storeId, sessionId) {
|
|
33
|
+
return APP_PAGES_HOST.replace('${STORE_ID}', storeId)
|
|
34
|
+
.replace('${APP_ID}', sessionId)
|
|
35
|
+
.replace('${ENV}', 'local');
|
|
36
|
+
}
|
|
@@ -12,7 +12,7 @@ interface ContentViewProps {
|
|
|
12
12
|
tabs: [];
|
|
13
13
|
}
|
|
14
14
|
type ContentView = 'edit' | 'list' | 'new';
|
|
15
|
-
type ContentType = 'asset' | 'basic_html' | '
|
|
15
|
+
type ContentType = 'asset' | 'basic_html' | 'boolean' | 'category_lookup' | 'checkbox' | 'checkboxes' | 'collection' | 'color' | 'color_scheme' | 'color_scheme_group' | 'currency' | 'customer_lookup' | 'date' | 'datetime' | 'document' | 'dropdown' | 'email' | 'field_group' | 'font_family' | 'generic_lookup' | 'html' | 'icon' | 'image' | 'long_text' | 'lookup' | 'markdown' | 'number' | 'percent' | 'phone' | 'product_lookup' | 'radio' | 'rich_html' | 'rich_text' | 'select' | 'short_text' | 'slider' | 'slug' | 'tags' | 'text' | 'textarea' | 'time' | 'toggle' | 'url' | 'variant_lookup' | 'video';
|
|
16
16
|
interface ContentFieldProps {
|
|
17
17
|
id: string;
|
|
18
18
|
label: string;
|
package/dist/lib/create/index.js
CHANGED
|
@@ -2,7 +2,11 @@ import { dasherize, pluralize, titleize, underscore } from 'inflection';
|
|
|
2
2
|
// Example: 'My Thing' => 'my-thing'
|
|
3
3
|
const toFileName = (value) => dasherize(underscore(value.split('.')[0].replace(' ', '_'))).toLowerCase();
|
|
4
4
|
// Example: 'my-things' => 'My Things'
|
|
5
|
-
const toAppName = (value) =>
|
|
5
|
+
const toAppName = (value) => titleize(value)
|
|
6
|
+
.replaceAll(/[_\s-:./-]+/g, ' ')
|
|
7
|
+
.replaceAll(/([a-z])([A-Z])/g, '$1 $2')
|
|
8
|
+
.replaceAll(/([0-9])([A-Z])/gi, '$1 $2')
|
|
9
|
+
.replaceAll(/([A-Z])([0-9])/gi, '$1 $2');
|
|
6
10
|
// Example: 'My App' => 'my_app'
|
|
7
11
|
const toAppId = (value) => String(value || '')
|
|
8
12
|
.replaceAll(/[^\s\w./:-]/g, '')
|
package/dist/lib/info.js
CHANGED
|
@@ -20,7 +20,7 @@ export class FieldDefinitions {
|
|
|
20
20
|
get client() {
|
|
21
21
|
return {
|
|
22
22
|
label: 'Test store',
|
|
23
|
-
transform: (client) => `${client.name} (${style.storeId(client.id)})`,
|
|
23
|
+
transform: (client) => client && `${client.name} (${style.storeId(client.id)})`,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
get dateCreated() {
|
|
@@ -57,7 +57,7 @@ export class FieldDefinitions {
|
|
|
57
57
|
label: 'Version',
|
|
58
58
|
transform: (_version) => {
|
|
59
59
|
if (this.versions.length === 0) {
|
|
60
|
-
return 'N/A';
|
|
60
|
+
return this.app.version || 'N/A';
|
|
61
61
|
}
|
|
62
62
|
return [
|
|
63
63
|
style.appConfigValue(this.versions[0].version),
|
package/dist/lib/stores.d.ts
CHANGED
|
@@ -62,5 +62,5 @@ declare function selectEnvironmentId(message?: string): Promise<string>;
|
|
|
62
62
|
declare function modifyDefaultStore({ currentStoreId, storeId, }: {
|
|
63
63
|
currentStoreId: string;
|
|
64
64
|
storeId: string;
|
|
65
|
-
}): Promise<void>;
|
|
65
|
+
}, force?: boolean): Promise<void>;
|
|
66
66
|
export { modifyDefaultStore, selectEnvironmentId, selectLoggedInStoreId, selectStoreId, showStores, };
|
package/dist/lib/stores.js
CHANGED
|
@@ -162,14 +162,14 @@ async function selectEnvironmentId(message) {
|
|
|
162
162
|
*
|
|
163
163
|
* @returns void
|
|
164
164
|
*/
|
|
165
|
-
async function modifyDefaultStore({ currentStoreId, storeId, }) {
|
|
165
|
+
async function modifyDefaultStore({ currentStoreId, storeId, }, force = false) {
|
|
166
166
|
let modifyDefault = false;
|
|
167
|
-
if (currentStoreId && currentStoreId !== storeId) {
|
|
167
|
+
if (!force && currentStoreId && currentStoreId !== storeId) {
|
|
168
168
|
modifyDefault = await confirm({
|
|
169
169
|
message: `Do you want to make ${style.storeId(storeId)} your default store?`,
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
|
-
if (!currentStoreId || modifyDefault) {
|
|
172
|
+
if (force || !currentStoreId || modifyDefault) {
|
|
173
173
|
config.setDefaultStore(storeId);
|
|
174
174
|
}
|
|
175
175
|
}
|
package/dist/lib/style.d.ts
CHANGED
|
@@ -5,9 +5,11 @@ declare const _default: {
|
|
|
5
5
|
link: import("chalk").ChalkInstance;
|
|
6
6
|
path: import("chalk").ChalkInstance;
|
|
7
7
|
dim: import("chalk").ChalkInstance;
|
|
8
|
+
strike: import("chalk").ChalkInstance;
|
|
8
9
|
command: import("chalk").ChalkInstance;
|
|
9
10
|
storeId: import("chalk").ChalkInstance;
|
|
10
11
|
currentUser: import("chalk").ChalkInstance;
|
|
12
|
+
appName: import("chalk").ChalkInstance;
|
|
11
13
|
appEnvLive: import("chalk").ChalkInstance;
|
|
12
14
|
appEnv: import("chalk").ChalkInstance;
|
|
13
15
|
appConfigName: import("chalk").ChalkInstance;
|
package/dist/lib/style.js
CHANGED
|
@@ -7,11 +7,13 @@ export default {
|
|
|
7
7
|
link: chalk.blueBright.underline,
|
|
8
8
|
path: chalk.underline,
|
|
9
9
|
dim: chalk.dim,
|
|
10
|
+
strike: chalk.strikethrough,
|
|
10
11
|
// styles for consistent output of some elements
|
|
11
12
|
command: chalk.magenta.bold,
|
|
12
13
|
storeId: chalk.yellow,
|
|
13
14
|
currentUser: chalk.blueBright.underline,
|
|
14
15
|
// apps
|
|
16
|
+
appName: chalk.yellow,
|
|
15
17
|
appEnvLive: chalk.magenta,
|
|
16
18
|
appEnv: chalk.yellow,
|
|
17
19
|
appConfigName: chalk.yellow,
|