@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.
Files changed (105) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +2 -140
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +7 -0
  7. package/dist/app-command.d.ts +22 -0
  8. package/dist/app-command.js +45 -0
  9. package/dist/commands/app/_pull.d.ts +8 -0
  10. package/dist/commands/app/_pull.js +45 -0
  11. package/dist/commands/app/_uninstall.d.ts +12 -0
  12. package/dist/commands/app/_uninstall.js +45 -0
  13. package/dist/commands/app/info.d.ts +15 -0
  14. package/dist/commands/app/info.js +92 -0
  15. package/dist/commands/app/install.d.ts +17 -0
  16. package/dist/commands/app/install.js +179 -0
  17. package/dist/commands/app/push.d.ts +20 -0
  18. package/dist/commands/app/push.js +170 -0
  19. package/dist/commands/app/version.d.ts +18 -0
  20. package/dist/commands/app/version.js +156 -0
  21. package/dist/commands/app/watch.d.ts +15 -0
  22. package/dist/commands/app/watch.js +110 -0
  23. package/dist/commands/create/app.d.ts +21 -0
  24. package/dist/commands/create/app.js +210 -0
  25. package/dist/commands/create/content.d.ts +19 -0
  26. package/dist/commands/create/content.js +87 -0
  27. package/dist/commands/create/function.d.ts +25 -0
  28. package/dist/commands/create/function.js +191 -0
  29. package/dist/commands/create/index.d.ts +6 -0
  30. package/dist/commands/create/index.js +34 -0
  31. package/dist/commands/create/model.d.ts +19 -0
  32. package/dist/commands/create/model.js +87 -0
  33. package/dist/commands/create/notification.d.ts +25 -0
  34. package/dist/commands/create/notification.js +170 -0
  35. package/dist/commands/login.d.ts +22 -0
  36. package/dist/commands/login.js +77 -0
  37. package/dist/commands/logout.d.ts +8 -0
  38. package/dist/commands/logout.js +45 -0
  39. package/dist/commands/logs.d.ts +24 -0
  40. package/dist/commands/logs.js +212 -0
  41. package/dist/commands/switch.d.ts +10 -0
  42. package/dist/commands/switch.js +41 -0
  43. package/dist/commands/whoami.d.ts +7 -0
  44. package/dist/commands/whoami.js +24 -0
  45. package/dist/create-collection-command.d.ts +26 -0
  46. package/dist/create-collection-command.js +97 -0
  47. package/dist/create-command.d.ts +16 -0
  48. package/dist/create-command.js +59 -0
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/dist/lib/api.d.ts +13 -0
  52. package/dist/lib/api.js +126 -0
  53. package/dist/lib/app-config.d.ts +29 -0
  54. package/dist/lib/app-config.js +127 -0
  55. package/dist/lib/apps/app-config.d.ts +42 -0
  56. package/dist/lib/apps/app-config.js +170 -0
  57. package/dist/lib/apps/index.d.ts +67 -0
  58. package/dist/lib/apps/index.js +167 -0
  59. package/dist/lib/apps/paths.d.ts +18 -0
  60. package/dist/lib/apps/paths.js +54 -0
  61. package/dist/lib/bundle.d.ts +1 -0
  62. package/dist/lib/bundle.js +43 -0
  63. package/dist/lib/config.d.ts +37 -0
  64. package/dist/lib/config.js +131 -0
  65. package/dist/lib/constants.d.ts +5 -0
  66. package/dist/lib/constants.js +17 -0
  67. package/dist/lib/create/content.d.ts +23 -0
  68. package/dist/lib/create/content.js +40 -0
  69. package/dist/lib/create/function.d.ts +17 -0
  70. package/dist/lib/create/function.js +36 -0
  71. package/dist/lib/create/index.d.ts +13 -0
  72. package/dist/lib/create/index.js +22 -0
  73. package/dist/lib/create/model.d.ts +22 -0
  74. package/dist/lib/create/model.js +30 -0
  75. package/dist/lib/create/notification.d.ts +25 -0
  76. package/dist/lib/create/notification.js +1 -0
  77. package/dist/lib/info.d.ts +38 -0
  78. package/dist/lib/info.js +91 -0
  79. package/dist/lib/logs/index.d.ts +23 -0
  80. package/dist/lib/logs/index.js +88 -0
  81. package/dist/lib/logs/line-output.d.ts +5 -0
  82. package/dist/lib/logs/line-output.js +13 -0
  83. package/dist/lib/logs/output.d.ts +7 -0
  84. package/dist/lib/logs/output.js +8 -0
  85. package/dist/lib/logs/table-output.d.ts +11 -0
  86. package/dist/lib/logs/table-output.js +128 -0
  87. package/dist/lib/sessions.d.ts +9 -0
  88. package/dist/lib/sessions.js +110 -0
  89. package/dist/lib/stores.d.ts +63 -0
  90. package/dist/lib/stores.js +173 -0
  91. package/dist/lib/style.d.ts +24 -0
  92. package/dist/lib/style.js +29 -0
  93. package/dist/lib/swell-function-wrapper.d.ts +88 -0
  94. package/dist/lib/swell-function-wrapper.js +302 -0
  95. package/dist/remote-app-command.d.ts +36 -0
  96. package/dist/remote-app-command.js +388 -0
  97. package/dist/swell-command.d.ts +21 -0
  98. package/dist/swell-command.js +43 -0
  99. package/oclif.manifest.json +1090 -0
  100. package/package.json +81 -43
  101. package/LICENSE +0 -674
  102. package/dist/bin/multipart-parser-85ef9626.js +0 -456
  103. package/dist/bin/swell-0f71f07d.js +0 -30670
  104. package/dist/bin/swell.js +0 -24
  105. 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
+ }