@intentic/providers 1.18.0 → 1.20.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/providers",
3
- "version": "1.18.0",
3
+ "version": "1.20.3",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,16 +33,16 @@
33
33
  "ssh2": "1.17.0",
34
34
  "tslib": "2.8.1",
35
35
  "zod": "4.4.3",
36
- "@intentic/engine": "1.18.0",
37
- "@intentic/graph": "1.18.0"
36
+ "@intentic/engine": "1.20.3",
37
+ "@intentic/graph": "1.20.3"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "24.13.2",
41
41
  "@types/ssh2": "1.15.5",
42
42
  "typescript": "5.9.3",
43
43
  "vitest": "4.1.9",
44
- "@intentic/sdk": "1.18.0",
45
- "@intentic/tsconfig": "0.0.0"
44
+ "@intentic/tsconfig": "0.0.0",
45
+ "@intentic/sdk": "1.20.3"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsc",
package/dist/app.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import type { Provider } from "@intentic/engine";
2
- import type { KomodoApi } from "./komodo-api.js";
3
- export declare const createAppProvider: (api?: KomodoApi) => Provider;
4
- //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,kBAAkB,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAmDjD,eAAO,MAAM,iBAAiB,GAAI,MAAK,SAAqB,KAAG,QAgC7D,CAAC"}
package/dist/app.js DELETED
@@ -1,72 +0,0 @@
1
- import { z } from "zod";
2
- import { gitProvider, parseInputs } from "./inputs.js";
3
- import { komodoApi } from "./komodo-api.js";
4
- const appSchema = z.object({
5
- komodoUrl: z.string(),
6
- adminUser: z.string(),
7
- adminPassword: z.string(),
8
- repoName: z.string(),
9
- gitInternalUrl: z.string(),
10
- });
11
- const parse = (inputs) => parseInputs(appSchema, inputs, "app");
12
- const SERVER = "Local";
13
- const BUILDER = "Local";
14
- const buildConfig = (parsed, builderId) => {
15
- const git = gitProvider(parsed.gitInternalUrl);
16
- return {
17
- builder_id: builderId,
18
- repo: `${parsed.adminUser}/${parsed.repoName}`,
19
- git_provider: git.domain,
20
- git_account: parsed.adminUser,
21
- git_https: git.https,
22
- };
23
- };
24
- const ensureBuilder = async (api, baseUrl, jwt) => {
25
- const find = async () => (await api.listBuilders({ baseUrl, jwt })).find((item) => item.name === BUILDER)?.id;
26
- const existing = await find();
27
- if (existing !== undefined) {
28
- return existing;
29
- }
30
- await api.createBuilder({ baseUrl, jwt, name: BUILDER, config: { type: "Server", params: { server_id: SERVER } } });
31
- const created = await find();
32
- if (created === undefined) {
33
- throw new Error("komodo Server builder was not created");
34
- }
35
- return created;
36
- };
37
- export const createAppProvider = (api = komodoApi) => ({
38
- read: async (inputs, ctx) => {
39
- if (typeof inputs["komodoUrl"] !== "string") {
40
- return undefined;
41
- }
42
- const parsed = parse(inputs);
43
- try {
44
- const jwt = await api.login({ baseUrl: parsed.komodoUrl, username: parsed.adminUser, password: parsed.adminPassword });
45
- const build = (await api.listBuilds({ baseUrl: parsed.komodoUrl, jwt })).find((item) => item.name === ctx.id);
46
- if (build === undefined) {
47
- return undefined;
48
- }
49
- return { outputs: {} };
50
- }
51
- catch (error) {
52
- ctx.log(`app "${ctx.id}": komodo not reachable yet, treating as not-yet-created: ${String(error)}`);
53
- return undefined;
54
- }
55
- },
56
- diff: () => ({ action: "noop" }),
57
- apply: async (inputs, _observed, ctx) => {
58
- const parsed = parse(inputs);
59
- const jwt = await api.login({ baseUrl: parsed.komodoUrl, username: parsed.adminUser, password: parsed.adminPassword });
60
- const builderId = await ensureBuilder(api, parsed.komodoUrl, jwt);
61
- const config = buildConfig(parsed, builderId);
62
- const existing = (await api.listBuilds({ baseUrl: parsed.komodoUrl, jwt })).find((item) => item.name === ctx.id);
63
- if (existing === undefined) {
64
- await api.createBuild({ baseUrl: parsed.komodoUrl, jwt, name: ctx.id, config });
65
- }
66
- else {
67
- await api.updateBuild({ baseUrl: parsed.komodoUrl, jwt, id: existing.id, config });
68
- }
69
- return {};
70
- },
71
- });
72
- //# sourceMappingURL=app.js.map
package/dist/app.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- import type { Provider } from "@intentic/engine";
2
- import type { ForgejoApi } from "./forgejo-api.js";
3
- export declare const createDeployHookProvider: (api?: ForgejoApi) => Provider;
4
- //# sourceMappingURL=deploy-hook.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy-hook.d.ts","sourceRoot":"","sources":["../src/deploy-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,kBAAkB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,kBAAkB,CAAC;AAyBhE,eAAO,MAAM,wBAAwB,GAAI,MAAK,UAAuB,KAAG,QAkEtE,CAAC"}
@@ -1,79 +0,0 @@
1
- import { z } from "zod";
2
- import { forgejoApi } from "./forgejo-api.js";
3
- import { parseInputs } from "./inputs.js";
4
- const deployHookSchema = z.object({
5
- forgejoUrl: z.string(),
6
- adminUser: z.string(),
7
- adminPassword: z.string(),
8
- repoName: z.string(),
9
- komodoUrl: z.string(),
10
- branch: z.string(),
11
- secret: z.string(),
12
- });
13
- const parse = (inputs) => parseInputs(deployHookSchema, inputs, "deploy-hook");
14
- const listenerUrl = (parsed) => `${parsed.komodoUrl}/listener/github/build/${parsed.repoName}`;
15
- const findHook = (hooks, url) => hooks.find((hook) => hook.config["url"] === url);
16
- export const createDeployHookProvider = (api = forgejoApi) => ({
17
- read: async (inputs, ctx) => {
18
- if (typeof inputs["forgejoUrl"] !== "string" || typeof inputs["komodoUrl"] !== "string") {
19
- return undefined;
20
- }
21
- const parsed = parse(inputs);
22
- try {
23
- const hook = findHook(await api.listHooks({
24
- baseUrl: parsed.forgejoUrl,
25
- user: parsed.adminUser,
26
- password: parsed.adminPassword,
27
- owner: parsed.adminUser,
28
- name: parsed.repoName,
29
- }), listenerUrl(parsed));
30
- if (hook === undefined) {
31
- return undefined;
32
- }
33
- return { outputs: {} };
34
- }
35
- catch (error) {
36
- ctx.log(`deploy-hook "${ctx.id}": forgejo not reachable yet, treating as not-yet-created: ${String(error)}`);
37
- return undefined;
38
- }
39
- },
40
- diff: () => ({ action: "noop" }),
41
- apply: async (inputs) => {
42
- const parsed = parse(inputs);
43
- const url = listenerUrl(parsed);
44
- const config = { url, content_type: "json", secret: parsed.secret };
45
- const existing = findHook(await api.listHooks({
46
- baseUrl: parsed.forgejoUrl,
47
- user: parsed.adminUser,
48
- password: parsed.adminPassword,
49
- owner: parsed.adminUser,
50
- name: parsed.repoName,
51
- }), url);
52
- if (existing === undefined) {
53
- await api.createHook({
54
- baseUrl: parsed.forgejoUrl,
55
- user: parsed.adminUser,
56
- password: parsed.adminPassword,
57
- owner: parsed.adminUser,
58
- name: parsed.repoName,
59
- type: "gitea",
60
- config,
61
- events: ["push"],
62
- });
63
- }
64
- else {
65
- await api.updateHook({
66
- baseUrl: parsed.forgejoUrl,
67
- user: parsed.adminUser,
68
- password: parsed.adminPassword,
69
- owner: parsed.adminUser,
70
- name: parsed.repoName,
71
- id: existing.id,
72
- config,
73
- events: ["push"],
74
- });
75
- }
76
- return {};
77
- },
78
- });
79
- //# sourceMappingURL=deploy-hook.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy-hook.js","sourceRoot":"","sources":["../src/deploy-hook.ts"],"names":[],"mappings":"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"}