@metacall/protocol 0.1.5
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/.eslintignore +1 -0
- package/LICENSE +201 -0
- package/dist/deployment.d.ts +76 -0
- package/dist/deployment.js +36 -0
- package/dist/doc/index.d.ts +1 -0
- package/dist/doc/index.js +22 -0
- package/dist/language.d.ts +12 -0
- package/dist/language.js +78 -0
- package/dist/login.d.ts +2 -0
- package/dist/login.js +23 -0
- package/dist/package.d.ts +18 -0
- package/dist/package.js +98 -0
- package/dist/plan.d.ts +5 -0
- package/dist/plan.js +9 -0
- package/dist/protocol.d.ts +29 -0
- package/dist/protocol.js +141 -0
- package/dist/token.d.ts +1 -0
- package/dist/token.js +16 -0
- package/package.json +110 -0
- package/src/deployment.ts +118 -0
- package/src/language.ts +94 -0
- package/src/login.ts +31 -0
- package/src/package.ts +132 -0
- package/src/plan.ts +5 -0
- package/src/protocol.ts +273 -0
- package/src/token.ts +10 -0
- package/swagger.yaml +819 -0
- package/tsconfig.json +12 -0
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
* About File:
|
|
5
|
+
|
|
6
|
+
this is just a client that implements all the rest API from the FaaS, so each function it contains is an endpoint in the FaaS for deploying and similar
|
|
7
|
+
|
|
8
|
+
refresh: updates the auth token
|
|
9
|
+
validate: validates the auth token
|
|
10
|
+
deployEnabled: checks if you're able to deploy
|
|
11
|
+
listSubscriptions: gives you a list of the subscription available
|
|
12
|
+
inspect: gives you are deploys with it's endpoints
|
|
13
|
+
upload: uploads a zip (package) into the faas
|
|
14
|
+
deploy: deploys the previously uploaded zip into the faas
|
|
15
|
+
deployDelete: deletes the deploy and the zip
|
|
16
|
+
|
|
17
|
+
*/
|
|
18
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.isProtocolError = void 0;
|
|
23
|
+
const axios_1 = __importDefault(require("axios"));
|
|
24
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
25
|
+
const deployment_1 = require("./deployment");
|
|
26
|
+
const isProtocolError = (err) => axios_1.default.isAxiosError(err);
|
|
27
|
+
exports.isProtocolError = isProtocolError;
|
|
28
|
+
exports.default = (token, baseURL) => {
|
|
29
|
+
const api = {
|
|
30
|
+
refresh: () => axios_1.default
|
|
31
|
+
.get(baseURL + '/api/account/refresh-token', {
|
|
32
|
+
headers: { Authorization: 'jwt ' + token }
|
|
33
|
+
})
|
|
34
|
+
.then(res => res.data),
|
|
35
|
+
validate: () => axios_1.default
|
|
36
|
+
.get(baseURL + '/validate', {
|
|
37
|
+
headers: { Authorization: 'jwt ' + token }
|
|
38
|
+
})
|
|
39
|
+
.then(res => res.data),
|
|
40
|
+
deployEnabled: () => axios_1.default
|
|
41
|
+
.get(baseURL + '/api/account/deploy-enabled', {
|
|
42
|
+
headers: { Authorization: 'jwt ' + token }
|
|
43
|
+
})
|
|
44
|
+
.then(res => res.data),
|
|
45
|
+
listSubscriptions: async () => {
|
|
46
|
+
const res = await axios_1.default.get(baseURL + '/api/billing/list-subscriptions', {
|
|
47
|
+
headers: { Authorization: 'jwt ' + token }
|
|
48
|
+
});
|
|
49
|
+
const subscriptions = {};
|
|
50
|
+
for (const id of res.data) {
|
|
51
|
+
if (subscriptions[id] === undefined) {
|
|
52
|
+
subscriptions[id] = 1;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
++subscriptions[id];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return subscriptions;
|
|
59
|
+
},
|
|
60
|
+
inspect: async () => axios_1.default
|
|
61
|
+
.get(baseURL + '/api/inspect', {
|
|
62
|
+
headers: { Authorization: 'jwt ' + token }
|
|
63
|
+
})
|
|
64
|
+
.then(res => res.data),
|
|
65
|
+
upload: async (name, blob, jsons = [], runners = []) => {
|
|
66
|
+
const fd = new form_data_1.default();
|
|
67
|
+
fd.append('id', name);
|
|
68
|
+
fd.append('type', 'application/x-zip-compressed');
|
|
69
|
+
fd.append('jsons', JSON.stringify(jsons));
|
|
70
|
+
fd.append('runners', JSON.stringify(runners));
|
|
71
|
+
fd.append('raw', blob, {
|
|
72
|
+
filename: 'blob',
|
|
73
|
+
contentType: 'application/x-zip-compressed'
|
|
74
|
+
});
|
|
75
|
+
const res = await axios_1.default.post(baseURL + '/api/package/create', fd, {
|
|
76
|
+
headers: {
|
|
77
|
+
Authorization: 'jwt ' + token,
|
|
78
|
+
...fd.getHeaders()
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return res.data;
|
|
82
|
+
},
|
|
83
|
+
add: (url, branch, jsons = []) => axios_1.default
|
|
84
|
+
.post(baseURL + '/api/repository/add', {
|
|
85
|
+
url,
|
|
86
|
+
branch,
|
|
87
|
+
jsons
|
|
88
|
+
}, {
|
|
89
|
+
headers: { Authorization: 'jwt ' + token }
|
|
90
|
+
})
|
|
91
|
+
.then((res) => res.data),
|
|
92
|
+
branchList: (url) => axios_1.default
|
|
93
|
+
.post(baseURL + '/api/repository/branchlist', {
|
|
94
|
+
url
|
|
95
|
+
}, {
|
|
96
|
+
headers: { Authorization: 'jwt ' + token }
|
|
97
|
+
})
|
|
98
|
+
.then((res) => res.data),
|
|
99
|
+
deploy: (name, env, plan, resourceType, release = Date.now().toString(16), version = 'v1') => axios_1.default
|
|
100
|
+
.post(baseURL + '/api/deploy/create', {
|
|
101
|
+
resourceType,
|
|
102
|
+
suffix: name,
|
|
103
|
+
release,
|
|
104
|
+
env,
|
|
105
|
+
plan,
|
|
106
|
+
version
|
|
107
|
+
}, {
|
|
108
|
+
headers: { Authorization: 'jwt ' + token }
|
|
109
|
+
})
|
|
110
|
+
.then(res => res.data),
|
|
111
|
+
deployDelete: (prefix, suffix, version = 'v1') => axios_1.default
|
|
112
|
+
.post(baseURL + '/api/deploy/delete', {
|
|
113
|
+
prefix,
|
|
114
|
+
suffix,
|
|
115
|
+
version
|
|
116
|
+
}, {
|
|
117
|
+
headers: { Authorization: 'jwt ' + token }
|
|
118
|
+
})
|
|
119
|
+
.then(res => res.data),
|
|
120
|
+
logs: (container, type = deployment_1.LogType.Deploy, suffix, prefix, version = 'v1') => axios_1.default
|
|
121
|
+
.post(baseURL + '/api/deploy/logs', {
|
|
122
|
+
container,
|
|
123
|
+
type,
|
|
124
|
+
suffix,
|
|
125
|
+
prefix,
|
|
126
|
+
version
|
|
127
|
+
}, {
|
|
128
|
+
headers: { Authorization: 'jwt ' + token }
|
|
129
|
+
})
|
|
130
|
+
.then(res => res.data),
|
|
131
|
+
fileList: (url, branch) => axios_1.default
|
|
132
|
+
.post(baseURL + '/api/repository/filelist', {
|
|
133
|
+
url,
|
|
134
|
+
branch
|
|
135
|
+
}, {
|
|
136
|
+
headers: { Authorization: 'jwt ' + token }
|
|
137
|
+
})
|
|
138
|
+
.then(res => res.data['files'])
|
|
139
|
+
};
|
|
140
|
+
return api;
|
|
141
|
+
};
|
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const expiresIn: (token: string) => number;
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.expiresIn = void 0;
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
+
const expiresIn = (token) => {
|
|
9
|
+
const decoded = jsonwebtoken_1.default.decode(token);
|
|
10
|
+
if (typeof decoded === 'string') {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
const now = Date.now() / 1000;
|
|
14
|
+
return new Date(((decoded === null || decoded === void 0 ? void 0 : decoded['exp']) || now) * 1000).getTime() - now * 1000;
|
|
15
|
+
};
|
|
16
|
+
exports.expiresIn = expiresIn;
|
package/package.json
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@metacall/protocol",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Tool for deploying into MetaCall FaaS platform.",
|
|
5
|
+
"exports": {
|
|
6
|
+
"./*": "./dist/*.js",
|
|
7
|
+
"./package.json": "./package.json"
|
|
8
|
+
},
|
|
9
|
+
"typesVersions": {
|
|
10
|
+
"*": {
|
|
11
|
+
"*": [
|
|
12
|
+
"dist/*.d.ts"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "npm run --silent build && mocha dist/test",
|
|
18
|
+
"unit": "npm run --silent test -- --ignore **/integration**",
|
|
19
|
+
"prepublishOnly": "npm run --silent build",
|
|
20
|
+
"build": "npm run --silent lint && tsc",
|
|
21
|
+
"postinstall": "npm run build",
|
|
22
|
+
"lint": "eslint . --ignore-pattern dist",
|
|
23
|
+
"fix": "eslint . --ignore-pattern dist --fix",
|
|
24
|
+
"doc": "node dist/doc/index.js"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/metacall/protocol.git"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"MetaCall",
|
|
32
|
+
"FaaS",
|
|
33
|
+
"protocol"
|
|
34
|
+
],
|
|
35
|
+
"author": "Thomas Rory Gummerson <thomas@gummerson.no> (https://trgwii.no/)",
|
|
36
|
+
"contributors": [
|
|
37
|
+
"Vicente Eduardo Ferrer Garcia <vic798@gmail.com> (https://metacall.io/)"
|
|
38
|
+
],
|
|
39
|
+
"license": "Apache-2.0",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/metacall/protocol/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/metacall/protocol#readme",
|
|
44
|
+
"prettier": {
|
|
45
|
+
"tabWidth": 4,
|
|
46
|
+
"useTabs": true,
|
|
47
|
+
"singleQuote": true,
|
|
48
|
+
"trailingComma": "none",
|
|
49
|
+
"arrowParens": "avoid"
|
|
50
|
+
},
|
|
51
|
+
"eslintConfig": {
|
|
52
|
+
"env": {
|
|
53
|
+
"es6": true,
|
|
54
|
+
"node": true
|
|
55
|
+
},
|
|
56
|
+
"plugins": [
|
|
57
|
+
"@typescript-eslint",
|
|
58
|
+
"eslint-plugin-tsdoc"
|
|
59
|
+
],
|
|
60
|
+
"extends": [
|
|
61
|
+
"eslint:recommended",
|
|
62
|
+
"prettier",
|
|
63
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
64
|
+
"plugin:@typescript-eslint/recommended",
|
|
65
|
+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
|
66
|
+
"prettier/@typescript-eslint",
|
|
67
|
+
"plugin:prettier/recommended"
|
|
68
|
+
],
|
|
69
|
+
"globals": {
|
|
70
|
+
"Atomics": "readonly",
|
|
71
|
+
"SharedArrayBuffer": "readonly"
|
|
72
|
+
},
|
|
73
|
+
"parser": "@typescript-eslint/parser",
|
|
74
|
+
"parserOptions": {
|
|
75
|
+
"ecmaVersion": 2020,
|
|
76
|
+
"sourceType": "module",
|
|
77
|
+
"project": "./tsconfig.json"
|
|
78
|
+
},
|
|
79
|
+
"rules": {
|
|
80
|
+
"tsdoc/syntax": "warn"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@types/ignore-walk": "^4.0.0",
|
|
85
|
+
"@types/jsonwebtoken": "^8.5.8",
|
|
86
|
+
"axios": "^0.21.0",
|
|
87
|
+
"form-data": "^3.0.0",
|
|
88
|
+
"ignore-walk": "^3.0.4",
|
|
89
|
+
"jsonwebtoken": "^8.5.1"
|
|
90
|
+
},
|
|
91
|
+
"devDependencies": {
|
|
92
|
+
"@types/express": "^4.17.13",
|
|
93
|
+
"@types/mocha": "^8.2.2",
|
|
94
|
+
"@types/node": "^14.14.7",
|
|
95
|
+
"@types/swagger-ui-express": "^4.1.3",
|
|
96
|
+
"@types/yamljs": "^0.2.31",
|
|
97
|
+
"@typescript-eslint/eslint-plugin": "^4.7.0",
|
|
98
|
+
"@typescript-eslint/parser": "^4.7.0",
|
|
99
|
+
"eslint": "^7.13.0",
|
|
100
|
+
"eslint-config-prettier": "^6.15.0",
|
|
101
|
+
"eslint-plugin-prettier": "^3.1.4",
|
|
102
|
+
"eslint-plugin-tsdoc": "^0.2.7",
|
|
103
|
+
"express": "^4.17.2",
|
|
104
|
+
"mocha": "^9.2.0",
|
|
105
|
+
"prettier": "^2.1.2",
|
|
106
|
+
"swagger-ui-express": "^4.3.0",
|
|
107
|
+
"typescript": "4.3.2",
|
|
108
|
+
"yamljs": "^0.3.0"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
* About File:
|
|
4
|
+
it defines the structure of the deployments (when we do inspect for example), it also defines the structure of metacall.json
|
|
5
|
+
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type DeployStatus = 'create' | 'ready' | 'fail';
|
|
9
|
+
|
|
10
|
+
export enum LogType {
|
|
11
|
+
Job = 'job',
|
|
12
|
+
Deploy = 'deploy'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type LanguageId =
|
|
16
|
+
| 'node'
|
|
17
|
+
| 'ts'
|
|
18
|
+
| 'rb'
|
|
19
|
+
| 'py'
|
|
20
|
+
| 'cs'
|
|
21
|
+
// | 'wasm'
|
|
22
|
+
// | 'java'
|
|
23
|
+
// | 'c'
|
|
24
|
+
| 'cob'
|
|
25
|
+
| 'file'
|
|
26
|
+
| 'rpc';
|
|
27
|
+
|
|
28
|
+
enum ValueId {
|
|
29
|
+
METACALL_BOOL = 0,
|
|
30
|
+
METACALL_CHAR = 1,
|
|
31
|
+
METACALL_SHORT = 2,
|
|
32
|
+
METACALL_INT = 3,
|
|
33
|
+
METACALL_LONG = 4,
|
|
34
|
+
METACALL_FLOAT = 5,
|
|
35
|
+
METACALL_DOUBLE = 6,
|
|
36
|
+
METACALL_STRING = 7,
|
|
37
|
+
METACALL_BUFFER = 8,
|
|
38
|
+
METACALL_ARRAY = 9,
|
|
39
|
+
METACALL_MAP = 10,
|
|
40
|
+
METACALL_PTR = 11,
|
|
41
|
+
METACALL_FUTURE = 12,
|
|
42
|
+
METACALL_FUNCTION = 13,
|
|
43
|
+
METACALL_NULL = 14,
|
|
44
|
+
METACALL_CLASS = 15,
|
|
45
|
+
METACALL_OBJECT = 16,
|
|
46
|
+
|
|
47
|
+
METACALL_SIZE,
|
|
48
|
+
METACALL_INVALID
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface Type {
|
|
52
|
+
name: string;
|
|
53
|
+
id: ValueId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface Return {
|
|
57
|
+
type: Type;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface Argument {
|
|
61
|
+
name: string;
|
|
62
|
+
type: Type;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface Signature {
|
|
66
|
+
ret: Return;
|
|
67
|
+
args: Argument[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface Func {
|
|
71
|
+
name: string;
|
|
72
|
+
signature: Signature;
|
|
73
|
+
async: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// TODO
|
|
77
|
+
/*
|
|
78
|
+
interface Class {
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface Object {
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
interface Scope {
|
|
88
|
+
name: string;
|
|
89
|
+
funcs: Func[];
|
|
90
|
+
classes: string[]; // TODO: Class[];
|
|
91
|
+
objects: string[]; // TODO: Object[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface Handle {
|
|
95
|
+
name: string;
|
|
96
|
+
scope: Scope;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface Deployment {
|
|
100
|
+
status: DeployStatus;
|
|
101
|
+
prefix: string;
|
|
102
|
+
suffix: string;
|
|
103
|
+
version: string;
|
|
104
|
+
packages: Record<LanguageId, Handle[]>;
|
|
105
|
+
ports: number[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface Create {
|
|
109
|
+
suffix: string;
|
|
110
|
+
prefix: string;
|
|
111
|
+
version: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export type MetaCallJSON = {
|
|
115
|
+
language_id: LanguageId;
|
|
116
|
+
path: string;
|
|
117
|
+
scripts: string[];
|
|
118
|
+
};
|
package/src/language.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
* About File:
|
|
4
|
+
this is already documented but it defines the languages supported, extensions, runners, coloring, etc
|
|
5
|
+
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { LanguageId } from './deployment';
|
|
9
|
+
|
|
10
|
+
interface Language {
|
|
11
|
+
tag: string; // Tag which corresponds to language_id in metacall.json
|
|
12
|
+
displayName: string; // Name for displaying the language
|
|
13
|
+
hexColor: string; // Color for displaying the language related things
|
|
14
|
+
fileExtRegex: RegExp; // Regex for selecting the metacall.json scripts field
|
|
15
|
+
runnerName?: string; // Id of the runner
|
|
16
|
+
runnerFilesRegexes: RegExp[]; // Regex for generating the runners list
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const Languages: Record<LanguageId, Language> = {
|
|
20
|
+
cs: {
|
|
21
|
+
tag: 'cs',
|
|
22
|
+
displayName: 'C#',
|
|
23
|
+
hexColor: '#953dac',
|
|
24
|
+
fileExtRegex: /^cs$/,
|
|
25
|
+
runnerName: 'csharp',
|
|
26
|
+
runnerFilesRegexes: [/^project\.json$/, /\.csproj$/]
|
|
27
|
+
},
|
|
28
|
+
py: {
|
|
29
|
+
tag: 'py',
|
|
30
|
+
displayName: 'Python',
|
|
31
|
+
hexColor: '#ffd43b',
|
|
32
|
+
fileExtRegex: /^py$/,
|
|
33
|
+
runnerName: 'python',
|
|
34
|
+
runnerFilesRegexes: [/^requirements\.txt$/]
|
|
35
|
+
},
|
|
36
|
+
rb: {
|
|
37
|
+
tag: 'rb',
|
|
38
|
+
displayName: 'Ruby',
|
|
39
|
+
hexColor: '#e53935',
|
|
40
|
+
fileExtRegex: /^rb$/,
|
|
41
|
+
runnerName: 'ruby',
|
|
42
|
+
runnerFilesRegexes: [/^Gemfile$/]
|
|
43
|
+
},
|
|
44
|
+
node: {
|
|
45
|
+
tag: 'node',
|
|
46
|
+
displayName: 'NodeJS',
|
|
47
|
+
hexColor: '#3c873a',
|
|
48
|
+
fileExtRegex: /^js$/,
|
|
49
|
+
runnerName: 'nodejs',
|
|
50
|
+
runnerFilesRegexes: [/^package\.json$/]
|
|
51
|
+
},
|
|
52
|
+
ts: {
|
|
53
|
+
tag: 'ts',
|
|
54
|
+
displayName: 'TypeScript',
|
|
55
|
+
hexColor: '#007acc',
|
|
56
|
+
fileExtRegex: /^(ts|tsx)$/,
|
|
57
|
+
runnerName: 'nodejs',
|
|
58
|
+
runnerFilesRegexes: [/^package\.json$/] // TODO: Use tsconfig instead?
|
|
59
|
+
},
|
|
60
|
+
file: {
|
|
61
|
+
tag: 'file',
|
|
62
|
+
displayName: 'Static Files',
|
|
63
|
+
hexColor: '#de5500',
|
|
64
|
+
fileExtRegex: /^\w+$/,
|
|
65
|
+
runnerName: undefined, // File has no runner (yet?)
|
|
66
|
+
runnerFilesRegexes: [] // File has no runner files (yet?)
|
|
67
|
+
},
|
|
68
|
+
cob: {
|
|
69
|
+
tag: 'cob',
|
|
70
|
+
displayName: 'Cobol',
|
|
71
|
+
hexColor: '#01325a',
|
|
72
|
+
fileExtRegex: /^(cob|cbl|cbl)$/,
|
|
73
|
+
runnerName: undefined, // Cobol has no runner (yet?)
|
|
74
|
+
runnerFilesRegexes: [] // Cobol has no runner files (yet?)
|
|
75
|
+
},
|
|
76
|
+
rpc: {
|
|
77
|
+
tag: 'rpc',
|
|
78
|
+
displayName: 'RPC',
|
|
79
|
+
hexColor: '#0f564d',
|
|
80
|
+
fileExtRegex: /^rpc$/,
|
|
81
|
+
runnerName: undefined, // RPC has no runner (yet?)
|
|
82
|
+
runnerFilesRegexes: [] // RPC has no runner files (yet?)
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const DisplayNameToLanguageId: Record<string, LanguageId> = Object.keys(
|
|
87
|
+
Languages
|
|
88
|
+
).reduce(
|
|
89
|
+
(obj, lang) =>
|
|
90
|
+
Object.assign(obj, {
|
|
91
|
+
[Languages[lang as LanguageId].displayName]: lang
|
|
92
|
+
}),
|
|
93
|
+
{}
|
|
94
|
+
);
|
package/src/login.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
|
|
3
|
+
interface Request {
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
'g-recaptcha-response'?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default (
|
|
10
|
+
email: string,
|
|
11
|
+
password: string,
|
|
12
|
+
baseURL: string
|
|
13
|
+
): Promise<string> => {
|
|
14
|
+
const request: Request = {
|
|
15
|
+
email,
|
|
16
|
+
password
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (!baseURL.includes('localhost'))
|
|
20
|
+
request['g-recaptcha-response'] = 'empty'; //TODO: Review the captcha
|
|
21
|
+
|
|
22
|
+
return axios
|
|
23
|
+
.post<string>(baseURL + '/login', request, {
|
|
24
|
+
headers: {
|
|
25
|
+
Accept: 'application/json, text/plain, */*',
|
|
26
|
+
Host: baseURL.split('//')[1],
|
|
27
|
+
Origin: baseURL
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.then(res => res.data);
|
|
31
|
+
};
|
package/src/package.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
* About File:
|
|
4
|
+
|
|
5
|
+
defines a package and its routines, a package is just a metacall.json with some extra details, for example, the runners needed to build a it (for example, if we find a requirements.txt then it means we need to run the python installer pip, so the python runner is needed)
|
|
6
|
+
|
|
7
|
+
it includes ignore files (like .gitignore), it is able to list all files in a path and classify them depending on what loader is the correct for each file extension
|
|
8
|
+
|
|
9
|
+
generatePackage is an exported function that given a path it generates all the information needed, for example, what runners are needed, what metacall-*.json are generated (depending on file extension) and the list of files that will be in that package (excluding the ones in gitignore)
|
|
10
|
+
|
|
11
|
+
generateJsonsFromFiles is similar but it is more fine grained, it uses a list of files and returns what are the metacall-*.json generated from them
|
|
12
|
+
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import walk from 'ignore-walk';
|
|
16
|
+
import { basename, extname } from 'path';
|
|
17
|
+
import { LanguageId, MetaCallJSON } from './deployment';
|
|
18
|
+
import { Languages } from './language';
|
|
19
|
+
|
|
20
|
+
export const findFilesPath = async (
|
|
21
|
+
path: string = process.cwd(),
|
|
22
|
+
ignoreFiles: string[] = ['.gitignore']
|
|
23
|
+
): Promise<string[]> =>
|
|
24
|
+
(
|
|
25
|
+
await walk({
|
|
26
|
+
path,
|
|
27
|
+
ignoreFiles,
|
|
28
|
+
includeEmpty: false,
|
|
29
|
+
follow: true
|
|
30
|
+
})
|
|
31
|
+
).filter(x => !x.startsWith('.git'));
|
|
32
|
+
|
|
33
|
+
const pathIsMetaCallJson = (path: string): boolean =>
|
|
34
|
+
!!/^metacall(-.+)?\.json$/.exec(basename(path));
|
|
35
|
+
|
|
36
|
+
export const findMetaCallJsons = (files: string[]): string[] =>
|
|
37
|
+
files.filter(pathIsMetaCallJson);
|
|
38
|
+
|
|
39
|
+
export const findRunners = (files: string[]): Set<string> => {
|
|
40
|
+
const runners: Set<string> = new Set<string>();
|
|
41
|
+
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
const fileName = basename(file);
|
|
44
|
+
for (const langId of Object.keys(Languages)) {
|
|
45
|
+
const lang = Languages[langId as LanguageId];
|
|
46
|
+
for (const re of lang.runnerFilesRegexes) {
|
|
47
|
+
if (re.exec(fileName) && lang.runnerName) {
|
|
48
|
+
runners.add(lang.runnerName);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return runners;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export enum PackageError {
|
|
58
|
+
Empty = 'No files found in the current folder',
|
|
59
|
+
JsonNotFound = 'No metacall.json found in the current folder',
|
|
60
|
+
None = 'Package correctly generated'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface PackageDescriptor {
|
|
64
|
+
error: PackageError;
|
|
65
|
+
files: string[];
|
|
66
|
+
jsons: string[];
|
|
67
|
+
runners: string[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const NullPackage: PackageDescriptor = {
|
|
71
|
+
error: PackageError.None,
|
|
72
|
+
files: [],
|
|
73
|
+
jsons: [],
|
|
74
|
+
runners: []
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const generatePackage = async (
|
|
78
|
+
path: string = process.cwd()
|
|
79
|
+
): Promise<PackageDescriptor> => {
|
|
80
|
+
const files = await findFilesPath(path);
|
|
81
|
+
|
|
82
|
+
if (files.length === 0) {
|
|
83
|
+
return { ...NullPackage, error: PackageError.Empty };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const jsons = findMetaCallJsons(files);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
error:
|
|
90
|
+
jsons.length === 0 ? PackageError.JsonNotFound : PackageError.None,
|
|
91
|
+
files,
|
|
92
|
+
jsons,
|
|
93
|
+
runners: Array.from(findRunners(files))
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const getExtension = (file: string) => {
|
|
98
|
+
const ext = extname(file || '').split('.');
|
|
99
|
+
return ext[ext.length - 1];
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const matchFilesByLanguage = (lang: LanguageId, files: string[]): string[] =>
|
|
103
|
+
files.reduce(
|
|
104
|
+
(arr: string[], file: string) =>
|
|
105
|
+
Languages[lang].fileExtRegex.exec(
|
|
106
|
+
getExtension(file) || basename(file)
|
|
107
|
+
)
|
|
108
|
+
? [...arr, file]
|
|
109
|
+
: arr,
|
|
110
|
+
[]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
export const generateJsonsFromFiles = (files: string[]): MetaCallJSON[] =>
|
|
114
|
+
(Object.keys(Languages) as LanguageId[]).reduce<MetaCallJSON[]>(
|
|
115
|
+
(jsons, lang) => {
|
|
116
|
+
const scripts = matchFilesByLanguage(lang, files);
|
|
117
|
+
|
|
118
|
+
if (scripts.length === 0) {
|
|
119
|
+
return jsons;
|
|
120
|
+
} else {
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
language_id: lang,
|
|
124
|
+
path: '.',
|
|
125
|
+
scripts
|
|
126
|
+
} as MetaCallJSON,
|
|
127
|
+
...jsons
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
[]
|
|
132
|
+
);
|