@swell/cli 1.0.2 → 2.0.1-alpha.10
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/LICENSE.md +21 -0
- package/README.md +2 -140
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +7 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +7 -0
- package/dist/app-command.d.ts +22 -0
- package/dist/app-command.js +45 -0
- package/dist/commands/app/_pull.d.ts +8 -0
- package/dist/commands/app/_pull.js +45 -0
- package/dist/commands/app/_uninstall.d.ts +12 -0
- package/dist/commands/app/_uninstall.js +45 -0
- package/dist/commands/app/info.d.ts +15 -0
- package/dist/commands/app/info.js +92 -0
- package/dist/commands/app/install.d.ts +17 -0
- package/dist/commands/app/install.js +179 -0
- package/dist/commands/app/push.d.ts +20 -0
- package/dist/commands/app/push.js +170 -0
- package/dist/commands/app/version.d.ts +18 -0
- package/dist/commands/app/version.js +156 -0
- package/dist/commands/app/watch.d.ts +15 -0
- package/dist/commands/app/watch.js +110 -0
- package/dist/commands/create/app.d.ts +21 -0
- package/dist/commands/create/app.js +210 -0
- package/dist/commands/create/content.d.ts +19 -0
- package/dist/commands/create/content.js +87 -0
- package/dist/commands/create/function.d.ts +25 -0
- package/dist/commands/create/function.js +191 -0
- package/dist/commands/create/index.d.ts +6 -0
- package/dist/commands/create/index.js +34 -0
- package/dist/commands/create/model.d.ts +19 -0
- package/dist/commands/create/model.js +87 -0
- package/dist/commands/create/notification.d.ts +25 -0
- package/dist/commands/create/notification.js +170 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +77 -0
- package/dist/commands/logout.d.ts +8 -0
- package/dist/commands/logout.js +45 -0
- package/dist/commands/logs.d.ts +24 -0
- package/dist/commands/logs.js +212 -0
- package/dist/commands/switch.d.ts +10 -0
- package/dist/commands/switch.js +41 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.js +24 -0
- package/dist/create-collection-command.d.ts +26 -0
- package/dist/create-collection-command.js +97 -0
- package/dist/create-command.d.ts +16 -0
- package/dist/create-command.js +59 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/api.d.ts +13 -0
- package/dist/lib/api.js +126 -0
- package/dist/lib/app-config.d.ts +29 -0
- package/dist/lib/app-config.js +127 -0
- package/dist/lib/apps/app-config.d.ts +42 -0
- package/dist/lib/apps/app-config.js +170 -0
- package/dist/lib/apps/index.d.ts +67 -0
- package/dist/lib/apps/index.js +167 -0
- package/dist/lib/apps/paths.d.ts +18 -0
- package/dist/lib/apps/paths.js +54 -0
- package/dist/lib/bundle.d.ts +1 -0
- package/dist/lib/bundle.js +43 -0
- package/dist/lib/config.d.ts +37 -0
- package/dist/lib/config.js +131 -0
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +17 -0
- package/dist/lib/create/content.d.ts +23 -0
- package/dist/lib/create/content.js +40 -0
- package/dist/lib/create/function.d.ts +17 -0
- package/dist/lib/create/function.js +36 -0
- package/dist/lib/create/index.d.ts +13 -0
- package/dist/lib/create/index.js +22 -0
- package/dist/lib/create/model.d.ts +22 -0
- package/dist/lib/create/model.js +30 -0
- package/dist/lib/create/notification.d.ts +25 -0
- package/dist/lib/create/notification.js +1 -0
- package/dist/lib/info.d.ts +38 -0
- package/dist/lib/info.js +91 -0
- package/dist/lib/logs/index.d.ts +23 -0
- package/dist/lib/logs/index.js +88 -0
- package/dist/lib/logs/line-output.d.ts +5 -0
- package/dist/lib/logs/line-output.js +13 -0
- package/dist/lib/logs/output.d.ts +7 -0
- package/dist/lib/logs/output.js +8 -0
- package/dist/lib/logs/table-output.d.ts +11 -0
- package/dist/lib/logs/table-output.js +128 -0
- package/dist/lib/sessions.d.ts +9 -0
- package/dist/lib/sessions.js +110 -0
- package/dist/lib/stores.d.ts +63 -0
- package/dist/lib/stores.js +173 -0
- package/dist/lib/style.d.ts +24 -0
- package/dist/lib/style.js +29 -0
- package/dist/lib/swell-function-wrapper.d.ts +88 -0
- package/dist/lib/swell-function-wrapper.js +302 -0
- package/dist/remote-app-command.d.ts +36 -0
- package/dist/remote-app-command.js +388 -0
- package/dist/swell-command.d.ts +21 -0
- package/dist/swell-command.js +43 -0
- package/oclif.manifest.json +1090 -0
- package/package.json +81 -43
- package/LICENSE +0 -674
- package/dist/bin/multipart-parser-85ef9626.js +0 -456
- package/dist/bin/swell-0f71f07d.js +0 -30670
- package/dist/bin/swell.js +0 -24
- package/dist/man/swell.1 +0 -85
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const origialConsoleLog = console.log;
|
|
3
|
+
addEventListener('fetch', (event) => {
|
|
4
|
+
event.respondWith(handleRequest(event.request, event.env, event));
|
|
5
|
+
});
|
|
6
|
+
async function handleRequest(originalRequest, _env, context) {
|
|
7
|
+
const req = new SwellRequest(originalRequest, context);
|
|
8
|
+
await req.initialize();
|
|
9
|
+
let response;
|
|
10
|
+
try {
|
|
11
|
+
response = await executeModuleHandler(req, context);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
// Log the error for Swell
|
|
15
|
+
console.error(err.stack);
|
|
16
|
+
response = new SwellResponse({ error: err.message }, { status: err.status || 500 });
|
|
17
|
+
}
|
|
18
|
+
// Create a response by default if one is not returned
|
|
19
|
+
if (!(response instanceof Response)) {
|
|
20
|
+
response = new SwellResponse(response);
|
|
21
|
+
}
|
|
22
|
+
// Send logs back to Swell
|
|
23
|
+
context.waitUntil(req.ingestLogs(response));
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Invokes one of the function types that are available.
|
|
28
|
+
*
|
|
29
|
+
* Type-1: Named export function handlers
|
|
30
|
+
* ```
|
|
31
|
+
* export function post (req) {
|
|
32
|
+
*
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* Important note:
|
|
37
|
+
* - `delete` func cannot be implemented in Type-1 since it's a reserved name. So, consider using Type-3.
|
|
38
|
+
*
|
|
39
|
+
* Type-2: Default export function handlers
|
|
40
|
+
* ```
|
|
41
|
+
* export default function (req) {
|
|
42
|
+
*
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Type-3: Default object with named function handlers
|
|
47
|
+
* ```
|
|
48
|
+
* export default {
|
|
49
|
+
* delete(req) {
|
|
50
|
+
*
|
|
51
|
+
* },
|
|
52
|
+
* post(req) {
|
|
53
|
+
*
|
|
54
|
+
* },
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @param {SwellRequest} req
|
|
59
|
+
* @param {Event} context
|
|
60
|
+
*/
|
|
61
|
+
async function executeModuleHandler(req, context) {
|
|
62
|
+
const method = req.method.toLowerCase();
|
|
63
|
+
const defaults = moduleExports.default;
|
|
64
|
+
if (moduleExports[method]) {
|
|
65
|
+
return moduleExports[method](req, context);
|
|
66
|
+
}
|
|
67
|
+
else if (defaults) {
|
|
68
|
+
if (typeof defaults === 'function') {
|
|
69
|
+
return defaults(req, context);
|
|
70
|
+
}
|
|
71
|
+
else if (defaults[method]) {
|
|
72
|
+
return defaults[method](req, context);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Function does not export a method to handle ${method.toUpperCase()} requests`);
|
|
76
|
+
}
|
|
77
|
+
class SwellRequest {
|
|
78
|
+
constructor(req, context) {
|
|
79
|
+
this.originalRequest = req;
|
|
80
|
+
this.assignRequestProps(req);
|
|
81
|
+
// Set environment specific variables
|
|
82
|
+
this.context = context;
|
|
83
|
+
this.appId = req.headers.get('Swell-App-Id');
|
|
84
|
+
this.storeId = req.headers.get('Swell-Store-Id');
|
|
85
|
+
this.accessToken = req.headers.get('Swell-Access-Token');
|
|
86
|
+
this.publicKey = req.headers.get('Swell-Public-Key');
|
|
87
|
+
this.store = this.parseJson(req.headers.get('Swell-Store-Details'));
|
|
88
|
+
this.session = this.parseJson(req.headers.get('Swell-Session'));
|
|
89
|
+
this.logParams = this.parseJson(req.headers.get('Swell-Request-Log'));
|
|
90
|
+
this.apiHost = req.headers.get('Swell-API-Host') || 'https://api.schema.io';
|
|
91
|
+
this.id = req.headers.get('Swell-Request-ID') || this.logParams?.req_id;
|
|
92
|
+
// Swell client
|
|
93
|
+
this.swell = new SwellAPI(this, context);
|
|
94
|
+
// URL of the original request
|
|
95
|
+
this.url;
|
|
96
|
+
// Original body of the request, JSON if applicable
|
|
97
|
+
this.body = {};
|
|
98
|
+
// URL query parameters as an object
|
|
99
|
+
this.query = {};
|
|
100
|
+
// Combined object of body and query parameters
|
|
101
|
+
this.data = {};
|
|
102
|
+
// Internal logs
|
|
103
|
+
this._logs = [];
|
|
104
|
+
}
|
|
105
|
+
assignRequestProps(req) {
|
|
106
|
+
['ur', 'method', 'headers', 'referrer', 'credentials'].forEach((prop) => {
|
|
107
|
+
this[prop] = req[prop];
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async initialize() {
|
|
111
|
+
this.body = await this.originalRequest.text();
|
|
112
|
+
try {
|
|
113
|
+
this.data = JSON.parse(this.body);
|
|
114
|
+
this.body = { ...this.data };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
this.data = {};
|
|
118
|
+
}
|
|
119
|
+
this.url = new URL(this.originalRequest.url);
|
|
120
|
+
// Convert the query parameters to an object
|
|
121
|
+
this.url.searchParams.forEach((value, key) => {
|
|
122
|
+
this.query[key] = value;
|
|
123
|
+
this.data[key] = value;
|
|
124
|
+
});
|
|
125
|
+
// Bind the console methods to the request
|
|
126
|
+
console.log = this.log.bind(this, 'info');
|
|
127
|
+
console.info = this.log.bind(this, 'info');
|
|
128
|
+
console.debug = this.log.bind(this, 'debug');
|
|
129
|
+
console.warn = this.log.bind(this, 'warn');
|
|
130
|
+
console.error = this.log.bind(this, 'error');
|
|
131
|
+
}
|
|
132
|
+
parseJson(input) {
|
|
133
|
+
try {
|
|
134
|
+
return JSON.parse(input);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return {};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
log(level, ...line) {
|
|
141
|
+
origialConsoleLog(...line);
|
|
142
|
+
this._logs.push({
|
|
143
|
+
date: Date.now(),
|
|
144
|
+
line: line.map((l) => JSON.stringify(l)),
|
|
145
|
+
...(level !== 'info' ? { level } : {}),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async ingestLogs(response) {
|
|
149
|
+
if (!this.logParams) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (this.logParams.$start) {
|
|
153
|
+
this.logParams.time = Date.now() - this.logParams.$start;
|
|
154
|
+
delete this.logParams.$start;
|
|
155
|
+
}
|
|
156
|
+
const result = await this.swell.post('/:logs', {
|
|
157
|
+
$ingest_function_logs: {
|
|
158
|
+
params: {
|
|
159
|
+
...this.logParams,
|
|
160
|
+
message: {
|
|
161
|
+
...this.logParams?.message,
|
|
162
|
+
logs: this._logs,
|
|
163
|
+
status: response.status,
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
if (!result?.success) {
|
|
169
|
+
console.error('Error ingesting logs', result);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
class SwellAPI {
|
|
174
|
+
constructor(req, context) {
|
|
175
|
+
this.request = req;
|
|
176
|
+
this.baseUrl = req.apiHost;
|
|
177
|
+
this.basicAuth = `${req.storeId}:${req.accessToken}`;
|
|
178
|
+
this.context = context;
|
|
179
|
+
}
|
|
180
|
+
toBase64(inputString) {
|
|
181
|
+
const utf8Bytes = new TextEncoder().encode(inputString);
|
|
182
|
+
let base64String = '';
|
|
183
|
+
for (let i = 0; i < utf8Bytes.length; i += 3) {
|
|
184
|
+
const chunk = utf8Bytes.slice(i, i + 3);
|
|
185
|
+
base64String += btoa(String.fromCharCode(...chunk));
|
|
186
|
+
}
|
|
187
|
+
return base64String;
|
|
188
|
+
}
|
|
189
|
+
stringifyQuery(queryObject, prefix) {
|
|
190
|
+
const result = [];
|
|
191
|
+
for (const [key, value] of Object.entries(queryObject)) {
|
|
192
|
+
const prefixKey = prefix ? `${prefix}[${key}]` : key;
|
|
193
|
+
const isObject = value !== null && typeof value === 'object';
|
|
194
|
+
const encodedResult = isObject
|
|
195
|
+
? this.stringifyQuery(value, prefixKey)
|
|
196
|
+
: `${encodeURIComponent(prefixKey)}=${encodeURIComponent(value)}`;
|
|
197
|
+
result.push(encodedResult);
|
|
198
|
+
}
|
|
199
|
+
return result.join('&');
|
|
200
|
+
}
|
|
201
|
+
async makeRequest(method, url, data) {
|
|
202
|
+
const requestOptions = {
|
|
203
|
+
method,
|
|
204
|
+
headers: {
|
|
205
|
+
Authorization: `Basic ${this.toBase64(this.basicAuth)}`,
|
|
206
|
+
'User-Agent': 'swell-functions/1.0',
|
|
207
|
+
'Content-Type': 'application/json',
|
|
208
|
+
...(this.request.id ? { 'Swell-Request-ID': this.request.id } : {}),
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
let query = '';
|
|
212
|
+
if (data) {
|
|
213
|
+
try {
|
|
214
|
+
if (method === 'GET') {
|
|
215
|
+
query = `?${this.stringifyQuery(data)}`;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
requestOptions.body = JSON.stringify(data);
|
|
219
|
+
requestOptions.headers['Content-Length'] = requestOptions.body.length;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
throw new Error(`Error serializing data: ${data}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const endpointUrl = String(url).startsWith('/') ? url.substring(1) : url;
|
|
227
|
+
const response = await fetch(`${this.baseUrl}/${endpointUrl}${query}`, requestOptions);
|
|
228
|
+
const responseText = await response.text();
|
|
229
|
+
let result;
|
|
230
|
+
try {
|
|
231
|
+
result = JSON.parse(responseText);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
result = String(responseText || '').trim();
|
|
235
|
+
}
|
|
236
|
+
if (response.status > 299) {
|
|
237
|
+
throw new SwellError(result, {
|
|
238
|
+
status: response.status,
|
|
239
|
+
method,
|
|
240
|
+
endpointUrl,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
else if (method !== 'GET' && result?.errors) {
|
|
244
|
+
throw new SwellError(result.errors, { status: 400, method, endpointUrl });
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
async get(url, query) {
|
|
249
|
+
return this.makeRequest('GET', url, query);
|
|
250
|
+
}
|
|
251
|
+
async put(url, data) {
|
|
252
|
+
return this.makeRequest('PUT', url, data);
|
|
253
|
+
}
|
|
254
|
+
async post(url, data) {
|
|
255
|
+
return this.makeRequest('POST', url, data);
|
|
256
|
+
}
|
|
257
|
+
async delete(url, data) {
|
|
258
|
+
return this.makeRequest('DELETE', url, data);
|
|
259
|
+
}
|
|
260
|
+
async settings(id = this.request.appId) {
|
|
261
|
+
return this.makeRequest('GET', `/settings/${id}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
class SwellError extends Error {
|
|
265
|
+
constructor(message, options = {}) {
|
|
266
|
+
let formattedMessage;
|
|
267
|
+
if (typeof message === 'string') {
|
|
268
|
+
formattedMessage = message;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
formattedMessage = JSON.stringify(message, null, 2);
|
|
272
|
+
}
|
|
273
|
+
if (options.method && options.endpointUrl) {
|
|
274
|
+
formattedMessage = `${options.method} /${options.endpointUrl}\n${formattedMessage}`;
|
|
275
|
+
}
|
|
276
|
+
super(formattedMessage);
|
|
277
|
+
this.name = 'SwellError';
|
|
278
|
+
this.status = options.status || 500;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
class SwellResponse extends Response {
|
|
282
|
+
constructor(data, options = {}) {
|
|
283
|
+
const resultHeaders = {};
|
|
284
|
+
let result;
|
|
285
|
+
if (typeof data === 'string') {
|
|
286
|
+
result = data;
|
|
287
|
+
resultHeaders['Content-Type'] = 'text/plain;charset=UTF-8';
|
|
288
|
+
}
|
|
289
|
+
else if (data !== undefined) {
|
|
290
|
+
result = JSON.stringify(data, null, 2);
|
|
291
|
+
resultHeaders['Content-Type'] = 'application/json;charset=UTF-8';
|
|
292
|
+
}
|
|
293
|
+
super(result?.toString?.('utf-8'), {
|
|
294
|
+
status: 200,
|
|
295
|
+
...options,
|
|
296
|
+
headers: {
|
|
297
|
+
...resultHeaders,
|
|
298
|
+
...(options.headers || {}),
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AppCommand } from './app-command.js';
|
|
2
|
+
import { App, AppConfig, AppVersion } from './lib/apps/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extends the AppCommand with methods that ease managing remote apps and
|
|
5
|
+
* configurations.
|
|
6
|
+
*/
|
|
7
|
+
export declare abstract class RemoteAppCommand extends AppCommand {
|
|
8
|
+
static orientation: AppCommandOrientation;
|
|
9
|
+
app: App;
|
|
10
|
+
dashboardUrl(flags?: {
|
|
11
|
+
[flag: string]: any;
|
|
12
|
+
}, storeId?: string): string;
|
|
13
|
+
protected deleteConfig(configId: string): Promise<any>;
|
|
14
|
+
protected getApp(id?: string): Promise<App>;
|
|
15
|
+
protected getAppWithConfig(id?: string, errorNotFound?: boolean): Promise<App>;
|
|
16
|
+
protected getCreateUpdateApp(updateApp?: App): Promise<App>;
|
|
17
|
+
protected handleRequestErrors(request: () => any, spinnerError?: () => void): Promise<any>;
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
protected postConfig(configJson: any): Promise<any>;
|
|
20
|
+
protected pushConfigFile(appConfig: AppConfig): Promise<any>;
|
|
21
|
+
protected removeConfig(config: AppConfig): Promise<any>;
|
|
22
|
+
protected showErrors(errors: any, spinnerError?: () => void): void;
|
|
23
|
+
protected syncAppConfigs(): Promise<{
|
|
24
|
+
installed: string[];
|
|
25
|
+
removed: string[];
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Reads the .swellrc file and sets up the remote app configuration.
|
|
29
|
+
*
|
|
30
|
+
* @returns App
|
|
31
|
+
*/
|
|
32
|
+
private initApp;
|
|
33
|
+
private showOrientation;
|
|
34
|
+
protected getVersions(version?: string | undefined | null): Promise<AppVersion[]>;
|
|
35
|
+
protected swellRcPath(): string;
|
|
36
|
+
}
|