@factorialco/fcode-cli 1.1.0
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/README.md +1021 -0
- package/bin/dev +17 -0
- package/bin/dev.cmd +3 -0
- package/bin/run +7 -0
- package/bin/run.cmd +3 -0
- package/dist/commands/add.d.ts +6 -0
- package/dist/commands/add.js +22 -0
- package/dist/commands/clone.d.ts +26 -0
- package/dist/commands/clone.js +177 -0
- package/dist/commands/dependencies/add.d.ts +9 -0
- package/dist/commands/dependencies/add.js +13 -0
- package/dist/commands/dependencies/install.d.ts +14 -0
- package/dist/commands/dependencies/install.js +44 -0
- package/dist/commands/dependencies/pull.d.ts +12 -0
- package/dist/commands/dependencies/pull.js +14 -0
- package/dist/commands/dependencies/push.d.ts +12 -0
- package/dist/commands/dependencies/push.js +14 -0
- package/dist/commands/dependencies/reset.d.ts +9 -0
- package/dist/commands/dependencies/reset.js +13 -0
- package/dist/commands/dependencies/status.d.ts +9 -0
- package/dist/commands/dependencies/status.js +13 -0
- package/dist/commands/http.d.ts +22 -0
- package/dist/commands/http.js +272 -0
- package/dist/commands/login.d.ts +18 -0
- package/dist/commands/login.js +62 -0
- package/dist/commands/logout.d.ts +10 -0
- package/dist/commands/logout.js +34 -0
- package/dist/commands/modules/add.d.ts +9 -0
- package/dist/commands/modules/add.js +13 -0
- package/dist/commands/modules/pull.d.ts +13 -0
- package/dist/commands/modules/pull.js +43 -0
- package/dist/commands/modules/push.d.ts +13 -0
- package/dist/commands/modules/push.js +35 -0
- package/dist/commands/modules/remove.d.ts +9 -0
- package/dist/commands/modules/remove.js +19 -0
- package/dist/commands/modules/reset.d.ts +9 -0
- package/dist/commands/modules/reset.js +13 -0
- package/dist/commands/modules/status.d.ts +11 -0
- package/dist/commands/modules/status.js +40 -0
- package/dist/commands/pre-debug.d.ts +20 -0
- package/dist/commands/pre-debug.js +120 -0
- package/dist/commands/process-metadata.d.ts +18 -0
- package/dist/commands/process-metadata.js +63 -0
- package/dist/commands/processes/add.d.ts +9 -0
- package/dist/commands/processes/add.js +13 -0
- package/dist/commands/processes/install-dependencies.d.ts +14 -0
- package/dist/commands/processes/install-dependencies.js +30 -0
- package/dist/commands/processes/pull.d.ts +13 -0
- package/dist/commands/processes/pull.js +47 -0
- package/dist/commands/processes/push.d.ts +13 -0
- package/dist/commands/processes/push.js +39 -0
- package/dist/commands/processes/remove.d.ts +9 -0
- package/dist/commands/processes/remove.js +19 -0
- package/dist/commands/processes/reset.d.ts +9 -0
- package/dist/commands/processes/reset.js +13 -0
- package/dist/commands/processes/status.d.ts +11 -0
- package/dist/commands/processes/status.js +58 -0
- package/dist/commands/pull.d.ts +9 -0
- package/dist/commands/pull.js +32 -0
- package/dist/commands/push.d.ts +9 -0
- package/dist/commands/push.js +29 -0
- package/dist/commands/remote/add.d.ts +10 -0
- package/dist/commands/remote/add.js +32 -0
- package/dist/commands/remote/list.d.ts +7 -0
- package/dist/commands/remote/list.js +33 -0
- package/dist/commands/remote/set.d.ts +10 -0
- package/dist/commands/remote/set.js +28 -0
- package/dist/commands/reset.d.ts +6 -0
- package/dist/commands/reset.js +19 -0
- package/dist/commands/run.d.ts +16 -0
- package/dist/commands/run.js +56 -0
- package/dist/commands/runtime-env.d.ts +12 -0
- package/dist/commands/runtime-env.js +42 -0
- package/dist/commands/settings/get.d.ts +12 -0
- package/dist/commands/settings/get.js +67 -0
- package/dist/commands/settings/remove.d.ts +9 -0
- package/dist/commands/settings/remove.js +35 -0
- package/dist/commands/settings/set.d.ts +10 -0
- package/dist/commands/settings/set.js +39 -0
- package/dist/commands/setup-debug.d.ts +12 -0
- package/dist/commands/setup-debug.js +118 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.js +22 -0
- package/dist/commands/team/pull.d.ts +8 -0
- package/dist/commands/team/pull.js +23 -0
- package/dist/commands/team/push.d.ts +11 -0
- package/dist/commands/team/push.js +41 -0
- package/dist/commands/team/status.d.ts +8 -0
- package/dist/commands/team/status.js +40 -0
- package/dist/commands/test/scaffold.d.ts +9 -0
- package/dist/commands/test/scaffold.js +61 -0
- package/dist/commands/test.d.ts +13 -0
- package/dist/commands/test.js +72 -0
- package/dist/commands/variables/add.d.ts +12 -0
- package/dist/commands/variables/add.js +21 -0
- package/dist/commands/variables/pull.d.ts +12 -0
- package/dist/commands/variables/pull.js +14 -0
- package/dist/commands/variables/push.d.ts +12 -0
- package/dist/commands/variables/push.js +14 -0
- package/dist/commands/variables/remove.d.ts +9 -0
- package/dist/commands/variables/remove.js +19 -0
- package/dist/commands/variables/reset.d.ts +9 -0
- package/dist/commands/variables/reset.js +13 -0
- package/dist/commands/variables/status.d.ts +12 -0
- package/dist/commands/variables/status.js +58 -0
- package/dist/config/global.d.ts +15 -0
- package/dist/config/global.js +77 -0
- package/dist/config/index.d.ts +14 -0
- package/dist/config/index.js +44 -0
- package/dist/config/remote.d.ts +15 -0
- package/dist/config/remote.js +60 -0
- package/dist/config/settings.d.ts +16 -0
- package/dist/config/settings.js +54 -0
- package/dist/config/workspace.d.ts +28 -0
- package/dist/config/workspace.js +158 -0
- package/dist/core/commands/api-client-command.d.ts +6 -0
- package/dist/core/commands/api-client-command.js +30 -0
- package/dist/core/commands/base-command.d.ts +11 -0
- package/dist/core/commands/base-command.js +61 -0
- package/dist/core/commands/dependency-command.d.ts +5 -0
- package/dist/core/commands/dependency-command.js +16 -0
- package/dist/core/commands/modules-command.d.ts +7 -0
- package/dist/core/commands/modules-command.js +18 -0
- package/dist/core/commands/processes-command.d.ts +8 -0
- package/dist/core/commands/processes-command.js +27 -0
- package/dist/core/commands/resource-command.d.ts +24 -0
- package/dist/core/commands/resource-command.js +92 -0
- package/dist/core/commands/variables-command.d.ts +5 -0
- package/dist/core/commands/variables-command.js +16 -0
- package/dist/core/dependencies/env-dependencies-command.d.ts +19 -0
- package/dist/core/dependencies/env-dependencies-command.js +70 -0
- package/dist/core/dependencies/env-process-dependencies-command.d.ts +15 -0
- package/dist/core/dependencies/env-process-dependencies-command.js +78 -0
- package/dist/core/dependencies/javascript-env-dependencies.d.ts +8 -0
- package/dist/core/dependencies/javascript-env-dependencies.js +77 -0
- package/dist/core/dependencies/python-env-dependencies.d.ts +9 -0
- package/dist/core/dependencies/python-env-dependencies.js +91 -0
- package/dist/core/errors.d.ts +55 -0
- package/dist/core/errors.js +144 -0
- package/dist/core/executors/execution-task.d.ts +29 -0
- package/dist/core/executors/execution-task.js +139 -0
- package/dist/core/executors/javascript-execution-task.d.ts +13 -0
- package/dist/core/executors/javascript-execution-task.js +618 -0
- package/dist/core/executors/python/context.d.ts +2 -0
- package/dist/core/executors/python/context.js +3 -0
- package/dist/core/executors/python/datastore.d.ts +2 -0
- package/dist/core/executors/python/datastore.js +4 -0
- package/dist/core/executors/python-execution-task.d.ts +11 -0
- package/dist/core/executors/python-execution-task.js +173 -0
- package/dist/core/executors/source-code-sanitizer.d.ts +4 -0
- package/dist/core/executors/source-code-sanitizer.js +45 -0
- package/dist/core/resource-merger.d.ts +14 -0
- package/dist/core/resource-merger.js +155 -0
- package/dist/core/resource-pusher.d.ts +12 -0
- package/dist/core/resource-pusher.js +133 -0
- package/dist/core/resource-repository.d.ts +8 -0
- package/dist/core/resource-repository.js +2 -0
- package/dist/core/types.d.ts +290 -0
- package/dist/core/types.js +238 -0
- package/dist/core/utils/dependencies.d.ts +5 -0
- package/dist/core/utils/dependencies.js +82 -0
- package/dist/core/utils/variables.d.ts +4 -0
- package/dist/core/utils/variables.js +10 -0
- package/dist/hooks/init/auth.d.ts +3 -0
- package/dist/hooks/init/auth.js +28 -0
- package/dist/hooks/init/update.d.ts +3 -0
- package/dist/hooks/init/update.js +42 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/repositories/process.d.ts +36 -0
- package/dist/repositories/process.js +339 -0
- package/dist/repositories/programming-language-manifest.d.ts +17 -0
- package/dist/repositories/programming-language-manifest.js +95 -0
- package/dist/repositories/resource.d.ts +29 -0
- package/dist/repositories/resource.js +79 -0
- package/dist/repositories/script-library.d.ts +28 -0
- package/dist/repositories/script-library.js +164 -0
- package/dist/repositories/team.d.ts +23 -0
- package/dist/repositories/team.js +74 -0
- package/dist/repositories/variable.d.ts +26 -0
- package/dist/repositories/variable.js +174 -0
- package/dist/runtime/executor.js +87 -0
- package/dist/runtime/executor.py +81 -0
- package/dist/runtime/libs/node/fcode/index.js +1 -0
- package/dist/runtime/libs/python/fcode/__init__.py +75 -0
- package/dist/runtime/libs/python/fcode/context.py +98 -0
- package/dist/runtime/libs/python/fcode/datastore.py +35 -0
- package/dist/runtime/libs/python/fcode/schedule.py +45 -0
- package/dist/runtime/libs/python/fcode/storage.py +271 -0
- package/dist/runtime/libs/python/fcode/variables.py +102 -0
- package/dist/services/auth-service.d.ts +12 -0
- package/dist/services/auth-service.js +114 -0
- package/dist/services/credential-prompter.d.ts +6 -0
- package/dist/services/credential-prompter.js +60 -0
- package/dist/services/fcode-graphql-client.d.ts +45 -0
- package/dist/services/fcode-graphql-client.js +721 -0
- package/dist/services/http-server.d.ts +3 -0
- package/dist/services/http-server.js +17 -0
- package/dist/services/oauth-browser-service.d.ts +9 -0
- package/dist/services/oauth-browser-service.js +164 -0
- package/dist/services/process-parameters-sampler.d.ts +2 -0
- package/dist/services/process-parameters-sampler.js +41 -0
- package/dist/services/process-runner.d.ts +22 -0
- package/dist/services/process-runner.js +97 -0
- package/dist/services/resource-checker.d.ts +8 -0
- package/dist/services/resource-checker.js +82 -0
- package/dist/services/test-runner.d.ts +17 -0
- package/dist/services/test-runner.js +228 -0
- package/dist/utils/canonical-hash.d.ts +9 -0
- package/dist/utils/canonical-hash.js +30 -0
- package/dist/utils/cli/index.d.ts +14 -0
- package/dist/utils/cli/index.js +50 -0
- package/dist/utils/cli/screen.d.ts +2 -0
- package/dist/utils/cli/screen.js +25 -0
- package/dist/utils/cli/styled/table.d.ts +23 -0
- package/dist/utils/cli/styled/table.js +272 -0
- package/dist/utils/colorize-resource.d.ts +1 -0
- package/dist/utils/colorize-resource.js +7 -0
- package/dist/utils/env-utils.d.ts +2 -0
- package/dist/utils/env-utils.js +16 -0
- package/dist/utils/file-utils.d.ts +11 -0
- package/dist/utils/file-utils.js +33 -0
- package/dist/utils/filenamify.d.ts +4 -0
- package/dist/utils/filenamify.js +73 -0
- package/dist/utils/gitignore.d.ts +17 -0
- package/dist/utils/gitignore.js +60 -0
- package/dist/utils/promise.d.ts +4 -0
- package/dist/utils/promise.js +38 -0
- package/dist/utils/url-utils.d.ts +2 -0
- package/dist/utils/url-utils.js +10 -0
- package/dist/utils/variable-warnings.d.ts +8 -0
- package/dist/utils/variable-warnings.js +38 -0
- package/oclif.manifest.json +1783 -0
- package/package.json +129 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const crypto = require("node:crypto");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const http_server_1 = require("../services/http-server");
|
|
6
|
+
const process_runner_1 = require("../services/process-runner");
|
|
7
|
+
const process_1 = require("../repositories/process");
|
|
8
|
+
const variable_1 = require("../repositories/variable");
|
|
9
|
+
const workspace_1 = require("../config/workspace");
|
|
10
|
+
class Http extends core_1.Command {
|
|
11
|
+
async run() {
|
|
12
|
+
const { flags: { port, logLevel, 'auth-user': authUser, 'auth-password': authPassword, jsonLogs }, } = await this.parse(Http);
|
|
13
|
+
const useBasicAuth = authUser !== undefined && authPassword !== undefined;
|
|
14
|
+
const expectedCredentials = useBasicAuth
|
|
15
|
+
? Buffer.from(`${authUser}:${authPassword}`).toString('base64')
|
|
16
|
+
: null;
|
|
17
|
+
const { slug: teamSlug } = await new workspace_1.default().getTeamOrigin();
|
|
18
|
+
const processRepository = new process_1.default();
|
|
19
|
+
const handler = async (req, res) => {
|
|
20
|
+
// CORS headers
|
|
21
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
22
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
23
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Fcode-Async');
|
|
24
|
+
if (req.method === 'OPTIONS') {
|
|
25
|
+
res.writeHead(204);
|
|
26
|
+
res.end();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Basic auth check
|
|
30
|
+
if (useBasicAuth) {
|
|
31
|
+
const authHeader = req.headers['authorization'] ?? '';
|
|
32
|
+
const match = authHeader.match(/^Basic (.+)$/);
|
|
33
|
+
if (!match || match[1] !== expectedCredentials) {
|
|
34
|
+
res.setHeader('WWW-Authenticate', 'Basic realm="Factorial Code"');
|
|
35
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
36
|
+
res.end(JSON.stringify({ success: false, error: 'Unauthorized' }));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const urlObj = new URL(req.url ?? '/', `http://localhost:${port}`);
|
|
41
|
+
// Expected path: /api/<team-slug>/<prefix>/<process-slug>
|
|
42
|
+
const segments = urlObj.pathname.replace(/^\//, '').split('/');
|
|
43
|
+
const [api, team, prefix, slug] = segments;
|
|
44
|
+
if (api !== 'api' || team !== teamSlug) {
|
|
45
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
46
|
+
res.end(JSON.stringify({ success: false, error: `Not found. Expected path prefix: /api/${teamSlug}/` }));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Route: GET|POST /api/<team-slug>/forms/:slug
|
|
50
|
+
// GET → return process parameters schema
|
|
51
|
+
// POST → trigger process execution (same as webhooks)
|
|
52
|
+
if (prefix === 'forms') {
|
|
53
|
+
if (!slug) {
|
|
54
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
55
|
+
res.end(JSON.stringify({ success: false, error: `Process slug required in path (e.g. /api/${teamSlug}/forms/my-process)` }));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (req.method === 'GET') {
|
|
59
|
+
try {
|
|
60
|
+
const process = await processRepository.find(slug);
|
|
61
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
62
|
+
res.end(JSON.stringify({ schema: process.script.parametersSchema ?? {} }));
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
66
|
+
res.end(JSON.stringify({ success: false, error: err?.message ?? String(err) }));
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
await this._handleProcessExecution(req, res, slug, urlObj, logLevel, jsonLogs);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Route: GET|POST /api/<team-slug>/webhooks/:slug
|
|
74
|
+
if (prefix === 'webhooks') {
|
|
75
|
+
if (!slug) {
|
|
76
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
77
|
+
res.end(JSON.stringify({ success: false, error: `Process slug required in path (e.g. /api/${teamSlug}/webhooks/my-process)` }));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!(await this._checkWebhookAuth(req, res, processRepository, slug))) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await this._handleProcessExecution(req, res, slug, urlObj, logLevel, jsonLogs);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// No matching route
|
|
87
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
88
|
+
res.end(JSON.stringify({ success: false, error: `Not found. Available: /api/${teamSlug}/webhooks/:process-slug, /api/${teamSlug}/forms/:process-slug` }));
|
|
89
|
+
};
|
|
90
|
+
const server = await (0, http_server_1.startServer)(port, '0.0.0.0', (req, res) => {
|
|
91
|
+
handler(req, res).catch((err) => {
|
|
92
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
93
|
+
res.end(JSON.stringify({ success: false, error: String(err) }));
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
console.log(`HTTP server listening on http://0.0.0.0:${port}`);
|
|
97
|
+
console.log(` GET|POST /api/${teamSlug}/webhooks/:process-slug — trigger a process`);
|
|
98
|
+
console.log(` GET /api/${teamSlug}/forms/:process-slug — get process parameters schema`);
|
|
99
|
+
console.log(` POST /api/${teamSlug}/forms/:process-slug — trigger a process`);
|
|
100
|
+
console.log(`\nExample:`);
|
|
101
|
+
console.log(` curl -X POST http://localhost:${port}/api/${teamSlug}/webhooks/<process-slug> \\`);
|
|
102
|
+
console.log(` -H "Content-Type: application/json" \\`);
|
|
103
|
+
console.log(` -d '{"param1": "value1"}'`);
|
|
104
|
+
process.on('SIGINT', async () => {
|
|
105
|
+
console.log('\nShutting down HTTP server...');
|
|
106
|
+
await (0, http_server_1.stopServer)(server);
|
|
107
|
+
process.exit(0);
|
|
108
|
+
});
|
|
109
|
+
// Keep process alive
|
|
110
|
+
await new Promise(() => { });
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Enforces the process's configured webhook basic auth, simulating the cloud
|
|
114
|
+
* webhook endpoint. The username/password come from processes/<slug>/metadata.json;
|
|
115
|
+
* an env-var placeholder (e.g. $WEBHOOK_PASSWORD) is resolved against the workspace
|
|
116
|
+
* variables. Returns true when the request may proceed, false after writing a 401.
|
|
117
|
+
*/
|
|
118
|
+
async _checkWebhookAuth(req, res, processRepository, slug) {
|
|
119
|
+
let webhook;
|
|
120
|
+
try {
|
|
121
|
+
webhook = (await processRepository.find(slug)).webhook;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Unknown process: let the execution path report the 404.
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (!webhook || (!webhook.username && !webhook.password)) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
const variables = await new variable_1.default().findAllForExecution();
|
|
131
|
+
const values = new Map(variables.map((variable) => [variable.key, variable.value]));
|
|
132
|
+
const resolvePlaceholder = (value) => {
|
|
133
|
+
if (!value)
|
|
134
|
+
return '';
|
|
135
|
+
const match = value.match(/^\$\{?([A-Za-z_]\w*)\}?$/);
|
|
136
|
+
return match ? values.get(match[1]) ?? value : value;
|
|
137
|
+
};
|
|
138
|
+
const expected = Buffer.from(`${resolvePlaceholder(webhook.username)}:${resolvePlaceholder(webhook.password)}`).toString('base64');
|
|
139
|
+
const authHeader = req.headers['authorization'] ?? '';
|
|
140
|
+
const match = authHeader.match(/^Basic (.+)$/);
|
|
141
|
+
if (!match || match[1] !== expected) {
|
|
142
|
+
res.setHeader('WWW-Authenticate', 'Basic realm="Factorial Code Webhook"');
|
|
143
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
144
|
+
res.end(JSON.stringify({ success: false, error: 'Unauthorized' }));
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
async _handleProcessExecution(req, res, slug, urlObj, logLevel, jsonLogs) {
|
|
150
|
+
if (req.method !== 'GET' && req.method !== 'POST') {
|
|
151
|
+
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
152
|
+
res.end(JSON.stringify({ success: false, error: 'Method Not Allowed' }));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const queryParams = {};
|
|
156
|
+
urlObj.searchParams.forEach((value, key) => {
|
|
157
|
+
queryParams[key] = value;
|
|
158
|
+
});
|
|
159
|
+
// Read request body
|
|
160
|
+
const rawBody = await new Promise((resolve, reject) => {
|
|
161
|
+
const chunks = [];
|
|
162
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
163
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
164
|
+
req.on('error', reject);
|
|
165
|
+
});
|
|
166
|
+
// Parse body as JSON parameters
|
|
167
|
+
let bodyParams = {};
|
|
168
|
+
if (rawBody.trim()) {
|
|
169
|
+
try {
|
|
170
|
+
bodyParams = JSON.parse(rawBody);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
174
|
+
res.end(JSON.stringify({ success: false, error: 'Invalid JSON body' }));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Merge query params + body (body takes precedence)
|
|
179
|
+
const parameters = { ...queryParams, ...bodyParams };
|
|
180
|
+
// Async mode detection
|
|
181
|
+
const isAsync = req.headers['fcode-async'] === 'true' || queryParams['async'] === 'true';
|
|
182
|
+
// Build request context
|
|
183
|
+
const headers = {};
|
|
184
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
185
|
+
if (typeof value === 'string')
|
|
186
|
+
headers[key] = value;
|
|
187
|
+
else if (Array.isArray(value))
|
|
188
|
+
headers[key] = value.join(', ');
|
|
189
|
+
}
|
|
190
|
+
const webhookRequest = {
|
|
191
|
+
headers,
|
|
192
|
+
rawBody,
|
|
193
|
+
query: queryParams,
|
|
194
|
+
method: req.method ?? 'GET',
|
|
195
|
+
};
|
|
196
|
+
if (isAsync) {
|
|
197
|
+
const executionId = crypto.randomUUID();
|
|
198
|
+
const asyncResponse = queryParams['async_response'];
|
|
199
|
+
if (asyncResponse === 'false') {
|
|
200
|
+
res.writeHead(201);
|
|
201
|
+
res.end();
|
|
202
|
+
}
|
|
203
|
+
else if (asyncResponse !== undefined) {
|
|
204
|
+
res.writeHead(201, { 'Content-Type': 'text/plain' });
|
|
205
|
+
res.end(asyncResponse);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
res.writeHead(201, { 'Content-Type': 'application/json' });
|
|
209
|
+
res.end(JSON.stringify({ id: executionId, status: 'CREATED', data: null }));
|
|
210
|
+
}
|
|
211
|
+
// Fire and forget
|
|
212
|
+
(0, process_runner_1.runProcess)({ slug, parameters, logLevel, request: webhookRequest, jsonLogs }).catch((err) => {
|
|
213
|
+
console.error(`[http] Error executing process '${slug}':`, err);
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// Synchronous execution
|
|
218
|
+
try {
|
|
219
|
+
const returnValue = await (0, process_runner_1.runProcess)({ slug, parameters, logLevel, request: webhookRequest, jsonLogs });
|
|
220
|
+
this._sendResponse(res, returnValue);
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
224
|
+
res.end(JSON.stringify({ success: false, error: err?.message ?? String(err) }));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
_sendResponse(res, returnValue) {
|
|
228
|
+
if (returnValue !== null && returnValue !== undefined && typeof returnValue === 'object' && !Array.isArray(returnValue)) {
|
|
229
|
+
const rv = returnValue;
|
|
230
|
+
const status = typeof rv['status'] === 'number' ? rv['status'] : 200;
|
|
231
|
+
const customHeaders = rv['headers'] && typeof rv['headers'] === 'object' ? rv['headers'] : {};
|
|
232
|
+
const body = 'body' in rv ? rv['body'] : returnValue;
|
|
233
|
+
res.writeHead(status, { 'Content-Type': 'application/json', ...customHeaders });
|
|
234
|
+
res.end(JSON.stringify(body));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
238
|
+
res.end(JSON.stringify(returnValue ?? { success: true }));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
Http.description = 'Start a local HTTP server to trigger Factorial Code processes via webhooks and expose forms schema';
|
|
243
|
+
Http.examples = [
|
|
244
|
+
'$ fcode http',
|
|
245
|
+
'$ fcode http --port 8080',
|
|
246
|
+
'$ fcode http --auth-user admin --auth-password secret',
|
|
247
|
+
];
|
|
248
|
+
Http.flags = {
|
|
249
|
+
port: core_1.Flags.integer({
|
|
250
|
+
char: 'P',
|
|
251
|
+
description: 'Port to listen on',
|
|
252
|
+
default: 3000,
|
|
253
|
+
}),
|
|
254
|
+
logLevel: core_1.Flags.string({
|
|
255
|
+
char: 'l',
|
|
256
|
+
description: 'Log level to use in process executions',
|
|
257
|
+
default: 'DEBUG',
|
|
258
|
+
options: ['DEBUG', 'INFO', 'WARNING', 'ERROR'],
|
|
259
|
+
}),
|
|
260
|
+
'auth-user': core_1.Flags.string({
|
|
261
|
+
description: 'Basic auth username',
|
|
262
|
+
}),
|
|
263
|
+
'auth-password': core_1.Flags.string({
|
|
264
|
+
description: 'Basic auth password',
|
|
265
|
+
}),
|
|
266
|
+
jsonLogs: core_1.Flags.boolean({
|
|
267
|
+
char: 'j',
|
|
268
|
+
description: 'Output process logs as newline-delimited JSON (NDJSON)',
|
|
269
|
+
default: false,
|
|
270
|
+
}),
|
|
271
|
+
};
|
|
272
|
+
exports.default = Http;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Login extends Command {
|
|
3
|
+
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
url: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
authUrl: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
email: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
password: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
clientId: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
clientSecret: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
accessToken: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
prompt: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
};
|
|
16
|
+
init(): Promise<void>;
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const global_1 = require("../config/global");
|
|
5
|
+
const cli_1 = require("../utils/cli");
|
|
6
|
+
class Login extends core_1.Command {
|
|
7
|
+
async init() {
|
|
8
|
+
const { flags } = await this.parse(Login);
|
|
9
|
+
const { failures } = await this.config.runHook('auth', {
|
|
10
|
+
argv: [flags.url, flags.authUrl, flags.email, flags.password, flags.clientId, flags.clientSecret, flags.accessToken, flags.prompt],
|
|
11
|
+
id: 'login',
|
|
12
|
+
});
|
|
13
|
+
if (failures.length > 0) {
|
|
14
|
+
throw failures[0].error;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async run() {
|
|
18
|
+
const { flags } = await this.parse(Login);
|
|
19
|
+
const userInfo = await new global_1.default().getUserInfo(flags.url);
|
|
20
|
+
cli_1.default.log(`👋 Hi, ${userInfo.name}!`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
Login.args = {};
|
|
24
|
+
Login.description = 'Login with your Factorial Code credentials (browser OAuth or email/password)';
|
|
25
|
+
Login.examples = ['$ fcode login', '$ fcode login --prompt', '$ fcode login -e you@example.com -p your-password'];
|
|
26
|
+
Login.flags = {
|
|
27
|
+
url: core_1.Flags.string({
|
|
28
|
+
char: 'u',
|
|
29
|
+
description: 'Factorial Code Cloud endpoint',
|
|
30
|
+
default: global_1.FCODE_CLOUD_URL,
|
|
31
|
+
}),
|
|
32
|
+
authUrl: core_1.Flags.string({
|
|
33
|
+
char: 'a',
|
|
34
|
+
description: 'Factorial Code Auth endpoint (including realm, ie: https://code.factorial.dev/auth/realms/fcode)). Only needed if auth domain is different than used cloud endpoint',
|
|
35
|
+
}),
|
|
36
|
+
email: core_1.Flags.string({
|
|
37
|
+
char: 'e',
|
|
38
|
+
description: 'Email (to be used with password)',
|
|
39
|
+
}),
|
|
40
|
+
password: core_1.Flags.string({
|
|
41
|
+
char: 'p',
|
|
42
|
+
description: 'Password (to be used with email)',
|
|
43
|
+
}),
|
|
44
|
+
clientId: core_1.Flags.string({
|
|
45
|
+
char: 'c',
|
|
46
|
+
description: 'Client ID (for oauth, to be used with Client Secret)',
|
|
47
|
+
}),
|
|
48
|
+
clientSecret: core_1.Flags.string({
|
|
49
|
+
char: 's',
|
|
50
|
+
description: 'Client Secret (for oauth, to be used with Client ID)',
|
|
51
|
+
}),
|
|
52
|
+
accessToken: core_1.Flags.string({
|
|
53
|
+
char: 't',
|
|
54
|
+
description: 'Access Token (to be used instead of email and password)',
|
|
55
|
+
}),
|
|
56
|
+
prompt: core_1.Flags.boolean({
|
|
57
|
+
char: 'x',
|
|
58
|
+
description: 'Prompt for email and password (instead of opening browser)',
|
|
59
|
+
default: false,
|
|
60
|
+
}),
|
|
61
|
+
};
|
|
62
|
+
exports.default = Login;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Logout extends Command {
|
|
3
|
+
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
url: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const auth_service_1 = require("../services/auth-service");
|
|
5
|
+
const global_1 = require("../config/global");
|
|
6
|
+
const errors_1 = require("../core/errors");
|
|
7
|
+
const cli_1 = require("../utils/cli");
|
|
8
|
+
class Logout extends core_1.Command {
|
|
9
|
+
async run() {
|
|
10
|
+
const { flags } = await this.parse(Logout);
|
|
11
|
+
try {
|
|
12
|
+
await auth_service_1.default.logout(flags.url);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (!(error instanceof errors_1.NotAuthenticated)) {
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
cli_1.default.log('👋 Session ended. See you soon!');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
Logout.args = {};
|
|
25
|
+
Logout.description = 'Logout from Factorial Code';
|
|
26
|
+
Logout.examples = ['$ fcode logout'];
|
|
27
|
+
Logout.flags = {
|
|
28
|
+
url: core_1.Flags.string({
|
|
29
|
+
char: 'u',
|
|
30
|
+
description: 'Factorial Code Cloud endpoint',
|
|
31
|
+
default: global_1.FCODE_CLOUD_URL,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
exports.default = Logout;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
export default class ModulesAdd extends ModulesCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
4
|
+
const types_1 = require("../../core/types");
|
|
5
|
+
class ModulesAdd extends modules_command_1.default {
|
|
6
|
+
async run() {
|
|
7
|
+
await super.addResources();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
ModulesAdd.description = 'Keeps track of a new local module';
|
|
11
|
+
ModulesAdd.examples = ['$ fcode modules:add'];
|
|
12
|
+
ModulesAdd.args = types_1.ResourceSlugArg;
|
|
13
|
+
exports.default = ModulesAdd;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
export default class ModulesPull extends ModulesCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
pullVersioned(): Promise<void>;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const color_1 = require("@oclif/color");
|
|
4
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
5
|
+
const types_1 = require("../../core/types");
|
|
6
|
+
const cli_1 = require("../../utils/cli");
|
|
7
|
+
class ModulesPull extends modules_command_1.default {
|
|
8
|
+
async pullVersioned() {
|
|
9
|
+
const scriptLibraries = (await this._resourceRepository.findAll()).filter((scriptLibrary) => scriptLibrary.id);
|
|
10
|
+
const scriptLibraryRepository = this._resourceRepository;
|
|
11
|
+
const allPromises = [];
|
|
12
|
+
for (const scriptLibrary of scriptLibraries) {
|
|
13
|
+
allPromises.push(this._versionedResourceQuery(scriptLibrary.id).then(async (remoteVersions) => {
|
|
14
|
+
const remoteVersionTags = new Set(remoteVersions.map((v) => v.tag));
|
|
15
|
+
// Remove local versions that were deleted in remote
|
|
16
|
+
for (const localTag of scriptLibraryRepository.getLocalVersionTags(scriptLibrary)) {
|
|
17
|
+
if (!remoteVersionTags.has(localTag)) {
|
|
18
|
+
cli_1.default.log(color_1.default.cyan(`🗑️ removing version '${localTag}' for module '${scriptLibrary.slug}'...`));
|
|
19
|
+
scriptLibraryRepository.removeVersion(scriptLibrary, localTag);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Add only new (non-existing) versions
|
|
23
|
+
for (const versionedScriptLibrary of remoteVersions) {
|
|
24
|
+
if (!scriptLibraryRepository.versionExistsLocally(scriptLibrary, versionedScriptLibrary.tag)) {
|
|
25
|
+
cli_1.default.log(color_1.default.cyan(`🗂️ pulling version '${versionedScriptLibrary.tag}' for module '${scriptLibrary.slug}'...`));
|
|
26
|
+
await scriptLibraryRepository.saveVersion(scriptLibrary, versionedScriptLibrary);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
31
|
+
}
|
|
32
|
+
await Promise.allSettled(allPromises);
|
|
33
|
+
}
|
|
34
|
+
async run() {
|
|
35
|
+
await super.pullResources();
|
|
36
|
+
await this.pullVersioned();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
ModulesPull.description = 'Fetch all modules from cloud and save them locally';
|
|
40
|
+
ModulesPull.examples = ['$ fcode modules:pull'];
|
|
41
|
+
ModulesPull.args = types_1.ResourceSlugArg;
|
|
42
|
+
ModulesPull.flags = types_1.ForceFlag;
|
|
43
|
+
exports.default = ModulesPull;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
export default class ModulesPush extends ModulesCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
pushVersioned(): Promise<void>;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const color_1 = require("@oclif/color");
|
|
4
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
5
|
+
const types_1 = require("../../core/types");
|
|
6
|
+
const cli_1 = require("../../utils/cli");
|
|
7
|
+
class ModulesPush extends modules_command_1.default {
|
|
8
|
+
async pushVersioned() {
|
|
9
|
+
const scriptLibraries = (await this._resourceRepository.findAll()).filter((process) => process.id);
|
|
10
|
+
const scriptLibraryRepository = this._resourceRepository;
|
|
11
|
+
const allPromises = [];
|
|
12
|
+
for (const scriptLibrary of scriptLibraries) {
|
|
13
|
+
allPromises.push(this._versionedResourceQuery(scriptLibrary.id).then(async (remoteVersionedScriptLibraries) => {
|
|
14
|
+
const localVersionedScriptLibraries = await scriptLibraryRepository.getVersions(scriptLibrary);
|
|
15
|
+
for (const localVersionedScriptLibrary of localVersionedScriptLibraries) {
|
|
16
|
+
if (!remoteVersionedScriptLibraries.find((remoteVersionedScriptLibrary) => remoteVersionedScriptLibrary.tag === localVersionedScriptLibrary.tag)) {
|
|
17
|
+
cli_1.default.log(color_1.default.cyan(`🗂️ pushing version '${localVersionedScriptLibrary.tag}' for module '${scriptLibrary.slug}'...`));
|
|
18
|
+
await this._pushVersionedResourceMutation(localVersionedScriptLibrary);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
23
|
+
}
|
|
24
|
+
await Promise.allSettled(allPromises);
|
|
25
|
+
}
|
|
26
|
+
async run() {
|
|
27
|
+
await super.pushResources();
|
|
28
|
+
await this.pushVersioned();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
ModulesPush.description = 'Update cloud modules with local ones';
|
|
32
|
+
ModulesPush.examples = ['$ fcode modules:push'];
|
|
33
|
+
ModulesPush.args = types_1.ResourceSlugArg;
|
|
34
|
+
ModulesPush.flags = types_1.ForceFlag;
|
|
35
|
+
exports.default = ModulesPush;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
export default class ModulesRemove extends ModulesCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const color_1 = require("@oclif/color");
|
|
4
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
5
|
+
const types_1 = require("../../core/types");
|
|
6
|
+
const cli_1 = require("../../utils/cli");
|
|
7
|
+
class ModulesRemove extends modules_command_1.default {
|
|
8
|
+
async run() {
|
|
9
|
+
if (!this.resourceSlug) {
|
|
10
|
+
cli_1.default.log(color_1.default.red(`You must specify a module slug`));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await super.removeResource(this.resourceSlug);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
ModulesRemove.description = 'Remove track of local modules';
|
|
17
|
+
ModulesRemove.examples = ['$ fcode modules:remove module-slug'];
|
|
18
|
+
ModulesRemove.args = types_1.ResourceSlugArg;
|
|
19
|
+
exports.default = ModulesRemove;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
export default class ProcessesReset extends ModulesCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
4
|
+
const types_1 = require("../../core/types");
|
|
5
|
+
class ProcessesReset extends modules_command_1.default {
|
|
6
|
+
async run() {
|
|
7
|
+
await super.resetResources();
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
ProcessesReset.description = 'Reset modules with contents from current remote';
|
|
11
|
+
ProcessesReset.examples = ['$ fcode modules:reset'];
|
|
12
|
+
ProcessesReset.args = types_1.ResourceSlugArg;
|
|
13
|
+
exports.default = ProcessesReset;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ModulesCommand from '../../core/commands/modules-command';
|
|
2
|
+
import { MergedResource } from '../../core/types';
|
|
3
|
+
export default class ModulesStatus extends ModulesCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
resourceSlug: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
resourcesTableLog(resources: Array<MergedResource>): Promise<void>;
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const modules_command_1 = require("../../core/commands/modules-command");
|
|
4
|
+
const types_1 = require("../../core/types");
|
|
5
|
+
const colorize_resource_1 = require("../../utils/colorize-resource");
|
|
6
|
+
const cli_1 = require("../../utils/cli");
|
|
7
|
+
class ModulesStatus extends modules_command_1.default {
|
|
8
|
+
async resourcesTableLog(resources) {
|
|
9
|
+
const hasInherited = resources.some((resource) => resource.resolvingTeamSlug);
|
|
10
|
+
cli_1.cli.table(resources, {
|
|
11
|
+
name: {
|
|
12
|
+
get({ slug, status }) {
|
|
13
|
+
return (0, colorize_resource_1.colorizeByStatus)(slug, status);
|
|
14
|
+
},
|
|
15
|
+
header: 'name',
|
|
16
|
+
},
|
|
17
|
+
...(hasInherited && {
|
|
18
|
+
inherited: {
|
|
19
|
+
get(resource) {
|
|
20
|
+
return (0, colorize_resource_1.colorizeByStatus)(resource.resolvingTeamSlug ? `🔗 ${resource.resolvingTeamSlug}` : '', resource.status);
|
|
21
|
+
},
|
|
22
|
+
header: 'inherited',
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
25
|
+
status: {
|
|
26
|
+
get({ status }) {
|
|
27
|
+
return (0, colorize_resource_1.colorizeByStatus)(status, status);
|
|
28
|
+
},
|
|
29
|
+
header: 'status',
|
|
30
|
+
},
|
|
31
|
+
}, { sort: 'name' });
|
|
32
|
+
}
|
|
33
|
+
async run() {
|
|
34
|
+
await this.resourcesLog();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
ModulesStatus.description = 'List all modules status';
|
|
38
|
+
ModulesStatus.examples = ['$ fcode modules:status'];
|
|
39
|
+
ModulesStatus.args = types_1.ResourceSlugArg;
|
|
40
|
+
exports.default = ModulesStatus;
|