@vaharoni/devops 1.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/app-support/crypto/index.d.ts +15 -0
- package/dist/app-support/crypto/index.d.ts.map +1 -0
- package/dist/app-support/crypto/index.js +30 -0
- package/dist/app-support/crypto/internal-token.d.ts +20 -0
- package/dist/app-support/crypto/internal-token.d.ts.map +1 -0
- package/dist/app-support/crypto/internal-token.js +42 -0
- package/dist/app-support/crypto/internal-token.spec.d.ts +2 -0
- package/dist/app-support/crypto/internal-token.spec.d.ts.map +1 -0
- package/dist/app-support/crypto/internal-token.spec.js +45 -0
- package/dist/app-support/crypto/secret.d.ts +3 -0
- package/dist/app-support/crypto/secret.d.ts.map +1 -0
- package/dist/app-support/crypto/secret.js +12 -0
- package/dist/app-support/crypto/secret.spec.d.ts +2 -0
- package/dist/app-support/crypto/secret.spec.d.ts.map +1 -0
- package/dist/app-support/crypto/secret.spec.js +15 -0
- package/dist/app-support/discovery/dev-discovery-loader.d.ts +2 -0
- package/dist/app-support/discovery/dev-discovery-loader.d.ts.map +1 -0
- package/dist/app-support/discovery/dev-discovery-loader.js +30 -0
- package/dist/app-support/discovery/service-endpoint.d.ts +2 -0
- package/dist/app-support/discovery/service-endpoint.d.ts.map +1 -0
- package/dist/app-support/discovery/service-endpoint.js +10 -0
- package/dist/cli/affected.d.ts +11 -0
- package/dist/cli/affected.d.ts.map +1 -0
- package/dist/cli/affected.js +103 -0
- package/dist/cli/common.d.ts +89 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +236 -0
- package/dist/cli/common.spec.d.ts +2 -0
- package/dist/cli/common.spec.d.ts.map +1 -0
- package/dist/cli/common.spec.js +64 -0
- package/dist/cli/console.d.ts +11 -0
- package/dist/cli/console.d.ts.map +1 -0
- package/dist/cli/console.js +35 -0
- package/dist/cli/constant.d.ts +11 -0
- package/dist/cli/constant.d.ts.map +1 -0
- package/dist/cli/constant.js +22 -0
- package/dist/cli/db.d.ts +11 -0
- package/dist/cli/db.d.ts.map +1 -0
- package/dist/cli/db.js +119 -0
- package/dist/cli/dml.d.ts +11 -0
- package/dist/cli/dml.d.ts.map +1 -0
- package/dist/cli/dml.js +116 -0
- package/dist/cli/env.d.ts +11 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +67 -0
- package/dist/cli/exec.d.ts +11 -0
- package/dist/cli/exec.d.ts.map +1 -0
- package/dist/cli/exec.js +50 -0
- package/dist/cli/image.d.ts +11 -0
- package/dist/cli/image.d.ts.map +1 -0
- package/dist/cli/image.js +140 -0
- package/dist/cli/init.d.ts +11 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +66 -0
- package/dist/cli/internal-curl.d.ts +11 -0
- package/dist/cli/internal-curl.d.ts.map +1 -0
- package/dist/cli/internal-curl.js +43 -0
- package/dist/cli/job.d.ts +11 -0
- package/dist/cli/job.d.ts.map +1 -0
- package/dist/cli/job.js +67 -0
- package/dist/cli/jwt.d.ts +11 -0
- package/dist/cli/jwt.d.ts.map +1 -0
- package/dist/cli/jwt.js +27 -0
- package/dist/cli/namespace.d.ts +11 -0
- package/dist/cli/namespace.d.ts.map +1 -0
- package/dist/cli/namespace.js +70 -0
- package/dist/cli/prep-build.d.ts +11 -0
- package/dist/cli/prep-build.d.ts.map +1 -0
- package/dist/cli/prep-build.js +82 -0
- package/dist/cli/prisma.d.ts +11 -0
- package/dist/cli/prisma.d.ts.map +1 -0
- package/dist/cli/prisma.js +25 -0
- package/dist/cli/redis.d.ts +11 -0
- package/dist/cli/redis.d.ts.map +1 -0
- package/dist/cli/redis.js +76 -0
- package/dist/cli/registry.d.ts +11 -0
- package/dist/cli/registry.d.ts.map +1 -0
- package/dist/cli/registry.js +58 -0
- package/dist/cli/run-many.d.ts +11 -0
- package/dist/cli/run-many.d.ts.map +1 -0
- package/dist/cli/run-many.js +50 -0
- package/dist/cli/run.d.ts +11 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +37 -0
- package/dist/cli/template.d.ts +11 -0
- package/dist/cli/template.d.ts.map +1 -0
- package/dist/cli/template.js +123 -0
- package/dist/cli/test.d.ts +11 -0
- package/dist/cli/test.d.ts.map +1 -0
- package/dist/cli/test.js +28 -0
- package/dist/devops.d.ts +3 -0
- package/dist/devops.d.ts.map +1 -0
- package/dist/devops.js +103 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/libs/affected-entities.d.ts +15 -0
- package/dist/libs/affected-entities.d.ts.map +1 -0
- package/dist/libs/affected-entities.js +52 -0
- package/dist/libs/config.d.ts +6 -0
- package/dist/libs/config.d.ts.map +1 -0
- package/dist/libs/config.js +98 -0
- package/dist/libs/dependencies.d.ts +19 -0
- package/dist/libs/dependencies.d.ts.map +1 -0
- package/dist/libs/dependencies.js +62 -0
- package/dist/libs/dependencies.spec.d.ts +2 -0
- package/dist/libs/dependencies.spec.d.ts.map +1 -0
- package/dist/libs/dependencies.spec.js +21 -0
- package/dist/libs/digital-ocean/container-reg.d.ts +6 -0
- package/dist/libs/digital-ocean/container-reg.d.ts.map +1 -0
- package/dist/libs/digital-ocean/container-reg.js +69 -0
- package/dist/libs/discovery/dependencies.d.ts +19 -0
- package/dist/libs/discovery/dependencies.d.ts.map +1 -0
- package/dist/libs/discovery/dependencies.js +62 -0
- package/dist/libs/discovery/dependencies.spec.d.ts +2 -0
- package/dist/libs/discovery/dependencies.spec.d.ts.map +1 -0
- package/dist/libs/discovery/dependencies.spec.js +21 -0
- package/dist/libs/discovery/images.d.ts +5 -0
- package/dist/libs/discovery/images.d.ts.map +1 -0
- package/dist/libs/discovery/images.js +45 -0
- package/dist/libs/discovery/index.d.ts +5 -0
- package/dist/libs/discovery/index.d.ts.map +1 -0
- package/dist/libs/discovery/index.js +55 -0
- package/dist/libs/discovery/package-json-processor.d.ts +3 -0
- package/dist/libs/discovery/package-json-processor.d.ts.map +1 -0
- package/dist/libs/discovery/package-json-processor.js +34 -0
- package/dist/libs/discovery/process-common.d.ts +25 -0
- package/dist/libs/discovery/process-common.d.ts.map +1 -0
- package/dist/libs/discovery/process-common.js +40 -0
- package/dist/libs/discovery/process-package-json.d.ts +3 -0
- package/dist/libs/discovery/process-package-json.d.ts.map +1 -0
- package/dist/libs/discovery/process-package-json.js +34 -0
- package/dist/libs/discovery/process-pyproject-toml.d.ts +3 -0
- package/dist/libs/discovery/process-pyproject-toml.d.ts.map +1 -0
- package/dist/libs/discovery/process-pyproject-toml.js +36 -0
- package/dist/libs/discovery/pyproject-toml-processor.d.ts +3 -0
- package/dist/libs/discovery/pyproject-toml-processor.d.ts.map +1 -0
- package/dist/libs/discovery/pyproject-toml-processor.js +39 -0
- package/dist/libs/git-helpers.d.ts +8 -0
- package/dist/libs/git-helpers.d.ts.map +1 -0
- package/dist/libs/git-helpers.js +20 -0
- package/dist/libs/hetzner/reg-secret.d.ts +3 -0
- package/dist/libs/hetzner/reg-secret.d.ts.map +1 -0
- package/dist/libs/hetzner/reg-secret.js +39 -0
- package/dist/libs/k8s-constants.d.ts +12 -0
- package/dist/libs/k8s-constants.d.ts.map +1 -0
- package/dist/libs/k8s-constants.js +66 -0
- package/dist/libs/k8s-db.d.ts +18 -0
- package/dist/libs/k8s-db.d.ts.map +1 -0
- package/dist/libs/k8s-db.js +73 -0
- package/dist/libs/k8s-generate.d.ts +17 -0
- package/dist/libs/k8s-generate.d.ts.map +1 -0
- package/dist/libs/k8s-generate.js +179 -0
- package/dist/libs/k8s-helpers.d.ts +11 -0
- package/dist/libs/k8s-helpers.d.ts.map +1 -0
- package/dist/libs/k8s-helpers.js +42 -0
- package/dist/libs/k8s-image-config.d.ts +8 -0
- package/dist/libs/k8s-image-config.d.ts.map +1 -0
- package/dist/libs/k8s-image-config.js +113 -0
- package/dist/libs/k8s-job-waiter.d.ts +8 -0
- package/dist/libs/k8s-job-waiter.d.ts.map +1 -0
- package/dist/libs/k8s-job-waiter.js +84 -0
- package/dist/libs/k8s-namespace.d.ts +7 -0
- package/dist/libs/k8s-namespace.d.ts.map +1 -0
- package/dist/libs/k8s-namespace.js +27 -0
- package/dist/libs/k8s-redis.d.ts +6 -0
- package/dist/libs/k8s-redis.d.ts.map +1 -0
- package/dist/libs/k8s-redis.js +31 -0
- package/dist/libs/k8s-secrets-manager.d.ts +5 -0
- package/dist/libs/k8s-secrets-manager.d.ts.map +1 -0
- package/dist/libs/k8s-secrets-manager.js +61 -0
- package/dist/libs/validate-env.d.ts +56 -0
- package/dist/libs/validate-env.d.ts.map +1 -0
- package/dist/libs/validate-env.js +214 -0
- package/dist/libs/validate-env.spec.d.ts +2 -0
- package/dist/libs/validate-env.spec.d.ts.map +1 -0
- package/dist/libs/validate-env.spec.js +168 -0
- package/dist/libs/workspace-discovery.d.ts +2 -0
- package/dist/libs/workspace-discovery.d.ts.map +1 -0
- package/dist/libs/workspace-discovery.js +75 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +1 -0
- package/dist/types/index.d.ts +925 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +79 -0
- package/package.json +55 -0
- package/src/app-support/crypto/index.ts +31 -0
- package/src/app-support/crypto/internal-token.spec.ts +53 -0
- package/src/app-support/crypto/internal-token.ts +82 -0
- package/src/app-support/crypto/secret.spec.ts +18 -0
- package/src/app-support/crypto/secret.ts +13 -0
- package/src/app-support/discovery/dev-discovery-loader.ts +35 -0
- package/src/app-support/discovery/service-endpoint.ts +12 -0
- package/src/cli/affected.ts +116 -0
- package/src/cli/common.spec.ts +78 -0
- package/src/cli/common.ts +323 -0
- package/src/cli/console.ts +46 -0
- package/src/cli/constant.ts +25 -0
- package/src/cli/db.ts +133 -0
- package/src/cli/dml.ts +126 -0
- package/src/cli/env.ts +87 -0
- package/src/cli/exec.sh +21 -0
- package/src/cli/exec.ts +57 -0
- package/src/cli/image.ts +197 -0
- package/src/cli/init.ts +75 -0
- package/src/cli/internal-curl.ts +48 -0
- package/src/cli/job.ts +80 -0
- package/src/cli/jwt.ts +32 -0
- package/src/cli/namespace.ts +78 -0
- package/src/cli/prep-build.ts +96 -0
- package/src/cli/prisma.ts +33 -0
- package/src/cli/redis.ts +83 -0
- package/src/cli/registry.ts +76 -0
- package/src/cli/run-many.ts +61 -0
- package/src/cli/run.ts +46 -0
- package/src/cli/template.ts +169 -0
- package/src/cli/test.ts +30 -0
- package/src/devops.ts +119 -0
- package/src/index.ts +3 -0
- package/src/libs/affected-entities.ts +71 -0
- package/src/libs/config.ts +117 -0
- package/src/libs/digital-ocean/container-reg.ts +81 -0
- package/src/libs/discovery/dependencies.spec.ts +25 -0
- package/src/libs/discovery/dependencies.ts +73 -0
- package/src/libs/discovery/images.ts +57 -0
- package/src/libs/discovery/index.ts +60 -0
- package/src/libs/discovery/process-common.ts +55 -0
- package/src/libs/discovery/process-package-json.ts +47 -0
- package/src/libs/discovery/process-pyproject-toml.ts +43 -0
- package/src/libs/git-helpers.ts +32 -0
- package/src/libs/hetzner/reg-secret.ts +54 -0
- package/src/libs/k8s-constants.ts +83 -0
- package/src/libs/k8s-db.ts +83 -0
- package/src/libs/k8s-generate.ts +211 -0
- package/src/libs/k8s-helpers.ts +59 -0
- package/src/libs/k8s-image-config.ts +165 -0
- package/src/libs/k8s-job-waiter.ts +124 -0
- package/src/libs/k8s-namespace.ts +41 -0
- package/src/libs/k8s-redis.ts +31 -0
- package/src/libs/k8s-secrets-manager.ts +79 -0
- package/src/libs/validate-env.spec.ts +223 -0
- package/src/libs/validate-env.ts +266 -0
- package/src/target-templates/.devops/config/constants.yaml +17 -0
- package/src/target-templates/.devops/config/images.yaml +88 -0
- package/src/target-templates/.devops/docker-images/common/docker-common.sh +23 -0
- package/src/target-templates/.devops/docker-images/node-services/node-exec.sh +8 -0
- package/src/target-templates/.devops/docker-images/node-services/node-run.sh +8 -0
- package/src/target-templates/.devops/docker-images/node-services.Dockerfile +34 -0
- package/src/target-templates/.devops/docker-images/python-services/python-exec.sh +8 -0
- package/src/target-templates/.devops/docker-images/python-services/python-run.sh +8 -0
- package/src/target-templates/.devops/docker-images/python-services.Dockerfile +29 -0
- package/src/target-templates/.devops/env.example.yaml +23 -0
- package/src/target-templates/.devops/infra/hetzner/abandoned/harbor-values.yaml +30 -0
- package/src/target-templates/.devops/infra/hetzner/abandoned/hcloud-config.yaml +134 -0
- package/src/target-templates/.devops/infra/hetzner/cert-manager.yaml +25 -0
- package/src/target-templates/.devops/infra/hetzner/harbor-cert.yaml +13 -0
- package/src/target-templates/.devops/infra/hetzner/harbor-values.yaml +76 -0
- package/src/target-templates/.devops/infra/hetzner/hcloud-config.yaml +113 -0
- package/src/target-templates/.devops/infra/hetzner/ingress-nginx-annotations.yaml +49 -0
- package/src/target-templates/.devops/infra/hetzner/ingress-nginx-configmap.yaml +8 -0
- package/src/target-templates/.devops/infra/hetzner/retain-storage-class.yaml +8 -0
- package/src/target-templates/.devops/infra/monitoring-ingress.yaml +62 -0
- package/src/target-templates/.devops/infra/stackgres-ui-ingress.yaml +35 -0
- package/src/target-templates/.devops/infra/test.yaml +60 -0
- package/src/target-templates/.devops/manifests/_index.yaml +21 -0
- package/src/target-templates/.devops/manifests/cron-jobs.yaml.hb +55 -0
- package/src/target-templates/.devops/manifests/db-migrate-job.yaml.hb +42 -0
- package/src/target-templates/.devops/manifests/deployment-debug.yaml.hb +44 -0
- package/src/target-templates/.devops/manifests/deployment-process.yaml.hb +47 -0
- package/src/target-templates/.devops/manifests/deployment-web.yaml.hb +53 -0
- package/src/target-templates/.devops/manifests/ingress.yaml.hb +21 -0
- package/src/target-templates/.devops/manifests/prefect.yaml.hb +62 -0
- package/src/target-templates/.devops/manifests/service.yaml.hb +15 -0
- package/src/target-templates/.devops/milvus/production/milvus-values.yaml +2 -0
- package/src/target-templates/.devops/milvus/staging/milvus-values.yaml +2 -0
- package/src/target-templates/.devops/postgres/DailyOperatorRestart.yaml +54 -0
- package/src/target-templates/.devops/postgres/production/cluster/PodDisruptionBudget.yaml +27 -0
- package/src/target-templates/.devops/postgres/production/cluster/SGCluster.yaml +47 -0
- package/src/target-templates/.devops/postgres/production/cluster/StackGres-alerts.yaml +191 -0
- package/src/target-templates/.devops/postgres/production/configurations/06-SGDistributedLogs.yaml +11 -0
- package/src/target-templates/.devops/postgres/production/configurations/07-SGObjectStorage.yaml +18 -0
- package/src/target-templates/.devops/postgres/production/configurations/08-SGScript.yaml +12 -0
- package/src/target-templates/.devops/postgres/staging/cluster/SGCluster.yaml +42 -0
- package/src/target-templates/.devops/postgres/staging/configurations/07-SGObjectStorage.yaml +18 -0
- package/src/target-templates/.devops/postgres/staging/configurations/08-SGScript.yaml +12 -0
- package/src/target-templates/.devops/prefect/production/prefect-values.yaml +14 -0
- package/src/target-templates/.devops/prefect/staging/prefect-values.yaml +14 -0
- package/src/target-templates/.devops/redis/production/redis-values.yaml +20 -0
- package/src/target-templates/.devops/redis/staging/redis-values.yaml +8 -0
- package/src/target-templates/.envrc +5 -0
- package/src/target-templates/.github/actions/build-image@v1/action.yaml +86 -0
- package/src/target-templates/.github/actions/connect-to-digital-ocean@v1/action.yaml +29 -0
- package/src/target-templates/.github/actions/connect-to-hetzner@v1/action.yaml +31 -0
- package/src/target-templates/.github/actions/connect-to-infra@v1/action.yaml +46 -0
- package/src/target-templates/.github/actions/db-migrate@v1/action.yaml +23 -0
- package/src/target-templates/.github/actions/deploy-image@v1/action.yaml +33 -0
- package/src/target-templates/.github/actions/setup-prereq@v1/action.yaml +29 -0
- package/src/target-templates/.github/workflows/k8s-build.yaml +84 -0
- package/src/target-templates/applications/example-data-pipeline/pyproject.toml +14 -0
- package/src/target-templates/applications/example-data-pipeline/src/example_data_pipeline/main.py +38 -0
- package/src/target-templates/applications/example-node/index.ts +30 -0
- package/src/target-templates/applications/example-node/package.json +26 -0
- package/src/target-templates/applications/example-node/tsconfig.json +3 -0
- package/src/target-templates/applications/example-python/pyproject.toml +20 -0
- package/src/target-templates/applications/example-python/src/example_python/__init__.py +0 -0
- package/src/target-templates/applications/example-python/src/example_python/main.py +13 -0
- package/src/target-templates/applications/example-python/src/example_python/scripts.py +17 -0
- package/src/target-templates/applications/example-python/tests/__init__.py +0 -0
- package/src/target-templates/applications/jobs/README.md +68 -0
- package/src/target-templates/applications/jobs/index.ts +1 -0
- package/src/target-templates/applications/jobs/package.json +30 -0
- package/src/target-templates/applications/jobs/tsconfig.json +3 -0
- package/src/target-templates/config/.env.development +1 -0
- package/src/target-templates/config/.env.global +4 -0
- package/src/target-templates/config/.env.test +1 -0
- package/src/target-templates/db/db/__init__.py +0 -0
- package/src/target-templates/db/db/db_client_test.py +46 -0
- package/src/target-templates/db/db-client-test.ts +140 -0
- package/src/target-templates/db/db-client.ts +19 -0
- package/src/target-templates/db/env.yaml +4 -0
- package/src/target-templates/db/package.json +17 -0
- package/src/target-templates/db/prisma/schema.prisma +24 -0
- package/src/target-templates/db/prisma-setup-vitest.ts +27 -0
- package/src/target-templates/db/pyproject.toml +14 -0
- package/src/target-templates/db/tsconfig.json +3 -0
- package/src/target-templates/devops +3 -0
- package/src/target-templates/devopspy +3 -0
- package/src/target-templates/dml/package.json +7 -0
- package/src/target-templates/dml/tsconfig.json +3 -0
- package/src/target-templates/libs/example-node-lib/bun.lock +27 -0
- package/src/target-templates/libs/example-node-lib/index.ts +3 -0
- package/src/target-templates/libs/example-node-lib/package.json +12 -0
- package/src/target-templates/libs/example-node-lib/tsconfig.json +3 -0
- package/src/target-templates/libs/example-python-lib/pyproject.toml +11 -0
- package/src/target-templates/libs/example-python-lib/src/example_python_lib/__init__.py +2 -0
- package/src/target-templates/pyproject.toml +19 -0
- package/src/target-templates/tmp/.gitkeep +0 -0
- package/src/target-templates/tsconfig.json +27 -0
- package/src/test.ts +0 -0
- package/src/types/index.ts +173 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
type EnvRequirement = 'optional' | 'boolean' | 'required' | string[];
|
2
|
+
type ParsedEnvYaml = Record<string, EnvRequirement>;
|
3
|
+
type CombinedErrors = Record<string, string[]>;
|
4
|
+
type KeysFromFiles = Record<string, string[]>;
|
5
|
+
export declare class CombinedEnvValidator {
|
6
|
+
envYamlPaths: string[];
|
7
|
+
dotEnvPaths: string[];
|
8
|
+
yamlValidators: SingleEnvValidator[];
|
9
|
+
dotEnvParsers: DotEnvParser[];
|
10
|
+
keysFromYamlFiles: Set<string>;
|
11
|
+
keysFromDotEnvFiles: KeysFromFiles;
|
12
|
+
errors: CombinedErrors;
|
13
|
+
warnings: string[];
|
14
|
+
constructor(envYamlPaths: string[], dotEnvPaths?: string[]);
|
15
|
+
validate(): void;
|
16
|
+
_handleYamlFiles(): void;
|
17
|
+
_handleDotEnvFiles(): void;
|
18
|
+
_loadYamlFiles(envYamlPaths: string[]): void;
|
19
|
+
_validateYamlFiles(): void;
|
20
|
+
_haltIfParsingErrors(): void;
|
21
|
+
_extractErrors(): void;
|
22
|
+
_loadDotEnvFiles(dotEnvPaths?: string[]): void;
|
23
|
+
_parseDotEnvFiles(): void;
|
24
|
+
_combineDotEnvFiles(): void;
|
25
|
+
_extractWarnings(): void;
|
26
|
+
_finalize(): void;
|
27
|
+
}
|
28
|
+
/**
|
29
|
+
* While we don't strictly need to parse .env files (we can simply use process.env), it is useful to give
|
30
|
+
* warnings to the user that there are unused entries in .env files compared to the stated requirements
|
31
|
+
* captured in env.yaml files.
|
32
|
+
*/
|
33
|
+
export declare class DotEnvParser {
|
34
|
+
path: string;
|
35
|
+
keys: string[] | undefined;
|
36
|
+
constructor(path: string);
|
37
|
+
parse(): void;
|
38
|
+
_readFile(path: string): string | undefined;
|
39
|
+
_parse(text: string): string[];
|
40
|
+
}
|
41
|
+
export declare class SingleEnvValidator {
|
42
|
+
envYamlPath: string;
|
43
|
+
parsedEnvYaml: ParsedEnvYaml | undefined;
|
44
|
+
parsingError: string | undefined;
|
45
|
+
errors: Record<string, string>;
|
46
|
+
constructor(envYamlPath: string);
|
47
|
+
validate(): void;
|
48
|
+
_readFile(): any;
|
49
|
+
_generateError(message: string): string;
|
50
|
+
_setParsingError(message: string): void;
|
51
|
+
_addError(key: string, message: string): void;
|
52
|
+
_parse(): ParsedEnvYaml | undefined;
|
53
|
+
_addAllErrors(): void;
|
54
|
+
}
|
55
|
+
export {};
|
56
|
+
//# sourceMappingURL=validate-env.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"validate-env.d.ts","sourceRoot":"","sources":["../../src/libs/validate-env.ts"],"names":[],"mappings":"AAIA,KAAK,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,EAAE,CAAC;AACrE,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AACpD,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/C,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE9C,qBAAa,oBAAoB;IAC/B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB,cAAc,EAAE,kBAAkB,EAAE,CAAM;IAC1C,aAAa,EAAE,YAAY,EAAE,CAAM;IAEnC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAC3C,mBAAmB,EAAE,aAAa,CAAM;IAExC,MAAM,EAAE,cAAc,CAAM;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAM;gBAEZ,YAAY,EAAE,MAAM,EAAE,EAAE,WAAW,GAAE,MAAM,EAAO;IAO9D,QAAQ;IAMR,gBAAgB;IAOhB,kBAAkB;IAOlB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE;IAOrC,kBAAkB;IAIlB,oBAAoB;IAapB,cAAc;IAYd,gBAAgB,CAAC,WAAW,GAAE,MAAM,EAAO;IAO3C,iBAAiB;IAIjB,mBAAmB;IAUnB,gBAAgB;IAShB,SAAS;CAkBV;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;gBAEf,IAAI,EAAE,MAAM;IAIxB,KAAK;IAKL,SAAS,CAAC,IAAI,EAAE,MAAM;IAKtB,MAAM,CAAC,IAAI,EAAE,MAAM;CAWpB;AAED,qBAAa,kBAAkB;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IACzC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;gBAExB,WAAW,EAAE,MAAM;IAI/B,QAAQ;IAKR,SAAS;IAQT,cAAc,CAAC,OAAO,EAAE,MAAM;IAI9B,gBAAgB,CAAC,OAAO,EAAE,MAAM;IAIhC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAItC,MAAM;IAmCN,aAAa;CAwBd"}
|
@@ -0,0 +1,214 @@
|
|
1
|
+
import fs from 'fs';
|
2
|
+
import yaml from 'yaml';
|
3
|
+
import { IGNORED_PATHS } from './discovery/process-common';
|
4
|
+
export class CombinedEnvValidator {
|
5
|
+
envYamlPaths;
|
6
|
+
dotEnvPaths;
|
7
|
+
yamlValidators = [];
|
8
|
+
dotEnvParsers = [];
|
9
|
+
keysFromYamlFiles = new Set();
|
10
|
+
keysFromDotEnvFiles = {};
|
11
|
+
errors = {};
|
12
|
+
warnings = [];
|
13
|
+
constructor(envYamlPaths, dotEnvPaths = []) {
|
14
|
+
this.envYamlPaths = envYamlPaths.filter(path => !IGNORED_PATHS.some((ignoredPath) => path.includes(ignoredPath)));
|
15
|
+
this.dotEnvPaths = dotEnvPaths;
|
16
|
+
}
|
17
|
+
validate() {
|
18
|
+
this._handleYamlFiles();
|
19
|
+
this._handleDotEnvFiles();
|
20
|
+
this._finalize();
|
21
|
+
}
|
22
|
+
_handleYamlFiles() {
|
23
|
+
this._loadYamlFiles(this.envYamlPaths);
|
24
|
+
this._validateYamlFiles();
|
25
|
+
this._haltIfParsingErrors();
|
26
|
+
this._extractErrors();
|
27
|
+
}
|
28
|
+
_handleDotEnvFiles() {
|
29
|
+
this._loadDotEnvFiles(this.dotEnvPaths);
|
30
|
+
this._parseDotEnvFiles();
|
31
|
+
this._combineDotEnvFiles();
|
32
|
+
this._extractWarnings();
|
33
|
+
}
|
34
|
+
_loadYamlFiles(envYamlPaths) {
|
35
|
+
envYamlPaths.forEach((path) => {
|
36
|
+
const validator = new SingleEnvValidator(path);
|
37
|
+
this.yamlValidators.push(validator);
|
38
|
+
});
|
39
|
+
}
|
40
|
+
_validateYamlFiles() {
|
41
|
+
this.yamlValidators.forEach((x) => x.validate());
|
42
|
+
}
|
43
|
+
_haltIfParsingErrors() {
|
44
|
+
const filesWithParsingErrors = this.yamlValidators.filter((validator) => Boolean(validator.parsingError));
|
45
|
+
if (filesWithParsingErrors.length === 0)
|
46
|
+
return;
|
47
|
+
console.error('The following env.yaml files have parsing errors:');
|
48
|
+
filesWithParsingErrors.forEach((validator) => {
|
49
|
+
console.error(`\t${validator.parsingError}`);
|
50
|
+
});
|
51
|
+
process.exit(1);
|
52
|
+
}
|
53
|
+
_extractErrors() {
|
54
|
+
this.yamlValidators.forEach((validator) => {
|
55
|
+
Object.keys(validator.parsedEnvYaml ?? {}).forEach((envVar) => {
|
56
|
+
this.keysFromYamlFiles.add(envVar);
|
57
|
+
});
|
58
|
+
Object.entries(validator.errors).forEach(([envVar, error]) => {
|
59
|
+
this.errors[envVar] ??= [];
|
60
|
+
this.errors[envVar].push(error);
|
61
|
+
});
|
62
|
+
});
|
63
|
+
}
|
64
|
+
_loadDotEnvFiles(dotEnvPaths = []) {
|
65
|
+
dotEnvPaths.forEach((path) => {
|
66
|
+
const parser = new DotEnvParser(path);
|
67
|
+
this.dotEnvParsers.push(parser);
|
68
|
+
});
|
69
|
+
}
|
70
|
+
_parseDotEnvFiles() {
|
71
|
+
this.dotEnvParsers.forEach((x) => x.parse());
|
72
|
+
}
|
73
|
+
_combineDotEnvFiles() {
|
74
|
+
this.dotEnvParsers.forEach((parser) => {
|
75
|
+
if (!parser.keys)
|
76
|
+
return;
|
77
|
+
parser.keys.forEach((key) => {
|
78
|
+
this.keysFromDotEnvFiles[key] ??= [];
|
79
|
+
this.keysFromDotEnvFiles[key].push(parser.path);
|
80
|
+
});
|
81
|
+
});
|
82
|
+
}
|
83
|
+
_extractWarnings() {
|
84
|
+
const unusedKeys = Object.keys(this.keysFromDotEnvFiles).filter((x) => !this.keysFromYamlFiles.has(x));
|
85
|
+
unusedKeys.forEach((x) => {
|
86
|
+
this.warnings.push(`${x} in: ${this.keysFromDotEnvFiles[x].join(', ')}`);
|
87
|
+
});
|
88
|
+
}
|
89
|
+
_finalize() {
|
90
|
+
if (this.warnings.length > 0) {
|
91
|
+
console.error('WARNING: some env variables exist in .env but not in env.yaml:');
|
92
|
+
this.warnings.forEach((warning) => console.error(`\t${warning}`));
|
93
|
+
console.error();
|
94
|
+
}
|
95
|
+
if (Object.keys(this.errors).length > 0) {
|
96
|
+
Object.entries(this.errors).forEach(([key, errors]) => {
|
97
|
+
console.error(`Errors for ${key}:`);
|
98
|
+
errors.forEach((error) => console.error(`\t${error}`));
|
99
|
+
console.error();
|
100
|
+
});
|
101
|
+
console.error();
|
102
|
+
process.exit(1);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
/**
|
107
|
+
* While we don't strictly need to parse .env files (we can simply use process.env), it is useful to give
|
108
|
+
* warnings to the user that there are unused entries in .env files compared to the stated requirements
|
109
|
+
* captured in env.yaml files.
|
110
|
+
*/
|
111
|
+
export class DotEnvParser {
|
112
|
+
path;
|
113
|
+
keys;
|
114
|
+
constructor(path) {
|
115
|
+
this.path = path;
|
116
|
+
}
|
117
|
+
parse() {
|
118
|
+
const text = this._readFile(this.path);
|
119
|
+
if (text)
|
120
|
+
this.keys = this._parse(text);
|
121
|
+
}
|
122
|
+
_readFile(path) {
|
123
|
+
if (!fs.existsSync(path))
|
124
|
+
return;
|
125
|
+
return fs.readFileSync(path).toString();
|
126
|
+
}
|
127
|
+
_parse(text) {
|
128
|
+
const lines = text.split('\n');
|
129
|
+
const withoutComments = lines
|
130
|
+
.map((x) => x.replace(/#.*$/, '').trim())
|
131
|
+
.filter(Boolean);
|
132
|
+
const keys = withoutComments
|
133
|
+
.map((x) => x.split('=').map((y) => y.trim()))
|
134
|
+
.filter((x) => x.length > 1)
|
135
|
+
.map((x) => x[0]);
|
136
|
+
return keys;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
export class SingleEnvValidator {
|
140
|
+
envYamlPath;
|
141
|
+
parsedEnvYaml;
|
142
|
+
parsingError;
|
143
|
+
errors = {};
|
144
|
+
constructor(envYamlPath) {
|
145
|
+
this.envYamlPath = envYamlPath;
|
146
|
+
}
|
147
|
+
validate() {
|
148
|
+
this.parsedEnvYaml = this._parse();
|
149
|
+
if (!this.parsingError)
|
150
|
+
this._addAllErrors();
|
151
|
+
}
|
152
|
+
_readFile() {
|
153
|
+
if (!fs.existsSync(this.envYamlPath)) {
|
154
|
+
console.error(`Skipping ${this.envYamlPath}: does not exist`);
|
155
|
+
return;
|
156
|
+
}
|
157
|
+
return yaml.parse(fs.readFileSync(this.envYamlPath).toString());
|
158
|
+
}
|
159
|
+
_generateError(message) {
|
160
|
+
return `Error in ${this.envYamlPath}: ${message}`;
|
161
|
+
}
|
162
|
+
_setParsingError(message) {
|
163
|
+
this.parsingError = this._generateError(message);
|
164
|
+
}
|
165
|
+
_addError(key, message) {
|
166
|
+
this.errors[key] = this._generateError(message);
|
167
|
+
}
|
168
|
+
_parse() {
|
169
|
+
const allEnv = {};
|
170
|
+
const envManifest = this._readFile();
|
171
|
+
if (!envManifest)
|
172
|
+
return;
|
173
|
+
if (!(envManifest instanceof Array)) {
|
174
|
+
this._setParsingError(`env.yaml file must resolve to an array`);
|
175
|
+
return;
|
176
|
+
}
|
177
|
+
envManifest.forEach((env) => {
|
178
|
+
if (env instanceof Object) {
|
179
|
+
const entries = Object.entries(env);
|
180
|
+
if (entries.length > 1) {
|
181
|
+
this._setParsingError(`every object in env.yaml must have one key. Error near: ${entries[0][0]}`);
|
182
|
+
return;
|
183
|
+
}
|
184
|
+
const [name, value] = entries[0];
|
185
|
+
if (!(value instanceof Array) &&
|
186
|
+
!['optional', 'boolean'].includes(value)) {
|
187
|
+
this._setParsingError(`invalid value for ${name}: ${JSON.stringify(value)}`);
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
allEnv[name] = value;
|
191
|
+
}
|
192
|
+
else {
|
193
|
+
allEnv[env] = 'required';
|
194
|
+
}
|
195
|
+
});
|
196
|
+
return allEnv;
|
197
|
+
}
|
198
|
+
_addAllErrors() {
|
199
|
+
Object.entries(this.parsedEnvYaml).forEach(([key, requirement]) => {
|
200
|
+
const value = process.env[key];
|
201
|
+
if (requirement !== 'optional' && !value) {
|
202
|
+
this._addError(key, `${key} is required but missing`);
|
203
|
+
}
|
204
|
+
else if (requirement === 'boolean' &&
|
205
|
+
!['true', 'false'].includes(String(value))) {
|
206
|
+
this._addError(key, `${key} must be either true or false. Value: ${value}`);
|
207
|
+
}
|
208
|
+
else if (requirement instanceof Array &&
|
209
|
+
!requirement.includes(value ?? '')) {
|
210
|
+
this._addError(key, `${key} must be one of ${requirement.join(', ')}. Value: ${value}`);
|
211
|
+
}
|
212
|
+
});
|
213
|
+
}
|
214
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"validate-env.spec.d.ts","sourceRoot":"","sources":["../../src/libs/validate-env.spec.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,168 @@
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
2
|
+
import { CombinedEnvValidator, DotEnvParser, SingleEnvValidator, } from './validate-env';
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
4
|
+
function withEnvVars(envVars, callbackFn) {
|
5
|
+
Object.entries(envVars).forEach(([key, value]) => (process.env[key] = value));
|
6
|
+
try {
|
7
|
+
callbackFn();
|
8
|
+
}
|
9
|
+
finally {
|
10
|
+
Object.keys(envVars).forEach((key) => delete process.env[key]);
|
11
|
+
}
|
12
|
+
}
|
13
|
+
describe('SingleEnvValidator', () => {
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
15
|
+
function createSubject(yamlContent) {
|
16
|
+
const subject = new SingleEnvValidator('dummy-path.yaml');
|
17
|
+
vi.spyOn(subject, '_readFile').mockReturnValue(yamlContent);
|
18
|
+
return subject;
|
19
|
+
}
|
20
|
+
describe('invalid yaml files', () => {
|
21
|
+
it('contains parsingError when not an array', () => {
|
22
|
+
const subject = createSubject({ DUMMY1: 'optional' });
|
23
|
+
subject.validate();
|
24
|
+
expect(subject.parsingError).toContain('env.yaml file must resolve to an array');
|
25
|
+
});
|
26
|
+
it('contains parsingError when an object has multiple keys', () => {
|
27
|
+
const subject = createSubject([
|
28
|
+
{ DUMMY1: 'optional', DUMMY2: 'optional' },
|
29
|
+
]);
|
30
|
+
subject.validate();
|
31
|
+
expect(subject.parsingError).toContain('every object in env.yaml must have one key. Error near: DUMMY1');
|
32
|
+
});
|
33
|
+
it('contains parsingError when an object has invalid requirement', () => {
|
34
|
+
const subject = createSubject([{ DUMMY1: 'optttttttional' }]);
|
35
|
+
subject.validate();
|
36
|
+
expect(subject.parsingError).toContain('invalid value for DUMMY1');
|
37
|
+
});
|
38
|
+
});
|
39
|
+
describe('valid yaml file', () => {
|
40
|
+
const validYaml = [
|
41
|
+
'TEST_ENV_MANDATORY',
|
42
|
+
{ TEST_ENV_OPTIONAL: 'optional' },
|
43
|
+
{ TEST_ENV_BOOLEAN1: 'boolean' },
|
44
|
+
{ TEST_ENV_BOOLEAN2: 'boolean' },
|
45
|
+
{ TEST_ENV_ENUM1: ['option1', 'option2'] },
|
46
|
+
{ TEST_ENV_ENUM2: ['option1', 'option2'] },
|
47
|
+
];
|
48
|
+
const defaultValues = {
|
49
|
+
TEST_ENV_MANDATORY: 'some_value',
|
50
|
+
TEST_ENV_BOOLEAN1: 'true',
|
51
|
+
TEST_ENV_BOOLEAN2: 'false',
|
52
|
+
TEST_ENV_ENUM1: 'option1',
|
53
|
+
TEST_ENV_ENUM2: 'option2',
|
54
|
+
};
|
55
|
+
function withEnvVarsHelper(envVars,
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
57
|
+
callbackFn) {
|
58
|
+
envVars = { ...defaultValues, ...envVars };
|
59
|
+
withEnvVars(envVars, callbackFn);
|
60
|
+
}
|
61
|
+
it('works when all env vars are provided as expected', () => {
|
62
|
+
const subject = createSubject(validYaml);
|
63
|
+
withEnvVarsHelper({}, () => subject.validate());
|
64
|
+
expect(subject.parsingError).toEqual(undefined);
|
65
|
+
expect(subject.errors).toEqual({});
|
66
|
+
});
|
67
|
+
it('works when an optional varilable is provided', () => {
|
68
|
+
const subject = createSubject(validYaml);
|
69
|
+
withEnvVarsHelper({ TEST_ENV_OPTIONAL: 'value' }, () => subject.validate());
|
70
|
+
expect(subject.parsingError).toEqual(undefined);
|
71
|
+
expect(subject.errors).toEqual({});
|
72
|
+
});
|
73
|
+
it('contains errors when mandatory is not provided', () => {
|
74
|
+
const subject = createSubject(validYaml);
|
75
|
+
withEnvVarsHelper({ TEST_ENV_MANDATORY: '' }, () => subject.validate());
|
76
|
+
expect(subject.parsingError).toEqual(undefined);
|
77
|
+
expect(Object.keys(subject.errors)).toEqual(['TEST_ENV_MANDATORY']);
|
78
|
+
});
|
79
|
+
it('contains errors when boolean is different than true or false', () => {
|
80
|
+
const subject = createSubject(validYaml);
|
81
|
+
withEnvVarsHelper({ TEST_ENV_BOOLEAN1: 'value' }, () => subject.validate());
|
82
|
+
expect(subject.parsingError).toEqual(undefined);
|
83
|
+
expect(Object.keys(subject.errors)).toEqual(['TEST_ENV_BOOLEAN1']);
|
84
|
+
});
|
85
|
+
it('contains errors when enum is different than provided options', () => {
|
86
|
+
const subject = createSubject(validYaml);
|
87
|
+
withEnvVarsHelper({ TEST_ENV_ENUM1: 'option3' }, () => subject.validate());
|
88
|
+
expect(subject.parsingError).toEqual(undefined);
|
89
|
+
expect(Object.keys(subject.errors)).toEqual(['TEST_ENV_ENUM1']);
|
90
|
+
});
|
91
|
+
});
|
92
|
+
});
|
93
|
+
describe('DotEnvParser', () => {
|
94
|
+
function createSubject(text) {
|
95
|
+
const subject = new DotEnvParser('dummy-path.env');
|
96
|
+
vi.spyOn(subject, '_readFile').mockReturnValue(text);
|
97
|
+
return subject;
|
98
|
+
}
|
99
|
+
it('works, taking into account comments and ignoring empty lines', () => {
|
100
|
+
const subject = createSubject(`
|
101
|
+
|
102
|
+
# Ignored
|
103
|
+
TEST1=hello
|
104
|
+
|
105
|
+
TEST2=world # also ignored
|
106
|
+
|
107
|
+
|
108
|
+
TEST3 = spaces should not normally be allowed in .env # so the parser is not strict
|
109
|
+
|
110
|
+
`);
|
111
|
+
subject.parse();
|
112
|
+
expect(subject.keys).toEqual(['TEST1', 'TEST2', 'TEST3']);
|
113
|
+
});
|
114
|
+
});
|
115
|
+
describe('CombinedEnvValidator', () => {
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
117
|
+
function createSubject(yamlContent, dotEnvContent) {
|
118
|
+
const yamlPaths = yamlContent.map((_, i) => `dummy-yaml-${i}`);
|
119
|
+
const dotEnvPaths = dotEnvContent.map((_, i) => `dummy-dotenv-${i}`);
|
120
|
+
const yamlValidators = yamlContent.map((content, i) => {
|
121
|
+
const validator = new SingleEnvValidator(yamlPaths[i]);
|
122
|
+
vi.spyOn(validator, '_readFile').mockReturnValue(content);
|
123
|
+
return validator;
|
124
|
+
});
|
125
|
+
const dotEnvParsers = dotEnvContent.map((content, i) => {
|
126
|
+
const parser = new DotEnvParser(dotEnvPaths[i]);
|
127
|
+
vi.spyOn(parser, '_readFile').mockReturnValue(content);
|
128
|
+
return parser;
|
129
|
+
});
|
130
|
+
const subject = new CombinedEnvValidator(yamlPaths, dotEnvPaths);
|
131
|
+
vi.spyOn(subject, '_loadYamlFiles').mockImplementation(() => (subject.yamlValidators = yamlValidators));
|
132
|
+
vi.spyOn(subject, '_loadDotEnvFiles').mockImplementation(() => (subject.dotEnvParsers = dotEnvParsers));
|
133
|
+
return subject;
|
134
|
+
}
|
135
|
+
it('works when no errors and no warnings', () => {
|
136
|
+
const yaml1 = ['TEST_ENV1', 'TEST_ENV2'];
|
137
|
+
const yaml2 = [{ TEST_ENV3: 'optional' }];
|
138
|
+
const dotEnv1 = 'TEST_ENV1=hi';
|
139
|
+
const dotEnv2 = 'TEST_ENV2=bye';
|
140
|
+
const subject = createSubject([yaml1, yaml2], [dotEnv1, dotEnv2]);
|
141
|
+
withEnvVars({ TEST_ENV1: 'hi', TEST_ENV2: 'bye' }, () => subject.validate());
|
142
|
+
expect(subject.warnings).toEqual([]);
|
143
|
+
expect(subject.errors).toEqual({});
|
144
|
+
});
|
145
|
+
it('emits warnings', () => {
|
146
|
+
const yaml1 = ['TEST_ENV1', 'TEST_ENV2'];
|
147
|
+
const yaml2 = [{ TEST_ENV3: 'optional' }];
|
148
|
+
const dotEnv1 = 'TEST_ENV1=hi';
|
149
|
+
const dotEnv2 = 'TEST_ENV2=bye';
|
150
|
+
const dotEnv3 = 'TEST_ENV4=boo';
|
151
|
+
const subject = createSubject([yaml1, yaml2], [dotEnv1, dotEnv2, dotEnv3]);
|
152
|
+
withEnvVars({ TEST_ENV1: 'hi', TEST_ENV2: 'bye' }, () => subject.validate());
|
153
|
+
expect(subject.warnings.length).toEqual(1);
|
154
|
+
expect(subject.warnings[0]).toContain('TEST_ENV4');
|
155
|
+
expect(subject.errors).toEqual({});
|
156
|
+
});
|
157
|
+
it('emits errors', () => {
|
158
|
+
vi.spyOn(process, 'exit').mockReturnValue(undefined);
|
159
|
+
const yaml1 = ['TEST_ENV1', 'TEST_ENV2'];
|
160
|
+
const yaml2 = [{ TEST_ENV3: 'optional' }];
|
161
|
+
const dotEnv1 = 'TEST_ENV1=hi';
|
162
|
+
const subject = createSubject([yaml1, yaml2], [dotEnv1]);
|
163
|
+
withEnvVars({ TEST_ENV1: 'hi' }, () => subject.validate());
|
164
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
165
|
+
expect(subject.warnings).toEqual([]);
|
166
|
+
expect(Object.keys(subject.errors)).toEqual(['TEST_ENV2']);
|
167
|
+
});
|
168
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workspace-discovery.d.ts","sourceRoot":"","sources":["../../src/libs/workspace-discovery.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
// import chalk from "chalk";
|
2
|
+
// import fs from "fs";
|
3
|
+
// import { globSync } from "glob";
|
4
|
+
// import path from "path";
|
5
|
+
// import type { PkgData, ProjectData } from "../types";
|
6
|
+
// import { WorkspaceDependencies } from "./dependencies";
|
7
|
+
// import { getImageData, getImageNames } from "./config";
|
8
|
+
export {};
|
9
|
+
// const _imageDescendents: Record<string, string[]> = {};
|
10
|
+
// let _imageDescendentsLoaded = false;
|
11
|
+
// function imageDescendents() {
|
12
|
+
// if (!_imageDescendentsLoaded) {
|
13
|
+
// for (const imageName of getImageNames()) {
|
14
|
+
// const imageData = getImageData(imageName);
|
15
|
+
// const descendents = new Set<string>();
|
16
|
+
// imageData.applications.forEach((project) => {
|
17
|
+
// descendents.add(project);
|
18
|
+
// getDescendentNames(project).forEach((name) => descendents.add(name));
|
19
|
+
// });
|
20
|
+
// _imageDescendents[imageName] = Array.from(descendents);
|
21
|
+
// }
|
22
|
+
// _imageDescendentsLoaded = true;
|
23
|
+
// }
|
24
|
+
// return _imageDescendents;
|
25
|
+
// }
|
26
|
+
// const _workspaceImages: Record<string, string[]> = {};
|
27
|
+
// let _workspaceImagesLoaded = false;
|
28
|
+
// function workspaceImages() {
|
29
|
+
// if (!_workspaceImagesLoaded) {
|
30
|
+
// for (const [imageName, descendents] of Object.entries(imageDescendents())) {
|
31
|
+
// for (const workspaceName of descendents) {
|
32
|
+
// _workspaceImages[workspaceName] ??= [];
|
33
|
+
// _workspaceImages[workspaceName].push(imageName);
|
34
|
+
// }
|
35
|
+
// }
|
36
|
+
// _workspaceImagesLoaded = true;
|
37
|
+
// }
|
38
|
+
// return _workspaceImages;
|
39
|
+
// }
|
40
|
+
// export function workspaceNames() {
|
41
|
+
// return Object.keys(workspaces());
|
42
|
+
// }
|
43
|
+
// export function getWorkspace(workspaceName: string) {
|
44
|
+
// const workspace = workspaces()[workspaceName];
|
45
|
+
// if (!workspace) {
|
46
|
+
// console.error(chalk.red(`\nWorkspace ${workspaceName} not found\n`));
|
47
|
+
// // The gha relies on the 13 exit code for "not found"
|
48
|
+
// process.exit(13);
|
49
|
+
// }
|
50
|
+
// return workspace;
|
51
|
+
// }
|
52
|
+
// const dependencyResolve = new WorkspaceDependencies(workspaces);
|
53
|
+
// /** Note: this includes the name of the provided workspace */
|
54
|
+
// export function getDescendentNames(workspaceName: string) {
|
55
|
+
// const _ensurePresence = getWorkspace(workspaceName);
|
56
|
+
// return dependencyResolve.getDependents(workspaceName);
|
57
|
+
// }
|
58
|
+
// /** Note: this includes the provided workspace's data */
|
59
|
+
// export function getDecendentData(workspaceName: string) {
|
60
|
+
// return getDescendentNames(workspaceName).map((name) => getWorkspace(name));
|
61
|
+
// }
|
62
|
+
// /** The dependent workspaces are specified in config/images.yaml */
|
63
|
+
// export function getImageDescendentNames(imageName: string) {
|
64
|
+
// return imageDescendents()[imageName];
|
65
|
+
// }
|
66
|
+
// /** The dependent workspaces are specified in config/images.yaml */
|
67
|
+
// export function getImageDescendentData(imageName: string) {
|
68
|
+
// return (
|
69
|
+
// getImageDescendentNames(imageName).map((name) => getWorkspace(name)) ?? []
|
70
|
+
// );
|
71
|
+
// }
|
72
|
+
// export function getWorkspaceImages(workspaceName: string) {
|
73
|
+
// const _verifyPresence = getWorkspace(workspaceName);
|
74
|
+
// return workspaceImages()[workspaceName] ?? [];
|
75
|
+
// }
|
package/dist/test.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":""}
|
package/dist/test.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|