@swell/cli 2.0.1-alpha.13 → 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 +4 -4
- package/dist/commands/app/install.js +37 -42
- package/dist/commands/app/pull.d.ts +15 -0
- package/dist/commands/app/pull.js +50 -0
- package/dist/commands/app/push.d.ts +11 -14
- package/dist/commands/app/push.js +71 -143
- 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 +64 -43
- 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 +150 -144
- package/dist/commands/create/content.d.ts +2 -2
- package/dist/commands/create/content.js +10 -10
- package/dist/commands/create/frontend.d.ts +12 -0
- package/dist/commands/create/frontend.js +41 -0
- package/dist/commands/create/function.d.ts +3 -3
- package/dist/commands/create/function.js +22 -22
- package/dist/commands/create/model.d.ts +2 -2
- package/dist/commands/create/model.js +11 -11
- package/dist/commands/create/notification.d.ts +4 -4
- package/dist/commands/create/notification.js +38 -40
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +12 -9
- package/dist/commands/logs.js +2 -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 +9 -9
- package/dist/create-collection-command.js +23 -23
- package/dist/{create-command.d.ts → create-config-command.d.ts} +1 -1
- package/dist/{create-command.js → create-config-command.js} +9 -7
- package/dist/lib/api.d.ts +6 -4
- package/dist/lib/api.js +58 -29
- package/dist/lib/app-config.d.ts +13 -5
- package/dist/lib/app-config.js +60 -23
- 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/bundle.js +4 -5
- 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 +22 -3
- package/dist/lib/create/content.d.ts +2 -2
- package/dist/lib/create/content.js +1 -1
- package/dist/lib/create/function.d.ts +2 -2
- package/dist/lib/create/function.js +2 -2
- package/dist/lib/create/index.d.ts +1 -1
- package/dist/lib/create/index.js +11 -7
- package/dist/lib/create/model.d.ts +2 -2
- package/dist/lib/create/notification.d.ts +2 -2
- package/dist/lib/info.js +2 -2
- package/dist/lib/sessions.js +2 -2
- package/dist/lib/stores.d.ts +5 -2
- package/dist/lib/stores.js +9 -6
- package/dist/lib/style.d.ts +2 -0
- package/dist/lib/style.js +2 -0
- package/dist/lib/swell-function-wrapper.d.ts +2 -2
- package/dist/lib/swell-function-wrapper.js +2 -2
- package/dist/push-app-command.d.ts +73 -0
- package/dist/push-app-command.js +765 -0
- package/dist/remote-app-command.d.ts +35 -9
- package/dist/remote-app-command.js +436 -164
- package/oclif.manifest.json +841 -125
- package/package.json +13 -1
- 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/bundle.js
CHANGED
|
@@ -24,7 +24,7 @@ export async function bundleFunction(filePath) {
|
|
|
24
24
|
.join('\n');
|
|
25
25
|
// Remove comments with to get a unique hash in the API
|
|
26
26
|
// Because esbuild puts the file name as a comment
|
|
27
|
-
code = code.
|
|
27
|
+
code = code.replaceAll(/^\n?\/\/.*/gm, '');
|
|
28
28
|
// eslint-disable-next-line no-new-func
|
|
29
29
|
const evalFn = new Function(`${code}\nreturn { ...moduleExports }`);
|
|
30
30
|
const { config, ...moduleExports } = evalFn();
|
|
@@ -32,7 +32,6 @@ export async function bundleFunction(filePath) {
|
|
|
32
32
|
return { code, config, dependencies, moduleExports };
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
35
|
-
console.log(error);
|
|
36
35
|
throw new Error(`Unable to compile function ${filePath}: ${error.message}`);
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -44,13 +43,13 @@ function getSwellFunctionWrapper() {
|
|
|
44
43
|
async function minifyCode(code) {
|
|
45
44
|
try {
|
|
46
45
|
const result = await esbuild.transform(code, {
|
|
47
|
-
minifyWhitespace: true,
|
|
48
46
|
minifyIdentifiers: false,
|
|
49
47
|
minifySyntax: false,
|
|
48
|
+
minifyWhitespace: true,
|
|
50
49
|
});
|
|
51
50
|
return result.code;
|
|
52
51
|
}
|
|
53
|
-
catch (
|
|
54
|
-
throw new Error('Compilation error:',
|
|
52
|
+
catch (error) {
|
|
53
|
+
throw new Error('Compilation error:', error.message);
|
|
55
54
|
}
|
|
56
55
|
}
|
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
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
/* eslint-disable no-template-curly-in-string */
|
|
1
2
|
import { env } from './config.js';
|
|
2
3
|
// note: env values stored in ~/.swell/env.json
|
|
3
4
|
// url for backend api calls
|
|
4
5
|
export const API_BASE_URL = env.get('API_BASE_URL') || 'https://api.swell.store';
|
|
5
6
|
// url for admin api calls
|
|
6
|
-
export const ADMIN_API_BASE_URL =
|
|
7
|
-
// eslint-disable-next-line no-template-curly-in-string
|
|
8
|
-
env.get('ADMIN_API_BASE_URL') || 'https://${STORE_ID}.swell.store/admin/api';
|
|
7
|
+
export const ADMIN_API_BASE_URL = env.get('ADMIN_API_BASE_URL') || 'https://${STORE_ID}.swell.store/admin/api';
|
|
9
8
|
// url host for admin login
|
|
10
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';
|
|
11
17
|
// helpers to get constants with replacements
|
|
12
18
|
export function getAdminApiBaseUrl(storeId) {
|
|
13
19
|
return ADMIN_API_BASE_URL.replace('${STORE_ID}', storeId);
|
|
@@ -15,3 +21,16 @@ export function getAdminApiBaseUrl(storeId) {
|
|
|
15
21
|
export function getLoginHost(storeId) {
|
|
16
22
|
return LOGIN_HOST.replace('${STORE_ID}', storeId || 'login');
|
|
17
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
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
interface CreateContentFileBody {
|
|
2
2
|
collection: string;
|
|
3
|
-
label?: string;
|
|
4
3
|
description?: string;
|
|
5
4
|
fields?: ContentFieldProps[];
|
|
5
|
+
label?: string;
|
|
6
6
|
views?: ContentViewProps[];
|
|
7
7
|
}
|
|
8
8
|
interface ContentViewProps {
|
|
@@ -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;
|
|
@@ -7,11 +7,11 @@ interface CreateFunctionArgs {
|
|
|
7
7
|
interface WriteFunctionFileParams {
|
|
8
8
|
description: string;
|
|
9
9
|
events: string;
|
|
10
|
-
route: string;
|
|
11
10
|
functionName: string;
|
|
12
11
|
language: FunctionLanguage;
|
|
12
|
+
route: string;
|
|
13
13
|
schedule: string;
|
|
14
14
|
trigger: FunctionType;
|
|
15
15
|
}
|
|
16
|
-
declare const getFunctionTemplate: ({ description, events, route, schedule,
|
|
16
|
+
declare const getFunctionTemplate: ({ description, events, language, route, schedule, trigger, }: WriteFunctionFileParams) => string;
|
|
17
17
|
export { CreateFunctionArgs, FunctionLanguage, FunctionType, WriteFunctionFileParams, getFunctionTemplate, };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const getFunctionTemplate = ({ description, events, route, schedule,
|
|
1
|
+
const getFunctionTemplate = ({ description, events, language, route, schedule, trigger, }) => {
|
|
2
2
|
let typeAppend = ``;
|
|
3
3
|
if (trigger === 'model') {
|
|
4
4
|
const eventsList = events
|
|
5
5
|
.split(/\s*,\s*/g)
|
|
6
|
-
.filter(
|
|
6
|
+
.filter(Boolean)
|
|
7
7
|
.map((eventName) => `'${eventName}'`)
|
|
8
8
|
.join(', ');
|
|
9
9
|
typeAppend = `,
|