@aloma.io/integration-sdk 3.0.2 → 3.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.
package/README.md CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  ## Creating a new Connector
4
4
 
5
- With the aloma integration SDK cli you can simply create a new connector via `npx @aloma.io/integration-sdk create connectorName --connector-id 1234`.
5
+ With the aloma integration SDK cli you can simply create a new connector via `npx @aloma.io/integration-sdk@latest create connectorName --connector-id 1234`.
@@ -1,4 +1,4 @@
1
- import RuntimeContext from './runtime-context.mjs';
1
+ import RuntimeContext from "./runtime-context.mjs";
2
2
  export declare class Builder {
3
3
  private data;
4
4
  config(arg: any): Builder;
@@ -1,8 +1,8 @@
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';
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
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
7
  const notEmpty = (what, name) => {
8
8
  if (!what?.trim())
@@ -10,7 +10,9 @@ const notEmpty = (what, name) => {
10
10
  return what;
11
11
  };
12
12
  export class Builder {
13
- data = { controller: './build/controller/.controller-for-types.mts' };
13
+ data = {
14
+ controller: "./build/controller/.controller-for-types.mts",
15
+ };
14
16
  config(arg) {
15
17
  this.data.config = arg;
16
18
  return this;
@@ -27,17 +29,19 @@ export class Builder {
27
29
  await this.parsePackageJson();
28
30
  await this.discoverTypes();
29
31
  // @ts-ignore
30
- const Controller = (await import(__dirname + '/../../../../../build/controller/index.mjs')).default;
32
+ const Controller = (await import(__dirname + "/../../../../../build/controller/index.mjs")).default;
31
33
  return new RuntimeContext(new Controller(), this.data);
32
34
  }
33
35
  async parsePackageJson() {
34
36
  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');
37
+ const packageJson = JSON.parse(fs.readFileSync(__dirname + "/../../../../../package.json", {
38
+ encoding: "utf-8",
39
+ }));
40
+ notEmpty((data.id = packageJson.connectorId), "id");
41
+ notEmpty((data.version = packageJson.version), "version");
38
42
  }
39
43
  async discoverTypes() {
40
- notEmpty(this.data.controller, 'controller');
44
+ notEmpty(this.data.controller, "controller");
41
45
  const content = fs.readFileSync(this.data.controller);
42
46
  const { text, methods } = parseTypes(this.data.controller);
43
47
  this.data.types = text;
@@ -1,4 +1,4 @@
1
- import { AbstractController } from '../controller/index.mjs';
1
+ import { AbstractController } from "../controller/index.mjs";
2
2
  export default class RuntimeContext {
3
3
  private controller;
4
4
  private data;
@@ -1,5 +1,5 @@
1
- import { AbstractController } from '../controller/index.mjs';
2
- import { Connector } from '../internal/index.cjs';
1
+ import { AbstractController } from "../controller/index.mjs";
2
+ import { Connector } from "../internal/index.cjs";
3
3
  export default class RuntimeContext {
4
4
  controller;
5
5
  data;
@@ -10,7 +10,7 @@ export default class RuntimeContext {
10
10
  async start() {
11
11
  const controller = this.controller;
12
12
  if (!(controller instanceof AbstractController))
13
- throw new Error('the controller needs to extend AbstractController');
13
+ throw new Error("the controller needs to extend AbstractController");
14
14
  const data = this.data;
15
15
  const connector = new Connector({
16
16
  id: data.id,
@@ -19,7 +19,12 @@ export default class RuntimeContext {
19
19
  });
20
20
  const configuration = connector.configure().config(data.config || {});
21
21
  const resolvers = {};
22
- const methods = [...data.methods, '__endpoint', '__configQuery', '__default'];
22
+ const methods = [
23
+ ...data.methods,
24
+ "__endpoint",
25
+ "__configQuery",
26
+ "__default",
27
+ ];
23
28
  methods.forEach((method) => {
24
29
  resolvers[method] = async (args) => {
25
30
  if (!methods.includes(method))
@@ -27,9 +32,7 @@ export default class RuntimeContext {
27
32
  return controller[method](args);
28
33
  };
29
34
  });
30
- configuration
31
- .types(data.types)
32
- .resolvers(resolvers);
35
+ configuration.types(data.types).resolvers(resolvers);
33
36
  if (data.options?.endpoint?.enabled) {
34
37
  configuration.endpoint((arg) => controller.__endpoint(arg));
35
38
  }
@@ -1,19 +1,19 @@
1
- import { parseFromFiles } from '@ts-ast-parser/core';
1
+ import { parseFromFiles } from "@ts-ast-parser/core";
2
2
  const transform = (meta) => {
3
3
  if (!meta?.length)
4
- throw new Error('metadata is empty');
4
+ throw new Error("metadata is empty");
5
5
  meta = meta[0];
6
6
  if (meta.getDeclarations()?.length !== 1) {
7
- throw new Error('connector file needs to export default class');
7
+ throw new Error("connector file needs to export default class");
8
8
  }
9
9
  const methods = {};
10
10
  const decl = meta.getDeclarations()[0];
11
11
  const members = decl.getMethods().filter((member) => {
12
12
  return !(member.isStatic() ||
13
13
  member.isInherited() ||
14
- member.getKind() !== 'Method' ||
15
- member.getModifier() !== 'public' ||
16
- member.getName().startsWith('_'));
14
+ member.getKind() !== "Method" ||
15
+ member.getModifier() !== "public" ||
16
+ member.getName().startsWith("_"));
17
17
  });
18
18
  const text = members
19
19
  .map((member) => {
@@ -22,13 +22,13 @@ const transform = (meta) => {
22
22
  .getSignatures()
23
23
  .map((sig) => {
24
24
  const docs = sig.getJSDoc().serialize() || [];
25
- const desc = docs.find((what) => what.kind === 'description')?.value;
25
+ const desc = docs.find((what) => what.kind === "description")?.value;
26
26
  const paramDocs = docs
27
- .filter((what) => what.kind === 'param')
27
+ .filter((what) => what.kind === "param")
28
28
  .map((what) => {
29
- return ` * @param {${what.value.type}} ${what.value.name} - ${what.value.description || ''}`;
29
+ return ` * @param {${what.value.type}} ${what.value.name} - ${what.value.description || ""}`;
30
30
  })
31
- .join('\n') || ' *';
31
+ .join("\n") || " *";
32
32
  const params = sig
33
33
  .getParameters()
34
34
  .map((param) => {
@@ -38,32 +38,32 @@ const transform = (meta) => {
38
38
  const tmp = param
39
39
  .getNamedElements()
40
40
  .map((p) => {
41
- const defaultVal = p.default != null ? ' = ' + p.default : '';
41
+ const defaultVal = p.default != null ? " = " + p.default : "";
42
42
  return `${p.name}${defaultVal}`;
43
43
  })
44
- .join('; ');
44
+ .join("; ");
45
45
  return `{${tmp}}: ${param.getType().text}`;
46
46
  case false:
47
47
  return `${param.getName()}: ${param.getType().text}`;
48
48
  }
49
49
  })
50
- .join(', ');
50
+ .join(", ");
51
51
  const retVal = sig
52
52
  .getReturnType()
53
- .type.text.replace(/^Promise</, '')
54
- .replace(/>$/, '');
53
+ .type.text.replace(/^Promise</, "")
54
+ .replace(/>$/, "");
55
55
  return `
56
56
  /**
57
- * ${desc || ''}
57
+ * ${desc || ""}
58
58
  *
59
59
  ${paramDocs}
60
60
  **/
61
61
  declare function ${member.getName()}(${params}): ${retVal};
62
62
  `;
63
63
  })
64
- .join('\n');
64
+ .join("\n");
65
65
  })
66
- .join('');
66
+ .join("");
67
67
  return { text, methods: Object.keys(methods) };
68
68
  };
69
69
  export default (path) => {
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/cli.mjs ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import fs from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import path from "node:path";
6
+ import JWE from './internal/util/jwe/index.cjs';
7
+ import util from 'node:util';
8
+ import ChildProcess from 'node:child_process';
9
+ const exec = util.promisify(ChildProcess.exec);
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const files = [
12
+ { name: "index.mts", dir: "src/controller" },
13
+ { name: "index.mts", dir: "src" },
14
+ { name: "package.json", dir: "" },
15
+ { name: "Containerfile", dir: "" },
16
+ { name: "entrypoint.sh", dir: "" },
17
+ { name: "tsconfig.json", dir: "" },
18
+ ];
19
+ const extract = ({ target, name, connectorId }) => {
20
+ const source = `${__dirname}/../template/connector/`;
21
+ if (!fs.existsSync(source)) {
22
+ throw new Error(`source ${source} does not exist`);
23
+ }
24
+ files.forEach(({ name, dir }) => {
25
+ if (dir) {
26
+ fs.mkdirSync(`${target}/${dir}`, { recursive: true });
27
+ }
28
+ const content = fs.readFileSync(`${source}/${dir}/${name}`, {
29
+ encoding: "utf-8",
30
+ });
31
+ fs.writeFileSync(`${target}/${dir}/${name}`, content);
32
+ });
33
+ const content = JSON.parse(fs.readFileSync(`${target}/package.json`, { encoding: "utf-8" }));
34
+ content.name = name;
35
+ content.connectorId = connectorId;
36
+ fs.writeFileSync(`${target}/package.json`, JSON.stringify(content, null, 2));
37
+ fs.writeFileSync(`${target}/.gitignore`, `.DS_Store
38
+ node_modules
39
+ build
40
+ .env`);
41
+ };
42
+ const generateKeys = async ({ target }) => {
43
+ const jwe = new JWE({});
44
+ await jwe.newPair();
45
+ const priv = await jwe.exportPrivateAsBase64();
46
+ const pub = await jwe.exportPublicAsBase64();
47
+ const content = `REGISTRATION_TOKEN=
48
+ PRIVATE_KEY=${priv}
49
+ PUBLIC_KEY=${pub}
50
+ `;
51
+ fs.writeFileSync(`${target}/.env`, content);
52
+ };
53
+ const program = new Command();
54
+ program
55
+ .name("npx @aloma.io/integration-sdk")
56
+ .description("aloma.io integration sdk")
57
+ .version("0.8.0")
58
+ .showHelpAfterError();
59
+ program
60
+ .command("create")
61
+ .description("Create a new connector project")
62
+ .argument("<name>", "name of the project")
63
+ .requiredOption("--connector-id <id>", "id of the connector")
64
+ .action(async (name, options) => {
65
+ name = name.replace(/[\/\.]/gi, "");
66
+ if (!name)
67
+ throw new Error("name is empty");
68
+ const target = `${process.cwd()}/${name}`;
69
+ fs.mkdirSync(target);
70
+ console.log('Creating connector ...');
71
+ extract({ ...options, target, name });
72
+ console.log('Generating keys ...');
73
+ await generateKeys({ target });
74
+ console.log('Installing dependencies ...');
75
+ await exec(`cd ${target}; yarn`);
76
+ console.log('Building ...');
77
+ await exec(`cd ${target}; yarn build`);
78
+ console.log(`
79
+ Success!
80
+
81
+ 1.) Add the connector to a workspace
82
+ 2.) Edit ./${name}/.env and insert the registration token
83
+ 3.) Start the connector with cd ./${name}/; yarn start`);
84
+ });
85
+ program
86
+ .command("build")
87
+ .description("Build the current connector project")
88
+ .action(async (str, options) => {
89
+ const { stdout, stderr } = await exec(`rm -rf build; mkdir -p build/controller; cp ./src/controller/index.mts ./build/controller/.controller-for-types.mts;`);
90
+ if (stdout)
91
+ console.log(stdout);
92
+ });
93
+ program.parse();
@@ -7,19 +7,19 @@ export class AbstractController {
7
7
  return Promise.resolve({});
8
8
  }
9
9
  fallback(arg) {
10
- throw new Error('method not found');
10
+ throw new Error("method not found");
11
11
  }
12
12
  endpoint(arg) {
13
- throw new Error('method not found');
13
+ throw new Error("method not found");
14
14
  }
15
15
  async newTask(name, data) {
16
- throw new Error('not implemented');
16
+ throw new Error("not implemented");
17
17
  }
18
18
  getClient({ baseUrl }) {
19
- throw new Error('not implemented');
19
+ throw new Error("not implemented");
20
20
  }
21
21
  async updateTask(name, data) {
22
- throw new Error('not implemented');
22
+ throw new Error("not implemented");
23
23
  }
24
24
  async __endpoint(arg) {
25
25
  return this.endpoint(arg);
package/build/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './builder/index.mjs';
2
- export * from './controller/index.mjs';
1
+ export * from "./builder/index.mjs";
2
+ export * from "./controller/index.mjs";
package/build/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export * from './builder/index.mjs';
2
- export * from './controller/index.mjs';
1
+ export * from "./builder/index.mjs";
2
+ export * from "./controller/index.mjs";
@@ -14,26 +14,26 @@ class Dispatcher {
14
14
  oauth: true,
15
15
  fields: {
16
16
  oauthResult: {
17
- name: 'OAuth Result',
18
- placeholder: 'will be set by finishing the oauth flow',
19
- type: 'managed',
17
+ name: "OAuth Result",
18
+ placeholder: "will be set by finishing the oauth flow",
19
+ type: "managed",
20
20
  },
21
21
  },
22
22
  });
23
23
  return this;
24
24
  }
25
25
  if (!arg.authorizationURL)
26
- throw new Error('need a authorizationURL');
26
+ throw new Error("need a authorizationURL");
27
27
  if (!arg.tokenURL && !arg.finishOAuth)
28
- throw new Error('need a tokenURL or finishOAuth()');
28
+ throw new Error("need a tokenURL or finishOAuth()");
29
29
  this._oauth = { ...arg };
30
30
  this.config({
31
31
  oauth: true,
32
32
  fields: {
33
33
  oauthResult: {
34
- name: 'OAuth Result',
35
- placeholder: 'will be set by finishing the oauth flow',
36
- type: 'managed',
34
+ name: "OAuth Result",
35
+ placeholder: "will be set by finishing the oauth flow",
36
+ type: "managed",
37
37
  },
38
38
  },
39
39
  });
@@ -41,14 +41,14 @@ class Dispatcher {
41
41
  this.config({
42
42
  fields: {
43
43
  clientId: {
44
- name: 'OAuth Client ID',
45
- placeholder: 'e.g. 1234',
46
- type: 'line',
44
+ name: "OAuth Client ID",
45
+ placeholder: "e.g. 1234",
46
+ type: "line",
47
47
  },
48
48
  clientSecret: {
49
- name: 'OAuth Client Secret',
50
- placeholder: 'e.g. axd5xde',
51
- type: 'line',
49
+ name: "OAuth Client Secret",
50
+ placeholder: "e.g. axd5xde",
51
+ type: "line",
52
52
  },
53
53
  },
54
54
  });
@@ -72,9 +72,9 @@ class Dispatcher {
72
72
  this.config({
73
73
  fields: {
74
74
  _endpointToken: {
75
- name: 'Endpoint Token (set to enable the endpoint)',
76
- placeholder: 'e.g. 1234',
77
- type: 'line',
75
+ name: "Endpoint Token (set to enable the endpoint)",
76
+ placeholder: "e.g. 1234",
77
+ type: "line",
78
78
  plain: true,
79
79
  optional: true,
80
80
  },
@@ -84,19 +84,19 @@ class Dispatcher {
84
84
  return this;
85
85
  }
86
86
  startOAuth() {
87
- throw new Error('oauth not configured');
87
+ throw new Error("oauth not configured");
88
88
  }
89
89
  finishOAuth() {
90
- throw new Error('oauth not configured');
90
+ throw new Error("oauth not configured");
91
91
  }
92
92
  build() {
93
93
  if (!this._types || !this._resolvers)
94
- throw new Error('missing types or resolvers');
94
+ throw new Error("missing types or resolvers");
95
95
  var local = this;
96
96
  const _resolvers = { ...this._resolvers };
97
97
  const main = this._main || (() => { });
98
98
  const start = async (transport) => {
99
- console.log('starting ...');
99
+ console.log("starting ...");
100
100
  await main(transport);
101
101
  };
102
102
  const resolveMethod = (query) => {
@@ -110,33 +110,44 @@ class Dispatcher {
110
110
  if (!Array.isArray(query))
111
111
  query = [query];
112
112
  query = query
113
- .filter((what) => !!what?.trim() && !['constructor', '__proto__', 'toString', 'toSource', 'prototype'].includes(what))
113
+ .filter((what) => !!what?.trim() &&
114
+ ![
115
+ "constructor",
116
+ "__proto__",
117
+ "toString",
118
+ "toSource",
119
+ "prototype",
120
+ ].includes(what))
114
121
  .slice(0, 20);
115
122
  const method = resolveMethod(query);
116
123
  if (!method && !_resolvers.__default)
117
124
  throw new Error(`${query} not found`);
118
- return method ? method(variables) : _resolvers.__default(variables ? { ...variables, __method: query } : variables);
125
+ return method
126
+ ? method(variables)
127
+ : _resolvers.__default(variables ? { ...variables, __method: query } : variables);
119
128
  };
120
129
  const introspect = () => local._types;
121
130
  const configSchema = () => local._config;
122
131
  const processPacket = async (packet) => {
123
132
  switch (packet.method()) {
124
- case 'connector.introspect':
133
+ case "connector.introspect":
125
134
  const intro = await introspect({});
126
135
  return { configSchema: local._config, introspect: intro };
127
- case 'connector.start-oauth':
136
+ case "connector.start-oauth":
128
137
  return await local.startOAuth(packet.args());
129
- case 'connector.finish-oauth':
138
+ case "connector.finish-oauth":
130
139
  return await local.finishOAuth(packet.args());
131
- case 'connector.query':
140
+ case "connector.query":
132
141
  const ret = await execute(packet.args());
133
- return typeof ret === 'object' && !Array.isArray(ret) ? ret : { [packet.args().query]: ret };
134
- case 'connector.set-config':
142
+ return typeof ret === "object" && !Array.isArray(ret)
143
+ ? ret
144
+ : { [packet.args().query]: ret };
145
+ case "connector.set-config":
135
146
  await local.onConfig({ ...packet.args().secrets });
136
147
  return;
137
148
  }
138
149
  console.dir(packet, { depth: null });
139
- throw new Error('cannot handle packet');
150
+ throw new Error("cannot handle packet");
140
151
  };
141
152
  return {
142
153
  introspect,