pepr 0.13.0 → 0.13.2

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 (51) hide show
  1. package/dist/cli.js +54 -28
  2. package/dist/controller.js +1 -1
  3. package/dist/lib/assets/index.d.ts +5 -6
  4. package/dist/lib/assets/index.d.ts.map +1 -1
  5. package/dist/lib/assets/loader.d.ts +2 -8
  6. package/dist/lib/assets/loader.d.ts.map +1 -1
  7. package/dist/lib/capability.d.ts +4 -7
  8. package/dist/lib/capability.d.ts.map +1 -1
  9. package/dist/lib/controller.d.ts +3 -49
  10. package/dist/lib/controller.d.ts.map +1 -1
  11. package/dist/lib/errors.d.ts +12 -0
  12. package/dist/lib/errors.d.ts.map +1 -0
  13. package/dist/lib/k8s/types.d.ts +5 -1
  14. package/dist/lib/k8s/types.d.ts.map +1 -1
  15. package/dist/lib/metrics.d.ts +6 -12
  16. package/dist/lib/metrics.d.ts.map +1 -1
  17. package/dist/lib/module.d.ts +2 -2
  18. package/dist/lib/module.d.ts.map +1 -1
  19. package/dist/lib/mutate-processor.d.ts.map +1 -1
  20. package/dist/lib/mutate-request.d.ts +2 -2
  21. package/dist/lib/mutate-request.d.ts.map +1 -1
  22. package/dist/lib/types.d.ts +3 -9
  23. package/dist/lib/types.d.ts.map +1 -1
  24. package/dist/lib/validate-processor.d.ts.map +1 -1
  25. package/dist/lib/validate-request.d.ts +2 -2
  26. package/dist/lib/validate-request.d.ts.map +1 -1
  27. package/dist/lib.js +247 -191
  28. package/dist/lib.js.map +3 -3
  29. package/jest.config.json +4 -0
  30. package/journey/before.ts +21 -0
  31. package/journey/k8s.ts +81 -0
  32. package/journey/pepr-build.ts +69 -0
  33. package/journey/pepr-deploy.ts +133 -0
  34. package/journey/pepr-dev.ts +155 -0
  35. package/journey/pepr-format.ts +13 -0
  36. package/journey/pepr-init.ts +12 -0
  37. package/package.json +20 -21
  38. package/src/lib/assets/index.ts +15 -8
  39. package/src/lib/assets/loader.ts +4 -12
  40. package/src/lib/assets/webhooks.ts +2 -2
  41. package/src/lib/capability.ts +34 -32
  42. package/src/lib/controller.ts +111 -93
  43. package/src/lib/errors.ts +20 -0
  44. package/src/lib/k8s/types.ts +5 -1
  45. package/src/lib/metrics.ts +45 -32
  46. package/src/lib/module.ts +24 -10
  47. package/src/lib/mutate-processor.ts +5 -3
  48. package/src/lib/mutate-request.ts +22 -9
  49. package/src/lib/types.ts +4 -10
  50. package/src/lib/validate-processor.ts +8 -0
  51. package/src/lib/validate-request.ts +19 -7
@@ -0,0 +1,69 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { expect, it } from "@jest/globals";
5
+ import { loadYaml } from "@kubernetes/client-node";
6
+ import { execSync } from "child_process";
7
+ import { promises as fs } from "fs";
8
+ import { resolve } from "path";
9
+
10
+ import { cwd } from "./entrypoint.test";
11
+
12
+ export function peprBuild() {
13
+ it("should successfully build the Pepr project", async () => {
14
+ execSync("npx pepr build", { cwd: cwd, stdio: "inherit" });
15
+ });
16
+
17
+ it("should generate produce the K8s yaml file", async () => {
18
+ await fs.access(resolve(cwd, "dist", "pepr-module-static-test.yaml"));
19
+ });
20
+
21
+ it("should generate the zarf.yaml f", async () => {
22
+ await fs.access(resolve(cwd, "dist", "zarf.yaml"));
23
+ await validateZarfYaml();
24
+ });
25
+ }
26
+
27
+ async function validateZarfYaml() {
28
+ // Get the version of the pepr binary
29
+ const peprVer = execSync("npx pepr --version", { cwd }).toString().trim();
30
+
31
+ // Read the generated yaml files
32
+ const k8sYaml = await fs.readFile(resolve(cwd, "dist", "pepr-module-static-test.yaml"), "utf8");
33
+ const zarfYAML = await fs.readFile(resolve(cwd, "dist", "zarf.yaml"), "utf8");
34
+
35
+ // The expected image name
36
+ const expectedImage = `ghcr.io/defenseunicorns/pepr/controller:v${peprVer}`;
37
+
38
+ // The expected zarf yaml contents
39
+ const expectedZarfYaml = {
40
+ kind: "ZarfPackageConfig",
41
+ metadata: {
42
+ name: "pepr-static-test",
43
+ description: "Pepr Module: A test module for Pepr",
44
+ url: "https://github.com/defenseunicorns/pepr",
45
+ version: "0.0.1",
46
+ },
47
+ components: [
48
+ {
49
+ name: "module",
50
+ required: true,
51
+ manifests: [
52
+ {
53
+ name: "module",
54
+ namespace: "pepr-system",
55
+ files: ["pepr-module-static-test.yaml"],
56
+ },
57
+ ],
58
+ images: [expectedImage],
59
+ },
60
+ ],
61
+ };
62
+
63
+ // Check the generated zarf yaml
64
+ const actualZarfYaml = loadYaml(zarfYAML);
65
+ expect(actualZarfYaml).toEqual(expectedZarfYaml);
66
+
67
+ // Check the generated k8s yaml
68
+ expect(k8sYaml).toMatch(`image: ${expectedImage}`);
69
+ }
@@ -0,0 +1,133 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { describe, expect, it } from "@jest/globals";
5
+ import { execSync, spawnSync } from "child_process";
6
+ import { resolve } from "path";
7
+
8
+ import { cwd } from "./entrypoint.test";
9
+ import { waitForConfigMap, waitForDeploymentReady, waitForNamespace, waitForSecret } from "./k8s";
10
+
11
+ export function peprDeploy() {
12
+ it("should deploy the Pepr controller into the test cluster", async () => {
13
+ execSync("npx pepr deploy -i pepr:dev --confirm", { cwd, stdio: "inherit" });
14
+
15
+ // Wait for the deployment to be ready
16
+ await waitForDeploymentReady("pepr-system", "pepr-static-test");
17
+ });
18
+
19
+ cleanupSamples();
20
+
21
+ it("should perform validation of resources applied to the test cluster", testValidate);
22
+
23
+ describe("should perform mutation of resources applied to the test cluster", testMutate);
24
+
25
+ cleanupSamples();
26
+ }
27
+
28
+ function cleanupSamples() {
29
+ try {
30
+ // Remove the sample yaml for the HelloPepr capability
31
+ execSync("kubectl delete -f hello-pepr.samples.yaml --ignore-not-found", {
32
+ cwd: resolve(cwd, "capabilities"),
33
+ stdio: "inherit",
34
+ });
35
+ } catch (e) {
36
+ // Ignore errors
37
+ }
38
+ }
39
+
40
+ async function testValidate() {
41
+ // Apply the sample yaml for the HelloPepr capability
42
+ const applyOut = spawnSync("kubectl apply -f hello-pepr.samples.yaml", {
43
+ shell: true, // Run command in a shell
44
+ encoding: "utf-8", // Encode result as string
45
+ cwd: resolve(cwd, "capabilities"),
46
+ });
47
+
48
+ const { stderr, status } = applyOut;
49
+
50
+ // Validation should return an error
51
+ expect(status).toBe(1);
52
+
53
+ // Check if the expected lines are in the output
54
+ const expected = [
55
+ `Error from server: error when creating "hello-pepr.samples.yaml": `,
56
+ `admission webhook "pepr-static-test.pepr.dev" denied the request: `,
57
+ `No evil CM annotations allowed.\n`,
58
+ ].join("");
59
+ expect(stderr).toBe(expected);
60
+ }
61
+
62
+ function testMutate() {
63
+ it("should mutate the namespace", async () => {
64
+ // Wait for the namespace to be created
65
+ const ns = await waitForNamespace("pepr-demo");
66
+
67
+ // Check if the namespace has the correct labels and annotations
68
+ expect(ns.metadata?.labels).toEqual({
69
+ "keep-me": "please",
70
+ "kubernetes.io/metadata.name": "pepr-demo",
71
+ });
72
+ expect(ns.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
73
+ });
74
+
75
+ it("should mutate example-1", async () => {
76
+ const cm1 = await waitForConfigMap("pepr-demo", "example-1");
77
+ expect(cm1.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
78
+ expect(cm1.metadata?.annotations?.["pepr.dev"]).toBe("annotations-work-too");
79
+ expect(cm1.metadata?.labels?.["pepr"]).toBe("was-here");
80
+ });
81
+
82
+ it("should mutate example-2", async () => {
83
+ const cm2 = await waitForConfigMap("pepr-demo", "example-2");
84
+ expect(cm2.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
85
+ expect(cm2.metadata?.annotations?.["pepr.dev"]).toBe("annotations-work-too");
86
+ expect(cm2.metadata?.labels?.["pepr"]).toBe("was-here");
87
+ });
88
+
89
+ it("should mutate example-3", async () => {
90
+ const cm3 = await waitForConfigMap("pepr-demo", "example-3");
91
+
92
+ expect(cm3.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
93
+ expect(cm3.metadata?.annotations?.["pepr.dev"]).toBe("making-waves");
94
+ expect(cm3.data).toEqual({ key: "ex-3-val", username: "system:admin" });
95
+ });
96
+
97
+ it("should mutate example-4", async () => {
98
+ const cm4 = await waitForConfigMap("pepr-demo", "example-4");
99
+ expect(cm4.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
100
+ expect(cm4.metadata?.labels?.["pepr.dev/first"]).toBe("true");
101
+ expect(cm4.metadata?.labels?.["pepr.dev/second"]).toBe("true");
102
+ expect(cm4.metadata?.labels?.["pepr.dev/third"]).toBe("true");
103
+ });
104
+
105
+ it("should mutate example-4a", async () => {
106
+ const cm4a = await waitForConfigMap("pepr-demo-2", "example-4a");
107
+ expect(cm4a.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
108
+ expect(cm4a.metadata?.labels?.["pepr.dev/first"]).toBe("true");
109
+ expect(cm4a.metadata?.labels?.["pepr.dev/second"]).toBe("true");
110
+ expect(cm4a.metadata?.labels?.["pepr.dev/third"]).toBe("true");
111
+ });
112
+
113
+ it("should mutate example-5", async () => {
114
+ const cm5 = await waitForConfigMap("pepr-demo", "example-5");
115
+
116
+ expect(cm5.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
117
+ expect(cm5.data?.["chuck-says"]).toBeTruthy();
118
+ });
119
+
120
+ it("should mutate secret-1", async () => {
121
+ const s1 = await waitForSecret("pepr-demo", "secret-1");
122
+
123
+ expect(s1.metadata?.annotations?.["static-test.pepr.dev/hello-pepr"]).toBe("succeeded");
124
+ expect(s1.data?.["example"]).toBe("dW5pY29ybiBtYWdpYyAtIG1vZGlmaWVkIGJ5IFBlcHI=");
125
+ expect(s1.data?.["magic"]).toBe("Y2hhbmdlLXdpdGhvdXQtZW5jb2Rpbmc=");
126
+ expect(s1.data?.["binary-data"]).toBe(
127
+ "iCZQUg8xYucNUqD+8lyl2YcKjYYygvTtiDSEV9b9WKUkxSSLFJTgIWMJ9GcFFYs4T9JCdda51u74jfq8yHzRuEASl60EdTS/NfWgIIFTGqcNRfqMw+vgpyTMmCyJVaJEDFq6AA==",
128
+ );
129
+ expect(s1.data?.["ascii-with-white-space"]).toBe(
130
+ "VGhpcyBpcyBzb21lIHJhbmRvbSB0ZXh0OgoKICAgIC0gd2l0aCBsaW5lIGJyZWFrcwogICAgLSBhbmQgdGFicw==",
131
+ );
132
+ });
133
+ }
@@ -0,0 +1,155 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { afterAll, expect, it } from "@jest/globals";
5
+ import { KubeConfig } from "@kubernetes/client-node";
6
+ import { ChildProcessWithoutNullStreams, spawn } from "child_process";
7
+ import { Agent } from "https";
8
+ import { RequestInit } from "node-fetch";
9
+
10
+ import { fetch } from "../src/lib/fetch";
11
+ import { cwd } from "./entrypoint.test";
12
+
13
+ const kc = new KubeConfig();
14
+ kc.loadFromDefault();
15
+
16
+ let expectedLines = [
17
+ "Establishing connection to Kubernetes",
18
+ "Capability hello-pepr registered",
19
+ "Mutate Action configured for CREATE",
20
+ "Validate Action configured for CREATE",
21
+ "Server listening on port 3000",
22
+ ];
23
+
24
+ export function peprDev() {
25
+ let cmd: ChildProcessWithoutNullStreams;
26
+ let success = false;
27
+
28
+ it("should start the Pepr dev server", () => {
29
+ cmd = spawn("npx", ["pepr", "dev", "--confirm"], { cwd });
30
+
31
+ // This command should not exit on its own
32
+ cmd.on("close", code => {
33
+ if (!success) {
34
+ throw new Error(`Command exited with code ${code}`);
35
+ }
36
+ });
37
+
38
+ // Log stderr
39
+ cmd.stderr.on("data", data => {
40
+ if (!success) {
41
+ console.error(`stderr: ${data}`);
42
+ }
43
+ });
44
+
45
+ // Reject on error
46
+ cmd.on("error", error => {
47
+ if (!success) {
48
+ throw error;
49
+ }
50
+ });
51
+ });
52
+
53
+ it("should be properly configured by the test module", done => {
54
+ cmd.stdout.on("data", (data: Buffer) => {
55
+ if (success) {
56
+ return;
57
+ }
58
+
59
+ // Convert buffer to string
60
+ const strData = data.toString();
61
+ console.log(strData);
62
+
63
+ // Check if any expected lines are found
64
+ expectedLines = expectedLines.filter(expectedLine => {
65
+ // Check if the expected line is found in the output, ignoring whitespace
66
+ return !strData.replace(/\s+/g, " ").includes(expectedLine);
67
+ });
68
+
69
+ // If all expected lines are found, resolve the promise
70
+ if (expectedLines.length < 1) {
71
+ // Abort all further processing
72
+ success = true;
73
+
74
+ // Finish the test
75
+ done();
76
+ }
77
+ });
78
+ });
79
+
80
+ it("should protect the controller endpoint with an API token", async () => {
81
+ await validateAPIKey();
82
+ });
83
+
84
+ it("should expose Prometheus metrics", async () => {
85
+ const metrics = await validateMetrics();
86
+ expect(metrics).toMatch("pepr_Validate");
87
+ expect(metrics).toMatch("pepr_Mutate");
88
+ expect(metrics).toMatch("pepr_errors");
89
+ expect(metrics).toMatch("pepr_alerts");
90
+ });
91
+
92
+ afterAll(() => {
93
+ // Close or destroy the streams
94
+ if (cmd.stdin) {
95
+ cmd.stdin.end();
96
+ }
97
+ if (cmd.stdout) {
98
+ cmd.stdout.destroy();
99
+ }
100
+ if (cmd.stderr) {
101
+ cmd.stderr.destroy();
102
+ }
103
+
104
+ // Remove the event listeners
105
+ cmd.removeAllListeners("close");
106
+ cmd.removeAllListeners("error");
107
+
108
+ // Kill the process
109
+ cmd.kill(9);
110
+ });
111
+ }
112
+
113
+ async function validateAPIKey() {
114
+ const base = "https://localhost:3000/mutate/";
115
+
116
+ const fetchOpts: RequestInit = {
117
+ agent: new Agent({
118
+ // Avoid tls issues for self-signed certs
119
+ rejectUnauthorized: false,
120
+ }),
121
+ method: "POST",
122
+ };
123
+
124
+ // Test api token validation
125
+ const evilToken = await fetch(`${base}evil-token`, fetchOpts);
126
+
127
+ // Test for empty api token
128
+ const emptyToken = await fetch(base, fetchOpts);
129
+
130
+ if (evilToken.status !== 401) {
131
+ throw new Error("Expected evil token to return 401");
132
+ }
133
+
134
+ if (emptyToken.status !== 404) {
135
+ throw new Error("Expected empty token to return 404");
136
+ }
137
+ }
138
+
139
+ async function validateMetrics() {
140
+ const metricsEndpoint = "https://localhost:3000/metrics";
141
+
142
+ const fetchOpts: RequestInit = {
143
+ agent: new Agent({
144
+ // Avoid tls issues for self-signed certs
145
+ rejectUnauthorized: false,
146
+ }),
147
+ };
148
+ const metricsOk = await fetch<string>(metricsEndpoint, fetchOpts);
149
+
150
+ if (metricsOk.status !== 200) {
151
+ throw new Error("Expected metrics ok to return a 200");
152
+ }
153
+
154
+ return metricsOk.data;
155
+ }
@@ -0,0 +1,13 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { it } from "@jest/globals";
5
+ import { execSync } from "child_process";
6
+
7
+ import { cwd } from "./entrypoint.test";
8
+
9
+ export function peprFormat() {
10
+ it("should format the Pepr project", () => {
11
+ execSync("npx pepr format", { cwd, stdio: "inherit" });
12
+ });
13
+ }
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { it } from "@jest/globals";
5
+ import { execSync } from "child_process";
6
+
7
+ export function peprInit() {
8
+ it("should create a new Pepr project", () => {
9
+ const peprAlias = "file:pepr-0.0.0-development.tgz";
10
+ execSync(`TEST_MODE=true npx --yes ${peprAlias} init`, { stdio: "inherit" });
11
+ });
12
+ }
package/package.json CHANGED
@@ -9,19 +9,20 @@
9
9
  "engines": {
10
10
  "node": ">=18.0.0"
11
11
  },
12
- "version": "0.13.0",
12
+ "version": "0.13.2",
13
13
  "main": "dist/lib.js",
14
14
  "types": "dist/lib.d.ts",
15
15
  "scripts": {
16
- "prebuild": "rm -fr dist/* && node hack/build-template-data.js",
16
+ "gen-data-json": "node hack/build-template-data.js",
17
+ "prebuild": "rm -fr dist/* && npm run gen-data-json",
17
18
  "build": "tsc && node build.mjs",
18
- "test": "npm run test:unit && npm run test:e2e",
19
- "test:unit": "npm run build && tsc -p tsconfig.tests.json && ava dist/**/*.test.js",
20
- "test:e2e": "npm run test:e2e:k3d && npm run test:e2e:build && npm run test:e2e:image && npm run test:e2e:run",
21
- "test:e2e:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'",
22
- "test:e2e:build": "npm run build && npm pack",
23
- "test:e2e:image": "docker buildx build --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev",
24
- "test:e2e:run": "ava hack/e2e.test.mjs --sequential --timeout=2m",
19
+ "test": "npm run test:unit && npm run test:journey",
20
+ "test:unit": "npm run gen-data-json && jest src --coverage",
21
+ "test:journey": "npm run test:journey:k3d && npm run test:journey:build && npm run test:journey:image && npm run test:journey:run",
22
+ "test:journey:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0'",
23
+ "test:journey:build": "npm run build && npm pack",
24
+ "test:journey:image": "docker buildx build --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev",
25
+ "test:journey:run": "jest journey/entrypoint.test.ts",
25
26
  "format:check": "eslint src && prettier src --check",
26
27
  "format:fix": "eslint src --fix && prettier src --write"
27
28
  },
@@ -37,6 +38,7 @@
37
38
  "ramda": "0.29.0"
38
39
  },
39
40
  "devDependencies": {
41
+ "@jest/globals": "29.6.4",
40
42
  "@types/eslint": "8.44.2",
41
43
  "@types/express": "4.17.17",
42
44
  "@types/node": "18.x.x",
@@ -45,24 +47,21 @@
45
47
  "@types/prettier": "3.0.0",
46
48
  "@types/prompts": "2.4.4",
47
49
  "@types/ramda": "0.29.3",
48
- "@types/uuid": "9.0.2",
49
- "ava": "5.3.1",
50
- "nock": "13.3.2"
50
+ "@types/uuid": "9.0.3",
51
+ "jest": "29.6.4",
52
+ "nock": "13.3.3",
53
+ "ts-jest": "29.1.1"
51
54
  },
52
55
  "peerDependencies": {
53
- "@typescript-eslint/eslint-plugin": "6.4.0",
54
- "@typescript-eslint/parser": "6.4.0",
56
+ "@typescript-eslint/eslint-plugin": "6.5.0",
57
+ "@typescript-eslint/parser": "6.5.0",
55
58
  "commander": "11.0.0",
56
59
  "esbuild": "0.19.2",
57
- "eslint": "8.47.0",
60
+ "eslint": "8.48.0",
58
61
  "node-forge": "1.3.1",
59
- "prettier": "3.0.1",
62
+ "prettier": "3.0.3",
60
63
  "prompts": "2.4.2",
61
- "typescript": "5.1.6",
64
+ "typescript": "5.2.2",
62
65
  "uuid": "9.0.0"
63
- },
64
- "ava": {
65
- "failFast": true,
66
- "verbose": true
67
66
  }
68
67
  }
@@ -4,16 +4,16 @@
4
4
  import crypto from "crypto";
5
5
 
6
6
  import { TLSOut, genTLS } from "../k8s/tls";
7
- import { ModuleConfig } from "../types";
7
+ import { CapabilityExport, ModuleConfig } from "../types";
8
8
  import { deploy } from "./deploy";
9
- import { ModuleCapabilities, loadCapabilities } from "./loader";
9
+ import { loadCapabilities } from "./loader";
10
10
  import { allYaml, zarfYaml } from "./yaml";
11
11
 
12
12
  export class Assets {
13
13
  readonly name: string;
14
14
  readonly tls: TLSOut;
15
15
  readonly apiToken: string;
16
- capabilities!: ModuleCapabilities[];
16
+ capabilities!: CapabilityExport[];
17
17
  image: string;
18
18
 
19
19
  constructor(
@@ -21,6 +21,11 @@ export class Assets {
21
21
  readonly path: string,
22
22
  readonly host?: string,
23
23
  ) {
24
+ // Bind public methods
25
+ this.deploy = this.deploy.bind(this);
26
+ this.zarfYaml = this.zarfYaml.bind(this);
27
+ this.allYaml = this.allYaml.bind(this);
28
+
24
29
  this.name = `pepr-${config.uuid}`;
25
30
 
26
31
  this.image = `ghcr.io/defenseunicorns/pepr/controller:v${config.peprVersion}`;
@@ -32,15 +37,17 @@ export class Assets {
32
37
  this.apiToken = crypto.randomBytes(32).toString("hex");
33
38
  }
34
39
 
35
- deploy = async (webhookTimeout?: number) => {
40
+ async deploy(webhookTimeout?: number) {
36
41
  this.capabilities = await loadCapabilities(this.path);
37
42
  await deploy(this, webhookTimeout);
38
- };
43
+ }
39
44
 
40
- zarfYaml = (path: string) => zarfYaml(this, path);
45
+ zarfYaml(path: string) {
46
+ return zarfYaml(this, path);
47
+ }
41
48
 
42
- allYaml = async () => {
49
+ async allYaml() {
43
50
  this.capabilities = await loadCapabilities(this.path);
44
51
  return allYaml(this);
45
- };
52
+ }
46
53
  }
@@ -3,22 +3,14 @@
3
3
 
4
4
  import { fork } from "child_process";
5
5
 
6
- import { Binding } from "../types";
7
-
8
- // We are receiving javascript so the private fields are now public
9
- export interface ModuleCapabilities {
10
- _name: string;
11
- _description: string;
12
- _namespaces: string[];
13
- _bindings: Binding[];
14
- }
6
+ import { CapabilityExport } from "../types";
15
7
 
16
8
  /**
17
9
  * Read the capabilities from the module by running it in build mode
18
10
  * @param path
19
11
  * @returns
20
12
  */
21
- export function loadCapabilities(path: string): Promise<ModuleCapabilities[]> {
13
+ export function loadCapabilities(path: string): Promise<CapabilityExport[]> {
22
14
  return new Promise((resolve, reject) => {
23
15
  // Fork is needed with the PEPR_MODE env var to ensure the module is loaded in build mode and will send back the capabilities
24
16
  const program = fork(path, {
@@ -32,11 +24,11 @@ export function loadCapabilities(path: string): Promise<ModuleCapabilities[]> {
32
24
  // Wait for the module to send back the capabilities
33
25
  program.on("message", message => {
34
26
  // Cast the message to the ModuleCapabilities type
35
- const capabilities = message.valueOf() as ModuleCapabilities[];
27
+ const capabilities = message.valueOf() as CapabilityExport[];
36
28
 
37
29
  // Iterate through the capabilities and generate the rules
38
30
  for (const capability of capabilities) {
39
- console.info(`Registered Pepr Capability "${capability._name}"`);
31
+ console.info(`Registered Pepr Capability "${capability.name}"`);
40
32
  }
41
33
 
42
34
  resolve(capabilities);
@@ -26,10 +26,10 @@ export async function generateWebhookRules(assets: Assets, isMutateWebhook: bool
26
26
 
27
27
  // Iterate through the capabilities and generate the rules
28
28
  for (const capability of capabilities) {
29
- console.info(`Module ${config.uuid} has capability: ${capability._name}`);
29
+ console.info(`Module ${config.uuid} has capability: ${capability.name}`);
30
30
 
31
31
  // Read the bindings and generate the rules
32
- for (const binding of capability._bindings) {
32
+ for (const binding of capability.bindings) {
33
33
  const { event, kind, isMutate, isValidate } = binding;
34
34
 
35
35
  // If the module doesn't have a callback for the event, skip it