pepr 0.1.26 → 0.1.28

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 (73) hide show
  1. package/{index.ts → dist/index.d.ts} +0 -2
  2. package/dist/index.js +5 -0
  3. package/dist/package.json +76 -0
  4. package/dist/src/cli/banner.d.ts +1 -0
  5. package/dist/{pepr-cli.js → src/cli/banner.js} +1 -1251
  6. package/dist/src/cli/build.d.ts +7 -0
  7. package/dist/src/cli/build.js +95 -0
  8. package/dist/src/cli/capability.d.ts +2 -0
  9. package/dist/src/cli/capability.js +12 -0
  10. package/dist/src/cli/deploy.d.ts +2 -0
  11. package/dist/src/cli/deploy.js +49 -0
  12. package/dist/src/cli/dev.d.ts +2 -0
  13. package/dist/src/cli/dev.js +90 -0
  14. package/dist/src/cli/index.d.ts +1 -0
  15. package/dist/src/cli/index.js +28 -0
  16. package/dist/src/cli/init/index.d.ts +2 -0
  17. package/dist/src/cli/init/index.js +48 -0
  18. package/dist/src/cli/init/templates.d.ts +82 -0
  19. package/dist/src/cli/init/templates.js +224 -0
  20. package/dist/src/cli/init/utils.d.ts +20 -0
  21. package/dist/src/cli/init/utils.js +50 -0
  22. package/dist/src/cli/init/walkthrough.d.ts +7 -0
  23. package/dist/src/cli/init/walkthrough.js +76 -0
  24. package/dist/src/cli/root.d.ts +4 -0
  25. package/dist/src/cli/root.js +14 -0
  26. package/dist/src/cli/test.d.ts +2 -0
  27. package/dist/src/cli/test.js +45 -0
  28. package/dist/src/lib/capability.d.ts +26 -0
  29. package/dist/src/lib/capability.js +112 -0
  30. package/dist/src/lib/controller.d.ts +13 -0
  31. package/dist/src/lib/controller.js +77 -0
  32. package/dist/src/lib/filter.d.ts +10 -0
  33. package/dist/src/lib/filter.js +41 -0
  34. package/dist/src/lib/k8s/index.d.ts +4 -0
  35. package/{src/lib/k8s/index.ts → dist/src/lib/k8s/index.js} +0 -3
  36. package/dist/src/lib/k8s/kinds.d.ts +3 -0
  37. package/dist/src/lib/k8s/kinds.js +427 -0
  38. package/dist/src/lib/k8s/tls.d.ts +17 -0
  39. package/dist/src/lib/k8s/tls.js +67 -0
  40. package/dist/src/lib/k8s/types.d.ts +136 -0
  41. package/dist/src/lib/k8s/types.js +9 -0
  42. package/dist/src/lib/k8s/upstream.d.ts +1 -0
  43. package/dist/src/lib/k8s/upstream.js +3 -0
  44. package/dist/src/lib/k8s/webhook.d.ts +33 -0
  45. package/dist/src/lib/k8s/webhook.js +490 -0
  46. package/dist/src/lib/logger.d.ts +54 -0
  47. package/dist/{types-1709b44f.js → src/lib/logger.js} +3 -40
  48. package/dist/src/lib/module.d.ts +22 -0
  49. package/dist/src/lib/module.js +32 -0
  50. package/dist/src/lib/processor.d.ts +4 -0
  51. package/dist/src/lib/processor.js +66 -0
  52. package/dist/src/lib/request.d.ts +77 -0
  53. package/dist/src/lib/request.js +117 -0
  54. package/dist/src/lib/types.d.ts +187 -0
  55. package/dist/src/lib/types.js +31 -0
  56. package/package.json +8 -11
  57. package/tsconfig.build.json +4 -0
  58. package/CODEOWNERS +0 -6
  59. package/dist/pepr-core.js +0 -950
  60. package/src/lib/capability.ts +0 -150
  61. package/src/lib/controller.ts +0 -92
  62. package/src/lib/filter.ts +0 -52
  63. package/src/lib/k8s/kinds.ts +0 -470
  64. package/src/lib/k8s/tls.ts +0 -90
  65. package/src/lib/k8s/types.ts +0 -170
  66. package/src/lib/k8s/upstream.ts +0 -47
  67. package/src/lib/k8s/webhook.ts +0 -540
  68. package/src/lib/logger.ts +0 -131
  69. package/src/lib/module.ts +0 -47
  70. package/src/lib/processor.ts +0 -83
  71. package/src/lib/request.ts +0 -140
  72. package/src/lib/types.ts +0 -211
  73. package/tsconfig.json +0 -15
@@ -0,0 +1,7 @@
1
+ import { RootCmd } from "./root";
2
+ export default function (program: RootCmd): void;
3
+ export declare function buildModule(moduleDir: string): Promise<{
4
+ path: string;
5
+ cfg: any;
6
+ uuid: any;
7
+ }>;
@@ -0,0 +1,95 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import json from "@rollup/plugin-json";
4
+ import nodeResolve from "@rollup/plugin-node-resolve";
5
+ import typescript from "@rollup/plugin-typescript";
6
+ import { promises as fs } from "fs";
7
+ import { resolve } from "path";
8
+ import { rollup } from "rollup";
9
+ import Log from "../lib/logger";
10
+ import { Webhook } from "../lib/k8s/webhook";
11
+ export default function (program) {
12
+ program
13
+ .command("build")
14
+ .description("Build a Pepr Module for deployment")
15
+ .option("-d, --dir [directory]", "Pepr module directory", ".")
16
+ .action(async (opts) => {
17
+ // Build the module
18
+ const { cfg, path, uuid } = await buildModule(opts.dir);
19
+ // Read the compiled module code
20
+ const code = await fs.readFile(path, { encoding: "utf-8" });
21
+ // Generate a secret for the module
22
+ const webhook = new Webhook({
23
+ ...cfg.pepr,
24
+ description: cfg.description,
25
+ });
26
+ const yamlFile = `pepr-module-${uuid}.yaml`;
27
+ const yamlPath = resolve("dist", yamlFile);
28
+ const yaml = webhook.allYaml(code);
29
+ const zarfPath = resolve("dist", "zarf.yaml");
30
+ const zarf = webhook.zarfYaml(yamlFile);
31
+ await fs.writeFile(yamlPath, yaml);
32
+ await fs.writeFile(zarfPath, zarf);
33
+ Log.debug(`Module compiled successfully at ${path}`);
34
+ Log.info(`K8s resource for the module saved to ${yamlPath}`);
35
+ });
36
+ }
37
+ const externalLibs = [
38
+ /@kubernetes\/client-node(\/.*)?/,
39
+ "express",
40
+ "fast-json-patch",
41
+ "ramda",
42
+ ];
43
+ export async function buildModule(moduleDir) {
44
+ try {
45
+ // Resolve the path to the module's package.json file
46
+ const cfgPath = resolve(moduleDir, "package.json");
47
+ const input = resolve(moduleDir, "pepr.ts");
48
+ // Read the module's UUID from the package.json filel
49
+ const moduleText = await fs.readFile(cfgPath, { encoding: "utf-8" });
50
+ const cfg = JSON.parse(moduleText);
51
+ const { uuid } = cfg.pepr;
52
+ const name = `pepr-${uuid}.js`;
53
+ // Exit if the module's UUID could not be found
54
+ if (!uuid) {
55
+ throw new Error("Could not load the uuid in package.json");
56
+ }
57
+ const plugins = [
58
+ nodeResolve({
59
+ preferBuiltins: true,
60
+ }),
61
+ json(),
62
+ typescript({
63
+ tsconfig: "./tsconfig.json",
64
+ declaration: false,
65
+ removeComments: true,
66
+ sourceMap: false,
67
+ include: ["**/*.ts"],
68
+ }),
69
+ ];
70
+ // Build the module using Rollup
71
+ const bundle = await rollup({
72
+ plugins,
73
+ external: externalLibs,
74
+ treeshake: true,
75
+ input,
76
+ });
77
+ // Write the module to the dist directory
78
+ await bundle.write({
79
+ dir: "dist",
80
+ format: "cjs",
81
+ entryFileNames: name,
82
+ });
83
+ return {
84
+ path: resolve("dist", name),
85
+ cfg,
86
+ uuid,
87
+ };
88
+ }
89
+ catch (e) {
90
+ // On any other error, exit with a non-zero exit code
91
+ Log.debug(e);
92
+ Log.error(e.message);
93
+ process.exit(1);
94
+ }
95
+ }
@@ -0,0 +1,2 @@
1
+ import { RootCmd } from "./root";
2
+ export default function (program: RootCmd): void;
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ export default function (program) {
4
+ program
5
+ .command("new")
6
+ .description("Create a new Pepr Capability")
7
+ .option("-d, --dir [directory]", "Pepr module directory", ".")
8
+ .action(() => {
9
+ // TODO: Create a new capability
10
+ console.log("new");
11
+ });
12
+ }
@@ -0,0 +1,2 @@
1
+ import { RootCmd } from "./root";
2
+ export default function (program: RootCmd): void;
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import { promises as fs } from "fs";
4
+ import { Webhook } from "../lib/k8s/webhook";
5
+ import Log from "../lib/logger";
6
+ import { buildModule } from "./build";
7
+ import { prompt } from "prompts";
8
+ export default function (program) {
9
+ program
10
+ .command("deploy")
11
+ .description("Deploy a Pepr Module")
12
+ .option("-d, --dir [directory]", "Pepr module directory", ".")
13
+ .option("-i, --image [image]", "Override the image tag")
14
+ .option("-f, --force", "Force redeployment")
15
+ .action(async (opts) => {
16
+ if (!opts.force) {
17
+ // Prompt the user to confirm
18
+ const confirm = await prompt({
19
+ type: "confirm",
20
+ name: "confirm",
21
+ message: "This will remove and redeploy the module. Continue?",
22
+ });
23
+ // Exit if the user doesn't confirm
24
+ if (!confirm.confirm) {
25
+ process.exit(0);
26
+ }
27
+ }
28
+ // Build the module
29
+ const { cfg, path } = await buildModule(opts.dir);
30
+ // Read the compiled module code
31
+ const code = await fs.readFile(path, { encoding: "utf-8" });
32
+ // Generate a secret for the module
33
+ const webhook = new Webhook({
34
+ ...cfg.pepr,
35
+ description: cfg.description,
36
+ });
37
+ if (opts.image) {
38
+ webhook.image = opts.image;
39
+ }
40
+ try {
41
+ await webhook.deploy(code);
42
+ Log.info(`Module deployed successfully`);
43
+ }
44
+ catch (e) {
45
+ Log.error(`Error deploying module: ${e}`);
46
+ process.exit(1);
47
+ }
48
+ });
49
+ }
@@ -0,0 +1,2 @@
1
+ import { RootCmd } from "./root";
2
+ export default function (program: RootCmd): void;
@@ -0,0 +1,90 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import { spawn } from "child_process";
4
+ import { watch } from "chokidar";
5
+ import { promises as fs } from "fs";
6
+ import { resolve } from "path";
7
+ import { prompt } from "prompts";
8
+ import { Webhook } from "../lib/k8s/webhook";
9
+ import Log from "../lib/logger";
10
+ import { buildModule } from "./build";
11
+ export default function (program) {
12
+ program
13
+ .command("dev")
14
+ .description("Setup a local webhook development environment")
15
+ .option("-d, --dir [directory]", "Pepr module directory", ".")
16
+ .option("-h, --host [host]", "Host to listen on", "host.docker.internal")
17
+ .action(async (opts) => {
18
+ // Prompt the user to confirm
19
+ const confirm = await prompt({
20
+ type: "confirm",
21
+ name: "confirm",
22
+ message: "This will remove and redeploy the module. Continue?",
23
+ });
24
+ // Exit if the user doesn't confirm
25
+ if (!confirm.confirm) {
26
+ process.exit(0);
27
+ }
28
+ // Build the module
29
+ const { cfg, path } = await buildModule(opts.dir);
30
+ // Read the compiled module code
31
+ const code = await fs.readFile(path, { encoding: "utf-8" });
32
+ // Generate a secret for the module
33
+ const webhook = new Webhook({
34
+ ...cfg.pepr,
35
+ description: cfg.description,
36
+ }, opts.host);
37
+ // Write the TLS cert and key to disk
38
+ await fs.writeFile("insecure-tls.crt", webhook.tls.pem.crt);
39
+ await fs.writeFile("insecure-tls.key", webhook.tls.pem.key);
40
+ try {
41
+ await webhook.deploy(code);
42
+ Log.info(`Module deployed successfully`);
43
+ const moduleFiles = resolve(opts.dir, "**", "*.ts");
44
+ const watcher = watch(moduleFiles);
45
+ const peprTS = resolve(opts.dir, "pepr.ts");
46
+ let program;
47
+ // Run the module once to start the server
48
+ runDev(peprTS);
49
+ // Watch for changes
50
+ watcher.on("ready", () => {
51
+ Log.info(`Watching for changes in ${moduleFiles}`);
52
+ watcher.on("all", async (event, path) => {
53
+ Log.debug({ event, path }, "File changed");
54
+ // Kill the running process
55
+ if (program) {
56
+ program.kill("SIGKILL");
57
+ }
58
+ // Start the process again
59
+ program = runDev(peprTS);
60
+ });
61
+ });
62
+ }
63
+ catch (e) {
64
+ Log.error(`Error deploying module: ${e}`);
65
+ process.exit(1);
66
+ }
67
+ });
68
+ }
69
+ function runDev(path) {
70
+ try {
71
+ const program = spawn("./node_modules/.bin/ts-node", [path], {
72
+ env: {
73
+ ...process.env,
74
+ SSL_KEY_PATH: "insecure-tls.key",
75
+ SSL_CERT_PATH: "insecure-tls.crt",
76
+ },
77
+ });
78
+ program.stdout.on("data", data => console.log(data.toString()));
79
+ program.stderr.on("data", data => console.error(data.toString()));
80
+ program.on("close", code => {
81
+ Log.info(`Process exited with code ${code}`);
82
+ });
83
+ return program;
84
+ }
85
+ catch (e) {
86
+ Log.debug(e);
87
+ Log.error(`Error running module: ${e}`);
88
+ process.exit(1);
89
+ }
90
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import { version } from "../../package.json";
4
+ import { banner } from "./banner";
5
+ import build from "./build";
6
+ import capability from "./capability";
7
+ import deploy from "./deploy";
8
+ import dev from "./dev";
9
+ import init from "./init";
10
+ import { RootCmd } from "./root";
11
+ import test from "./test";
12
+ const program = new RootCmd();
13
+ program
14
+ .version(version)
15
+ .description(`Pepr Kubernetes Thingy (v${version})`)
16
+ .action(() => {
17
+ if (program.args.length < 1) {
18
+ console.log(banner);
19
+ program.help();
20
+ }
21
+ });
22
+ init(program);
23
+ build(program);
24
+ capability(program);
25
+ test(program);
26
+ deploy(program);
27
+ dev(program);
28
+ program.parse();
@@ -0,0 +1,2 @@
1
+ import { RootCmd } from "../root";
2
+ export default function (program: RootCmd): void;
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import { execSync } from "child_process";
4
+ import { resolve } from "path";
5
+ import Log from "../../lib/logger";
6
+ import { capabilityHelloPeprTS, capabilitySnippet, genPeprTS, genPkgJSON, gitIgnore, prettierRC, readme, tsConfig, } from "./templates";
7
+ import { createDir, sanitizeName, write } from "./utils";
8
+ import { confirm, walkthrough } from "./walkthrough";
9
+ export default function (program) {
10
+ program
11
+ .command("init")
12
+ .description("Initialize a new Pepr Module")
13
+ .action(async () => {
14
+ const response = await walkthrough();
15
+ const dirName = sanitizeName(response.name);
16
+ const packageJSON = genPkgJSON(response);
17
+ const peprTS = genPeprTS();
18
+ const confirmed = await confirm(dirName, packageJSON, peprTS.path);
19
+ if (confirmed) {
20
+ console.log("Creating new Pepr module...");
21
+ try {
22
+ await createDir(dirName);
23
+ await createDir(resolve(dirName, ".vscode"));
24
+ await createDir(resolve(dirName, "capabilities"));
25
+ await write(resolve(dirName, gitIgnore.path), gitIgnore.data);
26
+ await write(resolve(dirName, prettierRC.path), prettierRC.data);
27
+ await write(resolve(dirName, packageJSON.path), packageJSON.data);
28
+ await write(resolve(dirName, readme.path), readme.data);
29
+ await write(resolve(dirName, tsConfig.path), tsConfig.data);
30
+ await write(resolve(dirName, peprTS.path), peprTS.data);
31
+ await write(resolve(dirName, ".vscode", capabilitySnippet.path), capabilitySnippet.data);
32
+ await write(resolve(dirName, "capabilities", capabilityHelloPeprTS.path), capabilityHelloPeprTS.data);
33
+ // run npm install from the new directory
34
+ process.chdir(dirName);
35
+ execSync("npm install", {
36
+ stdio: "inherit",
37
+ });
38
+ console.log(`New Pepr module created at ${dirName}`);
39
+ console.log(`Open VSCode or your editor of choice in ${dirName} to get started!`);
40
+ }
41
+ catch (e) {
42
+ Log.debug(e);
43
+ Log.error(e.message);
44
+ process.exit(1);
45
+ }
46
+ }
47
+ });
48
+ }
@@ -0,0 +1,82 @@
1
+ import { InitOptions } from "./walkthrough";
2
+ export declare function genPeprTS(): {
3
+ path: string;
4
+ data: string;
5
+ };
6
+ export declare function genPkgJSON(opts: InitOptions): {
7
+ data: {
8
+ name: string;
9
+ version: string;
10
+ description: any;
11
+ keywords: string[];
12
+ pepr: {
13
+ name: any;
14
+ version: string;
15
+ uuid: string;
16
+ onError: any;
17
+ alwaysIgnore: {
18
+ namespaces: any[];
19
+ labels: any[];
20
+ };
21
+ };
22
+ scripts: {
23
+ build: string;
24
+ start: string;
25
+ };
26
+ dependencies: {
27
+ pepr: string;
28
+ };
29
+ devDependencies: {
30
+ typescript: string;
31
+ };
32
+ };
33
+ path: string;
34
+ print: string;
35
+ };
36
+ export declare const tsConfig: {
37
+ path: string;
38
+ data: {
39
+ compilerOptions: {
40
+ esModuleInterop: boolean;
41
+ lib: string[];
42
+ moduleResolution: string;
43
+ resolveJsonModule: boolean;
44
+ rootDir: string;
45
+ strict: boolean;
46
+ target: string;
47
+ };
48
+ include: string[];
49
+ };
50
+ };
51
+ export declare const gitIgnore: {
52
+ path: string;
53
+ data: string;
54
+ };
55
+ export declare const prettierRC: {
56
+ path: string;
57
+ data: {
58
+ arrowParens: string;
59
+ bracketSameLine: boolean;
60
+ bracketSpacing: boolean;
61
+ embeddedLanguageFormatting: string;
62
+ insertPragma: boolean;
63
+ printWidth: number;
64
+ quoteProps: string;
65
+ requirePragma: boolean;
66
+ semi: boolean;
67
+ tabWidth: number;
68
+ useTabs: boolean;
69
+ };
70
+ };
71
+ export declare const readme: {
72
+ path: string;
73
+ data: string;
74
+ };
75
+ export declare const capabilityHelloPeprTS: {
76
+ path: string;
77
+ data: string;
78
+ };
79
+ export declare const capabilitySnippet: {
80
+ path: string;
81
+ data: string;
82
+ };
@@ -0,0 +1,224 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+ import { inspect } from "util";
4
+ import { v4 as uuidv4, v5 as uuidv5 } from "uuid";
5
+ import { dependencies, version } from "../../../package.json";
6
+ import { sanitizeName } from "./utils";
7
+ export function genPeprTS() {
8
+ return {
9
+ path: "pepr.ts",
10
+ data: `import { PeprModule } from "pepr";
11
+ import cfg from "./package.json";
12
+ import { HelloPepr } from "./capabilities/hello-pepr";
13
+
14
+ /**
15
+ * This is the main entrypoint for the Pepr module. It is the file that is run when the module is started.
16
+ * This is where you register your configurations and capabilities with the module.
17
+ */
18
+ new PeprModule(cfg, [
19
+ // "HelloPepr" is a demo capability that is included with Pepr. You can remove it if you want.
20
+ HelloPepr,
21
+
22
+ // Your additional capabilities go here
23
+ ]);
24
+ `,
25
+ };
26
+ }
27
+ export function genPkgJSON(opts) {
28
+ // Generate a random UUID for the module based on the module name
29
+ const uuid = uuidv5(opts.name, uuidv4());
30
+ // Generate a name for the module based on the module name
31
+ const name = sanitizeName(opts.name);
32
+ // Make typescript a dev dependency
33
+ const { typescript } = dependencies;
34
+ const data = {
35
+ name,
36
+ version: "0.0.1",
37
+ description: opts.description,
38
+ keywords: ["pepr", "k8s", "policy-engine", "pepr-module", "security"],
39
+ pepr: {
40
+ name: opts.name.trim(),
41
+ version,
42
+ uuid,
43
+ onError: opts.errorBehavior,
44
+ alwaysIgnore: {
45
+ namespaces: [],
46
+ labels: [],
47
+ },
48
+ },
49
+ scripts: {
50
+ build: "pepr build",
51
+ start: "pepr dev",
52
+ },
53
+ dependencies: {
54
+ pepr: `^${version}`,
55
+ },
56
+ devDependencies: {
57
+ typescript,
58
+ },
59
+ };
60
+ return {
61
+ data,
62
+ path: "package.json",
63
+ print: inspect(data, false, 5, true),
64
+ };
65
+ }
66
+ export const tsConfig = {
67
+ path: "tsconfig.json",
68
+ data: {
69
+ compilerOptions: {
70
+ esModuleInterop: true,
71
+ lib: ["ES2020"],
72
+ moduleResolution: "node",
73
+ resolveJsonModule: true,
74
+ rootDir: ".",
75
+ strict: false,
76
+ target: "ES2020",
77
+ },
78
+ include: ["**/*.ts"],
79
+ },
80
+ };
81
+ export const gitIgnore = {
82
+ path: ".gitignore",
83
+ data: `# Ignore node_modules
84
+ node_modules
85
+ dist
86
+ `,
87
+ };
88
+ export const prettierRC = {
89
+ path: ".prettierrc",
90
+ data: {
91
+ arrowParens: "avoid",
92
+ bracketSameLine: false,
93
+ bracketSpacing: true,
94
+ embeddedLanguageFormatting: "auto",
95
+ insertPragma: false,
96
+ printWidth: 80,
97
+ quoteProps: "as-needed",
98
+ requirePragma: false,
99
+ semi: true,
100
+ tabWidth: 2,
101
+ useTabs: false,
102
+ },
103
+ };
104
+ export const readme = {
105
+ path: "README.md",
106
+ data: `# Pepr Module
107
+
108
+ This is a Pepr module. It is a module that can be used with the [Pepr]() framework.
109
+
110
+ The \`capabilities\` directory contains all the capabilities for this module. By default,
111
+ a capability is a single typescript file in the format of \`capability-name.ts\` that is
112
+ imported in the root \`pepr.ts\` file as \`import { HelloPepr } from "./capabilities/hello-pepr";\`.
113
+ Because this is typescript, you can organize this however you choose, e.g. creating a sub-folder
114
+ per-capability or common logic in shared files or folders.
115
+
116
+ Example Structure:
117
+
118
+ \`\`\`
119
+ Module Root
120
+ ├── package.json
121
+ ├── pepr.ts
122
+ └── capabilities
123
+ ├── example-one.ts
124
+ ├── example-three.ts
125
+ └── example-two.ts
126
+ \`\`\`
127
+ `,
128
+ };
129
+ export const capabilityHelloPeprTS = {
130
+ path: "hello-pepr.ts",
131
+ data: `import { Capability, a } from "pepr";
132
+
133
+ export const HelloPepr = new Capability({
134
+ name: "hello-pepr",
135
+ description: "A simple example capability to show how things work.",
136
+ namespaces: ["pepr-demo"],
137
+ });
138
+
139
+ // Use the 'When' function to create a new Capability Action
140
+ const { When } = HelloPepr;
141
+
142
+ /**
143
+ * This is a single Capability Action. They can be in the same file or put imported from other files.
144
+ * In this exmaple, when a ConfigMap is created with the name \`example-1\`, then add a label and annotation.
145
+ *
146
+ * Equivelant to manually running:
147
+ * \`kubectl label configmap example-1 pepr=was-here\`
148
+ * \`kubectl annotate configmap example-1 pepr.dev=annotations-work-too\`
149
+ */
150
+ When(a.ConfigMap)
151
+ .IsCreated()
152
+ .WithName("example-1")
153
+ .Then(request =>
154
+ request
155
+ .SetLabel("pepr", "was-here")
156
+ .SetAnnotation("pepr.dev", "annotations-work-too")
157
+ );
158
+
159
+ /**
160
+ * This Capabiility Action does the exact same changes for example-2, except this time it uses the \`.ThenSet()\` feature.
161
+ * You can stack multiple \`.Then()\` calls, but only a single \`.ThenSet()\`
162
+ */
163
+ When(a.ConfigMap)
164
+ .IsCreated()
165
+ .WithName("example-2")
166
+ .ThenSet({
167
+ metadata: {
168
+ labels: {
169
+ pepr: "was-here",
170
+ },
171
+ annotations: {
172
+ "pepr.dev": "annotations-work-too",
173
+ },
174
+ },
175
+ });
176
+
177
+ /**
178
+ * This Capability Action combines different styles. Unlike the previous actions, this one will look for any ConfigMap
179
+ * in the \`pepr-demo\` namespace that has the label \`change=by-label\`. Note that all conditions added such as \`WithName()\`,
180
+ * \`WithLabel()\`, \`InNamespace()\`, are ANDs so all conditions must be true for the request to be procssed.
181
+ */
182
+ When(a.ConfigMap)
183
+ .IsCreated()
184
+ .WithLabel("change", "by-label")
185
+ .Then(request => {
186
+ // The K8s object e are going to mutate
187
+ const cm = request.Raw;
188
+
189
+ // Get the username and uid of the K8s reuest
190
+ const { username, uid } = request.Request.userInfo;
191
+
192
+ // Store some data about the request in the configmap
193
+ cm.data["username"] = username;
194
+ cm.data["uid"] = uid;
195
+
196
+ // You can still mix other ways of making changes too
197
+ request.SetAnnotation("pepr.dev", "making-waves");
198
+ });
199
+ `,
200
+ };
201
+ export const capabilitySnippet = {
202
+ path: "pepr.code-snippets",
203
+ data: `{
204
+ "Create a new Pepr capability": {
205
+ "prefix": "create pepr capability",
206
+ "body": [
207
+ "import { Capability, a } from 'pepr';",
208
+ "",
209
+ "export const $\{TM_FILENAME_BASE/(.*)/$\{1:/pascalcase}/} = new Capability({",
210
+ "\\tname: '$\{TM_FILENAME_BASE}',",
211
+ "\\tdescription: '$\{1:A brief description of this capability.}',",
212
+ "\\tnamespaces: [$\{2:}],",
213
+ "});",
214
+ "",
215
+ "// Use the 'When' function to create a new Capability Action",
216
+ "const { When } = $\{TM_FILENAME_BASE/(.*)/$\{1:/pascalcase}/};",
217
+ "",
218
+ "// When(a.<Kind>).Is<Event>().Then(change => change.<changes>",
219
+ "When($\{3:})"
220
+ ],
221
+ "description": "Creates a new Pepr capability with a specified description, and optional namespaces, and adds a When statement for the specified value."
222
+ }
223
+ }`,
224
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Sanitize a user input name to be used as a pepr module directory name
3
+ *
4
+ * @param name the user input name
5
+ * @returns the sanitized name
6
+ */
7
+ export declare function sanitizeName(name: string): string;
8
+ /**
9
+ * Creates a directory and throws an error if it already exists
10
+ *
11
+ * @param dir - The directory to create
12
+ */
13
+ export declare function createDir(dir: string): Promise<void>;
14
+ /**
15
+ * Write data to a file on disk
16
+ * @param path - The path to the file
17
+ * @param data - The data to write
18
+ * @returns A promise that resolves when the file has been written
19
+ */
20
+ export declare function write(path: string, data: unknown): Promise<void>;