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