From be94aac86710aca2c083ae098d94ac9f8ca09f51 Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 10:00:01 +0100
Subject: [PATCH 01/11] fix: added template selection to create-monokle-plugin
and improved docs
---
.gitignore | 3 +-
package-lock.json | 6 +-
packages/create-monokle-plugin/README.md | 29 +-
packages/create-monokle-plugin/index.js | 85 +-
packages/create-monokle-plugin/package.json | 4 +-
.../template-validation-ts/README.md | 37 -
.../template-validation-ts/src/plugin.ts | 17 -
.../src/rules/2-exampleRelated.ts | 32 -
.../src/rules/4-examplePod.ts | 36 -
.../template-validation-ts/src/utils.ts | 37 -
.../validation-ts/basic-template/README.md | 56 +
.../validation-ts/basic-template}/_gitignore | 0
.../basic-template}/package-lock.json | 2 +-
.../basic-template}/package.json | 0
.../basic-template/src/plugin.ts | 12 +
.../basic-template}/src/rules/1-example.ts | 2 +-
.../basic-template}/tsconfig.json | 4 +-
.../validation-ts/crd-template/README.md | 56 +
.../validation-ts/crd-template/_gitignore | 5 +
.../crd-template/package-lock.json | 2839 +++++++++++++++++
.../validation-ts/crd-template/package.json | 19 +
.../validation-ts/crd-template/src/plugin.ts | 12 +
.../crd-template/src/rules/1-exampleCrd.ts} | 2 +-
.../src/schemas/crds/prometheus.yaml | 0
.../validation-ts/crd-template/tsconfig.json | 22 +
packages/validation/README.md | 36 +-
packages/validation/docs/configuration.md | 173 +-
packages/validation/docs/core-plugins.md | 145 +
packages/validation/docs/custom-plugins.md | 96 +
packages/validation/docs/plugin-examples.md | 137 +
packages/validation/docs/plugin-metadata.md | 84 +
31 files changed, 3592 insertions(+), 396 deletions(-)
delete mode 100644 packages/create-monokle-plugin/template-validation-ts/README.md
delete mode 100644 packages/create-monokle-plugin/template-validation-ts/src/plugin.ts
delete mode 100644 packages/create-monokle-plugin/template-validation-ts/src/rules/2-exampleRelated.ts
delete mode 100644 packages/create-monokle-plugin/template-validation-ts/src/rules/4-examplePod.ts
delete mode 100644 packages/create-monokle-plugin/template-validation-ts/src/utils.ts
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/basic-template/README.md
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/basic-template}/_gitignore (100%)
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/basic-template}/package-lock.json (99%)
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/basic-template}/package.json (100%)
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/basic-template/src/plugin.ts
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/basic-template}/src/rules/1-example.ts (90%)
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/basic-template}/tsconfig.json (94%)
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/README.md
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/_gitignore
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/package-lock.json
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/package.json
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/src/plugin.ts
rename packages/create-monokle-plugin/{template-validation-ts/src/rules/3-exampleCrd.ts => templates/validation-ts/crd-template/src/rules/1-exampleCrd.ts} (98%)
rename packages/create-monokle-plugin/{template-validation-ts => templates/validation-ts/crd-template}/src/schemas/crds/prometheus.yaml (100%)
create mode 100644 packages/create-monokle-plugin/templates/validation-ts/crd-template/tsconfig.json
create mode 100644 packages/validation/docs/core-plugins.md
create mode 100644 packages/validation/docs/custom-plugins.md
create mode 100644 packages/validation/docs/plugin-examples.md
create mode 100644 packages/validation/docs/plugin-metadata.md
diff --git a/.gitignore b/.gitignore
index 0aafb2e98..0607605fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# dependencies
node_modules
+__generated__
/.pnp
.idea
.pnp.js
@@ -27,4 +28,4 @@ yarn-error.log*
.vscode
-electron/env.ts
\ No newline at end of file
+electron/env.ts
diff --git a/package-lock.json b/package-lock.json
index 8062e72be..72f2f89ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23428,7 +23428,7 @@
},
"packages/components": {
"name": "@monokle/components",
- "version": "0.0.18",
+ "version": "0.0.22",
"license": "MIT",
"devDependencies": {
"@ant-design/icons": "4.7.0",
@@ -25425,7 +25425,7 @@
}
},
"packages/create-monokle-plugin": {
- "version": "0.3.1",
+ "version": "0.4.0",
"license": "MIT",
"dependencies": {
"kolorist": "1.5.1",
@@ -26110,7 +26110,7 @@
},
"packages/validation": {
"name": "@monokle/validation",
- "version": "0.10.2",
+ "version": "0.10.3",
"license": "MIT",
"dependencies": {
"@open-policy-agent/opa-wasm": "1.8.0",
diff --git a/packages/create-monokle-plugin/README.md b/packages/create-monokle-plugin/README.md
index 0fe793075..2895db66b 100644
--- a/packages/create-monokle-plugin/README.md
+++ b/packages/create-monokle-plugin/README.md
@@ -1,25 +1,9 @@
-
-
-
-
-
-
-
-
-
-
# Welcome to Create Monokle Plugin
Use this library to scaffold your custom Monokle validation plugin in seconds - which can then
be used locally or contributed to our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.
-## Table of contents
-
-- [Usage](#usage)
- - [Interactive](#interactive)
- - [Create a TypeScript validation plugin](#create-a-typescript-validation-plugin)
- - [Example](#example)
-- [Acknowledgements](#acknowledgements)
+Read more about custom plugins in the [Custom Validator documentation](../validation/docs/custom-plugins.md)
## Usage
@@ -46,3 +30,14 @@ example on how to get started with your own plugin.
This project is a modified version of [create-vite](https://github.com/vitejs/vite/tree/main/packages/create-vite) and
most credits go to them.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/create-monokle-plugin/index.js b/packages/create-monokle-plugin/index.js
index 4a4e883a3..7310ff604 100755
--- a/packages/create-monokle-plugin/index.js
+++ b/packages/create-monokle-plugin/index.js
@@ -21,10 +21,23 @@ const PLUGIN_TYPES = [
{
name: "validation-ts",
display: "TypeScript",
+ description: "Validation plugin written in Typescript",
color: blue,
- },
- ],
- },
+ templates: [
+ {
+ name: "basic",
+ description: "A sample typescript plugin with a single sample rule",
+ path: "validation-ts/basic-template"
+ },
+ {
+ name: "with-custom-crd",
+ description: "A sample typescript plugin using a custom resource definition (CRD)",
+ path: "validation-ts/crd-template"
+ }
+ ]
+ }
+ ]
+ }
];
const TEMPLATES = PLUGIN_TYPES.map(
@@ -33,21 +46,21 @@ const TEMPLATES = PLUGIN_TYPES.map(
const renameFiles = {
_gitignore: ".gitignore",
- _npmrc: ".npmrc",
+ _npmrc: ".npmrc"
};
async function init() {
const defaultTargetDir = "monokle-plugin";
let targetDir = formatTargetDir(argv._[0]);
let template = argv.template || argv.t;
- let projectName;
+ let pluginName;
const hasTemplateArg = template !== undefined;
const communityPath = path.join(cwd, ".community");
const isMonokleCommunityRepository = fs.existsSync(communityPath);
const getProjectName = () =>
- targetDir === "." ? path.basename(path.resolve()) : projectName;
+ targetDir === "." ? path.basename(path.resolve()) : pluginName;
let result = {};
@@ -56,13 +69,13 @@ async function init() {
[
{
type: targetDir ? null : "text",
- name: "projectName",
- message: reset("Project name:"),
+ name: "pluginName",
+ message: reset("Plugin name:"),
initial: defaultTargetDir,
onState: (state) => {
- projectName = state.value ?? defaultTargetDir;
+ pluginName = state.value ?? defaultTargetDir;
targetDir = formatTargetDir(state.value) || defaultTargetDir;
- },
+ }
},
{
type: () => (isValidPackageName(getProjectName()) ? null : "text"),
@@ -70,7 +83,7 @@ async function init() {
message: reset("Package name:"),
initial: () => toValidPackageName(getProjectName()),
validate: (dir) =>
- isValidPackageName(dir) || "Invalid package.json name",
+ isValidPackageName(dir) || "Invalid package.json name"
},
{
type: template && TEMPLATES.includes(template) ? null : "select",
@@ -78,15 +91,15 @@ async function init() {
message:
typeof template === "string" && !TEMPLATES.includes(template)
? reset(
- `"${template}" isn't a valid template. Please choose from below: `
- )
+ `"${template}" isn't a valid template. Please choose from below: `
+ )
: reset("Select a plugin type:"),
initial: 0,
choices: PLUGIN_TYPES.map((pluginTypes) => {
const pluginTypeColor = pluginTypes.color;
return {
title: pluginTypeColor(pluginTypes.name),
- value: pluginTypes,
+ value: pluginTypes
};
}),
onState: (state) => {
@@ -95,7 +108,7 @@ async function init() {
}
targetDir = `${state.value.name}/${targetDir}`;
- },
+ }
},
{
type: (pluginType) =>
@@ -103,14 +116,32 @@ async function init() {
name: "variant",
message: reset("Select a variant:"),
// @ts-ignore
- choices: (framework) =>
- framework.variants.map((variant) => {
+ choices: (pluginType) =>
+ pluginType.variants.map((variant) => {
const variantColor = variant.color;
return {
title: variantColor(variant.name),
- value: variant.name,
+ description: variant.description,
+ value: variant.name
};
- }),
+ })
+ },
+ {
+ type: (variant, values) => {
+ return values.pluginType && variant &&
+ values.pluginType.variants.find(elm => elm.name === variant) ? "select" : null;
+ },
+ name: "variantTemplate",
+ message: reset("Select a template:"),
+ // @ts-ignore
+ choices: (variant, values) =>
+ values.pluginType.variants.find(elm => elm.name === variant)?.templates.map(template => {
+ return {
+ title: template.name,
+ description: template.description,
+ value: template.path
+ };
+ })
},
{
type: () =>
@@ -120,7 +151,7 @@ async function init() {
(targetDir === "."
? "Current directory"
: `Target directory "${targetDir}"`) +
- ` is not empty. Remove existing files and continue?`,
+ ` is not empty. Remove existing files and continue?`
},
{
type: (_, { overwrite } = {}) => {
@@ -129,14 +160,14 @@ async function init() {
}
return null;
},
- name: "overwriteChecker",
- },
+ name: "overwriteChecker"
+ }
],
{
onCancel: () => {
throw new Error(red("✖") + " Operation cancelled");
- },
+ }
}
);
} catch (cancelled) {
@@ -145,7 +176,7 @@ async function init() {
}
// user choice associated with prompts
- const { pluginType, overwrite, packageName, variant } = result;
+ const { pluginType, overwrite, packageName, variant, variantTemplate } = result;
if (hasTemplateArg && isMonokleCommunityRepository) {
if (template.startsWith("validation")) {
@@ -162,14 +193,14 @@ async function init() {
}
// determine template
- template = variant || pluginType || template;
+ template = variantTemplate ? path.join( "templates", variantTemplate ) : variant || pluginType || template;
console.log(`\nScaffolding plugin in ${root}...`);
const templateDir = path.resolve(
fileURLToPath(import.meta.url),
"..",
- `template-${template}`
+ template
);
const write = (file, content) => {
@@ -296,7 +327,7 @@ function pkgFromUserAgent(userAgent) {
const pkgSpecArr = pkgSpec.split("/");
return {
name: pkgSpecArr[0],
- version: pkgSpecArr[1],
+ version: pkgSpecArr[1]
};
}
diff --git a/packages/create-monokle-plugin/package.json b/packages/create-monokle-plugin/package.json
index 088053886..e082b8c9d 100644
--- a/packages/create-monokle-plugin/package.json
+++ b/packages/create-monokle-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "create-monokle-plugin",
- "version": "0.3.1",
+ "version": "0.4.0",
"type": "module",
"license": "MIT",
"author": "Kubeshop",
@@ -9,7 +9,7 @@
},
"files": [
"index.js",
- "template-*"
+ "templates/**/*"
],
"main": "index.js",
"engines": {
diff --git a/packages/create-monokle-plugin/template-validation-ts/README.md b/packages/create-monokle-plugin/template-validation-ts/README.md
deleted file mode 100644
index 41397b638..000000000
--- a/packages/create-monokle-plugin/template-validation-ts/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Monokle custom validator
-
-Welcome to Monokle custom validation plugin.
-
-Developing a plugin has is build with developer experience in mind and has a short feedback loop. Read more below.
-
-## Development
-
-To start development you should enable the development server with `npm run dev`.
-
-Afterwards you can open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository. A new validator labelled "development" will appear.
-
-You can now start editing code, the development server will automatically pick up code changes and forward it to the browser where Hot Module Replacement will give you the latest version of your code in real-time. You can play around with any of the resources in your project to make sure you got the validation right.
-
-### Generating type guard for CRDs
-
-The main use case for custom validators are adding validation to your custom resource definitions. To improve the developer experience, our tooling includes a small utility to generate types and type guards from CustomResourceDefinition resources.
-
-Simply drop your YAML file that defines the CRD into the _src/crds_ directory and run `npm run codegen` or `npm install` (it runs on a post-install hook as well).
-
-Example usage:
-
-```typescript
-defineRule({
- validate({ resources } {
- resources
- .filter(r => isPrometheus(r.content))
- .forEach(prometheus => {
- prometheus.content.spec; // this is now a fully typed object.
- })
- }
-})
-```
-
-## Distribution
-
-Simply create a pull request to monokle-community-plugins and our pipelines will take care of everything!
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/plugin.ts b/packages/create-monokle-plugin/template-validation-ts/src/plugin.ts
deleted file mode 100644
index bef3f8d64..000000000
--- a/packages/create-monokle-plugin/template-validation-ts/src/plugin.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { definePlugin } from "@monokle/plugin-toolkit";
-import { noEmptyAnnotations } from "./rules/1-example.js";
-import { noAdminApi } from "./rules/3-exampleCrd.js";
-import { noPortMismatch } from "./rules/2-exampleRelated.js";
-import { noLatestImage } from "./rules/4-examplePod.js";
-
-export default definePlugin({
- id: "YCP",
- name: "Your custom plugin",
- description: "Welcome to your first plugin!",
- rules: {
- noEmptyAnnotations,
- noPortMismatch,
- noAdminApi,
- noLatestImage,
- },
-});
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/rules/2-exampleRelated.ts b/packages/create-monokle-plugin/template-validation-ts/src/rules/2-exampleRelated.ts
deleted file mode 100644
index 7538aaf90..000000000
--- a/packages/create-monokle-plugin/template-validation-ts/src/rules/2-exampleRelated.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { defineRule } from "@monokle/plugin-toolkit";
-import { isDeployment } from "../schemas/__generated__/deployment.apps.v1.js";
-import { isService } from "../schemas/__generated__/service.v1.js";
-
-/**
- * An advanced example which uses related resources
- *
- * @remark use `npm run codegen` to generate types.
- */
-export const noPortMismatch = defineRule({
- id: 2,
- description: "The target port should match any container port.",
- help: "Change to target port to a port that matching a container's port.",
- validate({ resources }, { getRelated, report }) {
- resources.filter(isService).forEach((service) => {
- const deployments = getRelated(service).filter(isDeployment);
-
- const validPorts = deployments.flatMap((d) =>
- d.spec?.template.spec?.containers.flatMap((c) =>
- c.ports?.flatMap((p) => p.containerPort)
- )
- );
-
- const servicePorts = service.spec?.ports ?? [];
- servicePorts.forEach((port, index: number) => {
- if (!validPorts.includes(Number(port.targetPort))) {
- report(service, { path: `spec.ports.${index}.targetPort` });
- }
- });
- });
- },
-});
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/rules/4-examplePod.ts b/packages/create-monokle-plugin/template-validation-ts/src/rules/4-examplePod.ts
deleted file mode 100644
index eb6ea191b..000000000
--- a/packages/create-monokle-plugin/template-validation-ts/src/rules/4-examplePod.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { defineRule } from "@monokle/plugin-toolkit";
-import { validatePodSpec } from "../utils.js";
-
-/**
- * Example validation of pod in depoyment, statefulset, job, etc.
- *
- * @remark use `npm run codegen` to build the types
- */
-export const noLatestImage = defineRule({
- id: 4,
- description: "Disallow images with the latest tag.",
- fullDescription:
- "The latest image makes it difficult to know which version is exactly running which might introduce subtle bugs or run a version that is vulnerable.",
- help: "Pin the exact version of the image.",
- validate({ resources }, { report }) {
- validatePodSpec(resources, (resource, pod, prefix) => {
- pod.initContainers?.forEach((container, index) => {
- const valid = !container.image?.endsWith("latest");
- if (valid) return;
-
- report(resource, {
- path: `${prefix}.initContainers.${index}.image`,
- });
- });
-
- pod.containers.forEach((container, index) => {
- const valid = !container.image?.endsWith("latest");
- if (valid) return;
-
- report(resource, {
- path: `${prefix}.containers.${index}.image`,
- });
- });
- });
- },
-});
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/utils.ts b/packages/create-monokle-plugin/template-validation-ts/src/utils.ts
deleted file mode 100644
index ee7b70d7e..000000000
--- a/packages/create-monokle-plugin/template-validation-ts/src/utils.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { PodSpec } from "kubernetes-types/core/v1.js";
-import { isCronJob } from "./schemas/__generated__/cronjob.batch.v1.js";
-import { isDaemonSet } from "./schemas/__generated__/daemonset.apps.v1.js";
-import { isDeployment } from "./schemas/__generated__/deployment.apps.v1.js";
-import { isJob } from "./schemas/__generated__/job.batch.v1.js";
-import { isPod } from "./schemas/__generated__/pod.v1.js";
-import { isStatefulSet } from "./schemas/__generated__/statefulset.apps.v1.js";
-
-export function validatePodSpec(
- resources: any[],
- validateFn: (resource: any, pod: PodSpec, prefix: string) => void
-): void {
- resources.forEach((resource) => {
- if (
- isDeployment(resource) ||
- isStatefulSet(resource) ||
- isDaemonSet(resource) ||
- isJob(resource)
- ) {
- const pod = resource.spec?.template.spec;
- if (!pod) return;
- return validateFn(resource, pod, "spec.template.spec");
- }
-
- if (isCronJob(resource)) {
- const pod = resource.spec?.jobTemplate.spec?.template.spec;
- if (!pod) return;
- return validateFn(resource, pod, "spec.jobTemplate.spec.template.spec");
- }
-
- if (isPod(resource)) {
- const pod = resource.spec;
- if (!pod) return;
- return validateFn(resource, pod, "spec");
- }
- });
-}
diff --git a/packages/create-monokle-plugin/templates/validation-ts/basic-template/README.md b/packages/create-monokle-plugin/templates/validation-ts/basic-template/README.md
new file mode 100644
index 000000000..d70d45b55
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/basic-template/README.md
@@ -0,0 +1,56 @@
+# Monokle Custom Validator
+
+Welcome to your Monokle custom validation plugin!
+
+Follow these steps to get going:
+
+- Update the generated `src/plugin.ts` file with correct metadata ([read more](#plugin-metadata))
+- Implement your rule(s) in the `src/rules` folder and make sure to add them to the `src/plugin.ts` file
+- Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
+- If you want to share your plugin with the community, fork and add it to the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins)
+ repository, and open a PR back to the repository for us to review and merge.
+- Update this README as desired (if you plan to share the code/repo containing it).
+
+## Tips & Tricks
+
+### Local Development with Monokle Cloud
+
+To enable direct testing/debugging of your validators with Monokle Cloud, run
+
+```
+npm run dev
+```
+
+which will start a local development server that Monokle Cloud can connect to:
+
+- Open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository.
+- Enabled "Development Mode" at the bottom of the pane
+- A new validator labelled "development" will appear.
+
+You can now start editing code; the local development server will automatically pick up code changes and forward
+them to the browser where Hot Module Replacement will give you the latest version of your code in real-time.
+You can play around with any of the resources in your project to make sure you got the validation right.
+
+### Generate Resources
+
+Put any CRDs you might want to use/validation in the `src/schemas/crds` folder (in JSON format) and run
+
+```
+npm run codegen
+```
+
+This will generate utility methods and types for each CRD into the `src/schemas/__generated__` folder, for you
+to import/use in your validators.
+
+### Packaging
+
+To package your plugin into a single `plugin.js` file, run
+
+```
+npm run build
+```
+
+which will create a `dist/plugin.js` file in your repo.
+
+> NOTE: We will do all packaging/deployment for you if you submit your plugin to
+the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.
diff --git a/packages/create-monokle-plugin/template-validation-ts/_gitignore b/packages/create-monokle-plugin/templates/validation-ts/basic-template/_gitignore
similarity index 100%
rename from packages/create-monokle-plugin/template-validation-ts/_gitignore
rename to packages/create-monokle-plugin/templates/validation-ts/basic-template/_gitignore
diff --git a/packages/create-monokle-plugin/template-validation-ts/package-lock.json b/packages/create-monokle-plugin/templates/validation-ts/basic-template/package-lock.json
similarity index 99%
rename from packages/create-monokle-plugin/template-validation-ts/package-lock.json
rename to packages/create-monokle-plugin/templates/validation-ts/basic-template/package-lock.json
index 30059a7f9..aa7b8732c 100644
--- a/packages/create-monokle-plugin/template-validation-ts/package-lock.json
+++ b/packages/create-monokle-plugin/templates/validation-ts/basic-template/package-lock.json
@@ -10,7 +10,7 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@monokle/plugin-toolkit": "0.1.0"
+ "@monokle/plugin-toolkit": "^0.1.0"
}
},
"node_modules/@babel/code-frame": {
diff --git a/packages/create-monokle-plugin/template-validation-ts/package.json b/packages/create-monokle-plugin/templates/validation-ts/basic-template/package.json
similarity index 100%
rename from packages/create-monokle-plugin/template-validation-ts/package.json
rename to packages/create-monokle-plugin/templates/validation-ts/basic-template/package.json
diff --git a/packages/create-monokle-plugin/templates/validation-ts/basic-template/src/plugin.ts b/packages/create-monokle-plugin/templates/validation-ts/basic-template/src/plugin.ts
new file mode 100644
index 000000000..d508625a0
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/basic-template/src/plugin.ts
@@ -0,0 +1,12 @@
+import { definePlugin } from "@monokle/plugin-toolkit";
+import { noEmptyAnnotations } from "./rules/1-example.js";
+
+export default definePlugin({
+ id: "YCP",
+ name: "ycp",
+ displayName: "Your custom plugin",
+ description: "Welcome to your first plugin!",
+ rules: {
+ noEmptyAnnotations
+ },
+});
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/rules/1-example.ts b/packages/create-monokle-plugin/templates/validation-ts/basic-template/src/rules/1-example.ts
similarity index 90%
rename from packages/create-monokle-plugin/template-validation-ts/src/rules/1-example.ts
rename to packages/create-monokle-plugin/templates/validation-ts/basic-template/src/rules/1-example.ts
index 9fca72dea..2acb1723f 100644
--- a/packages/create-monokle-plugin/template-validation-ts/src/rules/1-example.ts
+++ b/packages/create-monokle-plugin/templates/validation-ts/basic-template/src/rules/1-example.ts
@@ -1,7 +1,7 @@
import { defineRule } from "@monokle/plugin-toolkit";
/**
- * A basic example.
+ * A basic example that checks if a resource has annotations
*/
export const noEmptyAnnotations = defineRule({
id: 1,
diff --git a/packages/create-monokle-plugin/template-validation-ts/tsconfig.json b/packages/create-monokle-plugin/templates/validation-ts/basic-template/tsconfig.json
similarity index 94%
rename from packages/create-monokle-plugin/template-validation-ts/tsconfig.json
rename to packages/create-monokle-plugin/templates/validation-ts/basic-template/tsconfig.json
index 7cc6b644d..7512bbe16 100644
--- a/packages/create-monokle-plugin/template-validation-ts/tsconfig.json
+++ b/packages/create-monokle-plugin/templates/validation-ts/basic-template/tsconfig.json
@@ -16,5 +16,7 @@
"removeComments": false,
"strict": true
},
- "include": ["src"]
+ "include": [
+ "src"
+ ]
}
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/README.md b/packages/create-monokle-plugin/templates/validation-ts/crd-template/README.md
new file mode 100644
index 000000000..39d910073
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/README.md
@@ -0,0 +1,56 @@
+# Monokle Custom Validator
+
+Welcome to your Monokle custom validation plugin!
+
+Follow these steps to get going:
+
+- Update the generated `src/plugin.ts` file with correct metadata ([read more](#plugin-metadata))
+- Implement your rule(s) in the `src/rules` folder and make sure to add them to the `src/plugin.ts` file
+- Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
+- If you want to share your plugin with the community, fork and add it to the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins)
+ repository, and open a PR back to the repository for us to review and merge.
+- Update this README as desired (if you plan to share the code/repo containing it).
+
+## Tips & Tricks
+
+### Local Development with Monokle Cloud
+
+To enable direct testing/debugging of your validators with Monokle Cloud, run
+
+```
+npm run dev
+```
+
+which will start a local development server that Monokle Cloud can connect to:
+
+- Open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository.
+- Enabled "Development Mode" at the bottom of the pane
+- A new validator labelled "development" will appear.
+
+You can now start editing code; the local development server will automatically pick up code changes and forward
+them to the browser where Hot Module Replacement will give you the latest version of your code in real-time.
+You can play around with any of the resources in your project to make sure you got the validation right.
+
+### Generate Resources
+
+Put any CRDs you might want to use/validation in the `src/schemas/crds` folder (in JSON format) and run
+
+```
+npm run codegen
+```
+
+This will generate utility methods and types for each CRD into the `src/schemas/__generated__` folder, for you
+to import/use in your validators.
+
+### Packaging
+
+To package your plugin into a single `plugin.js` file, run
+
+```
+npm run build
+```
+
+which will create a `dist/plugin.js` file in your repo.
+
+> NOTE: We will do all packaging/deployment for you if you submit your plugin to
+the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/_gitignore b/packages/create-monokle-plugin/templates/validation-ts/crd-template/_gitignore
new file mode 100644
index 000000000..3c47fb2c6
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/_gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+build
+dist
+node_modules
+**/__generated__/**
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/package-lock.json b/packages/create-monokle-plugin/templates/validation-ts/crd-template/package-lock.json
new file mode 100644
index 000000000..aa7b8732c
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/package-lock.json
@@ -0,0 +1,2839 @@
+{
+ "name": "monokle-custom-validator",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "monokle-custom-validator",
+ "version": "1.0.0",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@monokle/plugin-toolkit": "^0.1.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dependencies": {
+ "@babel/highlight": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcherny/json-schema-ref-parser": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz",
+ "integrity": "sha512-vmEmnJCfpkLdas++9OYg6riIezTYqTHpqUTODJzHLzs5UnXujbOJW9VwcVCnyo1mVRt32FRr23iXBx/sX8YbeQ==",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.6",
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
+ },
+ "node_modules/@monokle/plugin-toolkit": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@monokle/plugin-toolkit/-/plugin-toolkit-0.1.0.tgz",
+ "integrity": "sha512-ok8pwnPAOmX81MKt6yC5t6GuUnlHDMxMJ2wmf/4MkTj8mrIfS02y2+g/kb1va1/iT/Kb9cI1npkKj1bQ9ZlB1g==",
+ "dependencies": {
+ "@monokle/validation": "*",
+ "@rollup/plugin-json": "5.0.1",
+ "@rollup/plugin-node-resolve": "15.0.1",
+ "@rollup/plugin-typescript": "8.5.0",
+ "@types/connect": "3.4.35",
+ "@types/fs-extra": "9.0.13",
+ "@types/klaw-sync": "6.0.1",
+ "cac": "6.7.14",
+ "connect": "3.7.0",
+ "fs-extra": "10.1.0",
+ "json-schema-to-typescript": "11.0.2",
+ "klaw-sync": "6.0.0",
+ "kubernetes-types": "1.25.0",
+ "picocolors": "1.0.0",
+ "rollup": "3.2.3",
+ "rollup-plugin-terser": "7.0.2",
+ "tslib": "2.4.1",
+ "typescript": "4.8.4",
+ "yaml": "2.1.3"
+ },
+ "bin": {
+ "monokle-plugin-toolkit": "dist/cli/main.cjs"
+ }
+ },
+ "node_modules/@monokle/plugin-toolkit/node_modules/rollup": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.2.3.tgz",
+ "integrity": "sha512-qfadtkY5kl0F5e4dXVdj2D+GtOdifasXHFMiL1SMf9ADQDv5Eti6xReef9FKj+iQPR2pvtqWna57s/PjARY4fg==",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/@monokle/validation": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@monokle/validation/-/validation-0.9.1.tgz",
+ "integrity": "sha512-sd2FvdpVu6TxyS6Wypfhk9xFryDEFhFcXfOayBXpi9AQhKveTVhOtsaddjk1gE17Sgu9qUrxgbSwpIf4gszpFA==",
+ "dependencies": {
+ "@open-policy-agent/opa-wasm": "1.8.0",
+ "ajv": "6.12.6",
+ "change-case": "4.1.2",
+ "isomorphic-fetch": "3.0.0",
+ "lodash": "4.17.21",
+ "tiny-invariant": "1.2.0",
+ "yaml": "2.1.1",
+ "zod": "3.19.1"
+ }
+ },
+ "node_modules/@monokle/validation/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@monokle/validation/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/@monokle/validation/node_modules/yaml": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
+ "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@open-policy-agent/opa-wasm": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@open-policy-agent/opa-wasm/-/opa-wasm-1.8.0.tgz",
+ "integrity": "sha512-IFXh52ndKH5iWsB5ysWpjDxLtA5nUCMgalV7gbzW9VfjyDvu7Iq3G3wz3cXYtK1VWa94EeYi8oIrTrzzg33szQ==",
+ "dependencies": {
+ "sprintf-js": "^1.1.2",
+ "yaml": "^1.10.2"
+ }
+ },
+ "node_modules/@open-policy-agent/opa-wasm/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@rollup/plugin-json": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-5.0.1.tgz",
+ "integrity": "sha512-QCwhZZLvM8nRcTHyR1vOgyTMiAnjiNj1ebD/BMRvbO1oc/z14lZH6PfxXeegee2B6mky/u9fia4fxRM4TqrUaw==",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
+ "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-builtin-module": "^3.2.0",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-typescript": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz",
+ "integrity": "sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.1.0",
+ "resolve": "^1.17.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.14.0",
+ "tslib": "*",
+ "typescript": ">=3.7.0"
+ },
+ "peerDependenciesMeta": {
+ "tslib": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-typescript/node_modules/@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dependencies": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0"
+ }
+ },
+ "node_modules/@rollup/plugin-typescript/node_modules/@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
+ },
+ "node_modules/@rollup/plugin-typescript/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+ "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+ "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+ },
+ "node_modules/@types/fs-extra": {
+ "version": "9.0.13",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+ "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
+ },
+ "node_modules/@types/klaw-sync": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.1.tgz",
+ "integrity": "sha512-hqWJe0mMSxC5fiQjCJzziko2Xxh2HjDAPZNk7Zwv+Uo56XlViXR6p1RzjUCQvFvLd+IXEGeyVHTaAibrbyU1Rw==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.14.188",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz",
+ "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w=="
+ },
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="
+ },
+ "node_modules/@types/node": {
+ "version": "18.11.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg=="
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz",
+ "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow=="
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
+ },
+ "node_modules/acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "node_modules/builtin-modules": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
+ },
+ "node_modules/camel-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
+ "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+ "dependencies": {
+ "pascal-case": "^3.1.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/capital-case": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz",
+ "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case-first": "^2.0.2"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/change-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz",
+ "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==",
+ "dependencies": {
+ "camel-case": "^4.1.2",
+ "capital-case": "^1.0.4",
+ "constant-case": "^3.0.4",
+ "dot-case": "^3.0.4",
+ "header-case": "^2.0.4",
+ "no-case": "^3.0.4",
+ "param-case": "^3.0.4",
+ "pascal-case": "^3.1.2",
+ "path-case": "^3.0.4",
+ "sentence-case": "^3.0.4",
+ "snake-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/cli-color": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz",
+ "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==",
+ "dependencies": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.61",
+ "es6-iterator": "^2.0.3",
+ "memoizee": "^0.4.15",
+ "timers-ext": "^0.1.7"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/constant-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz",
+ "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case": "^2.0.2"
+ }
+ },
+ "node_modules/d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dependencies": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dependencies": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "node_modules/es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "node_modules/ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "dependencies": {
+ "type": "^2.7.2"
+ }
+ },
+ "node_modules/ext/node_modules/type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "node_modules/get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-promise": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz",
+ "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==",
+ "dependencies": {
+ "@types/glob": "^7.1.3"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://github.com/sponsors/ahmadnassri"
+ },
+ "peerDependencies": {
+ "glob": "^7.1.6"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/header-case": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz",
+ "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==",
+ "dependencies": {
+ "capital-case": "^1.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/is-builtin-module": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+ "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
+ "dependencies": {
+ "builtin-modules": "^3.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
+ },
+ "node_modules/is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+ },
+ "node_modules/isomorphic-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
+ "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
+ "dependencies": {
+ "node-fetch": "^2.6.1",
+ "whatwg-fetch": "^3.4.1"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-to-typescript": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-11.0.2.tgz",
+ "integrity": "sha512-XRyeXBJeo/IH4eTP5D1ptX78vCvH86nMDt2k3AxO28C3uYWEDmy4mgPyMpb8bLJ/pJMElOGuQbnKR5Y6NSh3QQ==",
+ "dependencies": {
+ "@bcherny/json-schema-ref-parser": "9.0.9",
+ "@types/json-schema": "^7.0.11",
+ "@types/lodash": "^4.14.182",
+ "@types/prettier": "^2.6.1",
+ "cli-color": "^2.0.2",
+ "get-stdin": "^8.0.0",
+ "glob": "^7.1.6",
+ "glob-promise": "^4.2.2",
+ "is-glob": "^4.0.3",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.6",
+ "mkdirp": "^1.0.4",
+ "mz": "^2.7.0",
+ "prettier": "^2.6.2"
+ },
+ "bin": {
+ "json2ts": "dist/src/cli.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/klaw-sync": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+ "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+ "dependencies": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "node_modules/kubernetes-types": {
+ "version": "1.25.0",
+ "resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.25.0.tgz",
+ "integrity": "sha512-PVbOhw7Rd6yRLjvkaN/agqDLjEq9iwUPTvO+lrYVlcWyC2/Qm9grHL1O8oNTPFisuSamdYdTxtSpmmaKKO6VGg=="
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lru-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
+ "dependencies": {
+ "es5-ext": "~0.10.2"
+ }
+ },
+ "node_modules/memoizee": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
+ "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
+ "dependencies": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.53",
+ "es6-weak-map": "^2.0.3",
+ "event-emitter": "^0.3.5",
+ "is-promise": "^2.2.2",
+ "lru-queue": "^0.1.0",
+ "next-tick": "^1.1.0",
+ "timers-ext": "^0.1.7"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/param-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
+ "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/pascal-case": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
+ "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/path-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz",
+ "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+ "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.79.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+ "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "peer": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup-plugin-terser": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
+ "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "jest-worker": "^26.2.1",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^5.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/sentence-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz",
+ "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case-first": "^2.0.2"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.15.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
+ "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/timers-ext": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+ "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+ "dependencies": {
+ "es5-ext": "~0.10.46",
+ "next-tick": "1"
+ }
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz",
+ "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg=="
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ },
+ "node_modules/type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "node_modules/typescript": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/upper-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz",
+ "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/upper-case-first": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz",
+ "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-fetch": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
+ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/yaml": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz",
+ "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.19.1",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.19.1.tgz",
+ "integrity": "sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ }
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "requires": {
+ "@babel/highlight": "^7.18.6"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
+ },
+ "@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@bcherny/json-schema-ref-parser": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz",
+ "integrity": "sha512-vmEmnJCfpkLdas++9OYg6riIezTYqTHpqUTODJzHLzs5UnXujbOJW9VwcVCnyo1mVRt32FRr23iXBx/sX8YbeQ==",
+ "requires": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.6",
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
+ },
+ "@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "requires": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
+ },
+ "@monokle/plugin-toolkit": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@monokle/plugin-toolkit/-/plugin-toolkit-0.1.0.tgz",
+ "integrity": "sha512-ok8pwnPAOmX81MKt6yC5t6GuUnlHDMxMJ2wmf/4MkTj8mrIfS02y2+g/kb1va1/iT/Kb9cI1npkKj1bQ9ZlB1g==",
+ "requires": {
+ "@monokle/validation": "*",
+ "@rollup/plugin-json": "5.0.1",
+ "@rollup/plugin-node-resolve": "15.0.1",
+ "@rollup/plugin-typescript": "8.5.0",
+ "@types/connect": "3.4.35",
+ "@types/fs-extra": "9.0.13",
+ "@types/klaw-sync": "6.0.1",
+ "cac": "6.7.14",
+ "connect": "3.7.0",
+ "fs-extra": "10.1.0",
+ "json-schema-to-typescript": "11.0.2",
+ "klaw-sync": "6.0.0",
+ "kubernetes-types": "1.25.0",
+ "picocolors": "1.0.0",
+ "rollup": "3.2.3",
+ "rollup-plugin-terser": "7.0.2",
+ "tslib": "2.4.1",
+ "typescript": "4.8.4",
+ "yaml": "2.1.3"
+ },
+ "dependencies": {
+ "rollup": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.2.3.tgz",
+ "integrity": "sha512-qfadtkY5kl0F5e4dXVdj2D+GtOdifasXHFMiL1SMf9ADQDv5Eti6xReef9FKj+iQPR2pvtqWna57s/PjARY4fg==",
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ }
+ }
+ },
+ "@monokle/validation": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@monokle/validation/-/validation-0.9.1.tgz",
+ "integrity": "sha512-sd2FvdpVu6TxyS6Wypfhk9xFryDEFhFcXfOayBXpi9AQhKveTVhOtsaddjk1gE17Sgu9qUrxgbSwpIf4gszpFA==",
+ "requires": {
+ "@open-policy-agent/opa-wasm": "1.8.0",
+ "ajv": "6.12.6",
+ "change-case": "4.1.2",
+ "isomorphic-fetch": "3.0.0",
+ "lodash": "4.17.21",
+ "tiny-invariant": "1.2.0",
+ "yaml": "2.1.1",
+ "zod": "3.19.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "yaml": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
+ "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw=="
+ }
+ }
+ },
+ "@open-policy-agent/opa-wasm": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@open-policy-agent/opa-wasm/-/opa-wasm-1.8.0.tgz",
+ "integrity": "sha512-IFXh52ndKH5iWsB5ysWpjDxLtA5nUCMgalV7gbzW9VfjyDvu7Iq3G3wz3cXYtK1VWa94EeYi8oIrTrzzg33szQ==",
+ "requires": {
+ "sprintf-js": "^1.1.2",
+ "yaml": "^1.10.2"
+ },
+ "dependencies": {
+ "yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
+ }
+ }
+ },
+ "@rollup/plugin-json": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-5.0.1.tgz",
+ "integrity": "sha512-QCwhZZLvM8nRcTHyR1vOgyTMiAnjiNj1ebD/BMRvbO1oc/z14lZH6PfxXeegee2B6mky/u9fia4fxRM4TqrUaw==",
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1"
+ }
+ },
+ "@rollup/plugin-node-resolve": {
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
+ "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
+ "requires": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-builtin-module": "^3.2.0",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ }
+ },
+ "@rollup/plugin-typescript": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz",
+ "integrity": "sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==",
+ "requires": {
+ "@rollup/pluginutils": "^3.1.0",
+ "resolve": "^1.17.0"
+ },
+ "dependencies": {
+ "@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "requires": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ }
+ },
+ "@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
+ },
+ "estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="
+ }
+ }
+ },
+ "@rollup/pluginutils": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
+ "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
+ "requires": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/estree": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
+ "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+ },
+ "@types/fs-extra": {
+ "version": "9.0.13",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+ "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
+ },
+ "@types/klaw-sync": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/klaw-sync/-/klaw-sync-6.0.1.tgz",
+ "integrity": "sha512-hqWJe0mMSxC5fiQjCJzziko2Xxh2HjDAPZNk7Zwv+Uo56XlViXR6p1RzjUCQvFvLd+IXEGeyVHTaAibrbyU1Rw==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/lodash": {
+ "version": "4.14.188",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz",
+ "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w=="
+ },
+ "@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="
+ },
+ "@types/node": {
+ "version": "18.11.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
+ "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg=="
+ },
+ "@types/prettier": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz",
+ "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow=="
+ },
+ "@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
+ },
+ "acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "builtin-modules": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw=="
+ },
+ "cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="
+ },
+ "call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
+ },
+ "camel-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
+ "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+ "requires": {
+ "pascal-case": "^3.1.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "capital-case": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz",
+ "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==",
+ "requires": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case-first": "^2.0.2"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "change-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz",
+ "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==",
+ "requires": {
+ "camel-case": "^4.1.2",
+ "capital-case": "^1.0.4",
+ "constant-case": "^3.0.4",
+ "dot-case": "^3.0.4",
+ "header-case": "^2.0.4",
+ "no-case": "^3.0.4",
+ "param-case": "^3.0.4",
+ "pascal-case": "^3.1.2",
+ "path-case": "^3.0.4",
+ "sentence-case": "^3.0.4",
+ "snake-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "cli-color": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz",
+ "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==",
+ "requires": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.61",
+ "es6-iterator": "^2.0.3",
+ "memoizee": "^0.4.15",
+ "timers-ext": "^0.1.7"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ }
+ },
+ "constant-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz",
+ "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==",
+ "requires": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case": "^2.0.2"
+ }
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+ },
+ "dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "requires": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+ },
+ "es5-ext": {
+ "version": "0.10.62",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+ "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+ "requires": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+ },
+ "estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "requires": {
+ "type": "^2.7.2"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+ "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+ }
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg=="
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-promise": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz",
+ "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==",
+ "requires": {
+ "@types/glob": "^7.1.3"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+ },
+ "header-case": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz",
+ "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==",
+ "requires": {
+ "capital-case": "^1.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "is-builtin-module": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+ "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
+ "requires": {
+ "builtin-modules": "^3.3.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
+ },
+ "is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+ },
+ "isomorphic-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
+ "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
+ "requires": {
+ "node-fetch": "^2.6.1",
+ "whatwg-fetch": "^3.4.1"
+ }
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "json-schema-to-typescript": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-11.0.2.tgz",
+ "integrity": "sha512-XRyeXBJeo/IH4eTP5D1ptX78vCvH86nMDt2k3AxO28C3uYWEDmy4mgPyMpb8bLJ/pJMElOGuQbnKR5Y6NSh3QQ==",
+ "requires": {
+ "@bcherny/json-schema-ref-parser": "9.0.9",
+ "@types/json-schema": "^7.0.11",
+ "@types/lodash": "^4.14.182",
+ "@types/prettier": "^2.6.1",
+ "cli-color": "^2.0.2",
+ "get-stdin": "^8.0.0",
+ "glob": "^7.1.6",
+ "glob-promise": "^4.2.2",
+ "is-glob": "^4.0.3",
+ "lodash": "^4.17.21",
+ "minimist": "^1.2.6",
+ "mkdirp": "^1.0.4",
+ "mz": "^2.7.0",
+ "prettier": "^2.6.2"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "klaw-sync": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+ "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+ "requires": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
+ "kubernetes-types": {
+ "version": "1.25.0",
+ "resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.25.0.tgz",
+ "integrity": "sha512-PVbOhw7Rd6yRLjvkaN/agqDLjEq9iwUPTvO+lrYVlcWyC2/Qm9grHL1O8oNTPFisuSamdYdTxtSpmmaKKO6VGg=="
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "requires": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "lru-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
+ "requires": {
+ "es5-ext": "~0.10.2"
+ }
+ },
+ "memoizee": {
+ "version": "0.4.15",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
+ "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
+ "requires": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.53",
+ "es6-weak-map": "^2.0.3",
+ "event-emitter": "^0.3.5",
+ "is-promise": "^2.2.2",
+ "lru-queue": "^0.1.0",
+ "next-tick": "^1.1.0",
+ "timers-ext": "^0.1.7"
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "requires": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+ },
+ "no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "requires": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "param-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
+ "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+ "requires": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "pascal-case": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
+ "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+ "requires": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "path-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz",
+ "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==",
+ "requires": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ },
+ "prettier": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+ "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "rollup": {
+ "version": "2.79.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+ "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "peer": true,
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "rollup-plugin-terser": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
+ "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "jest-worker": "^26.2.1",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^5.0.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "sentence-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz",
+ "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==",
+ "requires": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3",
+ "upper-case-first": "^2.0.2"
+ }
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "requires": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "terser": {
+ "version": "5.15.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
+ "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "requires": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ }
+ },
+ "thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "requires": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "requires": {
+ "thenify": ">= 3.1.0 < 4"
+ }
+ },
+ "timers-ext": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+ "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+ "requires": {
+ "es5-ext": "~0.10.46",
+ "next-tick": "1"
+ }
+ },
+ "tiny-invariant": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz",
+ "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg=="
+ },
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "typescript": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+ "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ=="
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
+ },
+ "upper-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz",
+ "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==",
+ "requires": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "upper-case-first": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz",
+ "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==",
+ "requires": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
+ },
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "whatwg-fetch": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
+ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
+ },
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "yaml": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz",
+ "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg=="
+ },
+ "zod": {
+ "version": "3.19.1",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.19.1.tgz",
+ "integrity": "sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA=="
+ }
+ }
+}
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/package.json b/packages/create-monokle-plugin/templates/validation-ts/crd-template/package.json
new file mode 100644
index 000000000..18d0b8b6a
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "monokle-custom-validator",
+ "author": "unknown",
+ "description": "Validates with custom rules.",
+ "license": "MIT",
+ "version": "1.0.0",
+ "main": "dist/plugin.js",
+ "type": "module",
+ "scripts": {
+ "postinstall": "npm run codegen",
+ "codegen": "monokle-plugin-toolkit codegen",
+ "dev": "monokle-plugin-toolkit dev",
+ "build": "monokle-plugin-toolkit build",
+ "debug": "monokle-plugin-toolkit build --debug"
+ },
+ "dependencies": {
+ "@monokle/plugin-toolkit": "^0.1.0"
+ }
+}
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/plugin.ts b/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/plugin.ts
new file mode 100644
index 000000000..9ca6809e0
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/plugin.ts
@@ -0,0 +1,12 @@
+import { definePlugin } from "@monokle/plugin-toolkit";
+import { noAdminApi } from "./rules/1-exampleCrd.js";
+
+export default definePlugin({
+ id: "YCP",
+ name: "ycp",
+ displayName: "Sample CRD plugin",
+ description: "Welcome to your first plugin!",
+ rules: {
+ noAdminApi,
+ },
+});
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/rules/3-exampleCrd.ts b/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/rules/1-exampleCrd.ts
similarity index 98%
rename from packages/create-monokle-plugin/template-validation-ts/src/rules/3-exampleCrd.ts
rename to packages/create-monokle-plugin/templates/validation-ts/crd-template/src/rules/1-exampleCrd.ts
index 74b776547..c56f283f5 100644
--- a/packages/create-monokle-plugin/template-validation-ts/src/rules/3-exampleCrd.ts
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/rules/1-exampleCrd.ts
@@ -7,7 +7,7 @@ import { isPrometheus } from "../schemas/__generated__/prometheus.monitoring.cor
* @remark use `npm run codegen` to build the types
*/
export const noAdminApi = defineRule({
- id: 3,
+ id: 1,
description: "Disallow the admin API for Prometheus instances.",
help: "Do not set enabledAdminAPI to true.",
validate({ resources }, { report }) {
diff --git a/packages/create-monokle-plugin/template-validation-ts/src/schemas/crds/prometheus.yaml b/packages/create-monokle-plugin/templates/validation-ts/crd-template/src/schemas/crds/prometheus.yaml
similarity index 100%
rename from packages/create-monokle-plugin/template-validation-ts/src/schemas/crds/prometheus.yaml
rename to packages/create-monokle-plugin/templates/validation-ts/crd-template/src/schemas/crds/prometheus.yaml
diff --git a/packages/create-monokle-plugin/templates/validation-ts/crd-template/tsconfig.json b/packages/create-monokle-plugin/templates/validation-ts/crd-template/tsconfig.json
new file mode 100644
index 000000000..7512bbe16
--- /dev/null
+++ b/packages/create-monokle-plugin/templates/validation-ts/crd-template/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "rootDir": "src",
+ "outDir": "build",
+ "lib": ["ESNext", "DOM"],
+ "module": "ESNext",
+ "target": "ESNext",
+ "moduleResolution": "NodeNext",
+ "allowSyntheticDefaultImports": true,
+ "declaration": false,
+ "forceConsistentCasingInFileNames": true,
+ "esModuleInterop": true,
+ "pretty": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "removeComments": false,
+ "strict": true
+ },
+ "include": [
+ "src"
+ ]
+}
diff --git a/packages/validation/README.md b/packages/validation/README.md
index 5794e7358..76574c2f1 100644
--- a/packages/validation/README.md
+++ b/packages/validation/README.md
@@ -16,53 +16,53 @@ Extensible, static Kubernetes analysis
Monokle Validation is a TypeScript library to validate your Kubernetes resources.
-**Key features**
+### Key features
- 🚀 Start in seconds with the user-friendly configuration.
- ⚡️ Real-time validation through incremental runs.
- ⚒ Extensible architecture with plugins.
-**Core plugins**
+### Core plugins
- YAML Syntax validates that your manifests have correct YAML syntax.
- Kubernetes Schema validates that your resources and CRDs are well-defined in the schema for their resource kind.
- Resource links validates that reference to other Kubernetes resources are valid.
- Open Policy agent validates security policies to reduce your attack surface.
-**Community Plugins**
+Learn more about each Core Plugin in the [Core Plugins Documentation](docs/core-plugins.md)
+
+### Community Plugins
Check out our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repo for
plugins contributed by our community, and details on how to create your own.
-**Try the CLI or Monokle Cloud now!**
+### Try the CLI or Monokle Cloud now!
-The [Monokle CLI](https://github.com/kubeshop/monokle-core/tree/update-readme/packages/cli) provides a convenient
+The [Monokle CLI](https://github.com/kubeshop/monokle-core/tree/main/packages/cli) provides a convenient
wrapper around this library. Use it to validate your resources in seconds:
```bash
kustomize build . | monokle validate -
```
-Or [visit Monokle Cloud](https://app.monokle.com); a free web application where you can apply this validation
+Or visit [Monokle Cloud](https://app.monokle.com); a free web application where you can apply this validation
library directly on public GitHub repositories.
## Table of contents
-- [Welcome to Monokle Validation](#welcome-to-monokle-validation)
-- [Table of contents](#table-of-contents)
- [Getting started](#getting-started)
- [Configuration](#configuration)
- [The validation response](#the-validation-response)
- [Advanced usage](#advanced-usage)
- [Preloading](#preloading)
- [Incremental validation](#incremental-validation)
- - [Community plugins](#community-plugins)
+ - [Community plugins](#using-community-plugins)
- [Building user interfaces](#building-user-interfaces)
- [Caveats](#caveats)
## Getting started
-First install the validator:
+First install the validator with npm:
```
npm install @monokle/validation
@@ -75,8 +75,8 @@ const validator = createDefaultMonokleValidator();
await validator.validate({ resources: RESOURCES });
```
-Monokle is extensible and has a rich plugin system.
-You can configure and preload plugins as follows:
+The Monokle validator is extensible and has a rich plugin system. You can configure and preload
+plugins as follows:
```typescript
const validator = createDefaultMonokleValidator();
@@ -94,8 +94,6 @@ await validator.validate({ resources });
You can customize the rules and settings of the Monokle Validator through an intuitive object.
-[Learn more](https://github.com/kubeshop/monokle-core/blob/update-readme/packages/validation/docs/configuration.md)
-
```yaml
plugins:
yaml-syntax: true
@@ -110,6 +108,8 @@ settings:
schemaVersion: v1.24.2
```
+[Learn more](https://github.com/kubeshop/monokle-core/blob/main/packages/validation/docs/configuration.md)
+
## The validation response
The response uses [Static Analysis Results Interchange Format (SARIF)](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html).
@@ -179,9 +179,11 @@ SARIF contains both metadata of the tool and the results of the validation. You
### Preloading
-The plugins have to be initialized which might require heavy operations such as fetching large JSON schemas, AJV compilation, WASM initialization and more.
+Each validation plugin has to be initialized which might require heavy operations such as fetching large
+JSON schemas, AJV compilation, WASM initialization and more.
-The `preload` API avoids a long first validation and is recommended in more interactive environments. It is idempotent so you can call it as often as you want without continuously reinstantiating the plugins.
+The `preload` API avoids a long first validation and is recommended in more interactive environments.
+It is idempotent so you can call it as often as you want without continuously reinstantiating the plugins.
Example:
@@ -217,7 +219,7 @@ await validator.validate({
await validator.clear();
```
-### Community plugins
+### Using Community plugins
The Monokle Validator allows you to add custom plugins from [our community repository](https://github.com/kubeshop/monokle-community-plugins). All community plugins are thoroughly reviewed and we take care of loading the plugins for you.
diff --git a/packages/validation/docs/configuration.md b/packages/validation/docs/configuration.md
index a77744372..985bd2d68 100644
--- a/packages/validation/docs/configuration.md
+++ b/packages/validation/docs/configuration.md
@@ -1,22 +1,7 @@
-
-
-
+## Monokle Validation configuration
-
-Shared configuration for consistent validation
-
-
-
-
-
-
-
-
-## Welcome to Monokle Validation configuration
-
-Our validator uses a shared configuration file.
-
-It gives a consistent experience no matter if you validate from the CLI, GitHub Action or either of our applications (desktop & web).
+The monokle validator uses a shared configuration file providing a consistent experience no
+matter if you validate from the CLI, GitHub Action or either of our applications (desktop & web).
The configuration format is heavily inspired by ESLint and aims to be flexible and configurable for your use case. You can turn off every rule and run only with basic syntax validation or mix and match the bundled rules and your custom rules to fit the needs of your project.
@@ -38,10 +23,8 @@ settings:
schemaVersion: v1.24.2
```
-## Table of content
+## Table of contents
-- [Welcome to Monokle Validation configuration](#welcome-to-monokle-validation-configuration)
-- [Table of content](#table-of-content)
- [Usage](#usage)
- [Create your configuration file](#create-your-configuration-file)
- [Enable/disable a plugin](#enabledisable-a-plugin)
@@ -71,6 +54,9 @@ plugins:
open-policy-agent: false
```
+Any additional plugins found in a `.monokle-plugins` folder below the cwd of where you are running the validator/CLI and
+it will be available to configure and use as described under
+
### Enable/disable a rule
A `boolean` indicates whether the rule is enabled or disabled.
@@ -106,148 +92,3 @@ settings:
Below you can find an overview of all the plugins with their available settings.
-## Core plugins
-
-There are four cores plugins:
-
-- Open Policy agent
-- Kubernetes Schema
-- Resource links
-- YAML Syntax
-
-By default plugins are enabled and all rules are enabled as a warning.
-
-### Open Policy Agent
-
-A collection of security rules.
-
-Under the hood it compiles Rego policies into a WebAssembly module that handles the validation. A big shout out to the DefSec team at [Aqua Security](https://www.aquasec.com/) as full credit for these rules goes to them. You can find the source of their Rego policies [here](https://github.com/aquasecurity/defsec).
-
-There are no settings for this plugin.
-
-```yaml
-plugins:
- open-policy-agent: true
-```
-
-**Rules**
-
-| id | name | description |
-| ------ | ------------------------------------------- | ------------------------------------------------------- |
-| KSV001 | open-policy-agent/no-elevated-process | Disallow the process from elevating its privileges. |
-| KSV002 | open-policy-agent/app-armor | Require a default AppArmor profile |
-| KSV003 | open-policy-agent/drop-capabilities | Require default capabilities to be dropped |
-| KSV005 | open-policy-agent/no-sys-admin | Disallow the SYS_ADMIN capability |
-| KSV006 | open-policy-agent/no-mounted-docker-sock | Disallow mounteing the hostPath volume with docker.sock |
-| KSV008 | open-policy-agent/no-host-ipc | Disallow access to host IPC namespace |
-| KSV009 | open-policy-agent/no-host-network | Disallow access to host network |
-| KSV010 | open-policy-agent/no-host-pid | Disallow access to host PID |
-| KSV011 | open-policy-agent/cpu-limit | Require the CPU to be limited |
-| KSV012 | open-policy-agent/run-as-non-root | Requires the container to runs as non root user |
-| KSV013 | open-policy-agent/no-latest-image | Disallow images with the latest tag |
-| KSV014 | open-policy-agent/no-writable-fs | Require a read-only root file system |
-| KSV015 | open-policy-agent/cpu-request | Require the CPU to be requested |
-| KSV016 | open-policy-agent/memory-request | Require the memory to be requested |
-| KSV017 | open-policy-agent/no-privileged | Disallow the use of privileged containers |
-| KSV018 | open-policy-agent/memory-limit | Require the memory to be limited |
-| KSV020 | open-policy-agent/no-low-user-id | Disallow running with a low user ID |
-| KSV021 | open-policy-agent/no-low-group-id | Disallow running with a low group ID |
-| KSV023 | open-policy-agent/no-host-mounted-path | Disallow mounting hostPath volumes |
-| KSV024 | open-policy-agent/no-host-port-access | Disallow accessing the host ports |
-| KSV025 | open-policy-agent/no-selinux | Disallow custom SELinux options |
-| KSV027 | open-policy-agent/no-proc-mount | Disallow setting proc masks |
-| KSV028 | open-policy-agent/no-non-emphemeral-volumes | Disallow use of non-ephemeral volume types |
-| KSV029 | open-policy-agent/no-root-group | Disallow setting runAsGroup to zero. |
-| KSV030 | open-policy-agent/seccomp-profile | Require a Seccomp profile |
-
-### Kubernetes Schema
-
-Validates whether the Kubernetes resources comply with a JSON schema.
-
-There are no settings for this plugin.
-
-```yaml
-plugins:
- kubernetes-schema: true
-settings:
- kubernetes-schema:
- schemaVersion: "v1.25.1"
-```
-
-| name | description | default |
-| ------------- | ------------------------------------ | --------- |
-| schemaVersion | The version of the Kubernetes schema | "v1.24.2" |
-
-**Rules**
-
-| id | name | description |
-| ------ | --------------------------------- | -------------------------------------- |
-| K8S001 | kubernetes-schema/schema-violated | The resource is formatted incorrectly. |
-
-### Resource Links
-
-Validates whether links/references between resources are valid - i.e. if the target
-object exists or not.
-
-This plugin has two rules; one for standard link validation, and another
-for optional link validation (disabled by default)
-
-For example - the configMapKeyRef below is set as optional; if the target
-configMap does not exist this would be ignored by the validator, unless the
-LNK002 rule is enabled.
-
-```yaml
- env:
- - name: SOME_VALUE
- valueFrom:
- configMapKeyRef:
- name: some-configmap-name
- key: some-key
- optional: true
-```
-
-**Rules**
-
-| id | name | description |
-|--------|------------------------------------------|----------------------------------|
-| LNK001 | resource-links/no-missing-links | Disallow missing links. |
-| LNK002 | resource-links/no-missing-optional-links | Disallow missing optional links. |
-
-### YAML Syntax
-
-Validate whether the resource uses proper YAML syntax.
-
-There are no settings for this plugin.
-
-```yaml
-plugins:
- yaml-syntax: true
-```
-
-**Rules**
-
-Generally you either want all of these to be enabled or disabled.
-
-| id | name | description |
-| ------ | ------------------------------------- | --------------------------------------------- |
-| YML001 | yaml-syntax/alias-props | The alias props are incorrect. |
-| YML002 | yaml-syntax/no-bad-alias | The alias' format is incorrect. |
-| YML003 | yaml-syntax/no-bad-directive | The directive is incorrect. |
-| YML004 | yaml-syntax/no-bad-dq-escape | The double quotes are escaped incorrectly. |
-| YML005 | yaml-syntax/no-bad-indent | The indentation is incorrect. |
-| YML006 | yaml-syntax/no-bad-prop-order | The anchors and tags are used incorrectly. |
-| YML007 | yaml-syntax/no-bad-scalar-start | The scalar is formatted incorrectly. |
-| YML008 | yaml-syntax/no-block-as-implicit-key | The identation is incorrect. |
-| YML009 | yaml-syntax/no-block-in-flow | Cannot use block within flow. |
-| YML010 | yaml-syntax/no-duplicate-key | Cannot use duplicate keys. |
-| YML011 | yaml-syntax/impossible | Something unexpected went wrong |
-| YML012 | yaml-syntax/no-long-key | The key is longer than 1024 characters. |
-| YML013 | yaml-syntax/no-missing-anchor | The anchor is missing. |
-| YML014 | yaml-syntax/no-missing-char | A character is missing. |
-| YML015 | yaml-syntax/no-multiline-implicit-key | Cannot use multiple lines with implicit keys. |
-| YML016 | yaml-syntax/no-multiple-anchors | Cannot have multiple anchors. |
-| YML017 | yaml-syntax/no-multiple-docs | Cannot parse this document. |
-| YML018 | yaml-syntax/no-multiple-tags | Cannot use multiple tags. |
-| YML019 | yaml-syntax/no-tab-as-indent | Cannot use tabs for identation. |
-| YML020 | yaml-syntax/no-failed-tag-resolve | Cannot resolve the tag. |
-| YML021 | yaml-syntax/no-unexpected-toke | The token was unexpected. |
diff --git a/packages/validation/docs/core-plugins.md b/packages/validation/docs/core-plugins.md
new file mode 100644
index 000000000..03f610c04
--- /dev/null
+++ b/packages/validation/docs/core-plugins.md
@@ -0,0 +1,145 @@
+## Core Validation plugins
+
+There are four cores plugins:
+
+- [Open Policy agent](#open-policy-agent)
+- [Kubernetes Schema](#kubernetes-schema)
+- [Resource links](#resource-links)
+- [YAML Syntax](#yaml-syntax)
+
+All plugins are enabled by default and all rules are enabled as a warning.
+
+### Open Policy Agent
+
+A collection of security rules.
+
+Under the hood it compiles Rego policies into a WebAssembly module that handles the validation. A big shout out to the DefSec team at [Aqua Security](https://www.aquasec.com/) as full credit for these rules goes to them. You can find the source of their Rego policies [here](https://github.com/aquasecurity/defsec).
+
+There are no settings for this plugin.
+
+```yaml
+plugins:
+ open-policy-agent: true
+```
+
+**Rules**
+
+| id | name | description |
+| ------ | ------------------------------------------- | ------------------------------------------------------- |
+| KSV001 | open-policy-agent/no-elevated-process | Disallow the process from elevating its privileges. |
+| KSV002 | open-policy-agent/app-armor | Require a default AppArmor profile |
+| KSV003 | open-policy-agent/drop-capabilities | Require default capabilities to be dropped |
+| KSV005 | open-policy-agent/no-sys-admin | Disallow the SYS_ADMIN capability |
+| KSV006 | open-policy-agent/no-mounted-docker-sock | Disallow mounteing the hostPath volume with docker.sock |
+| KSV008 | open-policy-agent/no-host-ipc | Disallow access to host IPC namespace |
+| KSV009 | open-policy-agent/no-host-network | Disallow access to host network |
+| KSV010 | open-policy-agent/no-host-pid | Disallow access to host PID |
+| KSV011 | open-policy-agent/cpu-limit | Require the CPU to be limited |
+| KSV012 | open-policy-agent/run-as-non-root | Requires the container to runs as non root user |
+| KSV013 | open-policy-agent/no-latest-image | Disallow images with the latest tag |
+| KSV014 | open-policy-agent/no-writable-fs | Require a read-only root file system |
+| KSV015 | open-policy-agent/cpu-request | Require the CPU to be requested |
+| KSV016 | open-policy-agent/memory-request | Require the memory to be requested |
+| KSV017 | open-policy-agent/no-privileged | Disallow the use of privileged containers |
+| KSV018 | open-policy-agent/memory-limit | Require the memory to be limited |
+| KSV020 | open-policy-agent/no-low-user-id | Disallow running with a low user ID |
+| KSV021 | open-policy-agent/no-low-group-id | Disallow running with a low group ID |
+| KSV023 | open-policy-agent/no-host-mounted-path | Disallow mounting hostPath volumes |
+| KSV024 | open-policy-agent/no-host-port-access | Disallow accessing the host ports |
+| KSV025 | open-policy-agent/no-selinux | Disallow custom SELinux options |
+| KSV027 | open-policy-agent/no-proc-mount | Disallow setting proc masks |
+| KSV028 | open-policy-agent/no-non-emphemeral-volumes | Disallow use of non-ephemeral volume types |
+| KSV029 | open-policy-agent/no-root-group | Disallow setting runAsGroup to zero. |
+| KSV030 | open-policy-agent/seccomp-profile | Require a Seccomp profile |
+
+### Kubernetes Schema
+
+Validates whether the Kubernetes resources comply with a JSON schema.
+
+There are no settings for this plugin.
+
+```yaml
+plugins:
+ kubernetes-schema: true
+settings:
+ kubernetes-schema:
+ schemaVersion: "v1.25.1"
+```
+
+| name | description | default |
+| ------------- | ------------------------------------ | --------- |
+| schemaVersion | The version of the Kubernetes schema | "v1.24.2" |
+
+**Rules**
+
+| id | name | description |
+| ------ | --------------------------------- | -------------------------------------- |
+| K8S001 | kubernetes-schema/schema-violated | The resource is formatted incorrectly. |
+
+### Resource Links
+
+Validates whether links/references between resources are valid - i.e. if the target
+object exists or not.
+
+This plugin has two rules; one for standard link validation, and another
+for optional link validation (disabled by default)
+
+For example - the configMapKeyRef below is set as optional; if the target
+configMap does not exist this would be ignored by the validator, unless the
+LNK002 rule is enabled.
+
+```yaml
+ env:
+ - name: SOME_VALUE
+ valueFrom:
+ configMapKeyRef:
+ name: some-configmap-name
+ key: some-key
+ optional: true
+```
+
+**Rules**
+
+| id | name | description |
+|--------|------------------------------------------|----------------------------------|
+| LNK001 | resource-links/no-missing-links | Disallow missing links. |
+| LNK002 | resource-links/no-missing-optional-links | Disallow missing optional links. |
+
+### YAML Syntax
+
+Validate whether the resource uses proper YAML syntax.
+
+There are no settings for this plugin.
+
+```yaml
+plugins:
+ yaml-syntax: true
+```
+
+**Rules**
+
+Generally you either want all of these to be enabled or disabled.
+
+| id | name | description |
+| ------ | ------------------------------------- | --------------------------------------------- |
+| YML001 | yaml-syntax/alias-props | The alias props are incorrect. |
+| YML002 | yaml-syntax/no-bad-alias | The alias' format is incorrect. |
+| YML003 | yaml-syntax/no-bad-directive | The directive is incorrect. |
+| YML004 | yaml-syntax/no-bad-dq-escape | The double quotes are escaped incorrectly. |
+| YML005 | yaml-syntax/no-bad-indent | The indentation is incorrect. |
+| YML006 | yaml-syntax/no-bad-prop-order | The anchors and tags are used incorrectly. |
+| YML007 | yaml-syntax/no-bad-scalar-start | The scalar is formatted incorrectly. |
+| YML008 | yaml-syntax/no-block-as-implicit-key | The identation is incorrect. |
+| YML009 | yaml-syntax/no-block-in-flow | Cannot use block within flow. |
+| YML010 | yaml-syntax/no-duplicate-key | Cannot use duplicate keys. |
+| YML011 | yaml-syntax/impossible | Something unexpected went wrong |
+| YML012 | yaml-syntax/no-long-key | The key is longer than 1024 characters. |
+| YML013 | yaml-syntax/no-missing-anchor | The anchor is missing. |
+| YML014 | yaml-syntax/no-missing-char | A character is missing. |
+| YML015 | yaml-syntax/no-multiline-implicit-key | Cannot use multiple lines with implicit keys. |
+| YML016 | yaml-syntax/no-multiple-anchors | Cannot have multiple anchors. |
+| YML017 | yaml-syntax/no-multiple-docs | Cannot parse this document. |
+| YML018 | yaml-syntax/no-multiple-tags | Cannot use multiple tags. |
+| YML019 | yaml-syntax/no-tab-as-indent | Cannot use tabs for identation. |
+| YML020 | yaml-syntax/no-failed-tag-resolve | Cannot resolve the tag. |
+| YML021 | yaml-syntax/no-unexpected-toke | The token was unexpected. |
diff --git a/packages/validation/docs/custom-plugins.md b/packages/validation/docs/custom-plugins.md
new file mode 100644
index 000000000..66cb5a209
--- /dev/null
+++ b/packages/validation/docs/custom-plugins.md
@@ -0,0 +1,96 @@
+# Custom Validation Plugins
+
+Monokle Validation plugins can currently be written in typescript and scaffolded using the
+[create-monokle-plugin](../create-monokle-plugin) library.
+
+- [Getting Started](#getting-started)
+- Tips & Tricks
+ - [Local Development with Monokle Cloud](#local-development-with-monokle-cloud)
+ - [Generate Resources & Typeguards](#generate-resources--typeguards)
+ - [Packaging](#packaging)
+ - [Sharing & Distribution](#sharing-and-distribution)
+
+Also have a look at
+- [Plugin Metadata](plugin-metadata.md) to learn more about the metadata a plugin needs to expose
+- [Plugin Examples](plugin-examples.md) to see a bunch of examples
+
+## Getting Started
+
+Follow these steps to get going with a custom plugin:
+
+- Use the create-monokle-plugin to scaffold your plugin
+- Update the generated `src/plugin.ts` file with correct metadata ([read more](plugin-metadata.md))
+- Implement your rule(s) in the `src/rules` folder and make sure to add them to the `src/plugin.ts` file
+- Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
+
+## Tips & Tricks
+
+### Local Development with Monokle Cloud
+
+To enable direct testing/debugging of your validators with Monokle Cloud, run
+
+```
+npm run dev
+```
+
+which will start a local development server that Monokle Cloud can connect to:
+
+- Open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository.
+- Enabled "Development Mode" at the bottom of the pane
+- A new validator labelled "development" will appear.
+
+You can now start editing code; the local development server will automatically pick up code changes and forward
+them to the browser where Hot Module Replacement will give you the latest version of your code in real-time.
+You can play around with any of the resources in your project to make sure you got the validation right.
+
+### Generate Resources & Typeguards
+
+Put any CRDs you might want to use/validation in the `src/schemas/crds` folder (in JSON format) and run
+
+```
+npm run codegen
+```
+
+This will generate utility methods and types for each CRD into the `src/schemas/__generated__` folder, for you
+to import/use in your validators.
+
+Example usage for code generated for the prometheus CRD:
+
+```typescript
+defineRule({
+ validate({ resources } {
+ resources
+ .filter(r => isPrometheus(r.content))
+ .forEach(prometheus => {
+ prometheus.content.spec; // this is now a fully typed object.
+ })
+ }
+})
+```
+
+### Packaging & Usage
+
+To package your plugin into a single `plugin.js` file, run
+
+```
+npm run build
+```
+
+which will create a `dist/plugin.js` file in your repo.
+
+Put this file in a `.monokle-plugins` folder below the cwd of where you are running the validator/CLI and
+it will be available to configure and use as described under
+
+
+### Sharing and Distribution
+
+If you want to share your plugin with the community, fork and add it to the
+[Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins)
+repository, and open a PR back to the repository for us to review and merge.
+
+
+
+
+
+
+
diff --git a/packages/validation/docs/plugin-examples.md b/packages/validation/docs/plugin-examples.md
new file mode 100644
index 000000000..9e65b2e83
--- /dev/null
+++ b/packages/validation/docs/plugin-examples.md
@@ -0,0 +1,137 @@
+# Validation Plugin Examples
+
+## Rule that checks for resources without any annotations
+
+```typescript
+export const noEmptyAnnotations = defineRule({
+ id: 1,
+ description: "Require annotations as metadata.",
+ help: "Add any annotation to the Kubernetes resource.",
+ validate({ resources }, { report }) {
+ resources.forEach((resource) => {
+ const annotations = Object.entries(resource.metadata?.annotations ?? {});
+ const hasAnnotations = annotations.length > 0;
+
+ if (!hasAnnotations) {
+ report(resource, { path: "metadata.annotations" });
+ }
+ });
+ },
+});
+```
+
+## Rule that checks for Prometheus instances with the Admin API enabled
+
+```typescript
+export const noAdminApi = defineRule({
+ id: 3,
+ description: "Disallow the admin API for Prometheus instances.",
+ help: "Do not set enabledAdminAPI to true.",
+ validate({ resources }, { report }) {
+ resources.filter(isPrometheus).forEach((prometheus) => {
+ const valid = prometheus.spec.enableAdminAPI !== true;
+ if (valid) return;
+ report(prometheus, { path: "spec.enableAdminAPI" });
+ });
+ },
+});
+```
+
+## Rule that checks for images using the latest tag
+
+```typescript
+export const noLatestImage = defineRule({
+ id: 4,
+ description: "Disallow images with the latest tag.",
+ fullDescription:
+ "The latest image makes it difficult to know which version is exactly running which might introduce subtle bugs or run a version that is vulnerable.",
+ help: "Pin the exact version of the image.",
+ validate({ resources }, { report }) {
+ validatePodSpec(resources, (resource, pod, prefix) => {
+ pod.initContainers?.forEach((container, index) => {
+ const valid = !container.image?.endsWith("latest");
+ if (valid) return;
+
+ report(resource, {
+ path: `${prefix}.initContainers.${index}.image`,
+ });
+ });
+
+ pod.containers.forEach((container, index) => {
+ const valid = !container.image?.endsWith("latest");
+ if (valid) return;
+
+ report(resource, {
+ path: `${prefix}.containers.${index}.image`,
+ });
+ });
+ });
+ },
+});
+```
+
+Utility method used by the above to identify PodSpecs in different resource types:
+
+```typescript
+
+export function validatePodSpec(
+ resources: any[],
+ validateFn: (resource: any, pod: PodSpec, prefix: string) => void
+): void {
+ resources.forEach((resource) => {
+ if (
+ isDeployment(resource) ||
+ isStatefulSet(resource) ||
+ isDaemonSet(resource) ||
+ isJob(resource)
+ ) {
+ const pod = resource.spec?.template.spec;
+ if (!pod) return;
+ return validateFn(resource, pod, "spec.template.spec");
+ }
+
+ if (isCronJob(resource)) {
+ const pod = resource.spec?.jobTemplate.spec?.template.spec;
+ if (!pod) return;
+ return validateFn(resource, pod, "spec.jobTemplate.spec.template.spec");
+ }
+
+ if (isPod(resource)) {
+ const pod = resource.spec;
+ if (!pod) return;
+ return validateFn(resource, pod, "spec");
+ }
+ });
+}
+```
+
+## Rule that checks if Services are exposing correct ports
+
+```typescript
+export const noPortMismatch = defineRule({
+ id: 2,
+ description: "The target port should match any container port.",
+ help: "Change to target port to a port that matching a container's port.",
+ validate({ resources }, { getRelated, report }) {
+ resources.filter(isService).forEach((service) => {
+ const deployments = getRelated(service).filter(isDeployment);
+
+ const validPorts = deployments.flatMap((d) =>
+ d.spec?.template.spec?.containers.flatMap((c) =>
+ c.ports?.flatMap((p) => p.containerPort)
+ )
+ );
+
+ const servicePorts = service.spec?.ports ?? [];
+ servicePorts.forEach((port, index: number) => {
+ if (!validPorts.includes(Number(port.targetPort))) {
+ report(service, { path: `spec.ports.${index}.targetPort` });
+ }
+ });
+ });
+ },
+});
+```
+
+
+
diff --git a/packages/validation/docs/plugin-metadata.md b/packages/validation/docs/plugin-metadata.md
new file mode 100644
index 000000000..b42ce9002
--- /dev/null
+++ b/packages/validation/docs/plugin-metadata.md
@@ -0,0 +1,84 @@
+# Validation Plugin Metadata
+
+Monokle Validation Plugins need to provide specific metadata for the validation package to use them in
+the Monokle CLI and Monokle Cloud.
+
+## Plugin metadata
+
+To ensure correct usage/configuration of your plugin the following
+properties should be set in a call to `definePlugin`
+
+- `id` : a unique (internal) identifier for your plugin
+- `name` : a unique camel-case name that will be used as a prefix in configuration files to identify
+ rules in the plugin
+- `displayName` : a user-friendly name for your plugin
+- `description` : a user-friendly description of your plugin
+
+The below example is taken from the Argo Validation plugin in the Community Repository
+
+```typescript
+export default definePlugin({
+ id: "ARGO",
+ name: "argo",
+ displayName: "ArgoCD Validation plugin",
+ description: "Validation rules related to ArgoCD",
+ rules: {
+ appDestination, // defined in the example below
+ ... more rules ...
+ },
+});
+```
+
+## Validator metadata
+
+Each validator needs to be defined with a call to `defineRule` and added to the `rules` object shown above.
+
+The following properties are required for `defineRule`
+
+- `id` : an internal id for your rule
+- `description` : a text to show if this rule fails
+- `help` : a text telling how to fix your errors for this rule
+
+Another example from the Argo Validation plugin:
+
+```typescript
+// used in the example above
+export const appDestination = defineRule({
+ id: 2,
+ description: "Argo Application's destination are mutually exclusive",
+ help: "Either use 'server' or 'name', but not both.",
+ validate({ resources }, { report }) {
+ ... validator implementation ...
+ });
+ },
+});
+```
+
+## Usage in validator / CLI configuration
+
+Plugins need to be contributed to the Community Plugins repository to be directly usable with
+the [Monokle CLI](https://github.com/kubeshop/monokle-core/tree/main/packages/cli) and Monokle Cloud.
+
+Once contributed you can simple use them by adding them to the `monokle.validation.yaml` file as follows:
+
+```yaml
+plugins:
+ : true
+rules:
+ /: "err"
+```
+
+The `rule-name` is generated from the actual rule property added to the plugin.ts by transforming it into
+a lower cased string with dashes between words.
+
+For the above Argo examples the configuration is
+
+```yaml
+# monokle.validation.yaml
+plugins:
+ argo: true
+rules:
+ argo/app-destination: "err"
+```
+
+Read more about the [Validator Configuration](configuration.md)
From 74fbe787b2f1a3e438bd3866c5ead4f25dbbe1db Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 10:07:53 +0100
Subject: [PATCH 02/11] fix: docs update
---
packages/cli/README.md | 2 +-
packages/validation/docs/custom-plugins.md | 10 ++++++----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/packages/cli/README.md b/packages/cli/README.md
index c27c4c7d1..c1e83106e 100644
--- a/packages/cli/README.md
+++ b/packages/cli/README.md
@@ -123,7 +123,7 @@ settings:
### Custom validators
-It is easy to extend the Monokle CLI with custom validators that can be shared with others using
+It is easy to extend the Monokle CLI with [custom validators](../validation/docs/custom-plugins.md) that can be shared with others using
our [Monokle Community Plugins][monokle-community-plugins] repository.
## GitHub Action
diff --git a/packages/validation/docs/custom-plugins.md b/packages/validation/docs/custom-plugins.md
index 66cb5a209..321246817 100644
--- a/packages/validation/docs/custom-plugins.md
+++ b/packages/validation/docs/custom-plugins.md
@@ -18,10 +18,12 @@ Also have a look at
Follow these steps to get going with a custom plugin:
-- Use the create-monokle-plugin to scaffold your plugin
-- Update the generated `src/plugin.ts` file with correct metadata ([read more](plugin-metadata.md))
-- Implement your rule(s) in the `src/rules` folder and make sure to add them to the `src/plugin.ts` file
-- Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
+1. Use [create-monokle-plugin](../../create-monokle-plugin) to scaffold your plugin
+2. Update the generated `src/plugin.ts` file with correct metadata - [read more](plugin-metadata.md)
+3. Optionally add any CRDs that you might want to validate to the `src/schemas` folder and generate corresponding objects - [see below](#generate-resources--typeguards)
+4. Implement your rule(s) in the generated `src/rules` folder and make sure to add them to the `definePlugin` call in the generated`src/plugin.ts` file
+5. Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
+6. Package and/or share your plugin in our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.
## Tips & Tricks
From 7a24f2b706791cf8b3c8e7f03bfcdb7fcf66551d Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 11:44:03 +0100
Subject: [PATCH 03/11] fix: added doc on implementing rules
---
packages/cli/README.md | 6 +-
packages/validation/docs/custom-plugins.md | 3 +-
.../validation/docs/rule-implementation.md | 109 ++++++++++++++++++
.../src/validators/custom/config.ts | 2 +-
4 files changed, 115 insertions(+), 5 deletions(-)
create mode 100644 packages/validation/docs/rule-implementation.md
diff --git a/packages/cli/README.md b/packages/cli/README.md
index c1e83106e..9161863c2 100644
--- a/packages/cli/README.md
+++ b/packages/cli/README.md
@@ -12,7 +12,8 @@
Monokle CLI is a command-line interface for static analysis of Kubernetes resources.
-Use it to prevent misconfigurations within Kustomize, Helm or default Kubernetes resources. The output is available as a SARIF file which you can upload to GitHub CodeScan.
+Use it to prevent misconfigurations within Kustomize, Helm or default Kubernetes resources. The output is available as a SARIF file
+which you can upload to GitHub CodeScan.
Monokle CLI includes built-in validators for
- YAML Syntax
@@ -100,8 +101,7 @@ You can use `--help` to access help information directly from the CLI.
The Monokle CLI looks for a Monokle Validation configuration file
at `./monokle.validation.yaml`. You can change this by using the `--config` flag.
-All rules are enabled by default and are
-described in the [Monokle Validation configuration][monokle-validation-docs] documentation.
+All rules are enabled by default and are described in the [Monokle Validation configuration][monokle-validation-docs] documentation.
**Example**
diff --git a/packages/validation/docs/custom-plugins.md b/packages/validation/docs/custom-plugins.md
index 321246817..38eb92300 100644
--- a/packages/validation/docs/custom-plugins.md
+++ b/packages/validation/docs/custom-plugins.md
@@ -13,6 +13,7 @@ Monokle Validation plugins can currently be written in typescript and scaffolded
Also have a look at
- [Plugin Metadata](plugin-metadata.md) to learn more about the metadata a plugin needs to expose
- [Plugin Examples](plugin-examples.md) to see a bunch of examples
+- [Rule Implementation](rule-implementation.md) to learn how to implement rules
## Getting Started
@@ -21,7 +22,7 @@ Follow these steps to get going with a custom plugin:
1. Use [create-monokle-plugin](../../create-monokle-plugin) to scaffold your plugin
2. Update the generated `src/plugin.ts` file with correct metadata - [read more](plugin-metadata.md)
3. Optionally add any CRDs that you might want to validate to the `src/schemas` folder and generate corresponding objects - [see below](#generate-resources--typeguards)
-4. Implement your rule(s) in the generated `src/rules` folder and make sure to add them to the `definePlugin` call in the generated`src/plugin.ts` file
+4. [Implement your rule(s)](rule-implementation.md) in the generated `src/rules` folder and make sure to add them to the `definePlugin` call in the generated`src/plugin.ts` file
5. Optionally use Monokle Cloud to test your plugin ([see below](#local-development-with-monokle-cloud))
6. Package and/or share your plugin in our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.
diff --git a/packages/validation/docs/rule-implementation.md b/packages/validation/docs/rule-implementation.md
new file mode 100644
index 000000000..1334de520
--- /dev/null
+++ b/packages/validation/docs/rule-implementation.md
@@ -0,0 +1,109 @@
+# Custom Rule Implementation
+
+Apart from providing rule metadata as described in [plugin metadata](plugin-metadata.md) each rule
+needs to implement a `validate` method that is called for each resource to be validated. This method
+takes two arguments:
+
+- a `RuleContext` object that provides metadata for the resource(s) to be validated
+- a `RuleApi` object that provides helper methods for rule execution
+
+These are both defined in [config.ts](../src/validators/custom/config.ts).
+
+Let's have a look at these in more detail.
+
+## RuleContext
+
+The RuleContext contains the following properties:
+
+### `resources`
+
+A list of Resource objects that need to be (re)validated in the call to validate. This is defined as follows in
+[types.ts](../src/common/types.ts):
+
+```typescript
+export type Resource = {
+ id: string;
+ fileId: string;
+ filePath: string;
+ fileOffset: number; // Offset of this resource's startLine within the parent file.
+ name: string;
+ apiVersion: string;
+ kind: string;
+ namespace?: string;
+ content?: any;
+ text: string;
+ isSelected?: boolean;
+ refs?: ResourceRef[];
+ range?: {
+ start: number;
+ length: number;
+ };
+};
+```
+
+The most important properties during validation will (probably) be:
+
+- `name` : the name of the resource, for example "petstore-deployment"
+- `kind` : the kind of resource, for example "Deployment"
+- `apiVersion` : the apiVersion, for example "apps/v1"
+- `metadata` : the metadata available in the resource (see example below)
+- `content` : the entire resource object, giving you access to any property you might want to validate
+
+### `allResources`
+
+A list of all resources available to the validator, use this to resolve references, etc.
+
+### `settings`
+
+A custom settings object provided to the validator - for example `monokle.validation.yaml`:
+
+```yaml
+plugins:
+ kubernetes-schema: true
+settings:
+ kubernetes-schema:
+ schemaVersion: v1.24.2
+```
+
+## RuleApi
+
+The RuleApi object provides the following methods:
+
+### `getRelated(resource: Resource): Resource[];`
+
+Returns all related resources of the given resource, using the `refs` property of the given Resource to resolve these.
+
+### `report(resource: Resource, args: ReportArgs)`
+
+Use this method to report a problem with the resource(s) being validated. ReportArgs takes two properties:
+
+- `path` : a path to the error, for example
+ - "metadata.annotations" for an incorrect annotation
+ - "spec.template.spec.containers.0.image" for an incorrect image in the first container of a Deployment.
+- `message` : an optional message with additional context
+
+### `parse(resource: Resource): Document.Parsed`
+
+Returns an internally cached parsed YAML instance of the resource, this is for advanced use cases for now.
+
+## Example
+
+The below validate call extracts the `resources` and `report` properties from the provided arguments and then
+iterates each resource, checking the `metadata` property for annotations and reporting an error if none found.
+
+```typescript
+validate({ resources }, { report }){
+ resources.forEach((resource) => {
+ // get annotations of resource
+ const annotations = Object.entries(resource.metadata?.annotations ?? {});
+
+ // were there any?
+ const hasAnnotations = annotations.length > 0;
+
+ if (!hasAnnotations) {
+ // report error for this resource
+ report(resource, { path: "metadata.annotations" });
+ }
+ });
+}
+```
diff --git a/packages/validation/src/validators/custom/config.ts b/packages/validation/src/validators/custom/config.ts
index afa76c711..0116192ff 100644
--- a/packages/validation/src/validators/custom/config.ts
+++ b/packages/validation/src/validators/custom/config.ts
@@ -128,7 +128,7 @@ export type RuleApi = {
report(resource: Resource, args: ReportArgs): void;
/**
- * Returns a parsed YAML instance of the resource.
+ * Returns an internally cached parsed YAML instance of the resource.
*
* @remark this is for advanced use cases.
*/
From 015ed6fcf948865fbfb23972d7f73bd33c660fde Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 11:52:29 +0100
Subject: [PATCH 04/11] fix: added more links to validation README.md
---
packages/validation/README.md | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/packages/validation/README.md b/packages/validation/README.md
index 76574c2f1..b01d8fb3e 100644
--- a/packages/validation/README.md
+++ b/packages/validation/README.md
@@ -12,17 +12,17 @@ Extensible, static Kubernetes analysis
-## Welcome to Monokle Validation
+# Welcome to Monokle Validation
Monokle Validation is a TypeScript library to validate your Kubernetes resources.
-### Key features
+## Key features
-- 🚀 Start in seconds with the user-friendly configuration.
+- 🚀 Start in seconds with the user-friendly configuration and powerful core plugins.
- ⚡️ Real-time validation through incremental runs.
-- ⚒ Extensible architecture with plugins.
+- ⚒ Extensible architecture with custom plugins.
-### Core plugins
+## Core plugins
- YAML Syntax validates that your manifests have correct YAML syntax.
- Kubernetes Schema validates that your resources and CRDs are well-defined in the schema for their resource kind.
@@ -31,12 +31,16 @@ Monokle Validation is a TypeScript library to validate your Kubernetes resources
Learn more about each Core Plugin in the [Core Plugins Documentation](docs/core-plugins.md)
-### Community Plugins
+## Custom Plugins
-Check out our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repo for
-plugins contributed by our community, and details on how to create your own.
+Easily create your own validators in typescript - [Read More](docs/custom-plugins.md)
-### Try the CLI or Monokle Cloud now!
+## Community Plugins
+
+Share your custom validators in the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repo,
+or use any existing community validators as [described below](#using-community-plugins).
+
+## Validate from the CLI or Monokle Cloud
The [Monokle CLI](https://github.com/kubeshop/monokle-core/tree/main/packages/cli) provides a convenient
wrapper around this library. Use it to validate your resources in seconds:
From 6c62e2cc8f49b3b18aaffeba8103d797752a19bc Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 11:55:26 +0100
Subject: [PATCH 05/11] fix: moving things around..
---
packages/validation/docs/custom-plugins.md | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/packages/validation/docs/custom-plugins.md b/packages/validation/docs/custom-plugins.md
index 38eb92300..91bebbde6 100644
--- a/packages/validation/docs/custom-plugins.md
+++ b/packages/validation/docs/custom-plugins.md
@@ -4,17 +4,15 @@ Monokle Validation plugins can currently be written in typescript and scaffolded
[create-monokle-plugin](../create-monokle-plugin) library.
- [Getting Started](#getting-started)
+- Documentation
+ - [Plugin Metadata](plugin-metadata.md) describes the metadata a plugin needs to expose
+ - [Rule Implementation](rule-implementation.md) shows how to implement rules
- Tips & Tricks
- [Local Development with Monokle Cloud](#local-development-with-monokle-cloud)
- [Generate Resources & Typeguards](#generate-resources--typeguards)
- [Packaging](#packaging)
- [Sharing & Distribution](#sharing-and-distribution)
-Also have a look at
-- [Plugin Metadata](plugin-metadata.md) to learn more about the metadata a plugin needs to expose
-- [Plugin Examples](plugin-examples.md) to see a bunch of examples
-- [Rule Implementation](rule-implementation.md) to learn how to implement rules
-
## Getting Started
Follow these steps to get going with a custom plugin:
From 1752dee2e110aa5b4b87ba253028b841c97f0d0f Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 11:57:11 +0100
Subject: [PATCH 06/11] fix: doc fixes..
---
packages/validation/README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/validation/README.md b/packages/validation/README.md
index b01d8fb3e..77ae646c7 100644
--- a/packages/validation/README.md
+++ b/packages/validation/README.md
@@ -42,8 +42,7 @@ or use any existing community validators as [described below](#using-community-p
## Validate from the CLI or Monokle Cloud
-The [Monokle CLI](https://github.com/kubeshop/monokle-core/tree/main/packages/cli) provides a convenient
-wrapper around this library. Use it to validate your resources in seconds:
+The [Monokle CLI](../cli) provides a convenient wrapper around this library. Use it to validate your resources in seconds:
```bash
kustomize build . | monokle validate -
From f6d19f3571734a29e07bb14b4e14b4550ed239e4 Mon Sep 17 00:00:00 2001
From: olensmar
Date: Wed, 21 Dec 2022 12:20:19 +0100
Subject: [PATCH 07/11] fix: doc fixes..
---
packages/create-monokle-plugin/README.md | 24 ++++++++-
packages/validation/docs/custom-plugins.md | 46 +++++++++---------
.../images/monokle-cloud-developer-mode.png | Bin 0 -> 263952 bytes
3 files changed, 44 insertions(+), 26 deletions(-)
create mode 100644 packages/validation/docs/images/monokle-cloud-developer-mode.png
diff --git a/packages/create-monokle-plugin/README.md b/packages/create-monokle-plugin/README.md
index 2895db66b..6b15329e1 100644
--- a/packages/create-monokle-plugin/README.md
+++ b/packages/create-monokle-plugin/README.md
@@ -11,10 +11,31 @@ Prerequisite: it's recommended to use NodeJs LTS or higher and NPM 7+.
### Interactive
-```
+Running in interactive mode:
+
+```shell
npm create monokle-plugin@latest
```
+will prompt for:
+
+```shell
+✔ Plugin name: … my-validation-plugin
+✔ Select a plugin type: › validation
+✔ Select a variant: › validation-ts
+✔ Select a template: › basic
+
+Scaffolding plugin in /Users/olensmar/WebstormProjects/monokle-core/packages/create-monokle-plugin/my-validation-plugin...
+
+Done. Now run:
+
+ cd my-validation-plugin
+ npm install
+ npm run dev
+```
+
+Now you're all set to implement your [Custom Plugin](../validation/docs/custom-plugins.md)
+
### Create a TypeScript validation plugin
```
@@ -31,7 +52,6 @@ example on how to get started with your own plugin.
This project is a modified version of [create-vite](https://github.com/vitejs/vite/tree/main/packages/create-vite) and
most credits go to them.
-
diff --git a/packages/validation/docs/custom-plugins.md b/packages/validation/docs/custom-plugins.md
index 91bebbde6..768923abd 100644
--- a/packages/validation/docs/custom-plugins.md
+++ b/packages/validation/docs/custom-plugins.md
@@ -26,24 +26,6 @@ Follow these steps to get going with a custom plugin:
## Tips & Tricks
-### Local Development with Monokle Cloud
-
-To enable direct testing/debugging of your validators with Monokle Cloud, run
-
-```
-npm run dev
-```
-
-which will start a local development server that Monokle Cloud can connect to:
-
-- Open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository.
-- Enabled "Development Mode" at the bottom of the pane
-- A new validator labelled "development" will appear.
-
-You can now start editing code; the local development server will automatically pick up code changes and forward
-them to the browser where Hot Module Replacement will give you the latest version of your code in real-time.
-You can play around with any of the resources in your project to make sure you got the validation right.
-
### Generate Resources & Typeguards
Put any CRDs you might want to use/validation in the `src/schemas/crds` folder (in JSON format) and run
@@ -52,7 +34,7 @@ Put any CRDs you might want to use/validation in the `src/schemas/crds` folder (
npm run codegen
```
-This will generate utility methods and types for each CRD into the `src/schemas/__generated__` folder, for you
+This will generate utility methods and types for each CRD into the `src/schemas/__generated__` folder, for you
to import/use in your validators.
Example usage for code generated for the prometheus CRD:
@@ -69,6 +51,26 @@ defineRule({
})
```
+### Local Development with Monokle Cloud
+
+To enable direct testing/debugging of your validators with Monokle Cloud, run
+
+```
+npm run dev
+```
+
+which will start a local development server that Monokle Cloud can connect to:
+
+- Open [app.monokle.com](https://app.monokle.com) and open the validation pane in your favourite repository.
+- Enabled "Development Mode" at the bottom of the pane
+- A new validator labelled "development" will appear.
+
+You can now start editing code; the local development server will automatically pick up code changes and forward
+them to the browser where Hot Module Replacement will give you the latest version of your code in real-time.
+You can play around with any of the resources in your project to make sure you got the validation right.
+
+![monokle-cloud-developer-mode.png](images/monokle-cloud-developer-mode.png)
+
### Packaging & Usage
To package your plugin into a single `plugin.js` file, run
@@ -77,11 +79,7 @@ To package your plugin into a single `plugin.js` file, run
npm run build
```
-which will create a `dist/plugin.js` file in your repo.
-
-Put this file in a `.monokle-plugins` folder below the cwd of where you are running the validator/CLI and
-it will be available to configure and use as described under
-
+which will create a `dist/plugin.js` file in your repo.
### Sharing and Distribution
diff --git a/packages/validation/docs/images/monokle-cloud-developer-mode.png b/packages/validation/docs/images/monokle-cloud-developer-mode.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ba50f83cc8918a60620386c5a824bb3ed2442a1
GIT binary patch
literal 263952
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