@aloma.io/integration-sdk 3.0.0-4

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 (56) hide show
  1. package/build/builder/index.d.mts +11 -0
  2. package/build/builder/index.mjs +51 -0
  3. package/build/builder/runtime-context.d.mts +7 -0
  4. package/build/builder/runtime-context.mjs +42 -0
  5. package/build/builder/transform/index.d.mts +5 -0
  6. package/build/builder/transform/index.mjs +72 -0
  7. package/build/controller/index.d.mts +19 -0
  8. package/build/controller/index.mjs +44 -0
  9. package/build/index.d.mts +2 -0
  10. package/build/index.mjs +2 -0
  11. package/build/internal/dispatcher/index.cjs +151 -0
  12. package/build/internal/dispatcher/index.d.cts +32 -0
  13. package/build/internal/index.cjs +461 -0
  14. package/build/internal/index.d.cts +14 -0
  15. package/build/internal/util/jwe/cli.cjs +13 -0
  16. package/build/internal/util/jwe/cli.d.cts +1 -0
  17. package/build/internal/util/jwe/index.cjs +57 -0
  18. package/build/internal/util/jwe/index.d.cts +32 -0
  19. package/build/internal/websocket/config.cjs +79 -0
  20. package/build/internal/websocket/config.d.cts +41 -0
  21. package/build/internal/websocket/connection/constants.cjs +21 -0
  22. package/build/internal/websocket/connection/constants.d.cts +2 -0
  23. package/build/internal/websocket/connection/index.cjs +53 -0
  24. package/build/internal/websocket/connection/index.d.cts +11 -0
  25. package/build/internal/websocket/connection/registration.cjs +31 -0
  26. package/build/internal/websocket/connection/registration.d.cts +5 -0
  27. package/build/internal/websocket/index.cjs +41 -0
  28. package/build/internal/websocket/index.d.cts +16 -0
  29. package/build/internal/websocket/transport/durable.cjs +61 -0
  30. package/build/internal/websocket/transport/durable.d.cts +20 -0
  31. package/build/internal/websocket/transport/index.cjs +148 -0
  32. package/build/internal/websocket/transport/index.d.cts +37 -0
  33. package/build/internal/websocket/transport/packet.cjs +44 -0
  34. package/build/internal/websocket/transport/packet.d.cts +16 -0
  35. package/build/internal/websocket/transport/processor.cjs +58 -0
  36. package/build/internal/websocket/transport/processor.d.cts +11 -0
  37. package/package.json +44 -0
  38. package/src/builder/index.mts +70 -0
  39. package/src/builder/runtime-context.mts +45 -0
  40. package/src/builder/transform/index.mts +89 -0
  41. package/src/controller/index.mts +58 -0
  42. package/src/index.mts +2 -0
  43. package/src/internal/dispatcher/index.cjs +189 -0
  44. package/src/internal/index.cjs +547 -0
  45. package/src/internal/util/jwe/cli.cjs +14 -0
  46. package/src/internal/util/jwe/index.cjs +69 -0
  47. package/src/internal/websocket/config.cjs +103 -0
  48. package/src/internal/websocket/connection/constants.cjs +25 -0
  49. package/src/internal/websocket/connection/index.cjs +70 -0
  50. package/src/internal/websocket/connection/registration.cjs +40 -0
  51. package/src/internal/websocket/index.cjs +46 -0
  52. package/src/internal/websocket/transport/durable.cjs +71 -0
  53. package/src/internal/websocket/transport/index.cjs +183 -0
  54. package/src/internal/websocket/transport/packet.cjs +54 -0
  55. package/src/internal/websocket/transport/processor.cjs +66 -0
  56. package/tsconfig.json +27 -0
@@ -0,0 +1,70 @@
1
+ import fs from 'fs';
2
+ import parseTypes from './transform/index.mjs';
3
+ import RuntimeContext from './runtime-context.mjs';
4
+ import {fileURLToPath} from 'node:url';
5
+ import path from 'node:path';
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ const notEmpty = (what, name) => {
10
+ if (!what?.trim()) throw new Error(`${name} cannot be empty`);
11
+
12
+ return what;
13
+ };
14
+
15
+ export class Builder {
16
+ private data: any = {controller: './build/controller/.controller-for-types.mts'};
17
+
18
+ id(what: string): Builder {
19
+ this.data.id = notEmpty(what, 'id');
20
+
21
+ return this;
22
+ }
23
+
24
+ version(what: string): Builder {
25
+ this.data.version = notEmpty(what, 'version');
26
+
27
+ return this;
28
+ }
29
+
30
+ config(arg: any): Builder {
31
+ return this;
32
+ }
33
+
34
+ options(arg: any): Builder {
35
+ return this;
36
+ }
37
+
38
+ auth(arg: any): Builder {
39
+ return this;
40
+ }
41
+
42
+ async build(): Promise<RuntimeContext> {
43
+ const data = this.data;
44
+
45
+ notEmpty(data.id, 'id');
46
+ notEmpty(data.version, 'version');
47
+
48
+ await this.discoverTypes();
49
+
50
+ // validate config
51
+ // validate options
52
+ // validate auth
53
+
54
+ console.log('dirname', __dirname);
55
+ // @ts-ignore
56
+ const Controller = (await import(__dirname + '/../../../../../build/controller/index.mjs')).default;
57
+
58
+ return new RuntimeContext(new Controller(), this.data);
59
+ }
60
+
61
+ private async discoverTypes() {
62
+ notEmpty(this.data.controller, 'controller');
63
+
64
+ const content = fs.readFileSync(this.data.controller);
65
+ const {text, methods} = parseTypes(this.data.controller);
66
+
67
+ this.data.types = text;
68
+ this.data.methods = methods;
69
+ }
70
+ }
@@ -0,0 +1,45 @@
1
+ import {AbstractController} from '../controller/index.mjs';
2
+ import {Connector} from '../internal/index.cjs';
3
+
4
+ export default class RuntimeContext {
5
+ constructor(private controller: AbstractController, private data: any) {}
6
+
7
+ async start(): Promise<void> {
8
+ const controller = this.controller;
9
+
10
+ const connector = new Connector({
11
+ id: this.data.id,
12
+ version: this.data.version,
13
+ name: `${this.data.id}/${this.data.version}`,
14
+ });
15
+
16
+ const resolvers: any = {};
17
+ const methods: string[] = [...this.data.methods, '__endpoint', '__configQuery', '__default'];
18
+
19
+ methods.forEach((method) => {
20
+ resolvers[method] = async (args) => {
21
+ console.log('call', method, args);
22
+ if (!methods.includes(method)) throw new Error(`${method} not found`);
23
+
24
+ return controller[method](args);
25
+ };
26
+ });
27
+
28
+ console.log(this.data.types);
29
+
30
+ connector
31
+ .configure()
32
+ .types(this.data.types)
33
+ .resolvers(resolvers)
34
+ .main(async ({newTask, updateTask, config, oauth, getClient}) => {
35
+ try {
36
+ await controller._doStop();
37
+ await controller._doStart(config, oauth, newTask, updateTask, getClient);
38
+ } catch (e) {
39
+ console.log(e);
40
+ }
41
+ });
42
+
43
+ connector.run();
44
+ }
45
+ }
@@ -0,0 +1,89 @@
1
+ import {parseFromFiles} from '@ts-ast-parser/core';
2
+
3
+ const transform = (meta: any) => {
4
+ if (!meta?.length) throw new Error('metadata is empty');
5
+ meta = meta[0];
6
+
7
+ if (meta.getDeclarations()?.length !== 1) {
8
+ throw new Error('connector file needs to export default class');
9
+ }
10
+
11
+ const methods = {};
12
+ const decl = meta.getDeclarations()[0];
13
+
14
+ // todo validate getConstructors
15
+
16
+ const members = decl.getMethods().filter((member: any) => {
17
+ return !(
18
+ member.isStatic() ||
19
+ member.isInherited() ||
20
+ member.getKind() !== 'Method' ||
21
+ member.getModifier() !== 'public' ||
22
+ member.getName().startsWith('_')
23
+ );
24
+ });
25
+
26
+ const text = members
27
+ .map((member: any) => {
28
+ methods[member.getName()] = true;
29
+
30
+ return member
31
+ .getSignatures()
32
+ .map((sig: any) => {
33
+ const docs = sig.getJSDoc().serialize() || [];
34
+ const desc = docs.find((what: any) => what.kind === 'description')?.value;
35
+
36
+ const paramDocs =
37
+ docs
38
+ .filter((what: any) => what.kind === 'param')
39
+ .map((what: any) => {
40
+ return ` * @param {${what.value.type}} ${what.value.name} - ${what.value.description || ''}`;
41
+ })
42
+ .join('\n') || ' *';
43
+
44
+ const params = sig
45
+ .getParameters()
46
+ .map((param: any) => {
47
+ const serialized = param.serialize();
48
+
49
+ switch (!!param.isNamed()) {
50
+ case true:
51
+ const tmp = param
52
+ .getNamedElements()
53
+ .map((p) => {
54
+ const defaultVal = p.default != null ? ' = ' + p.default : '';
55
+
56
+ return `${p.name}${defaultVal}`;
57
+ })
58
+ .join('; ');
59
+ return `{${tmp}}: ${param.getType().text}`;
60
+ case false:
61
+ return `${param.getName()}: ${param.getType().text}`;
62
+ }
63
+ })
64
+ .join(', ');
65
+
66
+ const retVal = sig
67
+ .getReturnType()
68
+ .type.text.replace(/^Promise</, '')
69
+ .replace(/>$/, '');
70
+
71
+ return `
72
+ /**
73
+ * ${desc || ''}
74
+ *
75
+ ${paramDocs}
76
+ **/
77
+ declare function ${member.getName()}(${params}): ${retVal};
78
+ `;
79
+ })
80
+ .join('\n');
81
+ })
82
+ .join('');
83
+
84
+ return {text, methods: Object.keys(methods)};
85
+ };
86
+
87
+ export default (path: string) => {
88
+ return transform(parseFromFiles([path]));
89
+ };
@@ -0,0 +1,58 @@
1
+ export abstract class AbstractController {
2
+ protected config;
3
+ protected client;
4
+
5
+ protected async start(): Promise<void> {}
6
+
7
+ protected async stop(): Promise<void> {}
8
+
9
+ protected configQuery(arg: any): Promise<any> {
10
+ return Promise.resolve({});
11
+ }
12
+
13
+ protected fallback(arg: any): Promise<any> {
14
+ throw new Error('method not found');
15
+ }
16
+
17
+ protected endpoint(arg: any): Promise<any> {
18
+ throw new Error('method not found');
19
+ }
20
+
21
+ protected async newTask(name: string, data: any): Promise<string> {
22
+ throw new Error('not implemented');
23
+ }
24
+
25
+ protected getClient({baseUrl}: {baseUrl: string}): Promise<any> {
26
+ throw new Error('not implemented');
27
+ }
28
+
29
+ protected async updateTask(name: string, data: any): Promise<string> {
30
+ throw new Error('not implemented');
31
+ }
32
+
33
+ async __endpoint(arg: any): Promise<any | null> {
34
+ return Promise.resolve(null);
35
+ }
36
+
37
+ async __configQuery(arg: any): Promise<any | null> {
38
+ return this.configQuery(arg);
39
+ }
40
+
41
+ async __default(arg: any): Promise<any | null> {
42
+ return this.fallback(arg);
43
+ }
44
+
45
+ async _doStart(config: any, client: any, newTask: any, updateTask: any, getClient: any): Promise<void> {
46
+ this.config = config;
47
+ this.client = client;
48
+ this.newTask = newTask;
49
+ this.updateTask = updateTask;
50
+ this.getClient = getClient;
51
+
52
+ await this.start();
53
+ }
54
+
55
+ async _doStop(): Promise<void> {
56
+ await this.stop();
57
+ }
58
+ }
package/src/index.mts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './builder/index.mjs';
2
+ export * from './controller/index.mjs';
@@ -0,0 +1,189 @@
1
+ class Dispatcher {
2
+ constructor() {
3
+ this._config = {fields: {}};
4
+ }
5
+
6
+ main(what) {
7
+ this._main = what;
8
+
9
+ return this;
10
+ }
11
+
12
+ oauth(arg) {
13
+ if (arg.platformOAuth) {
14
+ this.config({
15
+ oauth: true,
16
+ fields: {
17
+ oauthResult: {
18
+ name: 'OAuth Result',
19
+ placeholder: 'will be set by finishing the oauth flow',
20
+ type: 'managed',
21
+ },
22
+ },
23
+ });
24
+
25
+ return this;
26
+ }
27
+
28
+ if (!arg.authorizationURL) throw new Error('need a authorizationURL');
29
+ if (!arg.tokenURL && !arg.finishOAuth) throw new Error('need a tokenURL or finishOAuth()');
30
+
31
+ this._oauth = {...arg};
32
+
33
+ this.config({
34
+ oauth: true,
35
+ fields: {
36
+ oauthResult: {
37
+ name: 'OAuth Result',
38
+ placeholder: 'will be set by finishing the oauth flow',
39
+ type: 'managed',
40
+ },
41
+ },
42
+ });
43
+
44
+ if (arg.configurableClient) {
45
+ this.config({
46
+ fields: {
47
+ clientId: {
48
+ name: 'OAuth Client ID',
49
+ placeholder: 'e.g. 1234',
50
+ type: 'line',
51
+ },
52
+ clientSecret: {
53
+ name: 'OAuth Client Secret',
54
+ placeholder: 'e.g. axd5xde',
55
+ type: 'line',
56
+ },
57
+ },
58
+ });
59
+ }
60
+
61
+ return this;
62
+ }
63
+
64
+ types(what) {
65
+ this._types = what;
66
+
67
+ return this;
68
+ }
69
+
70
+ config({fields, oauth}) {
71
+ this._config.oauth = this._config.oauth || oauth;
72
+ this._config.fields = {...fields, ...this._config.fields};
73
+
74
+ return this;
75
+ }
76
+
77
+ resolvers(what) {
78
+ this._resolvers = {...this._resolvers, ...what};
79
+
80
+ return this;
81
+ }
82
+
83
+ endpoint(what) {
84
+ this.config({
85
+ fields: {
86
+ _endpointToken: {
87
+ name: 'Endpoint Token (set to enable the endpoint)',
88
+ placeholder: 'e.g. 1234',
89
+ type: 'line',
90
+ plain: true,
91
+ optional: true,
92
+ },
93
+ },
94
+ });
95
+
96
+ this.resolvers({_endpoint: what});
97
+
98
+ return this;
99
+ }
100
+
101
+ startOAuth() {
102
+ throw new Error('oauth not configured');
103
+ }
104
+
105
+ finishOAuth() {
106
+ throw new Error('oauth not configured');
107
+ }
108
+
109
+ build() {
110
+ if (!this._types || !this._resolvers) throw new Error('missing types or resolvers');
111
+ var local = this;
112
+
113
+ const _resolvers = {...this._resolvers};
114
+
115
+ const main = this._main || (() => {});
116
+
117
+ const start = async (transport) => {
118
+ console.log('starting ...');
119
+ await main(transport);
120
+ };
121
+
122
+ const resolveMethod = (query) => {
123
+ let current = _resolvers;
124
+
125
+ while (query.length && current) {
126
+ current = current[query.shift()];
127
+ }
128
+
129
+ return current;
130
+ };
131
+
132
+ const execute = async ({query, variables}) => {
133
+ if (!Array.isArray(query)) query = [query];
134
+
135
+ query = query
136
+ .filter(
137
+ (what) => !!what?.trim() && !['constructor', '__proto__', 'toString', 'toSource', 'prototype'].includes(what)
138
+ )
139
+ .slice(0, 20);
140
+
141
+ const method = resolveMethod(query);
142
+ console.log('found method', query, method);
143
+ if (!method && !_resolvers.__default) throw new Error(`${query} not found`);
144
+
145
+ return method ? method(variables) : _resolvers.__default(variables ? {...variables, __method: query} : variables);
146
+ };
147
+
148
+ const introspect = () => local._types;
149
+ const configSchema = () => local._config;
150
+
151
+ const processPacket = async (packet) => {
152
+ switch (packet.method()) {
153
+ case 'connector.introspect':
154
+ const intro = await introspect({});
155
+
156
+ return {configSchema: local._config, introspect: intro};
157
+
158
+ case 'connector.start-oauth':
159
+ return await local.startOAuth(packet.args());
160
+
161
+ case 'connector.finish-oauth':
162
+ return await local.finishOAuth(packet.args());
163
+
164
+ case 'connector.query':
165
+ const ret = await execute(packet.args());
166
+
167
+ return typeof ret === 'object' && !Array.isArray(ret) ? ret : {[packet.args().query]: ret};
168
+
169
+ case 'connector.set-config':
170
+ await local.onConfig({...packet.args().secrets});
171
+
172
+ return;
173
+ }
174
+
175
+ console.dir(packet, {depth: null});
176
+ throw new Error('cannot handle packet');
177
+ };
178
+
179
+ return {
180
+ introspect,
181
+ configSchema,
182
+ execute,
183
+ processPacket,
184
+ start,
185
+ };
186
+ }
187
+ }
188
+
189
+ module.exports = {Dispatcher};