diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25d36d4e..65ff8a44 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,14 +31,12 @@ jobs: node-version: lts/* - name: Install dependencies run: yarn install --check-files - - name: "Update snapshots: secret-inline" - run: yarn run projen integ:secret-inline:snapshot - - name: "Update snapshots: secret-asset" - run: yarn run projen integ:secret-asset:snapshot - - name: "Update snapshots: secret-multikms" - run: yarn run projen integ:secret-multikms:snapshot - - name: "Update snapshots: secret-manual" - run: yarn run projen integ:secret-manual:snapshot + - name: "Update snapshots: PARAMETER" + run: yarn run projen integ:PARAMETER:snapshot + - name: "Update snapshots: PARAMETER_MULTI" + run: yarn run projen integ:PARAMETER_MULTI:snapshot + - name: "Update snapshots: SECRET" + run: yarn run projen integ:SECRET:snapshot - name: build run: npx projen build - name: Upload coverage to Codecov diff --git a/.gitignore b/.gitignore index a3a8d04f..dd804af9 100644 --- a/.gitignore +++ b/.gitignore @@ -52,39 +52,31 @@ junit.xml .jsii tsconfig.json !/API.md -test/secret-asset.integ.snapshot/asset.* -test/secret-asset.integ.snapshot/**/asset.* -test/secret-asset.integ.snapshot/cdk.out -test/secret-asset.integ.snapshot/**/cdk.out -test/secret-asset.integ.snapshot/manifest.json -test/secret-asset.integ.snapshot/**/manifest.json -test/secret-asset.integ.snapshot/tree.json -test/secret-asset.integ.snapshot/**/tree.json -test/secret-inline.integ.snapshot/asset.* -test/secret-inline.integ.snapshot/**/asset.* -test/secret-inline.integ.snapshot/cdk.out -test/secret-inline.integ.snapshot/**/cdk.out -test/secret-inline.integ.snapshot/manifest.json -test/secret-inline.integ.snapshot/**/manifest.json -test/secret-inline.integ.snapshot/tree.json -test/secret-inline.integ.snapshot/**/tree.json -test/secret-manual.integ.snapshot/asset.* -test/secret-manual.integ.snapshot/**/asset.* -test/secret-manual.integ.snapshot/cdk.out -test/secret-manual.integ.snapshot/**/cdk.out -test/secret-manual.integ.snapshot/manifest.json -test/secret-manual.integ.snapshot/**/manifest.json -test/secret-manual.integ.snapshot/tree.json -test/secret-manual.integ.snapshot/**/tree.json +test/PARAMETER_MULTI.integ.snapshot/asset.* +test/PARAMETER_MULTI.integ.snapshot/**/asset.* +test/PARAMETER_MULTI.integ.snapshot/cdk.out +test/PARAMETER_MULTI.integ.snapshot/**/cdk.out +test/PARAMETER_MULTI.integ.snapshot/manifest.json +test/PARAMETER_MULTI.integ.snapshot/**/manifest.json +test/PARAMETER_MULTI.integ.snapshot/tree.json +test/PARAMETER_MULTI.integ.snapshot/**/tree.json +test/PARAMETER.integ.snapshot/asset.* +test/PARAMETER.integ.snapshot/**/asset.* +test/PARAMETER.integ.snapshot/cdk.out +test/PARAMETER.integ.snapshot/**/cdk.out +test/PARAMETER.integ.snapshot/manifest.json +test/PARAMETER.integ.snapshot/**/manifest.json +test/PARAMETER.integ.snapshot/tree.json +test/PARAMETER.integ.snapshot/**/tree.json test/.tmp -test/secret-multikms.integ.snapshot/asset.* -test/secret-multikms.integ.snapshot/**/asset.* -test/secret-multikms.integ.snapshot/cdk.out -test/secret-multikms.integ.snapshot/**/cdk.out -test/secret-multikms.integ.snapshot/manifest.json -test/secret-multikms.integ.snapshot/**/manifest.json -test/secret-multikms.integ.snapshot/tree.json -test/secret-multikms.integ.snapshot/**/tree.json +test/SECRET.integ.snapshot/asset.* +test/SECRET.integ.snapshot/**/asset.* +test/SECRET.integ.snapshot/cdk.out +test/SECRET.integ.snapshot/**/cdk.out +test/SECRET.integ.snapshot/manifest.json +test/SECRET.integ.snapshot/**/manifest.json +test/SECRET.integ.snapshot/tree.json +test/SECRET.integ.snapshot/**/tree.json *.iml .idea /assets diff --git a/.gitleaks.toml b/.gitleaks.toml index 48362bae..6f2956bf 100644 --- a/.gitleaks.toml +++ b/.gitleaks.toml @@ -36,5 +36,7 @@ paths = [ regexTarget = "match" regexes = [ '''AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3''', + '''ghp_abcd1234''', + '''sk-1234567890abcdef''', ] diff --git a/.go-version b/.go-version index 89144dbc..ca8ec414 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.22.3 +1.23.5 diff --git a/.npmignore b/.npmignore index 867547c3..e465bc97 100644 --- a/.npmignore +++ b/.npmignore @@ -24,11 +24,10 @@ dist tsconfig.tsbuildinfo /.eslintrc.json !.jsii -test/secret-asset.integ.snapshot -test/secret-inline.integ.snapshot -test/secret-manual.integ.snapshot +test/PARAMETER_MULTI.integ.snapshot +test/PARAMETER.integ.snapshot test/.tmp -test/secret-multikms.integ.snapshot +test/SECRET.integ.snapshot /lambda /dist-lambda /scripts diff --git a/.projen/deps.json b/.projen/deps.json index c44b8d55..0630fc21 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -81,6 +81,10 @@ "version": "~5.6.0", "type": "build" }, + { + "name": "json-schema-to-typescript", + "type": "build" + }, { "name": "prettier", "type": "build" @@ -107,7 +111,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.144.0", + "version": "^2.177.0", "type": "peer" }, { diff --git a/.projen/tasks.json b/.projen/tasks.json index 862269d5..bb8510dc 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -153,255 +153,192 @@ } ] }, - "integ:secret-asset:assert": { - "name": "integ:secret-asset:assert", - "description": "assert the snapshot of integration test 'secret-asset'", + "integ:PARAMETER_MULTI:assert": { + "name": "integ:PARAMETER_MULTI:assert", + "description": "assert the snapshot of integration test 'PARAMETER_MULTI'", "steps": [ { - "exec": "[ -d \"test/secret-asset.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-asset'. Run 'projen integ:secret-asset:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/PARAMETER_MULTI.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'PARAMETER_MULTI'. Run 'projen integ:PARAMETER_MULTI:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-asset.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/PARAMETER_MULTI.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-asset.integ.snapshot/ test/.tmp/secret-asset.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/PARAMETER_MULTI.integ.snapshot/ test/.tmp/PARAMETER_MULTI.integ/assert.cdk.out/" } ] }, - "integ:secret-asset:deploy": { - "name": "integ:secret-asset:deploy", - "description": "deploy integration test 'secret-asset' and capture snapshot", + "integ:PARAMETER_MULTI:deploy": { + "name": "integ:PARAMETER_MULTI:deploy", + "description": "deploy integration test 'PARAMETER_MULTI' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-asset.integ.snapshot" + "exec": "rm -fr test/PARAMETER_MULTI.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-asset.integ/deploy.cdk.out test/secret-asset.integ.snapshot" + "exec": "mv test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out test/PARAMETER_MULTI.integ.snapshot" }, { - "spawn": "integ:secret-asset:destroy" + "spawn": "integ:PARAMETER_MULTI:destroy" } ] }, - "integ:secret-asset:destroy": { - "name": "integ:secret-asset:destroy", - "description": "destroy integration test 'secret-asset'", + "integ:PARAMETER_MULTI:destroy": { + "name": "integ:PARAMETER_MULTI:destroy", + "description": "destroy integration test 'PARAMETER_MULTI'", "steps": [ { - "exec": "cdk destroy --app test/secret-asset.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/PARAMETER_MULTI.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-asset:snapshot": { - "name": "integ:secret-asset:snapshot", - "description": "update snapshot for integration test \"secret-asset\"", + "integ:PARAMETER_MULTI:snapshot": { + "name": "integ:PARAMETER_MULTI:snapshot", + "description": "update snapshot for integration test \"PARAMETER_MULTI\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-asset.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/PARAMETER_MULTI.integ.snapshot > /dev/null" } ] }, - "integ:secret-asset:watch": { - "name": "integ:secret-asset:watch", - "description": "watch integration test 'secret-asset' (without updating snapshots)", + "integ:PARAMETER_MULTI:watch": { + "name": "integ:PARAMETER_MULTI:watch", + "description": "watch integration test 'PARAMETER_MULTI' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" } ] }, - "integ:secret-inline:assert": { - "name": "integ:secret-inline:assert", - "description": "assert the snapshot of integration test 'secret-inline'", + "integ:PARAMETER:assert": { + "name": "integ:PARAMETER:assert", + "description": "assert the snapshot of integration test 'PARAMETER'", "steps": [ { - "exec": "[ -d \"test/secret-inline.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-inline'. Run 'projen integ:secret-inline:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/PARAMETER.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'PARAMETER'. Run 'projen integ:PARAMETER:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-inline.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/PARAMETER.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-inline.integ.snapshot/ test/.tmp/secret-inline.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/PARAMETER.integ.snapshot/ test/.tmp/PARAMETER.integ/assert.cdk.out/" } ] }, - "integ:secret-inline:deploy": { - "name": "integ:secret-inline:deploy", - "description": "deploy integration test 'secret-inline' and capture snapshot", + "integ:PARAMETER:deploy": { + "name": "integ:PARAMETER:deploy", + "description": "deploy integration test 'PARAMETER' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/PARAMETER.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/PARAMETER.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-inline.integ.snapshot" + "exec": "rm -fr test/PARAMETER.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-inline.integ/deploy.cdk.out test/secret-inline.integ.snapshot" + "exec": "mv test/.tmp/PARAMETER.integ/deploy.cdk.out test/PARAMETER.integ.snapshot" }, { - "spawn": "integ:secret-inline:destroy" + "spawn": "integ:PARAMETER:destroy" } ] }, - "integ:secret-inline:destroy": { - "name": "integ:secret-inline:destroy", - "description": "destroy integration test 'secret-inline'", + "integ:PARAMETER:destroy": { + "name": "integ:PARAMETER:destroy", + "description": "destroy integration test 'PARAMETER'", "steps": [ { - "exec": "cdk destroy --app test/secret-inline.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/PARAMETER.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-inline:snapshot": { - "name": "integ:secret-inline:snapshot", - "description": "update snapshot for integration test \"secret-inline\"", + "integ:PARAMETER:snapshot": { + "name": "integ:PARAMETER:snapshot", + "description": "update snapshot for integration test \"PARAMETER\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-inline.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/PARAMETER.integ.snapshot > /dev/null" } ] }, - "integ:secret-inline:watch": { - "name": "integ:secret-inline:watch", - "description": "watch integration test 'secret-inline' (without updating snapshots)", + "integ:PARAMETER:watch": { + "name": "integ:PARAMETER:watch", + "description": "watch integration test 'PARAMETER' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/PARAMETER.integ/deploy.cdk.out" } ] }, - "integ:secret-manual:assert": { - "name": "integ:secret-manual:assert", - "description": "assert the snapshot of integration test 'secret-manual'", + "integ:SECRET:assert": { + "name": "integ:SECRET:assert", + "description": "assert the snapshot of integration test 'SECRET'", "steps": [ { - "exec": "[ -d \"test/secret-manual.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-manual'. Run 'projen integ:secret-manual:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/SECRET.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'SECRET'. Run 'projen integ:SECRET:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-manual.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/SECRET.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-manual.integ.snapshot/ test/.tmp/secret-manual.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/SECRET.integ.snapshot/ test/.tmp/SECRET.integ/assert.cdk.out/" } ] }, - "integ:secret-manual:deploy": { - "name": "integ:secret-manual:deploy", - "description": "deploy integration test 'secret-manual' and capture snapshot", + "integ:SECRET:deploy": { + "name": "integ:SECRET:deploy", + "description": "deploy integration test 'SECRET' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-manual.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/SECRET.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-manual.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/SECRET.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-manual.integ.snapshot" + "exec": "rm -fr test/SECRET.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-manual.integ/deploy.cdk.out test/secret-manual.integ.snapshot" + "exec": "mv test/.tmp/SECRET.integ/deploy.cdk.out test/SECRET.integ.snapshot" }, { - "spawn": "integ:secret-manual:destroy" + "spawn": "integ:SECRET:destroy" } ] }, - "integ:secret-manual:destroy": { - "name": "integ:secret-manual:destroy", - "description": "destroy integration test 'secret-manual'", + "integ:SECRET:destroy": { + "name": "integ:SECRET:destroy", + "description": "destroy integration test 'SECRET'", "steps": [ { - "exec": "cdk destroy --app test/secret-manual.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/SECRET.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-manual:snapshot": { - "name": "integ:secret-manual:snapshot", - "description": "update snapshot for integration test \"secret-manual\"", + "integ:SECRET:snapshot": { + "name": "integ:SECRET:snapshot", + "description": "update snapshot for integration test \"SECRET\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-manual.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/SECRET.integ.snapshot > /dev/null" } ] }, - "integ:secret-manual:watch": { - "name": "integ:secret-manual:watch", - "description": "watch integration test 'secret-manual' (without updating snapshots)", + "integ:SECRET:watch": { + "name": "integ:SECRET:watch", + "description": "watch integration test 'SECRET' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-manual.integ/deploy.cdk.out" - } - ] - }, - "integ:secret-multikms:assert": { - "name": "integ:secret-multikms:assert", - "description": "assert the snapshot of integration test 'secret-multikms'", - "steps": [ - { - "exec": "[ -d \"test/secret-multikms.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-multikms'. Run 'projen integ:secret-multikms:deploy' to capture.\" && exit 1)" - }, - { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-multikms.integ/assert.cdk.out > /dev/null" - }, - { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-multikms.integ.snapshot/ test/.tmp/secret-multikms.integ/assert.cdk.out/" - } - ] - }, - "integ:secret-multikms:deploy": { - "name": "integ:secret-multikms:deploy", - "description": "deploy integration test 'secret-multikms' and capture snapshot", - "steps": [ - { - "exec": "rm -fr test/.tmp/secret-multikms.integ/deploy.cdk.out" - }, - { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-multikms.integ/deploy.cdk.out" - }, - { - "exec": "rm -fr test/secret-multikms.integ.snapshot" - }, - { - "exec": "mv test/.tmp/secret-multikms.integ/deploy.cdk.out test/secret-multikms.integ.snapshot" - }, - { - "spawn": "integ:secret-multikms:destroy" - } - ] - }, - "integ:secret-multikms:destroy": { - "name": "integ:secret-multikms:destroy", - "description": "destroy integration test 'secret-multikms'", - "steps": [ - { - "exec": "cdk destroy --app test/secret-multikms.integ.snapshot '**' --no-version-reporting" - } - ] - }, - "integ:secret-multikms:snapshot": { - "name": "integ:secret-multikms:snapshot", - "description": "update snapshot for integration test \"secret-multikms\"", - "steps": [ - { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-multikms.integ.snapshot > /dev/null" - } - ] - }, - "integ:secret-multikms:watch": { - "name": "integ:secret-multikms:watch", - "description": "watch integration test 'secret-multikms' (without updating snapshots)", - "steps": [ - { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-multikms.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/SECRET.integ/deploy.cdk.out" } ] }, @@ -410,16 +347,13 @@ "description": "update snapshot for all integration tests", "steps": [ { - "spawn": "integ:secret-asset:snapshot" - }, - { - "spawn": "integ:secret-inline:snapshot" + "spawn": "integ:PARAMETER_MULTI:snapshot" }, { - "spawn": "integ:secret-manual:snapshot" + "spawn": "integ:PARAMETER:snapshot" }, { - "spawn": "integ:secret-multikms:snapshot" + "spawn": "integ:SECRET:snapshot" } ] }, @@ -512,7 +446,8 @@ "name": "release", "description": "Prepare a release from \"main\" branch", "env": { - "RELEASE": "true" + "RELEASE": "true", + "MAJOR": "2" }, "steps": [ { @@ -544,16 +479,13 @@ "spawn": "eslint" }, { - "spawn": "integ:secret-asset:assert" - }, - { - "spawn": "integ:secret-inline:assert" + "spawn": "integ:PARAMETER_MULTI:assert" }, { - "spawn": "integ:secret-manual:assert" + "spawn": "integ:PARAMETER:assert" }, { - "spawn": "integ:secret-multikms:assert" + "spawn": "integ:SECRET:assert" } ] }, @@ -591,13 +523,13 @@ }, "steps": [ { - "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev,peer,prod,optional --filter=@types/jest,@types/node,eslint-config-prettier,eslint-import-resolver-typescript,eslint-plugin-import,eslint-plugin-prettier,jest,jsii-diff,jsii-pacmak,prettier,projen,ts-jest,ts-node,typescript,yaml" + "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev,peer,prod,optional --filter=@types/jest,@types/node,eslint-config-prettier,eslint-import-resolver-typescript,eslint-plugin-import,eslint-plugin-prettier,jest,jsii-diff,jsii-pacmak,json-schema-to-typescript,prettier,projen,ts-jest,ts-node,typescript,yaml" }, { "exec": "yarn install --check-files" }, { - "exec": "yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk commit-and-tag-version eslint-config-prettier eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit jsii-diff jsii-docgen jsii-pacmak jsii-rosetta jsii prettier projen ts-jest ts-node typescript yaml aws-cdk-lib constructs" + "exec": "yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk commit-and-tag-version eslint-config-prettier eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit jsii-diff jsii-docgen jsii-pacmak jsii-rosetta jsii json-schema-to-typescript prettier projen ts-jest ts-node typescript yaml aws-cdk-lib constructs" }, { "exec": "npx projen" diff --git a/.projenrc.js b/.projenrc.js index 506d2d60..d0cc8fb9 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -2,7 +2,8 @@ const { awscdk } = require('projen'); const project = new awscdk.AwsCdkConstructLibrary({ author: 'Markus Siebert', authorAddress: 'markus.siebert@deutschebahn.com', - cdkVersion: '2.144.0', + cdkVersion: '2.177.0', + majorVersion: 2, stability: 'stable', homepage: 'https://constructs.dev/packages/cdk-sops-secrets', description: @@ -32,7 +33,9 @@ const project = new awscdk.AwsCdkConstructLibrary({ bundledDeps: ['yaml'], // deps: [], /* Runtime dependencies of this module. */, // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ - // devDeps: [], /* Build dependencies for this module. */ + devDeps: [ + 'json-schema-to-typescript', + ] /* Build dependencies for this module. */, integrationTestAutoDiscover: true, prettier: true, prettierOptions: { @@ -105,22 +108,13 @@ additionalActions = [ ]; project.buildWorkflow.preBuildSteps.unshift(...additionalActions); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-inline', - run: 'yarn run projen integ:secret-inline:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-asset', - run: 'yarn run projen integ:secret-asset:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-multikms', - run: 'yarn run projen integ:secret-multikms:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-manual', - run: 'yarn run projen integ:secret-manual:snapshot', +['PARAMETER', 'PARAMETER_MULTI', 'SECRET'].forEach((type) => { + project.buildWorkflow.preBuildSteps.push({ + name: `Update snapshots: ${type}`, + run: `yarn run projen integ:${type}:snapshot`, + }); }); + project.buildWorkflow.addPostBuildSteps({ name: 'Upload coverage to Codecov', uses: 'codecov/codecov-action@v4', diff --git a/.tool-versions b/.tool-versions index 1f577776..bed478c6 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -golang 1.23.1 +golang 1.23.5 yarn 1.22.19 nodejs 20.15.1 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..233b8088 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "json.schemas": [ + { + "fileMatch": [ + "lambda/internal/event/testdata/*.json", + "lambda/events/*.json" + ], + "url": "./lambda/internal/event/config-schema.json" + } + ] +} \ No newline at end of file diff --git a/API.md b/API.md index 44419224..37c5dc7c 100644 --- a/API.md +++ b/API.md @@ -885,9 +885,6 @@ Any object. | **Name** | **Type** | **Description** | | --- | --- | --- | | node | constructs.Node | The tree node. | -| converToJSON | boolean | Was the format converted to json? | -| flatten | boolean | Was the structure flattened? | -| stringifiedValues | boolean | Were the values stringified? | | versionId | string | The current versionId of the secret populated via this resource. | --- @@ -904,42 +901,6 @@ The tree node. --- -##### `converToJSON`Required - -```typescript -public readonly converToJSON: boolean; -``` - -- *Type:* boolean - -Was the format converted to json? - ---- - -##### `flatten`Required - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean - -Was the structure flattened? - ---- - -##### `stringifiedValues`Required - -```typescript -public readonly stringifiedValues: boolean; -``` - -- *Type:* boolean - -Were the values stringified? - ---- - ##### `versionId`Required ```typescript @@ -1006,7 +967,9 @@ new SopsSyncProvider(scope: Construct, id?: string, props?: SopsSyncProviderProp | considerWarningOnInvokeFunctionPermissions | A warning will be added to functions under the following conditions: - permissions that include `lambda:InvokeFunction` are added to the unqualified function. | | grantInvoke | Grant the given identity permissions to invoke this Lambda. | | grantInvokeCompositePrincipal | Grant multiple principals the ability to invoke this Lambda via CompositePrincipal. | +| grantInvokeLatestVersion | Grant the given identity permissions to invoke the $LATEST version or unqualified version of this Lambda. | | grantInvokeUrl | Grant the given identity permissions to invoke this Lambda Function URL. | +| grantInvokeVersion | Grant the given identity permissions to invoke the given version of this Lambda. | | metric | Return the given named metric for this Function. | | metricDuration | How long execution of this Lambda takes. | | metricErrors | How many invocations of this Lambda fail. | @@ -1015,6 +978,7 @@ new SopsSyncProvider(scope: Construct, id?: string, props?: SopsSyncProviderProp | addDependency | Using node.addDependency() does not work on this method as the underlying lambda function is modeled as a singleton across the stack. Use this method instead to declare dependencies. | | addEnvironment | Adds an environment variable to this Lambda function. | | addLayers | Adds one or more Lambda Layers to this Lambda function. | +| addMetadata | Use this method to write to the construct tree. | | dependOn | The SingletonFunction construct cannot be added as a dependency of another construct using node.addDependency(). Use this method instead to declare this as a dependency of another construct. | | addAgeKey | *No description.* | @@ -1207,6 +1171,20 @@ Grant multiple principals the ability to invoke this Lambda via CompositePrincip --- +##### `grantInvokeLatestVersion` + +```typescript +public grantInvokeLatestVersion(grantee: IGrantable): Grant +``` + +Grant the given identity permissions to invoke the $LATEST version or unqualified version of this Lambda. + +###### `grantee`Required + +- *Type:* aws-cdk-lib.aws_iam.IGrantable + +--- + ##### `grantInvokeUrl` ```typescript @@ -1221,6 +1199,26 @@ Grant the given identity permissions to invoke this Lambda Function URL. --- +##### `grantInvokeVersion` + +```typescript +public grantInvokeVersion(grantee: IGrantable, version: IVersion): Grant +``` + +Grant the given identity permissions to invoke the given version of this Lambda. + +###### `grantee`Required + +- *Type:* aws-cdk-lib.aws_iam.IGrantable + +--- + +###### `version`Required + +- *Type:* aws-cdk-lib.aws_lambda.IVersion + +--- + ##### `metric` ```typescript @@ -1369,6 +1367,34 @@ the layers to be added. --- +##### `addMetadata` + +```typescript +public addMetadata(type: string, data: any, options?: MetadataOptions): void +``` + +Use this method to write to the construct tree. + +The metadata entries are written to the Cloud Assembly Manifest if the `treeMetadata` property is specified in the props of the App that contains this Construct. + +###### `type`Required + +- *Type:* string + +--- + +###### `data`Required + +- *Type:* any + +--- + +###### `options`Optional + +- *Type:* constructs.MetadataOptions + +--- + ##### `dependOn` ```typescript @@ -1472,6 +1498,7 @@ Check whether the given construct is a Resource. | permissionsNode | constructs.Node | The construct node where permissions are attached. | | resourceArnsForGrantInvoke | string[] | The ARN(s) to put into the resource field of the generated IAM policy for grantInvoke(). | | role | aws-cdk-lib.aws_iam.IRole | The IAM role associated with this function. | +| constructName | string | The name of the singleton function. | | currentVersion | aws-cdk-lib.aws_lambda.Version | Returns a `lambda.Version` which represents the current version of this singleton Lambda function. A new version will be created every time the function's configuration changes. | | logGroup | aws-cdk-lib.aws_logs.ILogGroup | The LogGroup where the Lambda function's logs are made available. | | runtime | aws-cdk-lib.aws_lambda.Runtime | The runtime environment for the Lambda function. | @@ -1654,6 +1681,20 @@ Undefined if the function was imported without a role. --- +##### `constructName`Required + +```typescript +public readonly constructName: string; +``` + +- *Type:* string + +The name of the singleton function. + +It acts as a unique ID within its CDK stack. + +--- + ##### `currentVersion`Required ```typescript @@ -1719,10 +1760,6 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | --- | --- | --- | | assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -1730,19 +1767,12 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| allowedPattern | string | A regular expression used to validate the parameter value. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | | description | string | Information about the parameter that you want to add to the system. | -| parameterName | string | The name of the parameter. | -| simpleName | boolean | Indicates if the parameter name is a simple name (i.e. does not include "/" separators). | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | -| stringValue | string | The value of the parameter. | -| dataType | aws-cdk-lib.aws_ssm.ParameterDataType | The data type of the parameter, such as `text` or `aws:ec2:image`. | -| type | aws-cdk-lib.aws_ssm.ParameterType | The type of the string parameter. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | -| keyPrefix | string | *No description.* | -| keySeparator | string | *No description.* | +| keyPrefix | string | The prefix used for all parameters. | +| keySeparator | string | The seperator used to seperate keys. | --- @@ -1772,63 +1802,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* '.' - -If the structure should be flattened use the provided separator between keys. - ---- - -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -1922,21 +1895,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -1950,19 +1908,16 @@ How should the secret be passed to the CustomResource? --- -##### `allowedPattern`Optional +##### `encryptionKey`Required ```typescript -public readonly allowedPattern: string; +public readonly encryptionKey: IKey; ``` -- *Type:* string -- *Default:* no validation is performed - -A regular expression used to validate the parameter value. +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. -For example, for String types with values restricted to -numbers, you can specify the following: ``^\d+$`` +The customer-managed encryption key to use for encrypting the secret value. --- @@ -1979,338 +1934,280 @@ Information about the parameter that you want to add to the system. --- -##### `parameterName`Optional +##### `tier`Optional ```typescript -public readonly parameterName: string; +public readonly tier: ParameterTier; ``` -- *Type:* string -- *Default:* a name will be generated by CloudFormation +- *Type:* aws-cdk-lib.aws_ssm.ParameterTier +- *Default:* undefined -The name of the parameter. +The tier of the string parameter. --- -##### `simpleName`Optional +##### `keyPrefix`Optional ```typescript -public readonly simpleName: boolean; +public readonly keyPrefix: string; ``` -- *Type:* boolean -- *Default:* auto-detect based on `parameterName` - -Indicates if the parameter name is a simple name (i.e. does not include "/" separators). - -This is required only if `parameterName` is a token, which means we -are unable to detect if the name is simple or "path-like" for the purpose -of rendering SSM parameter ARNs. +- *Type:* string +- *Default:* '/' -If `parameterName` is not specified, `simpleName` must be `true` (or -undefined) since the name generated by AWS CloudFormation is always a -simple name. +The prefix used for all parameters. --- -##### `tier`Optional +##### `keySeparator`Optional ```typescript -public readonly tier: ParameterTier; +public readonly keySeparator: string; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterTier -- *Default:* undefined +- *Type:* string +- *Default:* '/' -The tier of the string parameter. +The seperator used to seperate keys. --- -##### `stringValue`Required +### SopsCommonParameterProps + +The configuration options of the StringParameter. + +#### Initializer ```typescript -public readonly stringValue: string; -``` +import { SopsCommonParameterProps } from 'cdk-sops-secrets' -- *Type:* string +const sopsCommonParameterProps: SopsCommonParameterProps = { ... } +``` -The value of the parameter. +#### Properties -It may not reference another parameter and ``{{}}`` cannot be used in the value. +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | +| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | +| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | +| sopsFileFormat | string | The format of the sops file. | +| sopsFilePath | string | The filepath to the sops file. | +| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | +| sopsProvider | SopsSyncProvider | The custom resource provider to use. | +| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| uploadType | UploadType | How should the secret be passed to the CustomResource? | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | +| description | string | Information about the parameter that you want to add to the system. | +| tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | --- -##### `dataType`Optional +##### `assetEncryptionKey`Optional ```typescript -public readonly dataType: ParameterDataType; +public readonly assetEncryptionKey: IKey; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterDataType -- *Default:* ParameterDataType.TEXT +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* Trying to get the key using the CDK Bootstrap context. -The data type of the parameter, such as `text` or `aws:ec2:image`. +The encryption key used by the CDK default Asset S3 Bucket. --- -##### ~~`type`~~Optional - -- *Deprecated:* - type will always be 'String' +##### `autoGenerateIamPermissions`Optional ```typescript -public readonly type: ParameterType; +public readonly autoGenerateIamPermissions: boolean; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterType -- *Default:* ParameterType.STRING +- *Type:* boolean +- *Default:* true -The type of the string parameter. +Should this construct automatically create IAM permissions? --- -##### `encryptionKey`Required +##### `sopsAgeKey`Optional ```typescript -public readonly encryptionKey: IKey; +public readonly sopsAgeKey: SecretValue; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey +- *Type:* aws-cdk-lib.SecretValue + +The age key that should be used for encryption. --- -##### `keyPrefix`Optional +##### `sopsFileFormat`Optional ```typescript -public readonly keyPrefix: string; +public readonly sopsFileFormat: string; ``` - *Type:* string +- *Default:* The fileformat will be derived from the file ending + +The format of the sops file. --- -##### `keySeparator`Optional +##### `sopsFilePath`Optional ```typescript -public readonly keySeparator: string; +public readonly sopsFilePath: string; ``` - *Type:* string ---- - -### SopsSecretProps +The filepath to the sops file. -The configuration options of the SopsSecret. +--- -#### Initializer +##### `sopsKmsKey`Optional ```typescript -import { SopsSecretProps } from 'cdk-sops-secrets' - -const sopsSecretProps: SopsSecretProps = { ... } +public readonly sopsKmsKey: IKey[]; ``` -#### Properties +- *Type:* aws-cdk-lib.aws_kms.IKey[] +- *Default:* The key will be derived from the sops file -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| description | string | An optional, human-friendly description of the secret. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | -| generateSecretString | aws-cdk-lib.aws_secretsmanager.SecretStringGenerator | Configuration for how to generate a secret value. | -| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | -| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | -| secretName | string | A name for the secret. | -| secretObjectValue | {[ key: string ]: aws-cdk-lib.SecretValue} | Initial value for a JSON secret. | -| secretStringBeta1 | aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 | Initial value for the secret. | -| secretStringValue | aws-cdk-lib.SecretValue | Initial value for the secret. | -| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | -| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | -| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | -| sopsFileFormat | string | The format of the sops file. | -| sopsFilePath | string | The filepath to the sops file. | -| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | -| sopsProvider | SopsSyncProvider | The custom resource provider to use. | -| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | -| uploadType | UploadType | How should the secret be passed to the CustomResource? | +The kmsKey used to encrypt the sops file. + +Encrypt permissions +will be granted to the custom resource provider. --- -##### `description`Optional +##### `sopsProvider`Optional ```typescript -public readonly description: string; +public readonly sopsProvider: SopsSyncProvider; ``` -- *Type:* string -- *Default:* No description. +- *Type:* SopsSyncProvider +- *Default:* A new singleton provider will be created -An optional, human-friendly description of the secret. +The custom resource provider to use. + +If you don't specify any, a new +provider will be created - or if already exists within this stack - reused. --- -##### `encryptionKey`Optional +##### `sopsS3Bucket`Optional ```typescript -public readonly encryptionKey: IKey; +public readonly sopsS3Bucket: string; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey -- *Default:* A default KMS key for the account and region is used. +- *Type:* string -The customer-managed encryption key to use for encrypting the secret value. +If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. --- -##### `generateSecretString`Optional +##### `sopsS3Key`Optional ```typescript -public readonly generateSecretString: SecretStringGenerator; +public readonly sopsS3Key: string; ``` -- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringGenerator -- *Default:* 32 characters with upper-case letters, lower-case letters, punctuation and numbers (at least one from each category), per the default values of ``SecretStringGenerator``. +- *Type:* string -Configuration for how to generate a secret value. - -Only one of `secretString` and `generateSecretString` can be provided. +If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. --- -##### `removalPolicy`Optional +##### `uploadType`Optional ```typescript -public readonly removalPolicy: RemovalPolicy; +public readonly uploadType: UploadType; ``` -- *Type:* aws-cdk-lib.RemovalPolicy -- *Default:* Not set. +- *Type:* UploadType +- *Default:* INLINE -Policy to apply when the secret is removed from this stack. +How should the secret be passed to the CustomResource? --- -##### `replicaRegions`Optional +##### `encryptionKey`Required ```typescript -public readonly replicaRegions: ReplicaRegion[]; +public readonly encryptionKey: IKey; ``` -- *Type:* aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] -- *Default:* Secret is not replicated +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. -A list of regions where to replicate this secret. +The customer-managed encryption key to use for encrypting the secret value. --- -##### `secretName`Optional +##### `description`Optional ```typescript -public readonly secretName: string; +public readonly description: string; ``` - *Type:* string -- *Default:* A name is generated by CloudFormation. - -A name for the secret. +- *Default:* none -Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to -30 days blackout period. During that period, it is not possible to create another secret that shares the same name. +Information about the parameter that you want to add to the system. --- -##### `secretObjectValue`Optional +##### `tier`Optional ```typescript -public readonly secretObjectValue: {[ key: string ]: SecretValue}; +public readonly tier: ParameterTier; ``` -- *Type:* {[ key: string ]: aws-cdk-lib.SecretValue} -- *Default:* SecretsManager generates a new secret value. - -Initial value for a JSON secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret object -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies a JSON object that you want to encrypt and store in this new version of the secret. -To specify a simple string value instead, use `SecretProps.secretStringValue` +- *Type:* aws-cdk-lib.aws_ssm.ParameterTier +- *Default:* undefined -Only one of `secretStringBeta1`, `secretStringValue`, 'secretObjectValue', and `generateSecretString` can be provided. +The tier of the string parameter. --- -*Example* - -```typescript -declare const user: iam.User; -declare const accessKey: iam.AccessKey; -declare const stack: Stack; -new secretsmanager.Secret(stack, 'JSONSecret', { - secretObjectValue: { - username: SecretValue.unsafePlainText(user.userName), // intrinsic reference, not exposed as plaintext - database: SecretValue.unsafePlainText('foo'), // rendered as plain text, but not a secret - password: accessKey.secretAccessKey, // SecretValue - }, -}); -``` - +### SopsSecretProps -##### ~~`secretStringBeta1`~~Optional +The configuration options of the SopsSecret. -- *Deprecated:* Use `secretStringValue` instead. +#### Initializer ```typescript -public readonly secretStringBeta1: SecretStringValueBeta1; -``` - -- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 -- *Default:* SecretsManager generates a new secret value. - -Initial value for the secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret string -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies text data that you want to encrypt and store in this new version of the secret. -May be a simple string value, or a string representation of a JSON structure. - -Only one of `secretStringBeta1`, `secretStringValue`, and `generateSecretString` can be provided. - ---- - -##### `secretStringValue`Optional +import { SopsSecretProps } from 'cdk-sops-secrets' -```typescript -public readonly secretStringValue: SecretValue; +const sopsSecretProps: SopsSecretProps = { ... } ``` -- *Type:* aws-cdk-lib.SecretValue -- *Default:* SecretsManager generates a new secret value. - -Initial value for the secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret string -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies text data that you want to encrypt and store in this new version of the secret. -May be a simple string value. To provide a string representation of JSON structure, use `SecretProps.secretObjectValue` instead. +#### Properties -Only one of `secretStringBeta1`, `secretStringValue`, 'secretObjectValue', and `generateSecretString` can be provided. +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | +| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | +| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | +| sopsFileFormat | string | The format of the sops file. | +| sopsFilePath | string | The filepath to the sops file. | +| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | +| sopsProvider | SopsSyncProvider | The custom resource provider to use. | +| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| uploadType | UploadType | How should the secret be passed to the CustomResource? | +| description | string | An optional, human-friendly description of the secret. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | +| rawOutput | RawOutput | Should the secret parsed and transformed to json? | +| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | +| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | +| secretName | string | A name for the secret. | --- @@ -2340,63 +2237,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* '.' - -If the structure should be flattened use the provided separator between keys. - ---- - -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2490,157 +2330,154 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional +##### `uploadType`Optional ```typescript -public readonly stringifyValues: boolean; +public readonly uploadType: UploadType; ``` -- *Type:* boolean - -Shall all values be flattened? +- *Type:* UploadType +- *Default:* INLINE -This is usefull for dynamic references, as there -are lookup errors for certain float types +How should the secret be passed to the CustomResource? --- -##### `uploadType`Optional +##### `description`Optional ```typescript -public readonly uploadType: UploadType; +public readonly description: string; ``` -- *Type:* UploadType -- *Default:* INLINE +- *Type:* string +- *Default:* No description. -How should the secret be passed to the CustomResource? +An optional, human-friendly description of the secret. --- -### SopsStringParameterProps +##### `encryptionKey`Optional -The configuration options of the StringParameter. +```typescript +public readonly encryptionKey: IKey; +``` -#### Initializer +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. -```typescript -import { SopsStringParameterProps } from 'cdk-sops-secrets' +The customer-managed encryption key to use for encrypting the secret value. -const sopsStringParameterProps: SopsStringParameterProps = { ... } +--- + +##### `rawOutput`Optional + +```typescript +public readonly rawOutput: RawOutput; ``` -#### Properties +- *Type:* RawOutput +- *Default:* undefined - no raw output -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | -| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | -| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | -| sopsFileFormat | string | The format of the sops file. | -| sopsFilePath | string | The filepath to the sops file. | -| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | -| sopsProvider | SopsSyncProvider | The custom resource provider to use. | -| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | -| uploadType | UploadType | How should the secret be passed to the CustomResource? | -| allowedPattern | string | A regular expression used to validate the parameter value. | -| description | string | Information about the parameter that you want to add to the system. | -| parameterName | string | The name of the parameter. | -| simpleName | boolean | Indicates if the parameter name is a simple name (i.e. does not include "/" separators). | -| tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | -| stringValue | string | The value of the parameter. | -| dataType | aws-cdk-lib.aws_ssm.ParameterDataType | The data type of the parameter, such as `text` or `aws:ec2:image`. | -| type | aws-cdk-lib.aws_ssm.ParameterType | The type of the string parameter. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +Should the secret parsed and transformed to json? --- -##### `assetEncryptionKey`Optional +##### `removalPolicy`Optional ```typescript -public readonly assetEncryptionKey: IKey; +public readonly removalPolicy: RemovalPolicy; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey -- *Default:* Trying to get the key using the CDK Bootstrap context. +- *Type:* aws-cdk-lib.RemovalPolicy +- *Default:* Not set. -The encryption key used by the CDK default Asset S3 Bucket. +Policy to apply when the secret is removed from this stack. --- -##### `autoGenerateIamPermissions`Optional +##### `replicaRegions`Optional ```typescript -public readonly autoGenerateIamPermissions: boolean; +public readonly replicaRegions: ReplicaRegion[]; ``` -- *Type:* boolean -- *Default:* true +- *Type:* aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] +- *Default:* Secret is not replicated -Should this construct automatically create IAM permissions? +A list of regions where to replicate this secret. --- -##### `convertToJSON`Optional +##### `secretName`Optional ```typescript -public readonly convertToJSON: boolean; +public readonly secretName: string; ``` -- *Type:* boolean -- *Default:* true +- *Type:* string +- *Default:* A name is generated by CloudFormation. -Should the encrypted sops value should be converted to JSON? +A name for the secret. -Only JSON can be handled by cloud formations dynamic references. +Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to +30 days blackout period. During that period, it is not possible to create another secret that shares the same name. --- -##### `flatten`Optional +### SopsStringParameterProps + +#### Initializer ```typescript -public readonly flatten: boolean; -``` +import { SopsStringParameterProps } from 'cdk-sops-secrets' -- *Type:* boolean -- *Default:* true +const sopsStringParameterProps: SopsStringParameterProps = { ... } +``` -Should the structure be flattened? +#### Properties -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | +| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | +| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | +| sopsFileFormat | string | The format of the sops file. | +| sopsFilePath | string | The filepath to the sops file. | +| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | +| sopsProvider | SopsSyncProvider | The custom resource provider to use. | +| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| uploadType | UploadType | How should the secret be passed to the CustomResource? | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | +| description | string | Information about the parameter that you want to add to the system. | +| tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | +| parameterName | string | The name of the parameter. | --- -##### `flattenSeparator`Optional +##### `assetEncryptionKey`Optional ```typescript -public readonly flattenSeparator: string; +public readonly assetEncryptionKey: IKey; ``` -- *Type:* string -- *Default:* '.' +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* Trying to get the key using the CDK Bootstrap context. -If the structure should be flattened use the provided separator between keys. +The encryption key used by the CDK default Asset S3 Bucket. --- -##### `parameterKeyPrefix`Optional +##### `autoGenerateIamPermissions`Optional ```typescript -public readonly parameterKeyPrefix: string; +public readonly autoGenerateIamPermissions: boolean; ``` -- *Type:* string +- *Type:* boolean +- *Default:* true -Add this prefix to parameter names. +Should this construct automatically create IAM permissions? --- @@ -2737,21 +2574,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -2765,19 +2587,16 @@ How should the secret be passed to the CustomResource? --- -##### `allowedPattern`Optional +##### `encryptionKey`Required ```typescript -public readonly allowedPattern: string; +public readonly encryptionKey: IKey; ``` -- *Type:* string -- *Default:* no validation is performed - -A regular expression used to validate the parameter value. +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. -For example, for String types with values restricted to -numbers, you can specify the following: ``^\d+$`` +The customer-managed encryption key to use for encrypting the secret value. --- @@ -2794,40 +2613,6 @@ Information about the parameter that you want to add to the system. --- -##### `parameterName`Optional - -```typescript -public readonly parameterName: string; -``` - -- *Type:* string -- *Default:* a name will be generated by CloudFormation - -The name of the parameter. - ---- - -##### `simpleName`Optional - -```typescript -public readonly simpleName: boolean; -``` - -- *Type:* boolean -- *Default:* auto-detect based on `parameterName` - -Indicates if the parameter name is a simple name (i.e. does not include "/" separators). - -This is required only if `parameterName` is a token, which means we -are unable to detect if the name is simple or "path-like" for the purpose -of rendering SSM parameter ARNs. - -If `parameterName` is not specified, `simpleName` must be `true` (or -undefined) since the name generated by AWS CloudFormation is always a -simple name. - ---- - ##### `tier`Optional ```typescript @@ -2841,55 +2626,16 @@ The tier of the string parameter. --- -##### `stringValue`Required +##### `parameterName`Optional ```typescript -public readonly stringValue: string; +public readonly parameterName: string; ``` - *Type:* string +- *Default:* a name will be generated by CloudFormation -The value of the parameter. - -It may not reference another parameter and ``{{}}`` cannot be used in the value. - ---- - -##### `dataType`Optional - -```typescript -public readonly dataType: ParameterDataType; -``` - -- *Type:* aws-cdk-lib.aws_ssm.ParameterDataType -- *Default:* ParameterDataType.TEXT - -The data type of the parameter, such as `text` or `aws:ec2:image`. - ---- - -##### ~~`type`~~Optional - -- *Deprecated:* - type will always be 'String' - -```typescript -public readonly type: ParameterType; -``` - -- *Type:* aws-cdk-lib.aws_ssm.ParameterType -- *Default:* ParameterType.STRING - -The type of the string parameter. - ---- - -##### `encryptionKey`Required - -```typescript -public readonly encryptionKey: IKey; -``` - -- *Type:* aws-cdk-lib.aws_kms.IKey +The name of the parameter. --- @@ -2911,10 +2657,6 @@ const sopsSyncOptions: SopsSyncOptions = { ... } | --- | --- | --- | | assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2922,7 +2664,6 @@ const sopsSyncOptions: SopsSyncOptions = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | --- @@ -2953,63 +2694,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* '.' - -If the structure should be flattened use the provided separator between keys. - ---- - -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -3103,21 +2787,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -3149,10 +2818,6 @@ const sopsSyncProps: SopsSyncProps = { ... } | --- | --- | --- | | assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -3160,12 +2825,13 @@ const sopsSyncProps: SopsSyncProps = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used for encrypting the ssm parameter if `parameterName` is set. | -| parameterNames | string[] | The parameter names. | | resourceType | ResourceType | Will this Sync deploy a Secret or Parameter(s). | -| secret | aws-cdk-lib.aws_secretsmanager.ISecret | The secret that will be populated with the encrypted sops file content. | +| target | string | The target to populate with the sops file content. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used for encrypting the ssm parameter if `parameterName` is set. | +| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | +| parameterNames | string[] | *No description.* | +| secret | aws-cdk-lib.aws_secretsmanager.ISecret | *No description.* | --- @@ -3195,63 +2861,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* '.' - -If the structure should be flattened use the provided separator between keys. - ---- - -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -3345,31 +2954,44 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional +##### `uploadType`Optional ```typescript -public readonly stringifyValues: boolean; +public readonly uploadType: UploadType; ``` -- *Type:* boolean +- *Type:* UploadType +- *Default:* INLINE -Shall all values be flattened? +How should the secret be passed to the CustomResource? -This is usefull for dynamic references, as there -are lookup errors for certain float types +--- + +##### `resourceType`Required + +```typescript +public readonly resourceType: ResourceType; +``` + +- *Type:* ResourceType + +Will this Sync deploy a Secret or Parameter(s). --- -##### `uploadType`Optional +##### `target`Required ```typescript -public readonly uploadType: UploadType; +public readonly target: string; ``` -- *Type:* UploadType -- *Default:* INLINE +- *Type:* string -How should the secret be passed to the CustomResource? +The target to populate with the sops file content. + +for secret, it's the name or arn of the secret +- for parameter, it's the name of the parameter +- for parameter multi, it's the prefix of the parameters --- @@ -3385,29 +3007,26 @@ The encryption key used for encrypting the ssm parameter if `parameterName` is s --- -##### `parameterNames`Optional +##### `flattenSeparator`Optional ```typescript -public readonly parameterNames: string[]; +public readonly flattenSeparator: string; ``` -- *Type:* string[] - -The parameter names. +- *Type:* string +- *Default:* undefined -If set this creates encrypted SSM Parameters instead of a secret. +If the structure should be flattened use the provided separator between keys. --- -##### `resourceType`Optional +##### `parameterNames`Optional ```typescript -public readonly resourceType: ResourceType; +public readonly parameterNames: string[]; ``` -- *Type:* ResourceType - -Will this Sync deploy a Secret or Parameter(s). +- *Type:* string[] --- @@ -3419,8 +3038,6 @@ public readonly secret: ISecret; - *Type:* aws-cdk-lib.aws_secretsmanager.ISecret -The secret that will be populated with the encrypted sops file content. - --- ### SopsSyncProviderProps @@ -3504,6 +3121,31 @@ Where to place the network interfaces within the VPC. ## Enums +### RawOutput + +#### Members + +| **Name** | **Description** | +| --- | --- | +| STRING | Parse the secret as a string. | +| BINARY | Parse the secret as a binary. | + +--- + +##### `STRING` + +Parse the secret as a string. + +--- + + +##### `BINARY` + +Parse the secret as a binary. + +--- + + ### ResourceType #### Members @@ -3511,6 +3153,8 @@ Where to place the network interfaces within the VPC. | **Name** | **Description** | | --- | --- | | SECRET | *No description.* | +| SECRET_RAW | *No description.* | +| SECRET_BINARY | *No description.* | | PARAMETER | *No description.* | | PARAMETER_MULTI | *No description.* | @@ -3521,6 +3165,16 @@ Where to place the network interfaces within the VPC. --- +##### `SECRET_RAW` + +--- + + +##### `SECRET_BINARY` + +--- + + ##### `PARAMETER` --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f411e66..a5c8f21f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,19 +9,30 @@ We are committed to fostering a welcoming, respectful, and harassment-free envir Install all necessary tools with `yarn install` and others manually like `go` Build the go Lambda code: + ``` ./scripts/build.sh ``` + Build the package (for CDK development only the first `js` build has to complete): + ``` yarn projen build + +// to skip the tests you can also do + +yarn projen package ``` + Link the package: + ``` yarn link ``` + Switch to the path/project where you would like to use cdk-sops-secrets. \ Link the package to your local build source: + ``` yarn link "cdk-sops-secrets" -``` \ No newline at end of file +``` diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 06b8de23..557c8d7a 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,7 +1,7 @@ This page lists all active maintainers of this repository in alphabetical order. +[dariozachow](https://github.com/dariozachow) [henrysachs](https://github.com/henrysachs) +[lennartrommeiss](https://github.com/lenderom) [markussiebert](https://github.com/markussiebert) [thomaskrause](https://github.com/obirah) -[thomasgeese](https://github.com/zh32) -[lennartrommeiss](https://github.com/lenderom) diff --git a/README.md b/README.md index 3467c007..365ea92b 100644 --- a/README.md +++ b/README.md @@ -1,213 +1,346 @@ -

-![stability](https://img.shields.io/badge/Stability-stable-green)  -[![release](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml/badge.svg)](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml)
+![stability](https://img.shields.io/badge/Stability-stable-green) +[![release](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml/badge.svg)](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml) +[![cdk-construct-hub](https://img.shields.io/badge/CDK-ConstructHub-blue)](https://constructs.dev/packages/cdk-sops-secrets) +[![npm](https://img.shields.io/npm/v/cdk-sops-secrets.svg)](https://www.npmjs.com/package/cdk-sops-secrets) +[![npm downloads](https://img.shields.io/npm/dw/cdk-sops-secrets)](https://www.npmjs.com/package/cdk-sops-secrets) +[![pypi](https://img.shields.io/pypi/v/cdk-sops-secrets.svg)](https://pypi.org/project/cdk-sops-secrets) +[![pypi downloads](https://img.shields.io/pypi/dw/cdk-sops-secrets)](https://pypi.org/project/cdk-sops-secrets) +[![codecov](https://codecov.io/gh/dbsystel/cdk-sops-secrets/branch/main/graph/badge.svg?token=OT7P7HQHXB)](https://codecov.io/gh/dbsystel/cdk-sops-secrets) +[![security-vulnerabilities](https://img.shields.io/github/issues-search/dbsystel/cdk-sops-secrets?color=%23ff0000&label=security-vulnerabilities&query=is%3Aissue%20is%3Aopen%20label%3A%22Mend%3A%20dependency%20security%20vulnerability%22)](https://github.com/dbsystel/cdk-sops-secrets/issues?q=is%3Aissue+is%3Aopen+label%3A%22security+vulnerability%22) + +# Introduction + +_Create secret values in AWS with infrastructure-as-code easily_ + +This construct library offers CDK Constructs that facilitate syncing [SOPS-encrypted secrets](https://github.com/getsops/sops) to AWS Secrets Manager and SSM Parameter Store. +It enables secure storage of secrets in Git repositories while allowing seamless synchronization and usage within AWS. Even large sets of SSM Parameters can be created quickly from a single file. + +- Create AWS Secrets Manager secrets +- Create single SSM Parameter +- Create multiple SSM Parameter in a batch from a file +- Use SOPS json, yaml or dotenv as input files, as well as binary data +- No need for manual permission setups for the Custom Ressource due to automatic least-privilege generation for the SyncProvider + +# Table Of Contents + +- [Introduction](#introduction) +- [Table Of Contents](#table-of-contents) +- [Available Constructs](#available-constructs) + - [SopsSecret — Sops to SecretsManager](#sopssecret--sops-to-secretsmanager) + - [SopsStringParameter — Sops to single SSM ParameterStore Parameter](#sopsstringparameter--sops-to-single-ssm-parameterstore-parameter) + - [MultiStringParameter — Sops to multiple SSM ParameterStore Parameters](#multistringparameter--sops-to-multiple-ssm-parameterstore-parameters) + - [SopsSyncProvider](#sopssyncprovider) + - [Common configuration options for SopsSecret, SopsStringParameter and MultiStringParameter](#common-configuration-options-for-sopssecret-sopsstringparameter-and-multistringparameter) +- [Considerations](#considerations) + - [UploadType: INLINE / ASSET](#uploadtype-inline--asset) + - [Stability](#stability) +- [FAQ](#faq) + - [How can I migrate to V2](#how-can-i-migrate-to-v2) + - [SecretsManager](#secretsmanager) + - [Parameter](#parameter) + - [MultiParameter](#multiparameter) + - [It does not work, what can I do?](#it-does-not-work-what-can-i-do) + - [I get errors with `dotenv` formatted files](#i-get-errors-with-dotenv-formatted-files) + - [Error: Error getting data key: 0 successful groups required, got 0](#error-error-getting-data-key-0-successful-groups-required-got-0) + - [Error: Asset of sync lambda not found](#error-asset-of-sync-lambda-not-found) + - [Can I upload the sops file myself and provide the required information as CloudFormation Parameter?](#can-i-upload-the-sops-file-myself-and-provide-the-required-information-as-cloudformation-parameter) + - [Can I access older versions of the secret stored in the SecretsManager?](#can-i-access-older-versions-of-the-secret-stored-in-the-secretsmanager) + - [I want the `raw` content of the sops file, but I always get the content nested in json](#i-want-the-raw-content-of-the-sops-file-but-i-always-get-the-content-nested-in-json) +- [License](#license) + +# Available Constructs + +The construct library cdk-sops-secrets supports three different Constructs that help you to sync your encrypted sops secrets to secure places in AWS. + +Let's assume we want to store the following secret information in AWS: -[![cdk-construct-hub](https://img.shields.io/badge/CDK-ConstructHub-blue)](https://constructs.dev/packages/cdk-sops-secrets)
-[![npm](https://img.shields.io/npm/v/cdk-sops-secrets.svg)](https://www.npmjs.com/package/cdk-sops-secrets)  -[![npm downloads](https://img.shields.io/npm/dw/cdk-sops-secrets)](https://www.npmjs.com/package/cdk-sops-secrets)
-[![pypi](https://img.shields.io/pypi/v/cdk-sops-secrets.svg)](https://pypi.org/project/cdk-sops-secrets)  -[![pypi downloads](https://img.shields.io/pypi/dw/cdk-sops-secrets)](https://pypi.org/project/cdk-sops-secrets)
+```json +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "user": "admin", + "password": "P@ssw0rd!", + "host": "db.example.com" + }, + "tokens": [ + { "service": "github", "token": "ghp_abcd1234" }, + { "service": "aws", "token": "AKIAIOSFODNN7EXAMPLE" } + ], + "someOtherKey": "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" +} +``` -[![codecov](https://codecov.io/gh/dbsystel/cdk-sops-secrets/branch/main/graph/badge.svg?token=OT7P7HQHXB)](https://codecov.io/gh/dbsystel/cdk-sops-secrets)   -[![security-vulnerabilities](https://img.shields.io/github/issues-search/dbsystel/cdk-sops-secrets?color=%23ff0000&label=security-vulnerabilities&query=is%3Aissue%20is%3Aopen%20label%3A%22Mend%3A%20dependency%20security%20vulnerability%22)](https://github.com/dbsystel/cdk-sops-secrets/issues?q=is%3Aissue+is%3Aopen+label%3A%22security+vulnerability%22)  +It doesn't matter if this data is in `json`, `yaml` or `dotenv` format, `cdk-sops-secret` can handle them all. +Even binary data is supported with some limitations. -## Introduction +## SopsSecret — Sops to SecretsManager -This construct library provides a replacement for CDK SecretsManager secrets, with extended functionality for Mozilla/sops. +If you want to store your secret data in the AWS SecretsManager, use the `SopsSecret` construct. This is a "drop-in-replacement" for the [Secret Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager.Secret.html) of the AWS CDK. -

-Using this library it is possible to populate Secrets with values from a Mozilla/sops file without additional scripts and steps in the CI stage. Thereby transformations like JSON conversion of YAML files and transformation into a flat, JSONPath like structure will be performed, but can be disabled. +Minimal Example: -Secrets filled in this way can be used immediately within the CloudFormation stack and dynamic references. This construct should handle all dependencies, if you use the `secretValueFromJson()` or `secretValue()` call to access secret values. +```ts +const secret = new SopsSecret(stack, 'MySopsSecret', { + secertName: 'mySecret', // name of the secret in AWS SecretsManager + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', // filepath to the sops encrypted file +}); +``` -This way, secrets can be securely stored in git repositories and easily synchronized into AWS SecretsManager secrets. +The content referenced sops secret file will be synced to the AWS SecretsManager Secret with the name `mySecret`. +For convenience, several transformations apply: -## Stability +- Nested structures and arrays will be resolved and flattened to a JSONPath notation +- All values will be stored as strings -You can consider this package as stable. Updates will follow [Semantic Versioning](https://semver.org/).
-Nevertheless, I would recommend pinning the exact version of this library in your `package.json`. +This is done also because of limitations of CDK in conjunction with +[dynamic references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references-secretsmanager.html) and limitiations +of the `Key/Value` view of the AWS SecretsManager WebConsole. So the result, saved in the AWS SecretsManager will actually be: -## Prerequisites +```json +{ + "apiKey": "sk-1234567890abcdef", + "database.user": "admin", + "database.password": "P@ssw0rd!", + "database.host": "db.example.com", + "tokens[0].service": "github", + "tokens[0].token": "ghp_abcd1234", + "tokens[1].service": "aws", + "tokens[1].token": "AKIAIOSFODNN7EXAMPLE", + "someOtherKey": "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" +} +``` -- [AWS](https://aws.amazon.com/): I think you already knew it, but this construct will only work with an AWS account. +This allows you to access the values from your secret via CDK: -* [KMS Key](https://aws.amazon.com/kms/?nc1=h_ls): It makes most sense to encrypt your secrets with AWS KMS if you want to sync and use the secret content afterwards in your AWS account. -* [mozilla/sops](https://github.com/mozilla/sops): This construct assumes that you store your secrets encrypted via sops in your git repository. -* [CDK](https://aws.amazon.com/cdk/?nc1=h_ls): As this is a CDK construct, it's only useful if you use the CloudDevelopmentToolkit. +```ts +secret.secretValueFromJson('"database.password"').toString(), + secret.secretValueFromJson('"tokens[0].token"').toString(); +``` -## Getting started +If you don't want these conversions, you can completely disable them by using the `rawOutput` property. -1. Create a Mozilla/sops secrets file (encrypted with an already existing KMS key) and place it somewhere in your git repository -2. Create a secret with the SopsSecret construct inside your app - ```ts - const secret = new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'secrets/sopsfile-encrypted.json', - }); - ``` -3. Optional: Access the secret via dynamic references - ```ts - secret.secretValueFromJson('json.path.dotted.notation.accessor[0]').toString(), - ``` +```ts +const secret = new SopsSecret(stack, 'MySopsSecret', { + rawOutput: RawOutput.STRING, + ... +}); +``` -## Advanced configuration examples +This will turn off the conversions and just place the decrypted content in the target secret. It's also possible to use +`RawOutput.BINARY` than the AWS SecretsManager Secret will be populted with binary, instead of string data. -Even if using the main functionality should be done in 3 lines of code, there are more options to configure the constructs of this library. If you want to get an Overview of all available configuration options take a look at the [documentation at the CDK ConstructHub](https://constructs.dev/packages/cdk-sops-secrets). +## SopsStringParameter — Sops to single SSM ParameterStore Parameter -The most useful settings will be explained in the further chapters: +If you want to sync the whole content of a sops encrypted file to an encrypted AWS SSM ParameterStore Parameter, you can use the SopsStringParameter Construct. -### Binary - Just the raw file +```ts +const parameter = new SopsStringParameter(stack, 'MySopsParameter', { + encryptionKey: Key.fromLookup(stack, 'DefaultKey', { + aliasName: 'alias/aws/ssm', + }), + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', +}); +``` -If you have the need to just upload a sops encrypted binary file, just name your sops encrypted file *.binary, or specify the option "binary" as format. +This will create a Parameter with the value of the decrypted sops file content. No transformations are applied. +## MultiStringParameter — Sops to multiple SSM ParameterStore Parameters -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - ... - sopsFilePath: 'secrets/sopsfile-encrypted.binary', +If you have a structured sops file (yaml, json, dotenv) and want to populate the AWS SSM ParameterStore with it, you want to use the MultiStringParameter Construct. + +```ts +const multi = new MultiStringParameter(stack, 'MyMultiParameter', { + encryptionKey: Key.fromLookup(stack, 'DefaultKey', { + aliasName: 'alias/aws/ssm', + }), + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', }); ``` -or +This will create several AWS SSM ParameterStore Parameters: -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - ... - sopsFilePath: 'secrets/sopsfile-encrypted.something', - sopsFileFormat: 'binary', -}); +```bash +ParameterName => Value + +/apiKey => "sk-1234567890abcdef" +/database/user => "admin" +/database/password => "P@ssw0rd!" +/database/host => "db.example.com" +/tokens/0/service => "github" +/tokens/0/token => "ghp_abcd1234" +/tokens/1/service => "aws" +/tokens/1/token => "AKIAIOSFODNN7EXAMPLE" +/someOtherKey => "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" ``` +You can configure the naming schema via the properties `keySeperator` and `keyPrefix`: -### Getting a specific (older version) +```ts +const multi = new MultiStringParameter(stack, 'MyMultiParameter', { + keyPrefix: 'mykeyprefix.' // All keys will start with this string, default '/' + keySeperator: '-' // This seperator is used when converting to a flat structure, default '/' +}) +``` -While creating the secret or updating the entries of a secret, the native CDK function ```cdk.FileSystem.fingerprint(...)``` is used to generate the version information of the AWS SecretsManager secret. -Therefore, it is possible to reference the entries from a specific AWS SecretsManager version. +This would lead to Parameters -```typescript -const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`) -const passphrase = ecs.Secret.fromSecretsManagerVersion(secretMgmt, { versionId: versionId }, 'MY_PRIVATE_PASSPHRASE') +```bash +ParameterName => Value -const container = TaskDef.addContainer('Container', { - secrets: { - MY_PRIVATE_PASSPHRASE: passphrase, - }, -}); +mykeyprefix.apiKey => "sk-1234567890abcdef" +mykeyprefix.database-user => "admin" +mykeyprefix.tokens-0-service => "github" +... ``` -### Default conversions and how to disable them? +## SopsSyncProvider -As default behavior, the SopsSecret (via the SopsSync) will convert all content to JSON and flatten its structure. This is useful, because the AWS SecretsManager has some limitations if it comes to YAML and/or complex objects and decimal values. Even if you can store YAML, complex objects and even binaries in AWS SecretsManager secrets, you can't access their values via the SecretsManager API — you can only return them as is. So accessing (nested) values or values from YAML files won't be possible via [dynamic references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html) in CloudFormation (and CDK). That's why I decided that conversion to JSON, flatten the structure and stringify all values should be the default behavior. But you can turn off all of these conversion steps: +The SOPS-Provider is the custom resource AWS Lambda Function, that is doing all the work. It downloads, decrypts +and stores the secret content in your desired location. This Lambda Function needs several IAM permissions to do it's work. -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - convertToJSON: false, // disable converting the encrypted content to JSON - stringify: false, // disable stringifying all values - flatten: false, // disable flattening of the object structure - sopsFilePath: 'secrets/sopsfile-encrypted.json', +For most use cases, you don't need to create it on your own, as the other Constructs try to create this and derive the required IAM permissions from your input. + +But there are use cases, that require you to change the defaults of this Provider. If this is the case, +you have to create the provider on your own and add it to the other constructs. + +```ts +const provider = new SopsSyncProvider(this, 'MySopsSyncProvider', { + role: customRole, // you can pass a custom role + + vpc: customVpc, // The default SopsSync Provider + vpcSubnets: { // won't run in any VPC, + subnets: [ // as it does not require + customSubnet1, // access to any VPC resources. + customSubnet2, // But if you want, + ] // you can change this behaviour + }, // and set vpc, subnet and + securityGroups: [ // securitygroups to your + customSecurityGroup // needs. + ], }); -``` -### Resource provider is missing permissions +provider.addToRolePolicy( // You cann pass PolicyStatements + new PolicyStatement({ // via the addToRolePolicy Method + actions: ['...'], // + resources: ['...'], // + }) // +); // -Sometimes it can be necessary to access the IAM role of the SopsSync provider. If this is the case, you should create the provider before creating the SopsSecret, and pass the provider to it like this: +kmsKey.grantDecrypt( // The provider implements + provider // the IGrantable interface, +); // so you can use it as grant target -```typescript -// Create the provider -const provider = new SopsSyncProvider(this, 'CustomSopsSyncProvider'); -// Grant whatever you need to the provider -const myExtraKmsKey = Key.fromKeyArn(this, 'MyExtraKmsKey', 'YourKeyArn'); -myExtraKmsKey.grantDecrypt(provider); -// create the secret and pass the the provider to it -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - sopsProvider: provider, - secretName: 'myCoolSecret', - sopsFilePath: 'secrets/sopsfile-encrypted.json', +const secret = new SopsSecret(this, 'MySecret', { + sopsProvider: provider, // this property is available in all Constructs + ... }); ``` -### User Provided IAM Permissions +## Common configuration options for SopsSecret, SopsStringParameter and MultiStringParameter + +```ts + +const construct = new Sops...(this, 'My' { + /** + * use your own SopsSyncProvider + * @see SopsSyncProvider + */ + sopsProvider: myCustomProvider // default - a new provider will be created + + /** + * the constructs try to derive the required iam permissions from the sops file + * and the target. If you don't want this, you can disable this behaviour. + * You have to take care of all required permissions on your own. + */ + autoGenerateIamPermissions: false, // default: true + + /** + * the default behaviour of passing the sops file content to the provider is + * by embedding the base64 encoded content in the cloudformation template. + * Using CKD Assets is also supported. It might be required to switch to + * Assets, if your sops files are very large. + */ + uploadType: UploadType.ASSET, // default: UploadType.INLINE + + /** + * if you don't want this constructs to take care of passing the encrypted + * sops file to the sops provider, you can upload them yourself to a + * S3 bucket. + * You can pass bucket and key, and the constructs won't pass the content + * as ASSET or in the CloudFormation Template. + * As the construct isn't aware of the sopsfile, we can't derive the required + * permissions to decrypt the sops file. The same applies to the sopsFileFormat. + * You have to pass them all manually. + */ + sopsS3Bucket: 'my-custom-bucket', + sopsS3Key: 'encoded-sops.json', + sopsKmsKey: [ + kmsKeyUsedForEncryption, + ] + sopsFileFormat: 'json', // Allowed values are json, yaml, dotenv and binary +}) -If you don't want to use the IAM autogenration, you can provide your own IAM Role with all required permissions: +``` -```typescript -const sopsProviderRole = new Role(stack, 'SopsProviderRole', { - assumedBy: new ServicePrincipal('lambda.amazonaws.com'), -}); +# Considerations -sopsProviderRole.addManagedPolicy({ - managedPolicyArn: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', -}); +## UploadType: INLINE / ASSET -sopsProviderRole.addToPolicy( - new PolicyStatement({ - actions: ['todo:WriteYourRequiredPermissions'], - resources: ['*'], - }), -); +I decided, that the default behavior should be "INLINE" because of the following consideration: -new SopsSyncProvider(stack, 'SopsSyncProvider', { - role: sopsProviderRole, -}); +- Fewer permissions -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // disable auto IAM generation - autoGenerateIamPermissions: false, -}); -``` + _If we use inline content instead of a S3 asset, the SopsSyncProvider does not need permissions to access the asset bucket and its KMS key._ -### Use a VPC for the Lambda Function +- Faster -Internally, SopsSync uses a lambda function. In some environments it may be necessary to place this lambda function into a VPC and configure subnets and/or security groups for it. -This can be done by creating a custom `SopsSyncProvider`, setting the required networking configuration and passing it to the secret like this: + _If we don't have to upload and download things from and to S3, it should be a little faster._ -```typescript -// Create the provider -const provider = new SopsSyncProvider(this, 'CustomSopsSyncProvider', { - vpc: myVpc, - vpcSubnets: subnetSelection, - securityGroups: [mySecurityGroup], -}); -// create the secret and pass the the provider to it -const secret = new SopsSecret(this, 'SopsSecret', { - sopsProvider: provider, - secretName: 'myCoolSecret', - sopsFilePath: 'secrets/sopsfile-encrypted.json', -}); -``` +- Interchangeable + _As we use the same information to generate the version of the secret, + no new version of the secret should be created, if you change from INLINE to ASSET or vice versa, + even if the CloudFormation resource updates._ -### UploadType: INLINE / ASSET +## Stability -I decided, that the default behavior should be "INLINE" because of the following consideration: +You can consider this package as stable. Updates will follow [Semantic Versioning](https://semver.org/). -- Fewer permissions: If we use inline content instead of a S3 asset, the SopsSyncProvider does not need permissions to access the asset bucket and its KMS key. -- Faster: If we don't have to upload and download things from and to S3, it should be a little faster. -- Interchangeable: As we use the same information to generate the version of the secret, no new version of the secret should be created, if you change from INLINE to ASSET or vice versa, even if the CloudFormation resource updates. -- I personally think sops files are not that big, that we should run into limits, but if so — we can change to asset `uploadType`. +Nevertheless, I would recommend pinning the exact version of this library in your `package.json`. -You can change the uplaodType via the properties: +# FAQ -```typescript -const secret = new SopsSecret(this, 'SopsWithAssetUpload', { - sopsFilePath: 'secrets/sopsfile-encrypted.json', - uploadType: UploadType.ASSET, // instead of the default UploadType.INLINE -}); -``` +## How can I migrate to V2 + +It was required to change some user facing configuration properties. So minor changes are required to make things work again. + +### SecretsManager + +- Removed property convertToJSON, flatten, stringifiedValues +- Use property rawOutput instaed: + - `undefined / not set` => (default) convertToJSON and flatten and stringifiedValues = true + - `RawOutput.STRING` => convertToJSON and flatten and stringifiedValues = false + - `RawOutput.BINARY` => convertToJSON and flatten and stringifiedValues = false and Secret is binary -## FAQ +### Parameter -### It does not work, what can I do? +- Removed property convertToJSON, flatten, stringifiedValues => all of them made no sense - now only raw output of decrypted secret -Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: +### MultiParameter -```/aws/lambda/-SingletonLambdaSopsSyncProvider``` +- Removed property convertToJSON, flatten, stringifiedValues => most of this combinations made no sense +- Allways convertToJson and flatten (as we have to parse it to create multiple parameters) +- You are allowed to chose the flattenSeperator -### I get errors with dotenv formatted files +## It does not work, what can I do? + +Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: + +`/aws/lambda/-SingletonLambdaSopsSyncProvider` + +## I get errors with `dotenv` formatted files Only very basic dotenv syntax is working right now. Only single line values are accepted. The format must match: @@ -217,19 +350,19 @@ key=value comments must be a single line, not after value assignments. -### Error getting data key: 0 successful groups required, got 0 +## Error: Error getting data key: 0 successful groups required, got 0 -This error message (and failed sync) is related to the mozilla/sops issues [#948](https://github.com/mozilla/sops/issues/948) and [#634](https://github.com/mozilla/sops/issues/634). You must not create your secret with the ```--aws-profile``` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable ```AWS_PROFILE``` instead, to avoid this. +This error message (and failed sync) is related to the getsops/sops issues [#948](https://github.com/getsops/sops/issues/948) and [#634](https://github.com/getsops/sops/issues/634). You must not create your secret with the `--aws-profile` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable `AWS_PROFILE` instead, to avoid this. -### Asset of sync lambda not found +## Error: Asset of sync lambda not found The lambda asset code is generated relative to the path of the index.ts in this package. With tools like nx this can lead to wrong results, so that the asset could not be found. -You can override the asset path via the [cdk.json](https://docs.aws.amazon.com/cdk/v2/guide/get_context_var.html) or via the flag ```-c```of the cdk cli. +You can override the asset path via the [cdk.json](https://docs.aws.amazon.com/cdk/v2/guide/get_context_var.html) or via the flag `-c`of the cdk cli. -The context used for this override is ```sops_sync_provider_asset_path```. +The context used for this override is `sops_sync_provider_asset_path`. -So for example you can use +So for example you can use ```bash cdk deploy -c "sops_sync_provider_asset_path=some/path/asset.zip" @@ -241,27 +374,16 @@ or in your cdk.json { "context": { "sops_sync_provider_asset_path": "some/path/asset.zip" - } + } } ``` -### I want to upload the sops file myself and only want to reference it +## Can I upload the sops file myself and provide the required information as CloudFormation Parameter? -That's possible since version 1.8.0. You can reference the file in S3 like: +This should be possible the following way. Ensure, that you have created a custom sops provider, +with proper IAM permissions. ```typescript -new SopsSecret(stack, 'SopsSecret', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - // ... -}); -``` - -Passing those values as CloudFormation parameters should also be possible: - -```typescript - const sopsS3BucketParam = new CfnParameter(this, "s3BucketName", { type: "String", description: "The name of the Amazon S3 bucket where your sopsFile was uploaded."}); @@ -270,36 +392,63 @@ const sopsS3KeyParam = new CfnParameter(this, "s3KeyName", { type: "String", description: "The name of the key of the sopsFile inside the Amazon S3 bucket."}); +const sopsKmsKeyArn = new CfnParameter(this, "sopsKeyArn", { + type: "String", + description: "The ARN of the KMS Key used for sops encryption"}); + +const sopsKmsKey = Key.fromKeyArn(this, 'Key', sopsKmsKeyArn.valueAsString) + new SopsSecret(stack, 'SopsSecret', { sopsS3Bucket: sopsS3BucketParam.valueAsString, sopsS3Key: sopsS3KeyParam.valueAsString, + sopsKmsKey: [ + sopsKmsKey + ], sopsFileFormat: 'json', - // ... + ... +}); +``` + +## Can I access older versions of the secret stored in the SecretsManager? + +While creating the secret or updating the entries of a secret, the native CDK function `cdk.FileSystem.fingerprint(...)` is used +to generate the version information of the AWS SecretsManager secret. +Therefore, it is possible to reference the entries from a specific AWS SecretsManager version. + +```typescript +const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`); +const passphrase = ecs.Secret.fromSecretsManagerVersion( + secretMgmt, + { versionId: versionId }, + 'MY_PRIVATE_PASSPHRASE', +); + +const container = TaskDef.addContainer('Container', { + secrets: { + MY_PRIVATE_PASSPHRASE: passphrase, + }, }); ``` -## Motivation +## I want the `raw` content of the sops file, but I always get the content nested in json -I have created this project to solve a recurring problem of syncing Mozilla/sops secrets into AWS SecretsManager in a convenient, secure way. +To get the best raw experience, you should encrypt your sops files in binary format: -Other than that, or perhaps more importantly, my goal was to learn new things: +```bash +sops encrypt ... my-whatever-file --output my-secret-information.sops.binary --input-type binary +``` -- Write a Golang lambda -- Writing unit tests incl. mocks in Golang -- Reproducible builds of Golang binaries (byte-by-byte identical) -- Build reproducible zips (byte-by-byte identical) -- Release a NPM package -- Setting up projects with projen -- CI/CD with GitHub actions -- CDK unit and integration tests +You will lose features like only encrypting the values, not the keys. +The whole file content will be stored in the sops file. +You can store everything you like as binary, even binary data[^1]. -## Other Tools like this +When using binary encrypted secrets with this constructs, ensure the ending is also binary, or override via +`sopsFormat` property. -The problem this Construct addresses is so good, already two other implementations exist: +This does not work for `MultiStringParameter` -- [isotoma/sops-secretsmanager-cdk](https://github.com/isotoma/sops-secretsmanager-cdk): Does nearly the same. Uses CustomResource, wraps the sops CLI, does not support flatten. Found it after I published my solution to NPM :-/ -- [taimos/secretsmanager-versioning](https://github.com/taimos/secretsmanager-versioning): Different approach on the same problem. This is a CLI tool with very nice integration into CDK and also handles git versioning information. +[^1] Even if sops can handle binary data, only the AWS SecretsManager allows to store it. -## License +# License The Apache-2.0 license. Please have a look at the [LICENSE](LICENSE) and [LICENSE-3RD-PARTY](LICENSE-3RD-PARTY). diff --git a/lambda/README.md b/lambda/README.md new file mode 100644 index 00000000..1f51deee --- /dev/null +++ b/lambda/README.md @@ -0,0 +1,22 @@ +# Tested combinations + +| Test Case | Resource Type | Input Format | Expected Behavior | +| --------- | --------------- | ------------ | ----------------------------------------------- | +| 01 | SECRET | json | Save json as stringified, flattened JSON | +| 02 | SECRET | yaml | Save yaml as stringified, flattened JSON | +| 03 | SECRET | dotenv | Save dotenv as stringified, flattened JSON | +| 11 | SECRET_RAW | json | Save json as raw String SecretValue | +| 12 | SECRET_RAW | yaml | Save yaml as raw String SecretValue | +| 13 | SECRET_RAW | dotenv | Save dotenv as raw String SecretValue | +| 14 | SECRET_RAW | binary | Save binary as raw String SecretValue | +| 21 | SECRET_BINARY | json | Save json as Binary SecretValue | +| 22 | SECRET_BINARY | yaml | Save yaml as Binary SecretValue | +| 23 | SECRET_BINARY | dotenv | Save dotenv as Binary SecretValue | +| 24 | SECRET_BINARY | binary | Save binary as Binary SecretValue | +| 31 | PARAMETER | json | Save raw json into StringParameter | +| 32 | PARAMETER | yaml | Save raw yaml into StringParameter | +| 33 | PARAMETER | dotenv | Save raw dotenv into StringParameter | +| 34 | PARAMETER | binary | Save raw binary into StringParameter | +| 41 | PARAMETER_MULTI | json | Create multpiple Parameters (from json input) | +| 42 | PARAMETER_MULTI | yaml | Create multpiple Parameters (from yaml input) | +| 43 | PARAMETER_MULTI | dotenv | Create multpiple Parameters (from dotenv input) | diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap new file mode 100755 index 00000000..d08d088a --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/01-SECRET-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "01-SECRET-json": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap new file mode 100755 index 00000000..7e0d9670 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/02-SECRET-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "02-SECRET-yaml": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap new file mode 100755 index 00000000..74bc8685 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/03-SECRET-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "03-SECRET-dotenv": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database:host\": \"db.example.com\",\n \"database:password\": \"P@ssw0rd!\",\n \"database:user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific:HTLMEncodingTest3\": \"@\",\n \"specific:HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific:HTMLEncodingTest2\": \"\\u0026\",\n \"specific:SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific:boolean\": \"True\",\n \"specific:null\": \"\",\n \"specific:number1\": \"123\",\n \"specific:number2\": \"123.456\",\n \"tokens:0:service\": \"service1\",\n \"tokens:0:token\": \"token1\",\n \"tokens:1:service\": \"service2\",\n \"tokens:1:token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap new file mode 100755 index 00000000..f6080ce6 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/11-SECRET_RAW-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "11-SECRET_RAW-json": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap new file mode 100755 index 00000000..1bdba1ca --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/12-SECRET_RAW-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "12-SECRET_RAW-yaml": map[string]interface {}{ + "binary": bool(false), + "secretContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap new file mode 100755 index 00000000..27e7552f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "13-SECRET_RAW-dotenv": map[string]interface {}{ + "binary": bool(false), + "secretContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap new file mode 100755 index 00000000..65ba3039 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/21-SECRET_BINARY-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "21-SECRET_BINARY-json": map[string]interface {}{ + "binary": bool(true), + "secretContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap new file mode 100755 index 00000000..14f732de --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "22-SECRET_BINARY-yaml": map[string]interface {}{ + "binary": bool(true), + "secretContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap new file mode 100755 index 00000000..ddc1afe2 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "23-SECRET_BINARY-dotenv": map[string]interface {}{ + "binary": bool(true), + "secretContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap new file mode 100755 index 00000000..13b51467 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/24-SECRET_BINARY-binary.json - 1] +main.getObjectCalls{ + "test-secrets/README.gz.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.gz.sops.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/README.gz.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.gz.sops.binary"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "24-SECRET_BINARY-binary": map[string]interface {}{ + "binary": bool(true), + "secretContent": "\x1f\x8b\b\b+Æ©g\x00\x03README.md\x00m\x90\xc1n\x82@\x14E\xf7|\xc5K\xbai\x93\xa2(\xa0\x84\x1d\xb1`\xa3!U\xa1\xb5\xb5i\"\x1d\x06\x18\x1d\x98qf\xc0\xe0\xd7\x17j\x93v\xd1\xe5K\xee=\xf7\xe4\xdd@\xf4\xb4\x8a #\x14KȘ\x00\x85\xa5\"U\x0e\xbc\x16\x9cI\xaciq\x81A2.\x7f2\xa4\x02U\x10\t)\x11\x18)&Z8c\x81\x01\t\x9c(\x9c\xfe\x87\x18\x80'\x01WH\xb4\\\x11VABs&\x88*JxOr\xfcq[(Å¥;\x1cv\x87\xfe\x1b\x1b0\x91\x0f\xef\xa0[\xaa%N\xef!\xe9\xa6U×¥\xec\xdc\xd1\x12Ù‚,\x12\xd1Ï°\xec/\x9dT\x9dB\x99|#\xae\xf2\x19\xebK}\xf2\x88[y\xd5í™®\xa6\xed\xf7\xfb6)\xa9\xc6\xebOJ\x90\v\x9d\xc2(=Pz\x1e\xf3KÍ…8!\x03Wv\xe94\xc89\xda96Uid\x93|\x8a\x0e\x062r\x9a]\xb8e5)\xb2NÔ©\xf2\xa6Ö¸ M\xf7\x05\x17\xbc\xb9\xafG\xfel\xe3\xc7\xfa\xd2\x7f\xd3G~\xf0\xbc]\x18\xf3\xf1\xeb\"^\x04\xdb\xd8\v\xc7\x0f\xf3г^fKsc\xd8[\xdb\t\xa2\xf0q\xb72\xc3\xdd\xda\xd8\xc5\xde\xda\xf7\x82\xf5l\x12Oc\xb3WÔ¾\x00\x9a\x91g\xf1\xa5\x01\x00\x00", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap new file mode 100755 index 00000000..113cb831 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/31-PARAMETER-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ + "/31-PARAMETER-json": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap new file mode 100755 index 00000000..8b2a1068 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/32-PARAMETER-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ + "/32-PARAMETER-yaml": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap new file mode 100755 index 00000000..4488c56f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/33-PARAMETER-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ + "/33-PARAMETER-dotenv": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap new file mode 100755 index 00000000..5df09d2c --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/34-PARAMETER-binary.json - 1] +main.getObjectCalls{ + "test-secrets/README.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.sops.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/README.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.sops.binary"}, +} +main.putParameterCalls{ + "/34-PARAMETER-binary": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "# SOPS files for testing purpose\n\nThe sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information.\n\nThe following keys were used:\n\n```yaml\npublic: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu\nprivate: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3\n```\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap new file mode 100755 index 00000000..a914501f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ + "/41-PARAMETER_MULTI-json/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/41-PARAMETER_MULTI-json/database/host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/41-PARAMETER_MULTI-json/database/password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/41-PARAMETER_MULTI-json/database/user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/41-PARAMETER_MULTI-json/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/41-PARAMETER_MULTI-json/specific/HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/41-PARAMETER_MULTI-json/specific/SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/41-PARAMETER_MULTI-json/specific/boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "true", + }, + "/41-PARAMETER_MULTI-json/specific/null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/41-PARAMETER_MULTI-json/specific/number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/41-PARAMETER_MULTI-json/specific/number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/41-PARAMETER_MULTI-json/tokens/0/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/41-PARAMETER_MULTI-json/tokens/0/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/41-PARAMETER_MULTI-json/tokens/1/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/41-PARAMETER_MULTI-json/tokens/1/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap new file mode 100755 index 00000000..4e7efa95 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ + "/42-PARAMETER_MULTI-yaml/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/42-PARAMETER_MULTI-yaml/database/host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/42-PARAMETER_MULTI-yaml/database/password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/42-PARAMETER_MULTI-yaml/database/user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/42-PARAMETER_MULTI-yaml/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/42-PARAMETER_MULTI-yaml/specific/SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/42-PARAMETER_MULTI-yaml/specific/boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "true", + }, + "/42-PARAMETER_MULTI-yaml/specific/null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/42-PARAMETER_MULTI-yaml/specific/number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/42-PARAMETER_MULTI-yaml/specific/number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/42-PARAMETER_MULTI-yaml/tokens/0/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/42-PARAMETER_MULTI-yaml/tokens/0/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/42-PARAMETER_MULTI-yaml/tokens/1/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/42-PARAMETER_MULTI-yaml/tokens/1/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap new file mode 100755 index 00000000..b8cf0c80 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ + "/43-PARAMETER_MULTI-dotenv/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/43-PARAMETER_MULTI-dotenv/database_host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/43-PARAMETER_MULTI-dotenv/database_password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/43-PARAMETER_MULTI-dotenv/database_user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/43-PARAMETER_MULTI-dotenv/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/43-PARAMETER_MULTI-dotenv/specific_SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/43-PARAMETER_MULTI-dotenv/specific_boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "True", + }, + "/43-PARAMETER_MULTI-dotenv/specific_null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/43-PARAMETER_MULTI-dotenv/specific_number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/43-PARAMETER_MULTI-dotenv/specific_number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_0_service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_0_token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_1_service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_1_token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap new file mode 100755 index 00000000..b04b754d --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/01-SECRET-json.json - 1] +&"01-SECRET-json" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap new file mode 100755 index 00000000..3b5bfde4 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json - 1] +&"02-SECRET-yaml" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap new file mode 100755 index 00000000..4045689a --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json - 1] +&"03-SECRET-dotenv" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database:host\": \"db.example.com\",\n \"database:password\": \"P@ssw0rd!\",\n \"database:user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific:HTLMEncodingTest3\": \"@\",\n \"specific:HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific:HTMLEncodingTest2\": \"\\u0026\",\n \"specific:SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific:boolean\": \"True\",\n \"specific:null\": \"\",\n \"specific:number1\": \"123\",\n \"specific:number2\": \"123.456\",\n \"tokens:0:service\": \"service1\",\n \"tokens:0:token\": \"token1\",\n \"tokens:1:service\": \"service2\",\n \"tokens:1:token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap new file mode 100755 index 00000000..b8378595 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json - 1] +&"11-SECRET_RAW-json" +[]uint8(nil) +&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap new file mode 100755 index 00000000..3ea6cd76 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json - 1] +&"12-SECRET_RAW-yaml" +[]uint8(nil) +&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap new file mode 100755 index 00000000..eb7c7d1c --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json - 1] +&"13-SECRET_RAW-dotenv" +[]uint8(nil) +&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap new file mode 100755 index 00000000..34cd51b7 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json - 1] +&"21-SECRET_BINARY-json" +[]uint8{0x7b, 0xa, 0x9, 0x22, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x2c, 0xa, 0x9, 0x22, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x22, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0xa, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x22, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0x22, 0x2c, 0xa, 0x9, 0x22, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x22, 0x3a, 0x20, 0x22, 0x40, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x22, 0x3a, 0x20, 0x22, 0x26, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x5c, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0xa, 0x9, 0x9, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0x22, 0xa, 0x9, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x9, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0x22, 0xa, 0x9, 0x9, 0x7d, 0xa, 0x9, 0x5d, 0xa, 0x7d} +(*string)(nil) +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap new file mode 100755 index 00000000..26af2eaf --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json - 1] +&"22-SECRET_BINARY-yaml" +[]uint8{0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3a, 0x20, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0xa, 0x20, 0x20, 0x20, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x3a, 0x20, 0x27, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x3a, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x3a, 0x20, 0x27, 0x26, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x3a, 0x20, 0x27, 0x40, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x3a, 0x20, 0x31, 0x32, 0x33, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa} +(*string)(nil) +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap new file mode 100755 index 00000000..77074a3c --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json - 1] +&"23-SECRET_BINARY-dotenv" +[]uint8{0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x3d, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x68, 0x6f, 0x73, 0x74, 0x3d, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3d, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x3d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0xa, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x3d, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3d, 0x54, 0x72, 0x75, 0x65, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x3d, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x3d, 0x40, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x3d, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x3d, 0x26, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x3d, 0x31, 0x32, 0x33, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x3d, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x30, 0x3a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x30, 0x3a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x31, 0x3a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x31, 0x3a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa} +(*string)(nil) +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap new file mode 100755 index 00000000..267339f6 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json - 1] +&"24-SECRET_BINARY-binary" +[]uint8{0x1f, 0x8b, 0x8, 0x8, 0x2b, 0xc6, 0xa9, 0x67, 0x0, 0x3, 0x52, 0x45, 0x41, 0x44, 0x4d, 0x45, 0x2e, 0x6d, 0x64, 0x0, 0x6d, 0x90, 0xc1, 0x6e, 0x82, 0x40, 0x14, 0x45, 0xf7, 0x7c, 0xc5, 0x4b, 0xba, 0x69, 0x93, 0xa2, 0x28, 0xa0, 0x84, 0x1d, 0xb1, 0x60, 0xa3, 0x21, 0x55, 0xa1, 0xb5, 0xb5, 0x69, 0x22, 0x1d, 0x6, 0x18, 0x1d, 0x98, 0x71, 0x66, 0xc0, 0xe0, 0xd7, 0x17, 0x6a, 0x93, 0x76, 0xd1, 0xe5, 0x4b, 0xee, 0x3d, 0xf7, 0xe4, 0xdd, 0x40, 0xf4, 0xb4, 0x8a, 0x20, 0x23, 0x14, 0x4b, 0xc8, 0x98, 0x0, 0x85, 0xa5, 0x22, 0x55, 0xe, 0xbc, 0x16, 0x9c, 0x49, 0xac, 0x69, 0x71, 0x81, 0x41, 0x32, 0x2e, 0x7f, 0x32, 0xa4, 0x2, 0x55, 0x10, 0x9, 0x29, 0x11, 0x18, 0x29, 0x26, 0x5a, 0x38, 0x63, 0x81, 0x1, 0x9, 0x9c, 0x28, 0x9c, 0xfe, 0x87, 0x18, 0x80, 0x27, 0x1, 0x57, 0x48, 0xb4, 0x5c, 0x11, 0x56, 0x41, 0x42, 0x73, 0x26, 0x88, 0x2a, 0x4a, 0x78, 0x4f, 0x72, 0xfc, 0x71, 0x5b, 0x28, 0xc5, 0xa5, 0x3b, 0x1c, 0x76, 0x87, 0xfe, 0x1b, 0x1b, 0x30, 0x91, 0xf, 0xef, 0xa0, 0x5b, 0xaa, 0x25, 0x4e, 0xef, 0x21, 0xe9, 0xa6, 0x55, 0xd7, 0xa5, 0xec, 0xdc, 0xd1, 0x12, 0xd9, 0x82, 0x2c, 0x12, 0xd1, 0xcf, 0xb0, 0xec, 0x2f, 0x9d, 0x54, 0x9d, 0x42, 0x99, 0x7c, 0x23, 0xae, 0xf2, 0x19, 0xeb, 0x4b, 0x7d, 0xf2, 0x88, 0x5b, 0x79, 0xd5, 0xed, 0x99, 0xae, 0xa6, 0xed, 0xf7, 0xfb, 0x36, 0x29, 0xa9, 0xc6, 0xeb, 0x4f, 0x4a, 0x90, 0xb, 0x9d, 0xc2, 0x28, 0x3d, 0x50, 0x7a, 0x1e, 0xf3, 0x4b, 0xcd, 0x85, 0x38, 0x21, 0x3, 0x57, 0x76, 0xe9, 0x34, 0xc8, 0x39, 0xda, 0x39, 0x36, 0x55, 0x69, 0x64, 0x93, 0x7c, 0x8a, 0xe, 0x6, 0x32, 0x72, 0x9a, 0x5d, 0xb8, 0x65, 0x35, 0x29, 0xb2, 0x4e, 0xd4, 0xa9, 0xf2, 0xa6, 0xd6, 0xb8, 0x20, 0x4d, 0xf7, 0x5, 0x17, 0xbc, 0xb9, 0xaf, 0x47, 0xfe, 0x6c, 0xe3, 0xc7, 0xfa, 0xd2, 0x7f, 0xd3, 0x47, 0x7e, 0xf0, 0xbc, 0x5d, 0x18, 0xf3, 0xf1, 0xeb, 0x22, 0x5e, 0x4, 0xdb, 0xd8, 0xb, 0xc7, 0xf, 0xf3, 0xd0, 0xb3, 0x5e, 0x66, 0x4b, 0x73, 0x63, 0xd8, 0x5b, 0xdb, 0x9, 0xa2, 0xf0, 0x71, 0xb7, 0x32, 0xc3, 0xdd, 0xda, 0xd8, 0xc5, 0xde, 0xda, 0xf7, 0x82, 0xf5, 0x6c, 0x12, 0x4f, 0x63, 0xb3, 0x57, 0xd4, 0xbe, 0x0, 0x9a, 0x91, 0x67, 0xf1, 0xa5, 0x1, 0x0, 0x0} +(*string)(nil) +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap new file mode 100755 index 00000000..9344076b --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json - 1] +&"/31-PARAMETER-json" +&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap new file mode 100755 index 00000000..dd1d9e9f --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json - 1] +&"/32-PARAMETER-yaml" +&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap new file mode 100755 index 00000000..a374127d --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json - 1] +&"/33-PARAMETER-dotenv" +&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap new file mode 100755 index 00000000..d57d4e53 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json - 1] +&"/34-PARAMETER-binary" +&"# SOPS files for testing purpose\n\nThe sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information.\n\nThe following keys were used:\n\n```yaml\npublic: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu\nprivate: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3\n```\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap new file mode 100755 index 00000000..9a5f26c1 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 1] +&"/41-PARAMETER_MULTI-json/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 2] +&"/41-PARAMETER_MULTI-json/database/host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 3] +&"/41-PARAMETER_MULTI-json/database/password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 4] +&"/41-PARAMETER_MULTI-json/database/user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 5] +&"/41-PARAMETER_MULTI-json/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 6] +&"/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 7] +&"/41-PARAMETER_MULTI-json/specific/HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 8] +&"/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 9] +&"/41-PARAMETER_MULTI-json/specific/SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 10] +&"/41-PARAMETER_MULTI-json/specific/boolean" +&"true" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 11] +&"/41-PARAMETER_MULTI-json/specific/null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 12] +&"/41-PARAMETER_MULTI-json/specific/number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 13] +&"/41-PARAMETER_MULTI-json/specific/number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 14] +&"/41-PARAMETER_MULTI-json/tokens/0/service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 15] +&"/41-PARAMETER_MULTI-json/tokens/0/token" +&"token1" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 16] +&"/41-PARAMETER_MULTI-json/tokens/1/service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 17] +&"/41-PARAMETER_MULTI-json/tokens/1/token" +&"token2" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap new file mode 100755 index 00000000..f46872ad --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 1] +&"/42-PARAMETER_MULTI-yaml/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 2] +&"/42-PARAMETER_MULTI-yaml/database/host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 3] +&"/42-PARAMETER_MULTI-yaml/database/password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 4] +&"/42-PARAMETER_MULTI-yaml/database/user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 5] +&"/42-PARAMETER_MULTI-yaml/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 6] +&"/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 7] +&"/42-PARAMETER_MULTI-yaml/specific/boolean" +&"true" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 8] +&"/42-PARAMETER_MULTI-yaml/specific/null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 9] +&"/42-PARAMETER_MULTI-yaml/specific/number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 10] +&"/42-PARAMETER_MULTI-yaml/specific/HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 11] +&"/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 12] +&"/42-PARAMETER_MULTI-yaml/specific/SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 13] +&"/42-PARAMETER_MULTI-yaml/specific/number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 14] +&"/42-PARAMETER_MULTI-yaml/tokens/0/service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 15] +&"/42-PARAMETER_MULTI-yaml/tokens/0/token" +&"token1" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 16] +&"/42-PARAMETER_MULTI-yaml/tokens/1/service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 17] +&"/42-PARAMETER_MULTI-yaml/tokens/1/token" +&"token2" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap new file mode 100755 index 00000000..1c3c1431 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 1] +&"/43-PARAMETER_MULTI-dotenv/specific_number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 2] +&"/43-PARAMETER_MULTI-dotenv/tokens_1_service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 3] +&"/43-PARAMETER_MULTI-dotenv/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 4] +&"/43-PARAMETER_MULTI-dotenv/database_password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 5] +&"/43-PARAMETER_MULTI-dotenv/database_user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 6] +&"/43-PARAMETER_MULTI-dotenv/specific_HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 7] +&"/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 8] +&"/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 9] +&"/43-PARAMETER_MULTI-dotenv/specific_null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 10] +&"/43-PARAMETER_MULTI-dotenv/specific_number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 11] +&"/43-PARAMETER_MULTI-dotenv/tokens_0_service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 12] +&"/43-PARAMETER_MULTI-dotenv/tokens_1_token" +&"token2" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 13] +&"/43-PARAMETER_MULTI-dotenv/database_host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 14] +&"/43-PARAMETER_MULTI-dotenv/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 15] +&"/43-PARAMETER_MULTI-dotenv/specific_SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 16] +&"/43-PARAMETER_MULTI-dotenv/specific_boolean" +&"True" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 17] +&"/43-PARAMETER_MULTI-dotenv/tokens_0_token" +&"token1" +--- diff --git a/lambda/__snapshots__/conversion_test.snap b/lambda/__snapshots__/conversion_test.snap deleted file mode 100755 index 0d586cd3..00000000 --- a/lambda/__snapshots__/conversion_test.snap +++ /dev/null @@ -1,197 +0,0 @@ - -[Test_FromJSON - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": float64(12345), - "key3": bool(false), -} ---- - -[Test_FromJSON - 2] ->>>Complex -map[string]interface {}{ - "and now": map[string]interface {}{ - "some": []interface {}{ - map[string]interface {}{ - "basic": bool(false), - }, - map[string]interface {}{ - "nested": float64(12345), - }, - map[string]interface {}{ - "type": float64(1.2345), - }, - map[string]interface {}{ - "tests": "Finish!", - }, - }, - }, - "some": map[string]interface {}{ - "deep": map[string]interface {}{ - "nested": map[string]interface {}{ - "arrays": []interface {}{ - "with", - "several", - map[string]interface {}{ - "values": map[string]interface {}{ - "and": "objects", - }, - }, - }, - "object": "structure", - }, - }, - "notsodeep": "struct", - }, -} ---- - -[Test_FromYAML - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": int(12345), - "key3": bool(false), -} ---- - -[Test_FromYAML - 2] ->>>Complex -map[string]interface {}{ - "and now": map[string]interface {}{ - "some": []interface {}{ - map[string]interface {}{ - "basic": bool(false), - }, - map[string]interface {}{ - "nested": int(12345), - }, - map[string]interface {}{ - "type": float64(1.2345), - }, - map[string]interface {}{ - "tests": "Finish!", - }, - }, - }, - "some": map[string]interface {}{ - "deep": map[string]interface {}{ - "nested": map[string]interface {}{ - "arrays": []interface {}{ - "with", - "several", - map[string]interface {}{ - "values": map[string]interface {}{ - "and": "objects", - }, - }, - }, - "object": "structure", - }, - }, - "notsodeep": "struct", - }, -} ---- - -[Test_Flatten - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": float64(12345), - "key3": bool(false), -} ---- - -[Test_Flatten - 2] ->>>Complex -map[string]interface {}{ - "and now.some[0].basic": bool(false), - "and now.some[1].nested": float64(12345), - "and now.some[2].type": float64(1.2345), - "and now.some[3].tests": "Finish!", - "some.deep.nested.arrays[0]": "with", - "some.deep.nested.arrays[1]": "several", - "some.deep.nested.arrays[2].values.and": "objects", - "some.deep.nested.object": "structure", - "some.notsodeep": "struct", -} ---- - -[Test_toJSON - 1] ->>>Simple -{ - "key1": "value1", - "key2": 12345, - "key3": false -} ---- - -[Test_toJSON - 2] ->>>Complex -{ - "and now": { - "some": [ - { - "basic": false - }, - { - "nested": 12345 - }, - { - "type": 1.2345 - }, - { - "tests": "Finish!" - } - ] - }, - "some": { - "deep": { - "nested": { - "arrays": [ - "with", - "several", - { - "values": { - "and": "objects" - } - } - ], - "object": "structure" - } - }, - "notsodeep": "struct" - } -} ---- - -[Test_toYAML - 1] ->>>Simple -key1: value1 -key2: 12345 -key3: false - ---- - -[Test_toYAML - 2] ->>>Complex -and now: - some: - - basic: false - - nested: 12345 - - type: 1.2345 - - tests: Finish! -some: - deep: - nested: - arrays: - - with - - several - - values: - and: objects - object: structure - notsodeep: struct - ---- diff --git a/lambda/__snapshots__/handler_common_test.snap b/lambda/__snapshots__/handler_common_test.snap deleted file mode 100755 index d684791a..00000000 --- a/lambda/__snapshots__/handler_common_test.snap +++ /dev/null @@ -1,7 +0,0 @@ - -[Test_FullWorkflow_Delete - 1] ->>>syncSopsToSecretsmanager - -map[string]interface {}{} -nil ---- diff --git a/lambda/__snapshots__/handler_parameter_raw_test.snap b/lambda/__snapshots__/handler_parameter_raw_test.snap deleted file mode 100755 index 46007613..00000000 --- a/lambda/__snapshots__/handler_parameter_raw_test.snap +++ /dev/null @@ -1,46 +0,0 @@ - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 4] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "Tier": &"Standard", - "Version": &int64(1), -} -nil ---- diff --git a/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap b/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap deleted file mode 100755 index 8826756e..00000000 --- a/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap +++ /dev/null @@ -1,126 +0,0 @@ - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"/foo/bar/key1", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"foo", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 4] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"/foo/bar/key2", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"bar", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 5] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "Count": int(2), - "Prefix": "/", -} -nil ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"_foo.bar.key1", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"foo", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 4] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"_foo.bar.key2", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"bar", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 5] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "Count": int(2), - "Prefix": "_", -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_env_test.snap b/lambda/__snapshots__/handler_secret_env_test.snap deleted file mode 100755 index 0488553e..00000000 --- a/lambda/__snapshots__/handler_secret_env_test.snap +++ /dev/null @@ -1,88 +0,0 @@ - -[Test_FullWorkflow_Create_S3_ENV_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env" -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"banane=yellow\ncrypt=\"ajkscbuiuXA34%%&&=\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "6e5c42133fbe7c37503ffbd8e2c4dd792b6800a7aa022e5ee9d70892c3be4205", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env" -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"banane\": \"yellow\",\n \"crypt\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "853112768310b655f423f8e8338d83ca124ddfa16d70f60f0b82aeb3861744c5", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_json_test.snap b/lambda/__snapshots__/handler_secret_json_test.snap deleted file mode 100755 index 83ca106c..00000000 --- a/lambda/__snapshots__/handler_secret_json_test.snap +++ /dev/null @@ -1,284 +0,0 @@ - -[Test_FullWorkflow_Create_S3_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": \"false\"\n },\n {\n \"nested\": \"12345\"\n },\n {\n \"type\": \"1.2345\"\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "ddc702937cbed1b68f84659094f8db7c862114642ae2a98baa43c42e16b256f4", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": \"false\"\n },\n {\n \"nested\": \"12345\"\n },\n {\n \"type\": \"1.2345\"\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "ddc702937cbed1b68f84659094f8db7c862114642ae2a98baa43c42e16b256f4", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_raw_test.snap b/lambda/__snapshots__/handler_secret_raw_test.snap deleted file mode 100755 index 674c2da6..00000000 --- a/lambda/__snapshots__/handler_secret_raw_test.snap +++ /dev/null @@ -1,44 +0,0 @@ - -[Test_FullWorkflow_Create_S3_RAW_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary" -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "afe1e68ea88d603e524fc4854b2f33e8f56ce0cc80b539d21fddcbf82586fb38", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_yaml_test.snap b/lambda/__snapshots__/handler_secret_yaml_test.snap deleted file mode 100755 index 9e19453e..00000000 --- a/lambda/__snapshots__/handler_secret_yaml_test.snap +++ /dev/null @@ -1,443 +0,0 @@ - -[Test_FullWorkflow_Create_S3_YAML_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"key1: value1\nkey2: 12345\nkey3: false\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "656f2d935b86bfbefbd97f1c55c1578aef8d96c5647a6161e37f94fb34a84d61", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\nsome:\n deep:\n nested:\n arrays:\n - with\n - several\n - values:\n and: objects\n object: structure\n notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "99d08789c0db731bcf0f3a467759c84c11e1b18253f9d614be55c817a410e088", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now.some[0].basic: false\nand now.some[1].nested: 12345\nand now.some[2].type: 1.2345\nand now.some[3].tests: Finish!\nsome.deep.nested.arrays[0]: with\nsome.deep.nested.arrays[1]: several\nsome.deep.nested.arrays[2].values.and: objects\nsome.deep.nested.object: structure\nsome.notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "9383dcb62f4f91358496ec0e473c605325cf76d5162b1432f3efaaac14e6d07f", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"key1: value1\nkey2: 12345\nkey3: false\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "656f2d935b86bfbefbd97f1c55c1578aef8d96c5647a6161e37f94fb34a84d61", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\nsome:\n deep:\n nested:\n arrays:\n - with\n - several\n - values:\n and: objects\n object: structure\n notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "99d08789c0db731bcf0f3a467759c84c11e1b18253f9d614be55c817a410e088", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now.some[0].basic: false\nand now.some[1].nested: 12345\nand now.some[2].type: 1.2345\nand now.some[3].tests: Finish!\nsome.deep.nested.arrays[0]: with\nsome.deep.nested.arrays[1]: several\nsome.deep.nested.arrays[2].values.and: objects\nsome.deep.nested.object: structure\nsome.notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "9383dcb62f4f91358496ec0e473c605325cf76d5162b1432f3efaaac14e6d07f", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/main_test.snap b/lambda/__snapshots__/main_test.snap deleted file mode 100755 index eddfddd3..00000000 --- a/lambda/__snapshots__/main_test.snap +++ /dev/null @@ -1,80 +0,0 @@ - -[Test_GetS3FileContent - 1] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json" -} ---- - -[Test_GetS3FileContent - 2] -{ - "key1": "ENC[AES256_GCM,data:ArSjC0Vd,iv:NFrIj1ekM2dU8JCU6NpmnHFmwcFaEQagCw/fxKV2b6A=,tag:GrGgeNmtqFuyiTjKJ/78kw==,type:str]", - "key2": "ENC[AES256_GCM,data:NeoandY=,iv:2oCcBk0R/XxvH/O+aaCIa7V9pFsy7dhCKZ70ebjc5Ds=,tag:GVZXUFFwbpMVY/KCLNENAQ==,type:float]", - "key3": "ENC[AES256_GCM,data:y4tBaNg=,iv:mHuYrtf0Ke/oHBcunpgdPpzaYkBx7UjMcOQgpmVc8/Q=,tag:cuEg2UE17Po6opfpH8ikog==,type:bool]", - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOWlAxekVNNXdjenV5cmdR\nZDlQU3N5WC9oeENUbUpYcWxkeU9kVS9TeUR3Cm5zbGhIL0J6WG9TWi9KR3ZUTVph\nblpiUDZtQklnWlRrSGZzTXlZN2Z6WjgKLS0tIDI3ZHNHR0NmWTMzdTg0dEtXcU93\nbEdNWndKdWROWGdLdHAwTGFtRGlsaDQKV7HJG629rPWDBY046Hxj4utxUkex3SwU\nVUQRX00p6r9ffc+iC5DGUm/KOketAHunO4Kn0uOS4WHg+Jg2Cwu72Q==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2022-03-29T21:02:32Z", - "mac": "ENC[AES256_GCM,data:2vmzwW74OSJq18GEcScpMH76AWrhJdENlKw2vRzGrQfPixTNcrwJ0neTH+BvGKfR9OlLR2EZTheRphQ0Ikb4SdhfInoDjHo+0jXN7RQ4neTlko4j/YRVek61oePgAKAqcmvL2IhzRGO2VR8nDPuJuvRCmP5wOMOBkerydRKHeDc=,iv:NHWPNWDmuhekJUIJpC1cDJ51lLKTsXLE6dC4tpw/qSI=,tag:yV5ngRdIYZfUgj6ntsY5CQ==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.7.2" - } -} ---- - -[Test_UpdateSecret - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:${Partition}:secretsmanager:${Region}:${Account}:secret:${SecretId}", - SecretString: &"some-secret-data", - VersionStages: nil, -} ---- - -[Test_UpdateSecret - 2] -{ - ARN: "arn:custom:sopssync:${Region}:${Account}:secret:${SecretId}", - Name: "ea44991f303ca1fc043cd129e135eb477c9f102e05eff7b06813202bda64638b", - VersionId: "90543d7645d7aa15732054e8a94dc5409278eb964a5dd9a53faeadb0cd849ca1", - VersionStages: ["ea44991f303ca1fc043cd129e135eb477c9f102e05eff7b06813202bda64638b"] -} ---- - -[Test_UpdateSSMParameter - 1] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"key", - Name: &"/foo/bar", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"some-secret-data", -} ---- - -[Test_UpdateSSMParameter - 2] -{ - Tier: "Standard", - Version: 1 -} ---- diff --git a/lambda/conversion_test.go b/lambda/conversion_test.go deleted file mode 100644 index cece3a80..00000000 --- a/lambda/conversion_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FromJSON(t *testing.T) { - simpleStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile.json")) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", simpleStruct) - complexStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile-complex.json")) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", complexStruct) -} - -func Test_FromYAML(t *testing.T) { - simpleStruct, err := fromYAML(ReadFile("../test-secrets/yaml/sopsfile.yml")) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", simpleStruct) - complexStruct, err := fromYAML(ReadFile("../test-secrets/yaml/sopsfile-complex.yml")) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", complexStruct) -} - -func Test_Flatten(t *testing.T) { - simpleStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile.json")) - check(err) - flattenedSimpleStruct := make(map[string]interface{}) - err = flatten("", simpleStruct, flattenedSimpleStruct, ".") - snaps.MatchSnapshot(t, ">>>Simple", flattenedSimpleStruct) - complexStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile-complex.json")) - check(err) - flattenedComplexStruct := make(map[string]interface{}) - err = flatten("", complexStruct, flattenedComplexStruct, ".") - snaps.MatchSnapshot(t, ">>>Complex", flattenedComplexStruct) -} - -func Test_toJSON(t *testing.T) { - simpleJSON, err := toJSON(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", string(simpleJSON)) - complexJSON, err := toJSON(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile-complex.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", string(complexJSON)) -} - -func Test_toYAML(t *testing.T) { - simpleJSON, err := toYAML(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", string(simpleJSON)) - complexJSON, err := toYAML(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile-complex.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", string(complexJSON)) -} diff --git a/lambda/events/01-SECRET-json.json b/lambda/events/01-SECRET-json.json new file mode 100644 index 00000000..11da90f1 --- /dev/null +++ b/lambda/events/01-SECRET-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "01-SECRET-json" +} diff --git a/lambda/events/02-SECRET-yaml.json b/lambda/events/02-SECRET-yaml.json new file mode 100644 index 00000000..485b805b --- /dev/null +++ b/lambda/events/02-SECRET-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "02-SECRET-yaml" +} diff --git a/lambda/events/03-SECRET-dotenv.json b/lambda/events/03-SECRET-dotenv.json new file mode 100644 index 00000000..8cd4d002 --- /dev/null +++ b/lambda/events/03-SECRET-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "03-SECRET-dotenv" +} diff --git a/lambda/events/11-SECRET_RAW-json.json b/lambda/events/11-SECRET_RAW-json.json new file mode 100644 index 00000000..a9f758e7 --- /dev/null +++ b/lambda/events/11-SECRET_RAW-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "11-SECRET_RAW-json" +} diff --git a/lambda/events/12-SECRET_RAW-yaml.json b/lambda/events/12-SECRET_RAW-yaml.json new file mode 100644 index 00000000..554a5c95 --- /dev/null +++ b/lambda/events/12-SECRET_RAW-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "12-SECRET_RAW-yaml" +} diff --git a/lambda/events/13-SECRET_RAW-dotenv.json b/lambda/events/13-SECRET_RAW-dotenv.json new file mode 100644 index 00000000..81294125 --- /dev/null +++ b/lambda/events/13-SECRET_RAW-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "13-SECRET_RAW-dotenv" +} diff --git a/lambda/events/21-SECRET_BINARY-json.json b/lambda/events/21-SECRET_BINARY-json.json new file mode 100644 index 00000000..326f5eff --- /dev/null +++ b/lambda/events/21-SECRET_BINARY-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "21-SECRET_BINARY-json" +} diff --git a/lambda/events/22-SECRET_BINARY-yaml.json b/lambda/events/22-SECRET_BINARY-yaml.json new file mode 100644 index 00000000..65cdbb29 --- /dev/null +++ b/lambda/events/22-SECRET_BINARY-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "22-SECRET_BINARY-yaml" +} diff --git a/lambda/events/23-SECRET_BINARY-dotenv.json b/lambda/events/23-SECRET_BINARY-dotenv.json new file mode 100644 index 00000000..e6b0cb7c --- /dev/null +++ b/lambda/events/23-SECRET_BINARY-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "23-SECRET_BINARY-dotenv" +} diff --git a/lambda/events/24-SECRET_BINARY-binary.json b/lambda/events/24-SECRET_BINARY-binary.json new file mode 100644 index 00000000..7d08c3a4 --- /dev/null +++ b/lambda/events/24-SECRET_BINARY-binary.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/README.gz.sops.binary" + }, + "Target": "24-SECRET_BINARY-binary" +} diff --git a/lambda/events/31-PARAMETER-json.json b/lambda/events/31-PARAMETER-json.json new file mode 100644 index 00000000..128bdfcc --- /dev/null +++ b/lambda/events/31-PARAMETER-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "/31-PARAMETER-json" +} diff --git a/lambda/events/32-PARAMETER-yaml.json b/lambda/events/32-PARAMETER-yaml.json new file mode 100644 index 00000000..b5ed42e5 --- /dev/null +++ b/lambda/events/32-PARAMETER-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "/32-PARAMETER-yaml" +} diff --git a/lambda/events/33-PARAMETER-dotenv.json b/lambda/events/33-PARAMETER-dotenv.json new file mode 100644 index 00000000..2cc7bde6 --- /dev/null +++ b/lambda/events/33-PARAMETER-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "/33-PARAMETER-dotenv" +} diff --git a/lambda/events/34-PARAMETER-binary.json b/lambda/events/34-PARAMETER-binary.json new file mode 100644 index 00000000..9fa36ba0 --- /dev/null +++ b/lambda/events/34-PARAMETER-binary.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/README.sops.binary" + }, + "Target": "/34-PARAMETER-binary" +} diff --git a/lambda/events/41-PARAMETER_MULTI-json.json b/lambda/events/41-PARAMETER_MULTI-json.json new file mode 100644 index 00000000..abc8ede1 --- /dev/null +++ b/lambda/events/41-PARAMETER_MULTI-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "/41-PARAMETER_MULTI-json/" +} diff --git a/lambda/events/42-PARAMETER_MULTI-yaml.json b/lambda/events/42-PARAMETER_MULTI-yaml.json new file mode 100644 index 00000000..2a3f178b --- /dev/null +++ b/lambda/events/42-PARAMETER_MULTI-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "/42-PARAMETER_MULTI-yaml/" +} diff --git a/lambda/events/43-PARAMETER_MULTI-dotenv.json b/lambda/events/43-PARAMETER_MULTI-dotenv.json new file mode 100644 index 00000000..a7701b65 --- /dev/null +++ b/lambda/events/43-PARAMETER_MULTI-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "/43-PARAMETER_MULTI-dotenv/" +} diff --git a/lambda/events/event_create_s3_parameter_raw_simple.json b/lambda/events/event_create_s3_parameter_raw_simple.json deleted file mode 100644 index 0309d8c2..00000000 --- a/lambda/events/event_create_s3_parameter_raw_simple.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/binary/sopsfile.enc-age.binary" - }, - "Format": "binary", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_parameter_yaml_complex.json b/lambda/events/event_create_s3_parameter_yaml_complex.json deleted file mode 100644 index b84319a1..00000000 --- a/lambda/events/event_create_s3_parameter_yaml_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER_MULTI", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" - }, - "Format": "yaml", - "Flatten": "true", - "FlattenSeparator": "/", - "ParameterKeyPrefix": "/", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json b/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json deleted file mode 100644 index 893a909e..00000000 --- a/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER_MULTI", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" - }, - "Format": "yaml", - "Flatten": "true", - "FlattenSeparator": ".", - "ParameterKeyPrefix": "_", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_env_as_json_simple.json b/lambda/events/event_create_s3_secret_env_as_json_simple.json deleted file mode 100644 index bc276b4c..00000000 --- a/lambda/events/event_create_s3_secret_env_as_json_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/dotenv/encrypted-best-secret.env" - }, - "Format": "dotenv", - "ConvertToJSON": "true", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_env_simple.json b/lambda/events/event_create_s3_secret_env_simple.json deleted file mode 100644 index 9b1baf91..00000000 --- a/lambda/events/event_create_s3_secret_env_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/dotenv/encrypted-best-secret.env" - }, - "Format": "dotenv", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex.json b/lambda/events/event_create_s3_secret_json_complex.json deleted file mode 100644 index a94df6b3..00000000 --- a/lambda/events/event_create_s3_secret_json_complex.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex_flat.json b/lambda/events/event_create_s3_secret_json_complex_flat.json deleted file mode 100644 index 5a7286bc..00000000 --- a/lambda/events/event_create_s3_secret_json_complex_flat.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex_stringify.json b/lambda/events/event_create_s3_secret_json_complex_stringify.json deleted file mode 100644 index b08f818d..00000000 --- a/lambda/events/event_create_s3_secret_json_complex_stringify.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "false", - "StringifyValues": "true", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_simple.json b/lambda/events/event_create_s3_secret_json_simple.json deleted file mode 100644 index 5d657957..00000000 --- a/lambda/events/event_create_s3_secret_json_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile.enc-age.json" - }, - "Format": "json", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_raw_simple.json b/lambda/events/event_create_s3_secret_raw_simple.json deleted file mode 100644 index 8f85ba91..00000000 --- a/lambda/events/event_create_s3_secret_raw_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/binary/sopsfile.enc-age.binary" - }, - "Format": "binary", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_complex.json b/lambda/events/event_create_s3_secret_yaml_as_json_complex.json deleted file mode 100644 index 48801dad..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json b/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json deleted file mode 100644 index 995f00ed..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_simple.json b/lambda/events/event_create_s3_secret_yaml_as_json_simple.json deleted file mode 100644 index 02420ea7..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_simple.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_complex.json b/lambda/events/event_create_s3_secret_yaml_complex.json deleted file mode 100644 index a2e0403d..00000000 --- a/lambda/events/event_create_s3_secret_yaml_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_complex_flat.json b/lambda/events/event_create_s3_secret_yaml_complex_flat.json deleted file mode 100644 index d7d8cc78..00000000 --- a/lambda/events/event_create_s3_secret_yaml_complex_flat.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_simple.json b/lambda/events/event_create_s3_secret_yaml_simple.json deleted file mode 100644 index 8fecbe62..00000000 --- a/lambda/events/event_create_s3_secret_yaml_simple.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_delete.json b/lambda/events/event_delete.json deleted file mode 100644 index 4d2c57d9..00000000 --- a/lambda/events/event_delete.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "RequestType": "Delete", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": {}, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/go.mod b/lambda/go.mod index 417eaaf9..76024082 100644 --- a/lambda/go.mod +++ b/lambda/go.mod @@ -4,11 +4,16 @@ go 1.23 require ( github.com/aws/aws-lambda-go v1.47.0 - github.com/aws/aws-sdk-go v1.55.6 - github.com/aws/aws-sdk-go-v2 v1.34.0 + github.com/aws/aws-sdk-go-v2 v1.36.0 + github.com/aws/aws-sdk-go-v2/config v1.28.6 + github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16 + github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10 github.com/getsops/sops/v3 v3.9.2 github.com/gkampitakis/go-snaps v0.5.9 - github.com/go-test/deep v1.1.1 + github.com/invopop/jsonschema v0.13.0 + github.com/kaptinlin/jsonschema v0.2.2 + github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -35,12 +40,11 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect - github.com/aws/aws-sdk-go-v2/config v1.28.6 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect @@ -48,18 +52,20 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect github.com/aws/smithy-go v1.22.2 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/blang/semver v3.5.1+incompatible // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.4.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/envoyproxy/go-control-plane v0.13.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect github.com/fatih/color v1.18.0 // indirect @@ -70,6 +76,8 @@ require ( github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-test/deep v1.1.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.15.13 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -78,6 +86,8 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.0 // indirect + github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect + github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092 // indirect github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -89,11 +99,12 @@ require ( github.com/hashicorp/go-sockaddr v1.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/vault/api v1.15.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kaptinlin/go-i18n v0.1.3 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.10.9 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/maruel/natural v1.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -103,6 +114,7 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -112,6 +124,7 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/urfave/cli v1.22.16 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect diff --git a/lambda/go.sum b/lambda/go.sum index 0f6344d2..5bd694ba 100644 --- a/lambda/go.sum +++ b/lambda/go.sum @@ -65,10 +65,8 @@ github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXx github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/aws/aws-lambda-go v1.47.0 h1:0H8s0vumYx/YKs4sE7YM0ktwL2eWse+kfopsRI1sXVI= github.com/aws/aws-lambda-go v1.47.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A= -github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= -github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.34.0 h1:9iyL+cjifckRGEVpRKZP3eIxVlL06Qk1Tk13vreaVQU= -github.com/aws/aws-sdk-go-v2 v1.34.0/go.mod h1:JgstGg0JjWU1KpVJjD5H0y0yyAIpSdKEq556EI6yOOM= +github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk= +github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= @@ -79,10 +77,10 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42 h1:vEnk9vtjJ62OO2wOhEmgKMZgNcn1w0aF7XCiNXO5rK0= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42/go.mod h1:GUOPbPJWRZsdt1OJ355upCrry4d3ZFgdX6rhT7gtkto= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE= @@ -99,6 +97,10 @@ github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 h1:dZmNIRtPUvtvUIIDVNpvtnJQ8N8I github.com/aws/aws-sdk-go-v2/service/kms v1.37.7/go.mod h1:vj8PlfJH9mnGeIzd6uMLPi5VgiqzGG7AZoe1kf1uTXM= github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 h1:HrHFR8RoS4l4EvodRMFcJMYQ8o3UhmALn2nbInXaxZA= github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16 h1:tIgXdHiHVELZm56dCK7fQ8c4gFMoz6AkhHksrxpmAFQ= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16/go.mod h1:5WGcD7Mks8G/VNlpHp2ZwfP5pVIZp0zp8nauLU7NuLM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10 h1:GLRZnZtAxWIgROsRgVm8YPaAG0t9pUwaxrkda/g9JiU= +github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10/go.mod h1:kh7898L3bN432TMBiRBe5Ua4IrUAaq1LwHhbqabeOOk= github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= @@ -107,8 +109,12 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HS github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -173,6 +179,8 @@ github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.15.13 h1:Xd87Yddmr2rC1SLLTm2MNDcTjeO/GYo0JGiww6gSTDg= github.com/goccy/go-yaml v1.15.13/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -216,6 +224,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gT github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= +github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 h1:b70jEaX2iaJSPZULSUxKtm73LBfsCrMsIlYCUgNGSIs= +github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976/go.mod h1:ZGQeOwybjD8lkCjIyJfqR5LD2wMVHJ31d6GdPxoTsWY= +github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092 h1:c7gcNWTSr1gtLp6PyYi3wzvFCEcHJ4YRobDgqmIgf7Q= +github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092/go.mod h1:ZZAN4fkkful3l1lpJwF8JbW41ZiG9TwJ2ZlqzQovBNU= github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw= github.com/goware/prefixer v0.0.0-20160118172347-395022866408/go.mod h1:PE1ycukgRPJ7bJ9a1fdfQ9j8i/cEcRAoLZzbxYpNB/s= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -241,10 +253,13 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA= github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kaptinlin/go-i18n v0.1.3 h1:Zmc2sp3N3eNxAPEiyfdbZgF+QF8LZdOdZNR1gHefUe4= +github.com/kaptinlin/go-i18n v0.1.3/go.mod h1:giU+qqtzFZ2U0ksKKVuSxtIFzBLkMA/vlKTeJDyyM2c= +github.com/kaptinlin/jsonschema v0.2.2 h1:aspDbCaqAJ/GSnzmtaSesC0+lnTOjLRamFB/k8mo60s= +github.com/kaptinlin/jsonschema v0.2.2/go.mod h1:HkWM5Yd1hA7K5nvRx/A67wQw/khr6b0/DHrP5CWgAbY= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -255,6 +270,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -280,6 +297,8 @@ github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2 github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= +github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= +github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -313,6 +332,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -325,6 +346,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -437,7 +460,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lambda/handle.go b/lambda/handle.go new file mode 100644 index 00000000..8ac23199 --- /dev/null +++ b/lambda/handle.go @@ -0,0 +1,163 @@ +package main + +import ( + "fmt" + "log/slog" + "strings" + + "github.com/aws/smithy-go/ptr" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/data" + "github.com/markussiebert/cdk-sops-secrets/internal/event" +) + +type BaseProps struct { + properties *event.SopsSyncResourcePropertys + clients client.AwsClient + secretDecryptedData *data.Data +} + +func handleSecret(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleSecret") + var outData *[]byte + var outDataErr error + logger.Info("Handling secret data", "ResourceType", props.properties.ResourceType) + + var binary *bool + + // Prepare the data depending on the resource type + switch props.properties.ResourceType { + case event.SECRET: + // The secretsmanager does not support nested json objects, so we have to flatten the data + seperator := "." + if props.properties.FlattenSeparator != nil { + seperator = *props.properties.FlattenSeparator + } + logger.Info("Flattening secret data", "seperator", seperator, "ResourceType", props.properties.ResourceType) + if err := props.secretDecryptedData.Flatten(seperator); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + + // Make sure the values are strings to avoid issues while storing them in the secrets manager + logger.Info("Stringifying secret data", "ResourceType", props.properties.ResourceType) + if err := props.secretDecryptedData.StringifyValues(); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + + // Secretsmanager values have to be stored as JSON + logger.Info("Converting secret data to JSON", "ResourceType", props.properties.ResourceType) + outData, outDataErr = props.secretDecryptedData.ToJSON() + binary = ptr.Bool(false) + case event.SECRET_RAW: + logger.Info("Getting raw secret data", "ResourceType", props.properties.ResourceType) + outData, outDataErr = props.secretDecryptedData.GetRaw() + binary = ptr.Bool(false) + case event.SECRET_BINARY: + logger.Info("Getting raw secret data", "ResourceType", props.properties.ResourceType) + outData, outDataErr = props.secretDecryptedData.GetRaw() + binary = ptr.Bool(true) + default: + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("unknown ResourceType: %s", props.properties.ResourceType) + } + + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + + putSecretValueResp, putSecretValueRespErr := props.clients.SecretsManagerPutSecretValue(*props.secretDecryptedData.Hash, props.properties.Target, outData, binary) + if putSecretValueRespErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, putSecretValueRespErr + } + + logger.Info("Secret data updated", "ARN", *putSecretValueResp.ARN) + + return *putSecretValueResp.ARN, map[string]interface{}{ + "ARN": *putSecretValueResp.ARN, + "Name": *putSecretValueResp.Name, + "VersionStages": putSecretValueResp.VersionStages, + "VersionId": *putSecretValueResp.VersionId, + }, nil +} + +func handleParameterMulti(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleParameterMulti") + seperator := "/" + if props.properties.FlattenSeparator != nil { + seperator = *props.properties.FlattenSeparator + } + logger.Info("Flattening secret data", "seperator", seperator) + if err := props.secretDecryptedData.Flatten(seperator); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + logger.Info("Stringify values in data") + if err := props.secretDecryptedData.StringifyValues(); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + logger.Info("Converting secret data to map") + outData, outDataErr := props.secretDecryptedData.ToStringMap() + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + if props.properties.EncryptionKey == nil { + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("EncryptionKey must be set for PARAMETER_MULTI") + } + logger.Info("Writing secret data to parameter store") + for key, value := range outData { + // As we flatten array to [number] path notations, we have to fix this for parameter store + fixedKey := strings.ReplaceAll(key, "[", seperator) + fixedKey = strings.ReplaceAll(fixedKey, "]", seperator) + fixedKey = strings.TrimSuffix(fixedKey, seperator) + fixedKey = strings.ReplaceAll(fixedKey, seperator+seperator, seperator) + // The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@- + allowedChars := "/_+=.@-" + for i, char := range fixedKey { + if !(char >= 'a' && char <= 'z') && !(char >= 'A' && char <= 'Z') && !(char >= '0' && char <= '9') && !strings.ContainsRune(allowedChars, char) { + fixedKey = fixedKey[:i] + "_" + fixedKey[i+1:] + } + } + // Prefix with Target + fixedKey = props.properties.Target + fixedKey + // FixValue (can't be empty) + if len(value) == 0 { + value = []byte("") + } + _, err := props.clients.SsmPutParameter(fixedKey, &value, *props.properties.EncryptionKey) + if err != nil { + logger.Error("Failed to write parameter", "Parameter", fixedKey, "Error", err) + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) + } + logger.Info("Parameter written", "Parameter", fixedKey) + } + + logger.Info("Secret data updated", "ARN", props.properties.GeneratePhysicalResourceId()) + + return props.properties.GeneratePhysicalResourceId(), map[string]interface{}{ + "Prefix": props.properties.Target, + "Count": len(outData), + }, nil +} + +func handleParameter(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleParameter") + logger.Info("Getting raw secret data") + outData, outDataErr := props.secretDecryptedData.GetRaw() + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + if props.properties.EncryptionKey == nil { + return "", nil, fmt.Errorf("EncryptionKey must be set for PARAMETER") + } + putParameterResponse, putParameterResponseErr := props.clients.SsmPutParameter(props.properties.Target, outData, *props.properties.EncryptionKey) + if putParameterResponseErr != nil { + logger.Error("Failed to write parameter", "Parameter", props.properties.Target, "Error", putParameterResponseErr) + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", putParameterResponseErr) + } + logger.Info("Parameter written", "Parameter", props.properties.Target) + + logger.Info("Secret data updated", "ARN", props.properties.GeneratePhysicalResourceId()) + return props.properties.GeneratePhysicalResourceId(), map[string]interface{}{ + "ParameterName": props.properties.Target, + "Version": putParameterResponse.Version, + "Tier": putParameterResponse.Tier, + }, nil +} diff --git a/lambda/handler_common_test.go b/lambda/handler_common_test.go deleted file mode 100644 index f099b424..00000000 --- a/lambda/handler_common_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Delete(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_delete.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_parameter_raw_test.go b/lambda/handler_parameter_raw_test.go deleted file mode 100644 index f168a0be..00000000 --- a/lambda/handler_parameter_raw_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_Parameter_RAW_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_raw_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_parameter_yaml_multi_test.go b/lambda/handler_parameter_yaml_multi_test.go deleted file mode 100644 index 96b54b50..00000000 --- a/lambda/handler_parameter_yaml_multi_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_yaml_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_yaml_complex_custom_keys.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_env_test.go b/lambda/handler_secret_env_test.go deleted file mode 100644 index 2a960979..00000000 --- a/lambda/handler_secret_env_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_ENV_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_env_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_env_as_json_simple.json") - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_json_test.go b/lambda/handler_secret_json_test.go deleted file mode 100644 index bfae4a2d..00000000 --- a/lambda/handler_secret_json_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_stringify.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} -func Test_FullWorkflow_Create_S3_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_stringify.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} -func Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_raw_test.go b/lambda/handler_secret_raw_test.go deleted file mode 100644 index a6bb8559..00000000 --- a/lambda/handler_secret_raw_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_RAW_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_raw_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_yaml_test.go b/lambda/handler_secret_yaml_test.go deleted file mode 100644 index 4a6be298..00000000 --- a/lambda/handler_secret_yaml_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_YAML_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/internal/client/__snapshots__/s3_get_object.snap b/lambda/internal/client/__snapshots__/s3_get_object.snap new file mode 100755 index 00000000..712694b4 --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object.snap @@ -0,0 +1,27 @@ + +[TestS3GetObject - 1] +&s3.GetObjectInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ChecksumMode: "", + ExpectedBucketOwner: (*string)(nil), + IfMatch: (*string)(nil), + IfModifiedSince: (*time.Time)(nil), + IfNoneMatch: (*string)(nil), + IfUnmodifiedSince: (*time.Time)(nil), + PartNumber: (*int32)(nil), + Range: (*string)(nil), + RequestPayer: "", + ResponseCacheControl: (*string)(nil), + ResponseContentDisposition: (*string)(nil), + ResponseContentEncoding: (*string)(nil), + ResponseContentLanguage: (*string)(nil), + ResponseContentType: (*string)(nil), + ResponseExpires: (*time.Time)(nil), + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_etag.snap b/lambda/internal/client/__snapshots__/s3_get_object_etag.snap new file mode 100755 index 00000000..f09de08f --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_etag.snap @@ -0,0 +1,17 @@ + +[TestS3GetObjectETAG - 1] +&s3.GetObjectAttributesInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ObjectAttributes: {"ETag"}, + ExpectedBucketOwner: (*string)(nil), + MaxParts: (*int32)(nil), + PartNumberMarker: (*string)(nil), + RequestPayer: "", + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap b/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap new file mode 100755 index 00000000..f09de08f --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap @@ -0,0 +1,17 @@ + +[TestS3GetObjectETAG - 1] +&s3.GetObjectAttributesInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ObjectAttributes: {"ETag"}, + ExpectedBucketOwner: (*string)(nil), + MaxParts: (*int32)(nil), + PartNumberMarker: (*string)(nil), + RequestPayer: "", + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap b/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap new file mode 100755 index 00000000..712694b4 --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap @@ -0,0 +1,27 @@ + +[TestS3GetObject - 1] +&s3.GetObjectInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ChecksumMode: "", + ExpectedBucketOwner: (*string)(nil), + IfMatch: (*string)(nil), + IfModifiedSince: (*time.Time)(nil), + IfNoneMatch: (*string)(nil), + IfUnmodifiedSince: (*time.Time)(nil), + PartNumber: (*int32)(nil), + Range: (*string)(nil), + RequestPayer: "", + ResponseCacheControl: (*string)(nil), + ResponseContentDisposition: (*string)(nil), + ResponseContentEncoding: (*string)(nil), + ResponseContentLanguage: (*string)(nil), + ResponseContentType: (*string)(nil), + ResponseExpires: (*time.Time)(nil), + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap b/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap new file mode 100755 index 00000000..e169f774 --- /dev/null +++ b/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap @@ -0,0 +1,12 @@ + +[TestSecretsManagerPutSecretValue - 1] +&secretsmanager.PutSecretValueInput{ + SecretId: &"arn", + ClientRequestToken: &"hash", + RotationToken: (*string)(nil), + SecretBinary: nil, + SecretString: &"content", + VersionStages: nil, + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap b/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap new file mode 100755 index 00000000..9e392c3a --- /dev/null +++ b/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap @@ -0,0 +1,34 @@ + +[TestSsmUpdateUpdateParameter - 1] +&ssm.PutParameterInput{ + Name: &"parameter", + Value: &"content", + AllowedPattern: (*string)(nil), + DataType: (*string)(nil), + Description: (*string)(nil), + KeyId: &"key", + Overwrite: &bool(true), + Policies: (*string)(nil), + Tags: nil, + Tier: "", + Type: "SecureString", + noSmithyDocumentSerde: document.NoSerde{}, +} +--- + +[TestSsmPutParameter - 1] +&ssm.PutParameterInput{ + Name: &"parameter", + Value: &"content", + AllowedPattern: (*string)(nil), + DataType: (*string)(nil), + Description: (*string)(nil), + KeyId: &"key", + Overwrite: &bool(true), + Policies: (*string)(nil), + Tags: nil, + Tier: "", + Type: "SecureString", + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/client.go b/lambda/internal/client/client.go new file mode 100644 index 00000000..c4b8040f --- /dev/null +++ b/lambda/internal/client/client.go @@ -0,0 +1,136 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "log" + "log/slog" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/retry" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/s3" + s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" +) + +type S3Client interface { + GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) + GetObjectAttributes(ctx context.Context, params *s3.GetObjectAttributesInput, optFns ...func(*s3.Options)) (*s3.GetObjectAttributesOutput, error) +} + +type SecretsManagerClient interface { + PutSecretValue(ctx context.Context, params *secretsmanager.PutSecretValueInput, optFns ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) +} + +type SsmClient interface { + PutParameter(ctx context.Context, params *ssm.PutParameterInput, optFns ...func(*ssm.Options)) (*ssm.PutParameterOutput, error) +} + +type AwsClient interface { + S3GetObject(file SopsS3File) (data []byte, err error) + S3GetObjectETAG(file SopsS3File) (*string, error) + SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte, binary *bool) (data *secretsmanager.PutSecretValueOutput, err error) + SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (response *ssm.PutParameterOutput, err error) +} + +type Client struct { + ctx context.Context + s3 S3Client + secretsManager SecretsManagerClient + ssm SsmClient +} + +func CreateAwsClients(context context.Context) AwsClient { + cfg, err := config.LoadDefaultConfig(context, config.WithRetryer(func() aws.Retryer { + return retry.AddWithMaxAttempts(retry.NewStandard(), 5) + })) + if err != nil { + log.Fatalf("unable to load SDK config, %v", err) + } + return &Client{ + ctx: context, + s3: s3.NewFromConfig(cfg), + secretsManager: secretsmanager.NewFromConfig(cfg), + ssm: ssm.NewFromConfig(cfg), + } +} + +type SopsS3File struct { + Bucket string `json:"Bucket,omitempty"` + Key string `json:"Key,omitempty"` +} + +func (c *Client) S3GetObject(file SopsS3File) (data []byte, err error) { + logger := slog.With("Package", "client", "Function", "S3GetObject") + logger.Info("Downloading file", "Bucket", file.Bucket, "Key", file.Key) + + resp, err := c.s3.GetObject(c.ctx, &s3.GetObjectInput{ + Bucket: &file.Bucket, + Key: &file.Key, + }) + if err != nil { + return nil, fmt.Errorf("S3 get object error:\n%v", err) + } + defer resp.Body.Close() + + buf := new(bytes.Buffer) + _, err = buf.ReadFrom(resp.Body) + if err != nil { + return nil, fmt.Errorf("read buffer error:\n%v", err) + } + logger.Info("Downloaded file", "Size", buf.Len()) + return buf.Bytes(), nil +} + +func (c *Client) S3GetObjectETAG(file SopsS3File) (*string, error) { + attr, err := c.s3.GetObjectAttributes(c.ctx, &s3.GetObjectAttributesInput{ + Bucket: &file.Bucket, + Key: &file.Key, + ObjectAttributes: []s3Types.ObjectAttributes{ + "ETag", + }, + }) + + if err != nil { + return nil, fmt.Errorf("error while getting S3 object attributes:\n%v", err) + } + + if attr.ETag == nil { + return nil, fmt.Errorf("no ETag checksum found in S3 object:\n%v", err) + } + + return attr.ETag, nil +} + +func (c *Client) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretStringData *[]byte, binary *bool) (data *secretsmanager.PutSecretValueOutput, err error) { + if binary != nil && *binary { + input := &secretsmanager.PutSecretValueInput{ + SecretId: &secretArn, + SecretBinary: *secretStringData, + ClientRequestToken: &sopsHash, + } + return c.secretsManager.PutSecretValue(c.ctx, input) + } + input := &secretsmanager.PutSecretValueInput{ + SecretId: &secretArn, + SecretString: aws.String(string(*secretStringData)), + ClientRequestToken: &sopsHash, + } + return c.secretsManager.PutSecretValue(c.ctx, input) +} + +func (c *Client) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (response *ssm.PutParameterOutput, err error) { + parameterContentString := string(*parameterContent) + input := &ssm.PutParameterInput{ + Name: ¶meterName, + Value: ¶meterContentString, + Type: ssmTypes.ParameterTypeSecureString, + Overwrite: aws.Bool(true), + KeyId: &keyId, + } + return c.ssm.PutParameter(c.ctx, input) +} diff --git a/lambda/internal/client/client_test.go b/lambda/internal/client/client_test.go new file mode 100644 index 00000000..53db1aa8 --- /dev/null +++ b/lambda/internal/client/client_test.go @@ -0,0 +1,232 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "io" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/aws/smithy-go/ptr" + "github.com/stretchr/testify/assert" +) + +func TestS3GetObject(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedData []byte + expectedErrMsg string + }{ + { + name: "successful get object", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object", + GetObjectRet: &s3.GetObjectOutput{ + Body: io.NopCloser(bytes.NewReader([]byte("mock content"))), + }, + ReturnError: nil, + }, + expectedData: []byte("mock content"), + }, + { + name: "get object error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_error", + GetObjectRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + expectedErrMsg: "S3 get object error:\nmock error", + }, + { + name: "reader body error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_reader_error", + GetObjectRet: &s3.GetObjectOutput{ + Body: io.NopCloser(&mockErrorReader{}), + }, + ReturnError: nil, + }, + expectedErrMsg: "read buffer error:\nmock read error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + s3: tt.mockClient, + } + + data, err := client.S3GetObject(SopsS3File{Bucket: "test-bucket", Key: "test-key"}) + if tt.expectedErrMsg != "" { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.expectedErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedData, data) + } + }) + } +} + +func TestS3GetObjectETAG(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedETAG *string + expectedErrMsg string + }{ + { + name: "successful get object etag", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_etag", + GetObjectAttributesRet: &s3.GetObjectAttributesOutput{ + ETag: aws.String("mock-etag"), + }, + ReturnError: nil, + }, + expectedETAG: aws.String("mock-etag"), + }, + { + name: "get object attributes error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_attributes_error", + GetObjectAttributesRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + expectedErrMsg: "error while getting S3 object attributes:\nmock error", + }, + { + name: "etag not found", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_etag_not_found", + GetObjectAttributesRet: &s3.GetObjectAttributesOutput{ + ETag: nil, + }, + ReturnError: nil, + }, + expectedErrMsg: "no ETag checksum found in S3 object:\n", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + s3: tt.mockClient, + } + + etag, err := client.S3GetObjectETAG(SopsS3File{Bucket: "test-bucket", Key: "test-key"}) + if tt.expectedErrMsg != "" { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.expectedErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedETAG, etag) + } + }) + } +} + +func TestSecretsManagerPutSecretValue(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedARN *string + expectedErrMsg string + binary *bool + }{ + { + name: "successful put secret value", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "secrets_manager_put_secret_value", + PutSecretValueRet: &secretsmanager.PutSecretValueOutput{ + ARN: aws.String("mock-arn"), + }, + ReturnError: nil, + }, + binary: ptr.Bool(false), + expectedARN: aws.String("mock-arn"), + }, + { + name: "put secret value error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "secrets_manager_put_secret_value_error", + PutSecretValueRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + binary: ptr.Bool(false), + expectedErrMsg: "failed to store secret value:\nsecretArn: test-arn\nClientRequestToken: test-hash\nmock error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + secretsManager: tt.mockClient, + } + + content := []byte("content") + resp, err := client.SecretsManagerPutSecretValue("hash", "arn", &content, tt.binary) + assert.Equal(t, tt.mockClient.ReturnError, err) + assert.Equal(t, tt.mockClient.PutSecretValueRet, resp) + }) + } +} + +func TestSsmPutParameter(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedVersion *int64 + expectedErrMsg string + }{ + { + name: "successful update parameter", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "ssm_update_update_parameter", + PutParameterRet: &ssm.PutParameterOutput{ + Version: *aws.Int64(1), + }, + ReturnError: nil, + }, + }, + { + name: "update parameter error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "ssm_update_update_parameter_error", + PutParameterRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + ssm: tt.mockClient, + } + content := []byte("content") + resp, err := client.SsmPutParameter("parameter", &content, "key") + assert.Equal(t, tt.mockClient.ReturnError, err) + assert.Equal(t, tt.mockClient.PutParameterRet, resp) + }) + } +} diff --git a/lambda/internal/client/mock.go b/lambda/internal/client/mock.go new file mode 100644 index 00000000..89ec3d92 --- /dev/null +++ b/lambda/internal/client/mock.go @@ -0,0 +1,81 @@ +package client + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/gkampitakis/go-snaps/snaps" +) + +type mockErrorReader struct{} + +func (r *mockErrorReader) Read(p []byte) (n int, err error) { + return 0, fmt.Errorf("mock read error") +} + +// MockAwsClient is a mock for the real AWS client +type MockAwsClient struct { + t *testing.T + snapsFileName string + ReturnError error + GetObjectRet *s3.GetObjectOutput + GetObjectAttributesRet *s3.GetObjectAttributesOutput + PutParameterRet *ssm.PutParameterOutput + PutSecretValueRet *secretsmanager.PutSecretValueOutput +} + +func (s *MockAwsClient) GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.GetObjectRet, s.ReturnError +} + +func (s *MockAwsClient) GetObjectAttributes(ctx context.Context, params *s3.GetObjectAttributesInput, optFns ...func(*s3.Options)) (*s3.GetObjectAttributesOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.GetObjectAttributesRet, s.ReturnError +} + +func (s *MockAwsClient) PutParameter(ctx context.Context, params *ssm.PutParameterInput, optFns ...func(*ssm.Options)) (*ssm.PutParameterOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.PutParameterRet, s.ReturnError +} + +func (s *MockAwsClient) PutSecretValue(ctx context.Context, params *secretsmanager.PutSecretValueInput, optFns ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.PutSecretValueRet, s.ReturnError +} + +// MockClient is a mock for "our" AWS client +type MockClient struct { + S3Content []byte + S3Etag string + S3Err error + S3EtagErr error +} + +func (m *MockClient) S3GetObject(file SopsS3File) ([]byte, error) { + return m.S3Content, m.S3Err +} + +func (m *MockClient) S3GetObjectETAG(file SopsS3File) (*string, error) { + return &m.S3Etag, m.S3EtagErr +} + +func (m *MockClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (*secretsmanager.PutSecretValueOutput, error) { + return nil, nil +} + +func (m *MockClient) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (*ssm.PutParameterOutput, error) { + return nil, nil +} diff --git a/lambda/internal/data/__snapshots__/1.simple.flatten.snap b/lambda/internal/data/__snapshots__/1.simple.flatten.snap new file mode 100755 index 00000000..e98a4ff9 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.flatten.snap @@ -0,0 +1,12 @@ + +[Test_Flatten/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.fromJson.snap b/lambda/internal/data/__snapshots__/1.simple.fromJson.snap new file mode 100755 index 00000000..3906e71e --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.fromJson.snap @@ -0,0 +1,12 @@ + +[Test_FromJSON/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x7b, 0xa, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x7d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap b/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap new file mode 100755 index 00000000..be426370 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap @@ -0,0 +1,12 @@ + +[Test_FromYAML/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.stringify.snap b/lambda/internal/data/__snapshots__/1.simple.stringify.snap new file mode 100755 index 00000000..d20f9162 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.stringify.snap @@ -0,0 +1,12 @@ + +[Test_Stringify/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toJson.snap b/lambda/internal/data/__snapshots__/1.simple.toJson.snap new file mode 100755 index 00000000..27892f2d --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toJson.snap @@ -0,0 +1,8 @@ + +[Test_ToJSON/1.simple - 1] +{ + "bool": true, + "number": 1.1, + "string": "examplestring" +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap b/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap new file mode 100755 index 00000000..ff867a39 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap @@ -0,0 +1,8 @@ + +[Test_ToStringMap/1.simple - 1] +map[string][]uint8{ + "bool": {0x74, 0x72, 0x75, 0x65}, + "number": {0x31, 0x2e, 0x31}, + "string": {0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67}, +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toYaml.snap b/lambda/internal/data/__snapshots__/1.simple.toYaml.snap new file mode 100755 index 00000000..b530a2a5 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toYaml.snap @@ -0,0 +1,7 @@ + +[Test_ToYAML/1.simple - 1] +bool: true +number: 1.1 +string: examplestring + +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.flatten.snap b/lambda/internal/data/__snapshots__/2.nested.flatten.snap new file mode 100755 index 00000000..0c4d7caf --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.flatten.snap @@ -0,0 +1,15 @@ + +[Test_Flatten/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested.bool": bool(true), + "nested.number": float64(1.1), + "nested.string": "examplestring", + "number": float64(1.1), + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.fromJson.snap b/lambda/internal/data/__snapshots__/2.nested.fromJson.snap new file mode 100755 index 00000000..429561de --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.fromJson.snap @@ -0,0 +1,17 @@ + +[Test_FromJSON/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested": map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x7b, 0xa, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x7d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap b/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap new file mode 100755 index 00000000..06907f87 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap @@ -0,0 +1,17 @@ + +[Test_FromYAML/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested": map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.stringify.snap b/lambda/internal/data/__snapshots__/2.nested.stringify.snap new file mode 100755 index 00000000..7678d147 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.stringify.snap @@ -0,0 +1,17 @@ + +[Test_Stringify/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": "true", + "nested": map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + "number": "1.1", + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.toJson.snap b/lambda/internal/data/__snapshots__/2.nested.toJson.snap new file mode 100755 index 00000000..8dc44f67 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.toJson.snap @@ -0,0 +1,13 @@ + +[Test_ToJSON/2.nested - 1] +{ + "bool": true, + "nested": { + "bool": true, + "number": 1.1, + "string": "examplestring" + }, + "number": 1.1, + "string": "examplestring" +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.toYaml.snap b/lambda/internal/data/__snapshots__/2.nested.toYaml.snap new file mode 100755 index 00000000..ccf4fb7a --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.toYaml.snap @@ -0,0 +1,11 @@ + +[Test_ToYAML/2.nested - 1] +bool: true +nested: + bool: true + number: 1.1 + string: examplestring +number: 1.1 +string: examplestring + +--- diff --git a/lambda/internal/data/__snapshots__/3.array.flatten.snap b/lambda/internal/data/__snapshots__/3.array.flatten.snap new file mode 100755 index 00000000..8bb596b8 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.flatten.snap @@ -0,0 +1,15 @@ + +[Test_Flatten/3.array - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "[0].bool": bool(true), + "[0].number": float64(1.1), + "[0].string": "examplestring", + "[1].bool": bool(true), + "[1].number": float64(1.1), + "[1].string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.fromJson.snap b/lambda/internal/data/__snapshots__/3.array.fromJson.snap new file mode 100755 index 00000000..9e92db61 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.fromJson.snap @@ -0,0 +1,19 @@ + +[Test_FromJSON/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + }, + raw: &[]uint8{0x5b, 0xa, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0x2c, 0xa, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0xa, 0x5d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.fromYaml.snap b/lambda/internal/data/__snapshots__/3.array.fromYaml.snap new file mode 100755 index 00000000..1779f97f --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.fromYaml.snap @@ -0,0 +1,19 @@ + +[Test_FromYAML/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + }, + raw: &[]uint8{0x2d, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0x2d, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.stringify.snap b/lambda/internal/data/__snapshots__/3.array.stringify.snap new file mode 100755 index 00000000..a4f9a598 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.stringify.snap @@ -0,0 +1,19 @@ + +[Test_Stringify/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.toJson.snap b/lambda/internal/data/__snapshots__/3.array.toJson.snap new file mode 100755 index 00000000..97532691 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.toJson.snap @@ -0,0 +1,15 @@ + +[Test_ToJSON/3.array - 1] +[ + { + "bool": true, + "number": 1.1, + "string": "examplestring" + }, + { + "bool": true, + "number": 1.1, + "string": "examplestring" + } +] +--- diff --git a/lambda/internal/data/__snapshots__/3.array.toYaml.snap b/lambda/internal/data/__snapshots__/3.array.toYaml.snap new file mode 100755 index 00000000..bdf39d0f --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.toYaml.snap @@ -0,0 +1,10 @@ + +[Test_ToYAML/3.array - 1] +- bool: true + number: 1.1 + string: examplestring +- bool: true + number: 1.1 + string: examplestring + +--- diff --git a/lambda/internal/data/data.go b/lambda/internal/data/data.go new file mode 100644 index 00000000..7fef47c0 --- /dev/null +++ b/lambda/internal/data/data.go @@ -0,0 +1,288 @@ +package data + +import ( + "encoding/json" + "fmt" + "reflect" + "slices" + "strings" + + "gopkg.in/yaml.v3" +) + +type Data struct { + parsed *any + raw *[]byte + Hash *string +} + +var ( + ErrorUnparsedData = fmt.Errorf("Data does not contain parsed data") +) + +// FromBinary creates a Data object from a binary formatted byte slice. +// It stores the binary content in the raw field of the Data object without parsing it. +func FromBinary(in []byte, hash *string) (*Data, error) { + return &Data{ + raw: &in, + Hash: hash, + }, nil +} + +// Parse from yaml formatted byte slice into a map and stores it in the parsed field of the Data object. +func FromYAML(in []byte, hash *string) (*Data, error) { + var content any + err := yaml.Unmarshal(in, &content) + if err != nil { + return nil, err + } + return &Data{ + parsed: &content, + raw: &in, + Hash: hash, + }, nil +} + +// Parse from json formatted byte slice into a map and stores it in the parsed field of the Data object. +func FromJSON(in []byte, hash *string) (*Data, error) { + var content any + err := json.Unmarshal(in, &content) + if err != nil { + return nil, err + } + return &Data{ + parsed: &content, + raw: &in, + Hash: hash, + }, nil +} + +// Parse from dotenv formatted byte slice into a map and stores it in the parsed field of the Data object. +func FromDotEnv(in []byte, hash *string) (*Data, error) { + var dotEnvMap any = map[string]string{} + dotenvLines := strings.Split(string(in), "\n") + for _, line := range dotenvLines { + // Ignore empty lines and comments + if line != "" && !strings.HasPrefix(line, "#") { + // Split the line into key and value + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 { + key := strings.TrimSpace(parts[0]) + value := strings.TrimSpace(parts[1]) + // Add the key-value pair to the map + dotEnvMap.(map[string]string)[key] = value + } + } + } + return &Data{ + parsed: &dotEnvMap, + raw: &in, + Hash: hash, + }, nil +} + +func (d *Data) ToJSON() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + content := *d.parsed + ret, err := json.MarshalIndent(content, "", " ") + if err != nil { + return nil, err + } + return &ret, nil +} + +func (d *Data) ToYAML() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + ret, err := yaml.Marshal(d.parsed) + if err != nil { + return nil, err + } + return &ret, nil +} + +func (d *Data) ToDotEnv() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + stringMap, err := d.ToStringMap() + if err != nil { + return nil, err + } + var sb strings.Builder + for k, v := range stringMap { + sb.WriteString(fmt.Sprintf("%s=%s\n", k, v)) + } + ret := []byte(sb.String()) + return &ret, nil +} + +func (d *Data) ToStringMap() (map[string][]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + if result, ok := (*d.parsed).(map[string]interface{}); ok { + stringMap := make(map[string][]byte) + keys := make([]string, 0, len(result)) + for k := range result { + keys = append(keys, k) + } + slices.Sort(keys) + for _, k := range keys { + switch result[k].(type) { + case string, float32, float64, int, int32, int64, uint, uint32, uint64, bool, []byte: + stringMap[k] = []byte(fmt.Sprintf("%v", result[k])) + default: + return nil, fmt.Errorf(`value for key %s is a complex type (map or slice), maybe run "Flatten" first`, k) + } + } + return stringMap, nil + } + return nil, fmt.Errorf("parsed data is not a map[string]interface{}") +} + +func (d *Data) GetRaw() (*[]byte, error) { + if d.raw == nil { + return nil, ErrorUnparsedData + } + return d.raw, nil +} + +func (d *Data) StringifyValues() error { + if d.parsed == nil { + return ErrorUnparsedData + } + stringified, err := stringifyValues(*d.parsed) + if err != nil { + return err + } + d.parsed = &stringified + return nil +} + +func (d *Data) Flatten(separator string) error { + if d.parsed == nil { + return ErrorUnparsedData + } + output := make(map[string]interface{}) + err := flatten("", *d.parsed, output, separator) + if err != nil { + return err + } + var content interface{} = output + d.parsed = &content + return nil +} + +func (d *Data) stripEmptyKey() error { + if d.parsed == nil { + return ErrorUnparsedData + } + if parsedMap, ok := (*d.parsed).(map[string]interface{}); ok { + if val, exists := parsedMap[""]; exists && len(parsedMap) == 1 { + if nestedMap, ok := val.(map[string]interface{}); ok { + var nestedAny any = nestedMap + d.parsed = &nestedAny + } + } + } + return nil +} + +// stringifyValues recursively stringifies primitive values in complex types +func stringifyValues(input any) (any, error) { + // Get the type of the input + v := reflect.ValueOf(input) + + // If the value is a pointer, dereference it to get the actual value + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + // Handle based on the kind of the value + switch v.Kind() { + case reflect.Map: + // If it's a map, iterate through the map and recursively stringify the values + output := make(map[string]interface{}) + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + strVal, err := stringifyValues(val.Interface()) + if err != nil { + return nil, err + } + output[key.String()] = strVal + } + return output, nil + case reflect.Array, reflect.Slice: + // If it's a slice or array, recursively stringify each element + output := []interface{}{} + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + strElem, err := stringifyValues(elem.Interface()) + if err != nil { + return nil, err + } + output = append(output, strElem) + } + return output, nil + case reflect.Struct: + // If it's a struct, iterate through its fields and recursively stringify them + output := make(map[string]interface{}) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + strField, err := stringifyValues(field.Interface()) + if err != nil { + return nil, err + } + output[v.Type().Field(i).Name] = strField + } + return output, nil + case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64, reflect.Bool, reflect.Complex64, reflect.Complex128: + // If it's a primitive type, convert it to a string + return fmt.Sprintf("%v", input), nil + case reflect.Invalid: + return "", nil + default: + // If it's an unsupported type, return an error + return nil, fmt.Errorf("unsupported type: %v", v.Kind()) + } +} + +func flatten(parentKey string, input any, output map[string]interface{}, separator string) error { + v := reflect.ValueOf(input) + + // If the value is a pointer, dereference it to get the actual value + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Map: + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + newKey := key.String() + if parentKey != "" { + newKey = parentKey + separator + newKey + } + if err := flatten(newKey, val.Interface(), output, separator); err != nil { + return err + } + } + case reflect.Slice, reflect.Array: + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + newKey := fmt.Sprintf("%s[%d]", parentKey, i) + if err := flatten(newKey, elem.Interface(), output, separator); err != nil { + return err + } + } + default: + output[parentKey] = input + } + return nil +} diff --git a/lambda/internal/data/data_test.go b/lambda/internal/data/data_test.go new file mode 100644 index 00000000..d4b149d0 --- /dev/null +++ b/lambda/internal/data/data_test.go @@ -0,0 +1,274 @@ +package data + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/gkampitakis/go-snaps/snaps" +) + +var testData = map[string]interface{}{ + "1.simple": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + "2.nested": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + "nested": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + }, + "3.array": []interface{}{ + map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + }, +} + +func read(filename string) ([]byte, error) { + filePath := "__snapshots__/" + filename + existingContent, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + lines := bytes.Split(existingContent, []byte("\n")) + if len(lines) > 2 { + existingContent = bytes.Join(lines[2:len(lines)-2], []byte("\n")) + } + return existingContent, nil +} + +func Test_ToJSON(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + jsonData, err := data.ToJSON() + if err != nil { + t.Errorf("ToJson() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toJson"), + ).MatchSnapshot(t, string(*jsonData)) + }) + } +} + +func Test_ToJSON_fail(t *testing.T) { + data := &Data{} + _, err := data.ToJSON() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_ToYAML(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + jsonData, err := data.ToYAML() + if err != nil { + t.Errorf("toYAML() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toYaml"), + ).MatchSnapshot(t, string(*jsonData)) + }) + } +} + +func Test_ToYAML_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_ToStringMap(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + stringMap, err := data.ToStringMap() + + if tName == "3.array" { + errExp := fmt.Errorf("parsed data is not a map[string]interface{}") + if err.Error() != errExp.Error() { + t.Errorf("Expected error %v, got %v", errExp, err) + } + return + } + if tName == "2.nested" { + errExp := fmt.Errorf(`value for key nested is a complex type (map or slice), maybe run "Flatten" first`) + if err.Error() != errExp.Error() { + t.Errorf("Expected error %v, got %v", errExp, err) + } + return + } + if err != nil { + t.Errorf("ToStringMap() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toStringMap"), + ).MatchSnapshot(t, stringMap) + }) + } +} + +func Test_FromJSON(t *testing.T) { + for tName := range testData { + t.Run(tName, func(t *testing.T) { + jsonData, err := read(tName + ".toJson.snap") + if err != nil { + t.Errorf("Read() error = %v", err) + return + } + data, err := FromJSON(jsonData, nil) + if err != nil { + t.Errorf("FromJSON() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".fromJson"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_FromYAML(t *testing.T) { + for tName := range testData { + t.Run(tName, func(t *testing.T) { + jsonData, err := read(tName + ".toYaml.snap") + if err != nil { + t.Errorf("Read() error = %v", err) + return + } + data, err := FromYAML(jsonData, nil) + if err != nil { + t.Errorf("FromYAML() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".fromYaml"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_FromDotEnv(t *testing.T) { + dotEnvData := []byte(` + # This is a comment + STRING=examplestring + NUMBER=1.1 + BOOL=true + NESTED_STRING=examplestring + NESTED_NUMBER=1.1 + NESTED_BOOL=true + `) + + expectedData := map[string]string{ + "STRING": "examplestring", + "NUMBER": "1.1", + "BOOL": "true", + "NESTED_STRING": "examplestring", + "NESTED_NUMBER": "1.1", + "NESTED_BOOL": "true", + } + + data, err := FromDotEnv(dotEnvData, nil) + if err != nil { + t.Errorf("FromDotEnv() error = %v", err) + return + } + + if data.parsed == nil { + t.Errorf("FromDotEnv() parsed data is nil") + return + } + + parsedData, ok := (*data.parsed).(map[string]string) + if !ok { + t.Errorf("FromDotEnv() parsed data is not of type map[string]string") + return + } + + for key, expectedValue := range expectedData { + if parsedValue, exists := parsedData[key]; !exists || parsedValue != expectedValue { + t.Errorf("FromDotEnv() key %s: expected %s, got %s", key, expectedValue, parsedValue) + } + } +} + +func Test_Stringify(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + err := data.StringifyValues() + if err != nil { + t.Errorf("StringifyValues() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".stringify"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_Stringify_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_Flatten(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + err := data.Flatten(".") + if err != nil { + t.Errorf("Flatten() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".flatten"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_Flatten_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} diff --git a/lambda/internal/event/__snapshots__/invalid_empty.json.snap b/lambda/internal/event/__snapshots__/invalid_empty.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/invalid_empty.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap b/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap new file mode 100755 index 00000000..ddc10087 --- /dev/null +++ b/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[] +--- diff --git a/lambda/internal/event/__snapshots__/valid_full.json.snap b/lambda/internal/event/__snapshots__/valid_full.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_full.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/valid_full.json_err.snap b/lambda/internal/event/__snapshots__/valid_full.json_err.snap new file mode 100755 index 00000000..d70e1d43 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_full.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[EncryptionKey:string Flatten:false FlattenSeparator:string Format:json OutputFormat:json ParameterKeyPrefix:string ParameterName:string ResourceType:SECRET SecretARN:string SopsInline:map[Content:string Hash:string] SopsS3File:map[Bucket:string Key:string] StringifyValues:false] +--- diff --git a/lambda/internal/event/__snapshots__/valid_minimal.json.snap b/lambda/internal/event/__snapshots__/valid_minimal.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_minimal.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap b/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap new file mode 100755 index 00000000..6f80e85d --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[Flatten:false FlattenSeparator: Format:yaml OutputFormat:json ResourceType:SECRET StringifyValues:false] +--- diff --git a/lambda/internal/event/config-schema.json b/lambda/internal/event/config-schema.json new file mode 100644 index 00000000..209c6d78 --- /dev/null +++ b/lambda/internal/event/config-schema.json @@ -0,0 +1,84 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "SopsSyncResourcePropertys", + "$defs": { + "SopsInline": { + "properties": { + "Content": { + "type": "string" + }, + "Hash": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Content", + "Hash" + ] + }, + "SopsS3File": { + "properties": { + "Bucket": { + "type": "string" + }, + "Key": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Bucket", + "Key" + ] + } + }, + "properties": { + "ResourceType": { + "type": "string", + "enum": [ + "SECRET", + "SECRET_RAW", + "SECRET_BINARY", + "PARAMETER_MULTI", + "PARAMETER" + ] + }, + "Format": { + "type": "string", + "enum": [ + "json", + "yaml", + "dotenv", + "binary" + ] + }, + "Target": { + "type": "string" + }, + "EncryptionKey": { + "type": "string" + }, + "SopsS3File": { + "$ref": "#/$defs/SopsS3File" + }, + "SopsInline": { + "$ref": "#/$defs/SopsInline" + }, + "FlattenSeparator": { + "type": "string" + }, + "ServiceToken": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ResourceType", + "Format", + "Target" + ] +} \ No newline at end of file diff --git a/lambda/internal/event/event.go b/lambda/internal/event/event.go new file mode 100644 index 00000000..a6d1f002 --- /dev/null +++ b/lambda/internal/event/event.go @@ -0,0 +1,193 @@ +package event + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "log" + "log/slog" + "os" + "strings" + + _ "embed" + + "github.com/aws/aws-lambda-go/cfn" + jsonSchemaGen "github.com/invopop/jsonschema" + jsonSchemaValidate "github.com/kaptinlin/jsonschema" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/sops" +) + +//go:embed config-schema.json +var configSchema []byte + +type SopsS3File struct { + Bucket string `json:"Bucket"` + Key string `json:"Key"` +} + +func (s *SopsS3File) IsEmpty() bool { + return s == nil || (s.Bucket == "" && s.Key == "") +} + +type SopsInline struct { + Content string `json:"Content"` + Hash string `json:"Hash"` +} + +func (s *SopsInline) IsEmpty() bool { + return s == nil || (s.Content == "" && s.Hash == "") +} + +type ResourceType string + +const ( + // Secret, flattened and stringified + SECRET ResourceType = "SECRET" + // Secret, just the raw value stored as binary + SECRET_RAW ResourceType = "SECRET_RAW" + // Secret, just the raw value stored as binary + SECRET_BINARY ResourceType = "SECRET_BINARY" + // The JSON object is flattened into multiple parameters + PARAMETER_MULTI ResourceType = "PARAMETER_MULTI" + // The raw value is stored as Parameter + PARAMETER ResourceType = "PARAMETER" +) + +type SopsSyncResourcePropertys struct { + ResourceType ResourceType `json:"ResourceType" jsonschema:"enum=SECRET,enum=SECRET_RAW,enum=SECRET_BINARY,enum=PARAMETER_MULTI,enum=PARAMETER"` + Format sops.Format `json:"Format" jsonschema:"enum=json,enum=yaml,enum=dotenv,enum=binary"` + Target string `json:"Target"` + EncryptionKey *string `json:"EncryptionKey,omitempty"` + SopsS3File *SopsS3File `json:"SopsS3File,omitempty"` + SopsInline *SopsInline `json:"SopsInline,omitempty"` + FlattenSeparator *string `json:"FlattenSeparator,omitempty"` + // ServiceToken is the ARN of the service token that was passed to the custom resource + // Populated by the CloudFormation + ServiceToken *string `json:"ServiceToken,omitempty"` +} + +func FromCfnEvent(event cfn.Event) (*SopsSyncResourcePropertys, error) { + logger := slog.With("Package", "event", "Function", "FromCfnEvent") + compiler := jsonSchemaValidate.NewCompiler() + schema, err := compiler.Compile(configSchema) + if err != nil { + logger.Error("Failed to compile schema", "Error", err) + } + + slog.Debug("FromCfnEvent", "Event", event) + + result := schema.Validate(event.ResourceProperties) + if !result.IsValid() { + // Sort the details by evaluationPath + logger.Info("Invalid ResourceProperties", "EvaluationResult", result) + return nil, fmt.Errorf("invalid resource properties (more details in log):\n%v", event.ResourceProperties) + } + + var props SopsSyncResourcePropertys + data, err := json.Marshal(event.ResourceProperties) + if err != nil { + return nil, fmt.Errorf("failed to marshal resource properties: %v", err) + } + + err = json.Unmarshal(data, &props) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal resource properties: %v", err) + } + + return &props, nil +} + +func (p *SopsSyncResourcePropertys) GeneratePhysicalResourceId() string { + return fmt.Sprintf("%s:%s:%s", "arn:custom:sopssync:", p.ResourceType, p.Target) +} + +func (p *SopsSyncResourcePropertys) sopsInlineToSopsEncryptedSecret() (*sops.EncryptedSopsSecret, error) { + // Read the encrypted secret content from inline + content, contentErr := base64.StdEncoding.DecodeString(p.SopsInline.Content) + if contentErr != nil { + return nil, contentErr + } + // Generate a uniform EncryptedSopsSecret object from the content for later use + return sops.CreateEncryptedSopsSecret(content, p.Format, p.SopsInline.Hash) +} + +func (p *SopsSyncResourcePropertys) sopsS3FileToSopsEncryptedSecret(clients client.AwsClient) (*sops.EncryptedSopsSecret, error) { + // Read the encrypted secret content from S3 + s3File := client.SopsS3File{ + Bucket: p.SopsS3File.Bucket, + Key: p.SopsS3File.Key, + } + s3Content, s3ContentErr := clients.S3GetObject(s3File) + if s3ContentErr != nil { + return nil, s3ContentErr + } + + // Get the Hash of the S3 object to compare it later + s3Etag, s3EtagErr := clients.S3GetObjectETAG(s3File) + if s3EtagErr != nil { + return nil, s3EtagErr + } + + // Generate a uniform EncryptedSopsSecret object from the content for later use + return sops.CreateEncryptedSopsSecret(s3Content, p.Format, *s3Etag) +} + +func (p *SopsSyncResourcePropertys) GetEncryptedSopsSecret(client client.AwsClient) (*sops.EncryptedSopsSecret, error) { + // Find out from where to get the secret content + if !p.SopsInline.IsEmpty() && !p.SopsS3File.IsEmpty() { + return nil, fmt.Errorf("both inline and S3 secret content found") + } + if !p.SopsInline.IsEmpty() { + return p.sopsInlineToSopsEncryptedSecret() + } + if !p.SopsS3File.IsEmpty() { + return p.sopsS3FileToSopsEncryptedSecret(client) + } + return nil, fmt.Errorf("no secret content found") +} + +// generates a JSON schema for the SopsSyncResourcePropertys struct +func GenerateSchema() { + schema := jsonSchemaGen.Reflect(&SopsSyncResourcePropertys{}) + + parts := strings.Split(schema.Ref, "/") + resourceName := parts[len(parts)-1] + schema.Properties = schema.Definitions[resourceName].Properties + schema.AdditionalProperties = schema.Definitions[resourceName].AdditionalProperties + schema.Type = schema.Definitions[resourceName].Type + schema.Required = schema.Definitions[resourceName].Required + delete(schema.Definitions, resourceName) + schema.Ref = "" + schema.ID = "SopsSyncResourcePropertys" + schemaJSON, err := schema.MarshalJSON() + if err != nil { + log.Fatalf("Error marshaling JSON schema: %v", err) + } + + var prettyJSON bytes.Buffer + + err = json.Indent(&prettyJSON, schemaJSON, "", " ") + if err != nil { + log.Fatalf("Error indenting JSON schema: %v", err) + } + + schemaJSON = prettyJSON.Bytes() + if err != nil { + log.Fatalf("Error generating JSON schema: %v", err) + } + + file, err := os.Create("config-schema.json") + if err != nil { + log.Fatalf("Error creating schema file: %v", err) + } + defer file.Close() + + _, err = file.Write(schemaJSON) + if err != nil { + log.Fatalf("Error writing JSON schema to file: %v", err) + } + + log.Printf("Generated JSON schema") +} diff --git a/lambda/internal/event/event_test.go b/lambda/internal/event/event_test.go new file mode 100644 index 00000000..9c497d77 --- /dev/null +++ b/lambda/internal/event/event_test.go @@ -0,0 +1,43 @@ +package event + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/aws/aws-lambda-go/cfn" + "github.com/gkampitakis/go-snaps/snaps" + "github.com/stretchr/testify/assert" +) + +func TestGenerateSchema(t *testing.T) { + GenerateSchema() +} + +func createTestSchema(t *testing.T, filename string) cfn.Event { + file, err := os.Open("testdata/" + filename) + assert.NoError(t, err) + defer file.Close() + var i map[string]interface{} + err = json.NewDecoder(file).Decode(&i) + assert.NoError(t, err) + return cfn.Event{ + ResourceProperties: i, + } +} + +func TestFromCfnEvent(t *testing.T) { + tests := []string{ + "valid_minimal.json", + "valid_full.json", + "invalid_empty.json", + } + + for _, test := range tests { + mockEvent := createTestSchema(t, test) + props, err := FromCfnEvent(mockEvent) + snaps.WithConfig(snaps.Filename(test)).MatchSnapshot(t, props) + snaps.WithConfig(snaps.Filename(test+"_err")).MatchSnapshot(t, fmt.Sprintf("%v", err)) + } +} diff --git a/lambda/internal/event/testdata/invalid_empty.json b/lambda/internal/event/testdata/invalid_empty.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/lambda/internal/event/testdata/invalid_empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/lambda/internal/event/testdata/valid_full.json b/lambda/internal/event/testdata/valid_full.json new file mode 100644 index 00000000..61eb1bbc --- /dev/null +++ b/lambda/internal/event/testdata/valid_full.json @@ -0,0 +1,20 @@ +{ + "OutputFormat": "json", + "EncryptionKey": "string", + "Flatten": false, + "FlattenSeparator": "string", + "Format": "json", + "ParameterKeyPrefix": "string", + "ParameterName": "string", + "ResourceType": "SECRET", + "SecretARN": "string", + "SopsInline": { + "Content": "string", + "Hash": "string" + }, + "SopsS3File": { + "Bucket": "string", + "Key": "string" + }, + "StringifyValues": false +} \ No newline at end of file diff --git a/lambda/internal/event/testdata/valid_minimal.json b/lambda/internal/event/testdata/valid_minimal.json new file mode 100644 index 00000000..e8034cc6 --- /dev/null +++ b/lambda/internal/event/testdata/valid_minimal.json @@ -0,0 +1,8 @@ +{ + "OutputFormat": "json", + "Flatten": false, + "FlattenSeparator": "", + "Format": "yaml", + "ResourceType": "SECRET", + "StringifyValues": false +} \ No newline at end of file diff --git a/lambda/internal/sops/__snapshots__/README.sops.binary.snap b/lambda/internal/sops/__snapshots__/README.sops.binary.snap new file mode 100755 index 00000000..f1db1e0b --- /dev/null +++ b/lambda/internal/sops/__snapshots__/README.sops.binary.snap @@ -0,0 +1,14 @@ + +[TestDecrypt/README.sops.binary - 1] +# SOPS files for testing purpose + +The sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information. + +The following keys were used: + +```yaml +public: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu +private: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3 +``` + +--- diff --git a/lambda/internal/sops/__snapshots__/sops_test.snap b/lambda/internal/sops/__snapshots__/sops_test.snap new file mode 100755 index 00000000..f6a5f3f1 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/sops_test.snap @@ -0,0 +1,44 @@ + +[TestToData/Test_JSON_ToData - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "key": "value", + }, + raw: &[]uint8{0x7b, 0x22, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7d}, + Hash: &"", +} +--- + +[TestToData/Test_YAML_ToData - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "key": "value", + }, + raw: &[]uint8{0x6b, 0x65, 0x79, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65}, + Hash: &"", +} +--- + +[TestToData/Test_DotEnv_ToData - 1] +&data.Data{ + parsed: &map[string]string{"KEY":"value"}, + raw: &[]uint8{0x4b, 0x45, 0x59, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65}, + Hash: &"", +} +--- + +[TestToData/Test_Binary_ToData - 1] +&data.Data{ + parsed: (*interface {})(nil), + raw: &[]uint8{0x0, 0x1, 0x2, 0x3}, + Hash: &"", +} +--- + +[TestCreateEncryptedSopsSecret/Valid_JSON_Secret - 1] +&sops.EncryptedSopsSecret{ + Content: {0x7b, 0x22, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7d}, + Format: "json", + Hash: "somehash", +} +--- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap new file mode 100755 index 00000000..cdf6b030 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap @@ -0,0 +1,21 @@ + +[TestDecrypt/testsecret.sops.env - 1] +apiKey=sk-1234567890abcdef +database:host=db.example.com +database:password=P@ssw0rd! +database:user=admin +someOtherKey=base64:aGFsbG8gd2VsdAo= +specific:boolean=True +specific:SpecialCharacters="ajkscbuiuXA34%%&&= +specific:HTLMEncodingTest3=@ +specific:HTMLEncodingTest1=test +specific:HTMLEncodingTest2=& +specific:null= +specific:number1=123 +specific:number2=123.456 +tokens:0:service=service1 +tokens:0:token=token1 +tokens:1:service=service2 +tokens:1:token=token2 + +--- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap new file mode 100755 index 00000000..0d253c3a --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap @@ -0,0 +1,32 @@ + +[TestDecrypt/testsecret.sops.json - 1] +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "host": "db.example.com", + "password": "P@ssw0rd!", + "user": "admin" + }, + "someOtherKey": "base64:aGFsbG8gd2VsdAo=", + "specific": { + "HTLMEncodingTest3": "@", + "HTMLEncodingTest1": "test ", + "HTMLEncodingTest2": "&", + "SpecialCharacters": "\"ajkscbuiuXA34%%&&=", + "boolean": true, + "null": null, + "number1": 123, + "number2": 123.456 + }, + "tokens": [ + { + "service": "service1", + "token": "token1" + }, + { + "service": "service2", + "token": "token2" + } + ] +} +--- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap new file mode 100755 index 00000000..043e7346 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap @@ -0,0 +1,24 @@ + +[TestDecrypt/testsecret.sops.yaml - 1] +apiKey: sk-1234567890abcdef +database: + user: admin + password: P@ssw0rd! + host: db.example.com +tokens: + - service: service1 + token: token1 + - service: service2 + token: token2 +someOtherKey: base64:aGFsbG8gd2VsdAo= +specific: + SpecialCharacters: '"ajkscbuiuXA34%%&&=' + HTMLEncodingTest1: test + HTMLEncodingTest2: '&' + HTLMEncodingTest3: '@' + "null": null + boolean: true + number1: 123 + number2: 123.456 + +--- diff --git a/lambda/internal/sops/sops.go b/lambda/internal/sops/sops.go new file mode 100644 index 00000000..455e2bc2 --- /dev/null +++ b/lambda/internal/sops/sops.go @@ -0,0 +1,110 @@ +package sops + +import ( + "bytes" + "encoding/json" + "fmt" + "log/slog" + + "github.com/getsops/sops/v3/decrypt" + "github.com/markussiebert/cdk-sops-secrets/internal/data" +) + +type Format string + +const ( + JSON Format = "json" + YAML Format = "yaml" + DOTENV Format = "dotenv" + BINARY Format = "binary" +) + +type EncryptedSopsSecret struct { + Content []byte + Format Format + Hash string +} + +func CreateEncryptedSopsSecret(content []byte, format Format, hash string) (*EncryptedSopsSecret, error) { + if len(content) == 0 { + return nil, fmt.Errorf("content cannot be empty") + } + if format == "" { + return nil, fmt.Errorf("format cannot be empty") + } + if hash == "" { + return nil, fmt.Errorf("hash cannot be empty") + } + return &EncryptedSopsSecret{ + Content: content, + Format: format, + Hash: hash, + }, nil +} + +type DecryptedSopsSecret struct { + content []byte + format Format + hash string +} + +func (e EncryptedSopsSecret) Decrypt() (*DecryptedSopsSecret, error) { + // Create a logger with context information + logger := slog.With("Package", "sops", "Function", "Decrypt") + logger.Info("Decrypting content", "Format", e.Format) + + // Decrypt the content using the specified format + cleartext, err := decrypt.Data(e.Content, string(e.Format)) + if err != nil { + return nil, fmt.Errorf("decryption error:\n%v", err) + } + logger.Info("Decryption successful") + + // If the format is JSON, process the cleartext to ensure proper formatting + if e.Format == JSON { + var jsonObj interface{} + var buf bytes.Buffer + + // Unmarshal the JSON content into an interface + err := json.Unmarshal(cleartext, &jsonObj) + if err != nil { + return nil, fmt.Errorf("decoding error:\n%v", err) + } + + // Create a JSON encoder with specific settings + encoder := json.NewEncoder(&buf) + encoder.SetEscapeHTML(false) + encoder.SetIndent("", " ") // tab inside + + // Encode the JSON object back into bytes + err = encoder.Encode(jsonObj) + if err != nil { + return nil, fmt.Errorf("encoding error:\n%v", err) + } + + // Trim any extra whitespace from the encoded JSON + cleartext = bytes.TrimSpace(buf.Bytes()) + } + + return &DecryptedSopsSecret{ + content: cleartext, + format: e.Format, + hash: e.Hash, + }, nil +} + +func (d DecryptedSopsSecret) ToData() (*data.Data, error) { + // Generate a data object by parsing the decrypted secret depending on the data input type + switch d.format { + case JSON: + return data.FromJSON(d.content, &d.hash) + case YAML: + return data.FromYAML(d.content, &d.hash) + case DOTENV: + return data.FromDotEnv(d.content, &d.hash) + case BINARY: + return data.FromBinary(d.content, &d.hash) + default: + return nil, fmt.Errorf("unsupported format %s", d.format) + } +} diff --git a/lambda/internal/sops/sops_test.go b/lambda/internal/sops/sops_test.go new file mode 100644 index 00000000..c1d2a4d3 --- /dev/null +++ b/lambda/internal/sops/sops_test.go @@ -0,0 +1,149 @@ +package sops + +import ( + "os" + "testing" + + "github.com/gkampitakis/go-snaps/snaps" +) + +func read(filename string) ([]byte, error) { + filePath := "../../../test-secrets/" + filename + existingContent, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + return existingContent, nil +} + +func TestDecrypt(t *testing.T) { + tests := map[Format]string{ + BINARY: "README.sops.binary", + DOTENV: "testsecret.sops.env", + JSON: "testsecret.sops.json", + YAML: "testsecret.sops.yaml", + } + + t.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + + for format, file := range tests { + t.Run(file, func(t *testing.T) { + + content, err := read(file) + + if err != nil { + t.Fatalf("Failed to read file: %v", err) + } + + encryptedSecret := EncryptedSopsSecret{ + Content: content, + Format: format, + } + + decryptedSecret, err := encryptedSecret.Decrypt() + if err != nil { + t.Fatalf("Failed to decrypt: %v", err) + } + + snaps.WithConfig( + snaps.Filename(file), + ).MatchSnapshot(t, string(decryptedSecret.content)) + }) + } +} + +func TestToData(t *testing.T) { + tests := []struct { + name string + content []byte + format Format + }{ + { + name: "Test JSON ToData", + content: []byte(`{"key": "value"}`), + format: JSON, + }, + { + name: "Test YAML ToData", + content: []byte(`key: value`), + format: YAML, + }, + { + name: "Test DotEnv ToData", + content: []byte(`KEY=value`), + format: DOTENV, + }, + { + name: "Test Binary ToData", + content: []byte{0x00, 0x01, 0x02, 0x03}, + format: BINARY, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + decryptedSecret := DecryptedSopsSecret{ + content: tt.content, + format: tt.format, + } + + data, err := decryptedSecret.ToData() + if err != nil { + t.Fatalf("Failed to convert to data: %v", err) + } + + snaps.MatchSnapshot(t, data) + }) + } +} + +func TestCreateEncryptedSopsSecret(t *testing.T) { + tests := []struct { + name string + content []byte + format Format + hash string + wantErr bool + }{ + { + name: "Valid JSON Secret", + content: []byte(`{"key": "value"}`), + format: JSON, + hash: "somehash", + wantErr: false, + }, + { + name: "Empty Content", + content: []byte{}, + format: JSON, + hash: "somehash", + wantErr: true, + }, + { + name: "Empty Format", + content: []byte(`{"key": "value"}`), + format: "", + hash: "somehash", + wantErr: true, + }, + { + name: "Empty Hash", + content: []byte(`{"key": "value"}`), + format: JSON, + hash: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encryptedSecret, err := CreateEncryptedSopsSecret(tt.content, tt.format, tt.hash) + if (err != nil) != tt.wantErr { + t.Fatalf("CreateEncryptedSopsSecret() error = %v, wantErr %v", err, tt.wantErr) + } + if err == nil { + snaps.MatchSnapshot(t, encryptedSecret) + } + }) + } +} diff --git a/lambda/main.go b/lambda/main.go index 5ab7fd30..27db6196 100644 --- a/lambda/main.go +++ b/lambda/main.go @@ -2,477 +2,79 @@ package main import ( "context" - "encoding/base64" - "encoding/json" "fmt" - "log" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - - runtime "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/aws/aws-sdk-go/service/s3/s3iface" - "github.com/aws/aws-sdk-go/service/s3/s3manager" - "github.com/aws/aws-sdk-go/service/s3/s3manager/s3manageriface" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - "github.com/getsops/sops/v3/decrypt" - "gopkg.in/yaml.v3" + "log/slog" "github.com/aws/aws-lambda-go/cfn" + runtime "github.com/aws/aws-lambda-go/lambda" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/event" ) -type SopsS3File struct { - Bucket string `json:"Bucket,omitempty"` - Key string `json:"Key,omitempty"` -} - -type SopsInline struct { - Content string `json:"Content,omitempty"` - Hash string `json:"Hash,omitempty"` -} -type SopsSyncResourcePropertys struct { - SecretARN string `json:"SecretARN,omitempty"` - ParameterName string `json:"ParameterName,omitempty"` - EncryptionKey string `json:"EncryptionKey,omitempty"` - SopsS3File SopsS3File `json:"SopsS3File,omitempty"` - SopsInline SopsInline `json:"SopsInline,omitempty"` - Format string `json:"Format"` - ConvertToJSON string `json:"ConvertToJSON,omitempty"` - Flatten string `json:"Flatten,omitempty"` - FlattenSeparator string `json:"FlattenSeparator,omitempty"` - ParameterKeyPrefix string `json:"ParameterKeyPrefix,omitempty"` - StringifyValues string `json:"StringifyValues,omitempty"` - ResourceType string `json:"ResourceType,omitempty"` -} - -type AWS struct { - secretsmanager secretsmanageriface.SecretsManagerAPI - ssm ssmiface.SSMAPI - s3Downloader s3manageriface.DownloaderAPI - s3Api s3iface.S3API -} +func HandleRequestWithClients(clients client.AwsClient, e cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "HandleRequestWithClients") + logger.Debug("Incoming Event", "Event", e) -func (a AWS) getS3FileContent(file SopsS3File) (data []byte, err error) { - log.Printf("Downloading file '%s' from bucket '%s'\n", file.Key, file.Bucket) - buf := aws.NewWriteAtBuffer([]byte{}) - resp, err := a.s3Downloader.Download(buf, &s3.GetObjectInput{ - Bucket: &file.Bucket, - Key: &file.Key, - }) - if err != nil { - return nil, fmt.Errorf("S3 download error:\n%v", err) + // If it's a delete request, we don't have to do anything + if e.RequestType == cfn.RequestDelete { + return "", nil, nil + } + // We have to run this code only, if it is a CloudFormation Create or Update request + if e.RequestType != cfn.RequestCreate && e.RequestType != cfn.RequestUpdate { + return "", nil, fmt.Errorf("requestType '%s' not supported", e.RequestType) } - log.Printf("Downloaded %d bytes", resp) - return buf.Bytes(), nil -} -func decryptSopsFileContent(content []byte, format string) (data []byte, err error) { - log.Printf("Decrypting content with format %s\n", format) - resp, err := decrypt.Data(content, format) + // Get the event input from the cloudformation event + props, err := event.FromCfnEvent(e) if err != nil { - return nil, fmt.Errorf("decryption error:\n%v", err) + return "", nil, err } - log.Println("Decrypted") - return resp, nil -} -func (a AWS) updateSecret(sopsHash string, secretArn string, secretContent []byte) (data *secretsmanager.PutSecretValueOutput, err error) { - secretContentString := string(secretContent) - input := &secretsmanager.PutSecretValueInput{ - SecretId: &secretArn, - SecretString: &secretContentString, - ClientRequestToken: &sopsHash, + // Get the encrypted secret input provided by the user + secretEncrypted, secretEncryptedErr := props.GetEncryptedSopsSecret(clients) + if secretEncryptedErr != nil { + return "", nil, secretEncryptedErr } - secretResp, secretErr := a.secretsmanager.PutSecretValue(input) - if secretErr != nil { - return nil, fmt.Errorf("failed to store secret value:\nsecretArn: %s\nClientRequestToken: %s\n%v", secretArn, sopsHash, secretErr) - } - arn := generatePhysicalResourceId(*secretResp.ARN) - secretResp.ARN = &arn - log.Printf("Succesfully stored secret:\n%v\n", secretResp) - return secretResp, nil -} -func (a AWS) updateSSMParameter(parameterName string, parameterContent []byte, keyId string) (response *ssm.PutParameterOutput, err error) { - parameterContentString := string(parameterContent) - input := &ssm.PutParameterInput{ - Name: ¶meterName, - Value: ¶meterContentString, - Type: aws.String("SecureString"), - Overwrite: aws.Bool(true), - KeyId: &keyId, + // Decrypt the secret input with sops + secretDecrypted, secretDecryptedErr := secretEncrypted.Decrypt() + if secretDecryptedErr != nil { + return "", nil, secretDecryptedErr } - paramResp, paramErr := a.ssm.PutParameter(input) - if paramErr != nil { - return nil, fmt.Errorf("failed to store parameter value:\nparameterName: %s\n%v", parameterName, paramErr) - } - log.Printf("Successfully stored parameter:\n%v\n", paramResp) - return paramResp, nil -} - -func generatePhysicalResourceId(input string) string { - re := regexp.MustCompile(`(^arn:.*:secretsmanager:|ssm:)(.*)`) - return re.ReplaceAllString(input, `arn:custom:sopssync:$2`) -} - -func (a AWS) syncSopsToSecretsmanager(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { - // event - // eventJson, _ := json.MarshalIndent(event, "", " ") - // log.Printf("Function invoked with:\n %s", eventJson) - - if event.RequestType == cfn.RequestCreate || event.RequestType == cfn.RequestUpdate { - // some casting - - jsonResourceProps, err := json.Marshal(event.ResourceProperties) - if err != nil { - return "error", nil, err - } - - resourceProperties := SopsSyncResourcePropertys{} - if err := json.Unmarshal(jsonResourceProps, &resourceProperties); err != nil { - return "", nil, err - } - - tempArn := generatePhysicalResourceId(resourceProperties.SecretARN + resourceProperties.ParameterName) - - sopsFile := resourceProperties.SopsS3File - sopsInline := resourceProperties.SopsInline - - var encryptedContent []byte - var sopsHash string - - // If SopsS3File is provided, we have to download this file - if sopsFile != (SopsS3File{}) { - attr, err := a.s3Api.GetObjectAttributes(&s3.GetObjectAttributesInput{ - Bucket: &sopsFile.Bucket, - Key: &sopsFile.Key, - ObjectAttributes: []*string{ - aws.String("ETag"), - }, - }) - if err != nil { - return tempArn, nil, fmt.Errorf("error while getting S3 object attributes:\n%v", err) - } - encryptedContent, err = a.getS3FileContent(sopsFile) - if err != nil { - return tempArn, nil, fmt.Errorf("error while getting S3 file content:\n%v", err) - } - if attr.ETag == nil { - return tempArn, nil, fmt.Errorf("no ETag checksum found in S3 object:\n%v", err) - } - sopsHash = *attr.ETag - } - - // If SopsInline is provided, we have to base64 decode this content - if sopsInline != (SopsInline{}) { - encryptedContent, err = base64.StdEncoding.DecodeString(sopsInline.Content) - sopsHash = sopsInline.Hash - if err != nil { - return tempArn, nil, err - } - } - - if encryptedContent == nil { - return tempArn, nil, fmt.Errorf("no encrypted content found! Did you pass SopsS3File or SopsInline:\n%v", err) - } - if sopsHash == "" { - return tempArn, nil, fmt.Errorf("no sopsHash found! Did you pass SopsS3File or SopsInline:\n%v", err) - } - - decryptedContent, err := decryptSopsFileContent(encryptedContent, resourceProperties.Format) - if err != nil { - return tempArn, nil, fmt.Errorf("error while decrypting file content\n%v", err) - } - var decryptedInterface interface{} - switch resourceProperties.Format { - case "json": - { - err := json.Unmarshal(decryptedContent, &decryptedInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse json content:\n%v", err) - } - } - case "yaml": - { - err := yaml.Unmarshal(decryptedContent, &decryptedInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse yaml content:\n%v", err) - } - } - case "dotenv": - { - var dotEnvMap = make(map[string]string) - dotenvLines := strings.Split(string(decryptedContent), "\n") - for _, line := range dotenvLines { - if line != "" && !strings.HasPrefix(line, "#") { - parts := strings.SplitN(line, "=", 2) - if len(parts) == 2 { - key := strings.TrimSpace(parts[0]) - value := strings.TrimSpace(parts[1]) - dotEnvMap[key] = value - } - } - } - decryptedInterface = dotEnvMap - resourceProperties.Flatten = "false" - resourceProperties.StringifyValues = "false" - } - case "binary": - { - resourceProperties.Flatten = "false" - resourceProperties.StringifyValues = "false" - resourceProperties.ConvertToJSON = "false" - } - default: - return "", nil, fmt.Errorf("format %s not supported", resourceProperties.Format) - } - if resourceProperties.Flatten == "" { - resourceProperties.Flatten = "true" - } - resourcePropertiesFlatten, err := strconv.ParseBool(resourceProperties.Flatten) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - - var finalInterface interface{} - if resourcePropertiesFlatten { - flattenedInterface := make(map[string]interface{}) - err := flatten("", decryptedInterface, flattenedInterface, resourceProperties.FlattenSeparator) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to flatten:\n%v", err) - } - finalInterface = flattenedInterface - } else { - finalInterface = decryptedInterface - } - - if resourceProperties.StringifyValues == "" { - resourceProperties.StringifyValues = "true" - } - resourcePropertiesStringifyValues, err := strconv.ParseBool(resourceProperties.StringifyValues) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - if resourcePropertiesStringifyValues { - finalInterface, _, err = stringifyValues(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to stringify values:\n%v", err) - } - } - - if resourceProperties.ConvertToJSON == "" { - resourceProperties.ConvertToJSON = "true" - } - resourcePropertieConvertToJSON, err := strconv.ParseBool(resourceProperties.ConvertToJSON) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - if resourcePropertieConvertToJSON || resourceProperties.Format == "json" { - decryptedContent, err = toJSON(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to convert to JSON:\n%v", err) - } - } else if resourceProperties.Format == "yaml" { - decryptedContent, err = toYAML(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to convert to YAML:\n%v", err) - } - } - - if resourceProperties.ResourceType == "SECRET" { - updateSecretResp, err := a.updateSecret(sopsHash, resourceProperties.SecretARN, decryptedContent) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update secret:\n%v", err) - } - returnData := make(map[string]interface{}) - returnData["ARN"] = *updateSecretResp.ARN - returnData["Name"] = *updateSecretResp.Name - returnData["VersionStages"] = updateSecretResp.VersionStages - returnData["VersionId"] = *updateSecretResp.VersionId - return *updateSecretResp.ARN, returnData, nil - } else if resourceProperties.ResourceType == "PARAMETER_MULTI" { - log.Printf("Patching multiple string parameters") - v := reflect.ValueOf(finalInterface) - returnData := make(map[string]interface{}) - keys := v.MapKeys() - keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) } - sort.Slice(keys, keysOrder) - for _, key := range keys { - strKey := resourceProperties.ParameterKeyPrefix + key.String() - log.Printf("Parameter: " + strKey) - value := v.MapIndex(key).Interface() - strValue, ok := value.(string) - if !ok { - return tempArn, nil, nil - } - _, err := a.updateSSMParameter(strKey, []byte(strValue), resourceProperties.EncryptionKey) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) - } - // A returnData map for each parameter is not created, because it would limit the number of possible parameters unnecessarily - } - returnData["Prefix"] = resourceProperties.ParameterKeyPrefix - returnData["Count"] = len(keys) - return tempArn, returnData, nil - } else if resourceProperties.ResourceType == "PARAMETER" { - log.Printf("Patching single string parameter") - response, err := a.updateSSMParameter(resourceProperties.ParameterName, decryptedContent, resourceProperties.EncryptionKey) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) - } - returnData := make(map[string]interface{}) - returnData["ParameterName"] = resourceProperties.ParameterName - returnData["Version"] = response.Version - returnData["Tier"] = response.Tier - return tempArn, returnData, nil - } else { - // Should never happen ... - return tempArn, nil, fmt.Errorf("neither SecretARN nor ParameterName is provided:\n%v", err) - } - } else if event.RequestType == cfn.RequestDelete { - return "", nil, nil - } else { - return "", nil, fmt.Errorf("requestType '%s' not supported", event.RequestType) + // Generate a data object by parsing the decrypted secret depending on the data input type + secretDecryptedData, secretDecryptedDataErr := secretDecrypted.ToData() + if secretDecryptedDataErr != nil { + return "", nil, secretDecryptedDataErr } -} - -func handleRequest(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { - awsSession := session.New() - a := &AWS{ - secretsmanager: secretsmanager.New(awsSession), - ssm: ssm.New(awsSession), - s3Downloader: s3manager.NewDownloader(awsSession), - s3Api: s3.New(awsSession), - } - return a.syncSopsToSecretsmanager(ctx, event) -} -func main() { - runtime.Start(cfn.LambdaWrap(handleRequest)) -} - -func fromYAML(in []byte) (interface{}, error) { - var ret interface{} - err := yaml.Unmarshal(in, &ret) - if err != nil { - return nil, err + baseProps := BaseProps{ + properties: props, + clients: clients, + secretDecryptedData: secretDecryptedData, } - return ret, nil -} -func fromJSON(in []byte) (interface{}, error) { - var ret interface{} - err := json.Unmarshal(in, &ret) - if err != nil { - return nil, err - } - return ret, nil -} - -func toJSON(in any) ([]byte, error) { - ret, err := json.MarshalIndent(in, "", " ") - if err != nil { - return nil, err + // Fill the secret values in the ressource depending on the ressource type + switch props.ResourceType { + case event.SECRET, event.SECRET_RAW, event.SECRET_BINARY: + return handleSecret(baseProps) + case event.PARAMETER_MULTI: + return handleParameterMulti(baseProps) + case event.PARAMETER: + return handleParameter(baseProps) + default: + return "", nil, fmt.Errorf("unsupported resource type %s", props.ResourceType) } - return ret, nil } -func toYAML(in any) ([]byte, error) { - ret, err := yaml.Marshal(in) - if err != nil { - return nil, err - } - return ret, nil -} +// Just a Wrapper function to allow injecting clients for testing +func HandleRequest(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { -func stringifyValues(input any) (interface{}, string, error) { - switch child := input.(type) { - case map[string]interface{}: - { - output := make(map[string]interface{}) - for k, v := range child { - object, val, err := stringifyValues(v) - if err != nil { - return nil, "", err - } - if object != nil { - output[k] = object - } else { - output[k] = val - } - } - return output, "", nil - } - case []interface{}: - { - output := []interface{}{} - for _, v := range child { - object, val, err := stringifyValues(v) - if err != nil { - return nil, "", err - } - if object != nil { - output = append(output, object) - } else { - output = append(output, val) - } - } - return output, "", nil - } - default: - { - return nil, fmt.Sprint(input), nil - } - } -} + clients := client.CreateAwsClients(ctx) -func flatten(parentkey string, input any, output map[string]interface{}, separator string) error { - switch child := input.(type) { - case map[string]interface{}: - { - for k, v := range child { - if parentkey == "" { - flatten(k, v, output, separator) - } else { - flatten(fmt.Sprintf("%s%s%s", parentkey, separator, k), v, output, separator) - } - } - } - case []interface{}: - { - for i, v := range child { - if parentkey == "" { - flatten(fmt.Sprintf("[%d]", i), v, output, separator) - } else { - flatten(fmt.Sprintf("%s[%d]", parentkey, i), v, output, separator) - } - } - } - default: - { - output[parentkey] = input - } - } - return nil + return HandleRequestWithClients(clients, event) } -func toSopsSyncResourcePropertys(input *map[string]interface{}) (*SopsSyncResourcePropertys, error) { - jsonResourceProps, err := json.Marshal(&input) - if err != nil { - return nil, err - } - resourceProperties := SopsSyncResourcePropertys{} - if err := json.Unmarshal(jsonResourceProps, &resourceProperties); err != nil { - return nil, err - } - return &resourceProperties, nil +func main() { + runtime.Start(cfn.LambdaWrap(HandleRequest)) } diff --git a/lambda/main_integration_test.go b/lambda/main_integration_test.go new file mode 100644 index 00000000..56d63209 --- /dev/null +++ b/lambda/main_integration_test.go @@ -0,0 +1,401 @@ +package main + +import ( + "context" + "encoding/json" + "os" + "slices" + "strings" + "testing" + "time" + + "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/gkampitakis/go-snaps/snaps" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/stretchr/testify/assert" +) + +func prepareUploadS3(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + sopsS3File := resourceProps["SopsS3File"].(map[string]interface{}) + + s3Key := sopsS3File["Key"].(string) + s3Bucket := sopsS3File["Bucket"].(string) + localFile := "../" + s3Key + + file, err := os.Open(localFile) + if err != nil { + t.Errorf("failed to open file: %v", err) + } + defer file.Close() + + s3Client := s3.NewFromConfig(cfg) + _, err = s3Client.PutObject(context.Background(), &s3.PutObjectInput{ + Bucket: &s3Bucket, + Key: &s3Key, + Body: file, + }) + + if err != nil { + t.Errorf("failed to upload file to S3: %v", err) + } +} + +func prepareSecret(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" && ResourceType != "SECRET_RAW" { + return + } + + secretValue := "empty" + + _, err = secretsManagerClient.CreateSecret(context.Background(), &secretsmanager.CreateSecretInput{ + Name: &secretName, + SecretString: &secretValue, + }) + + if err != nil { + t.Logf("failed to create secret: %v", err) + } +} + +func cleanupSecret(t *testing.T, resourceProps map[string]interface{}) { + + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" && ResourceType != "SECRET_RAW" { + return + } + + forceDelete := true + + _, err = secretsManagerClient.DeleteSecret(context.Background(), &secretsmanager.DeleteSecretInput{ + SecretId: &secretName, + ForceDeleteWithoutRecovery: &forceDelete, + }) + + if err != nil { + t.Logf("failed to delete secret: %v", err) + } +} + +func snapshotSecret(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_RAW" && ResourceType != "SECRET_BINARY" { + return + } + + resp, err := secretsManagerClient.GetSecretValue(context.Background(), &secretsmanager.GetSecretValueInput{ + SecretId: &secretName, + }) + snaps.WithConfig(snaps.Filename(t.Name())).MatchSnapshot(t, resp.Name, resp.SecretBinary, resp.SecretString) + + if err != nil { + t.Logf("failed to snapshot secret: %v", err) + } +} + +func cleanupParameter(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + ssmClient := ssm.NewFromConfig(cfg) + parameterNames := []string{} + parameterName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType == "PARAMETER_MULTI" { + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + t.Errorf("failed to describe parameters: %v", err) + return + } + for _, param := range output.Parameters { + if strings.HasPrefix(*param.Name, parameterName) { + parameterNames = append(parameterNames, *param.Name) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } + } else if ResourceType == "PARAMETER" { + parameterNames = append(parameterNames, parameterName) + } else { + t.Logf("unknown resource type: %s", ResourceType) + return + } + + for _, p := range parameterNames { + t.Logf("deleting parameter %s", p) + _, err = ssmClient.DeleteParameter(context.Background(), &ssm.DeleteParameterInput{ + Name: &p, + }) + if err != nil { + t.Logf("failed to delete parameter: %v", err) + } + } +} + +func snapshotParameter(t *testing.T, resourceProps map[string]interface{}) { + + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + ssmClient := ssm.NewFromConfig(cfg) + parameterNames := []string{} + parameterName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType == "PARAMETER_MULTI" { + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + t.Errorf("failed to describe parameters: %v", err) + return + } + for _, param := range output.Parameters { + if strings.HasPrefix(*param.Name, parameterName) { + parameterNames = append(parameterNames, *param.Name) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } + } else if ResourceType == "PARAMETER" { + parameterNames = append(parameterNames, parameterName) + } else { + t.Logf("unknown resource type: %s", ResourceType) + return + } + + for _, p := range parameterNames { + t.Logf("snapshotting parameter %s", p) + resp, err := ssmClient.GetParameter(context.Background(), &ssm.GetParameterInput{ + Name: &p, + WithDecryption: aws.Bool(true), + }) + snaps.WithConfig(snaps.Filename(t.Name())).MatchSnapshot(t, resp.Parameter.Name, resp.Parameter.Value) + if err != nil { + t.Logf("failed to snapshot parameter: %v", err) + } + } + +} + +func TestIntegration_HandleRequestWithClients(t *testing.T) { + if os.Getenv("GITHUB_REPOSITORY") != "" { + t.Skip("Skipping test in GitHub Actions environment") + } + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") + os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } + + var tests []struct { + name string + event cfn.Event + } + + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + tests = append(tests, struct { + name string + event cfn.Event + }{ + name: file.Name(), + event: cfn.Event{ + RequestType: cfn.RequestCreate, + ResourceProperties: resourceProperties, + }, + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + prepareUploadS3(t, tt.event.ResourceProperties) + prepareSecret(t, tt.event.ResourceProperties) + + clients := client.CreateAwsClients(context.Background()) + + physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) + + snapshotSecret(t, tt.event.ResourceProperties) + snapshotParameter(t, tt.event.ResourceProperties) + + assert.NoError(t, err) + assert.NotEmpty(t, physicalResourceID) + assert.NotNil(t, data) + }) + } +} + +func TestIntegration_Cleanup(t *testing.T) { + if os.Getenv("GITHUB_REPOSITORY") != "" { + t.Skip("Skipping test in GitHub Actions environment") + } + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") + + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } + + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + t.Run(file.Name(), func(t *testing.T) { + + cleanupSecret(t, resourceProperties) + cleanupParameter(t, resourceProperties) + + }) + } +} + +func Test_CleanUpHard(t *testing.T) { + t.Skip("Skipping cleanup") + deleteAllSecrets() + deleteAllParametersExcept([]string{"/cdk-bootstrap/hnb659fds/version"}) +} + +func deleteAllSecrets() { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryMaxAttempts(5)) + + if err != nil { + panic(err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + input := &secretsmanager.ListSecretsInput{ + IncludePlannedDeletion: aws.Bool(true), + } + for { + output, err := secretsManagerClient.ListSecrets(context.Background(), input) + if err != nil { + panic(err) + } + for _, secret := range output.SecretList { + _, err := secretsManagerClient.DeleteSecret(context.Background(), &secretsmanager.DeleteSecretInput{ + ForceDeleteWithoutRecovery: aws.Bool(true), + SecretId: secret.ARN, + }) + if err != nil { + panic(err) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } +} + +func deleteAllParametersExcept(except []string) { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryMaxAttempts(5)) + + if err != nil { + panic(err) + } + + ssmClient := ssm.NewFromConfig(cfg) + + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + panic(err) + } + for _, param := range output.Parameters { + if !slices.Contains(except, *param.Name) { + _, err := ssmClient.DeleteParameter(context.Background(), &ssm.DeleteParameterInput{ + Name: param.Name, + }) + if err != nil { + panic(err) + } + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } +} diff --git a/lambda/main_test.go b/lambda/main_test.go index d9ffd4a8..b4b9db3d 100644 --- a/lambda/main_test.go +++ b/lambda/main_test.go @@ -1,73 +1,120 @@ package main import ( + "encoding/json" "os" "testing" + "time" + "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" "github.com/gkampitakis/go-snaps/snaps" - "github.com/go-test/deep" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/stretchr/testify/assert" ) -func TestMain(t *testing.M) { - - //log.SetOutput(ioutil.Discard) - - v := t.Run() - // After all tests have run `go-snaps` can check for not used snapshots - snaps.Clean(t) - - os.Exit(v) +type putParameterCalls map[string]interface{} +type putSecretValueCalls map[string]interface{} +type getObjectEtagCalls map[string]client.SopsS3File +type getObjectCalls map[string]client.SopsS3File +type MockAwsClient struct { + t *testing.T + putParameter putParameterCalls + putSecretValue putSecretValueCalls + getObjectEtag getObjectEtagCalls + getObject getObjectCalls } -func Test_GetS3FileContent(t *testing.T) { - mocks := getMocks(t) - data, err := mocks.getS3FileContent(SopsS3File{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json", - }) - check(err) - snaps.MatchSnapshot(t, string(data)) +func (m *MockAwsClient) S3GetObject(file client.SopsS3File) ([]byte, error) { + m.getObject[file.Key] = file + localFile := "../" + file.Key + content, err := os.ReadFile(localFile) + if err != nil { + return nil, err + } + return content, nil } -func Test_UpdateSecret(t *testing.T) { - mocks := getMocks(t) - fileName := "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - inputArn := "arn:${Partition}:secretsmanager:${Region}:${Account}:secret:${SecretId}" - secretValue := []byte("some-secret-data") - - response, err := mocks.updateSecret(fileName, inputArn, secretValue) - check(err) - - snaps.MatchSnapshot(t, response) +func (m *MockAwsClient) S3GetObjectETAG(file client.SopsS3File) (*string, error) { + etag := "mock-etag" + m.getObjectEtag[file.Key] = file + return &etag, nil } -func Test_UpdateSSMParameter(t *testing.T) { - mocks := getMocks(t) - - paramterName := "/foo/bar" - parameterValue := []byte("some-secret-data") - - response, err := mocks.updateSSMParameter(paramterName, parameterValue, "key") - check(err) - - snaps.MatchSnapshot(t, response) +func (m *MockAwsClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte, binary *bool) (*secretsmanager.PutSecretValueOutput, error) { + m.putSecretValue[secretArn] = map[string]interface{}{"sopsHash": sopsHash, "secretContent": string(*secretContent), "binary": *binary} + arn := "mock-arn" + return &secretsmanager.PutSecretValueOutput{ + ARN: &arn, + Name: &secretArn, + VersionStages: []string{"mock-version-stage"}, + VersionId: &sopsHash, + }, nil } -func Test_DecryptSopsFileContent(t *testing.T) { +func (m *MockAwsClient) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (*ssm.PutParameterOutput, error) { + m.putParameter[parameterName] = map[string]interface{}{"parameterContent": string(*parameterContent), "keyId": keyId} + return &ssm.PutParameterOutput{Version: 1}, nil +} +func TestHandleRequestWithClients(t *testing.T) { + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } - sopsEncrypted, err := os.ReadFile("../test-secrets/json/sopsfile.enc-age.json") - check(err) - sopsDecrypted, err := decryptSopsFileContent(sopsEncrypted, "json") - check(err) - sopsExpected, err := os.ReadFile("../test-secrets/json/sopsfile.json") - check(err) + var tests []struct { + name string + event cfn.Event + } - sopsDecryptedJ := UnmarshalAny(sopsDecrypted) - sopsExpectedJ := UnmarshalAny(sopsExpected) + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + tests = append(tests, struct { + name string + event cfn.Event + }{ + name: file.Name(), + event: cfn.Event{ + RequestType: cfn.RequestCreate, + ResourceProperties: resourceProperties, + }, + }) + } - if diff := deep.Equal(sopsDecryptedJ, sopsExpectedJ); diff != nil { - t.Error(diff) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clients := &MockAwsClient{ + t: t, + putParameter: putParameterCalls{}, + putSecretValue: putSecretValueCalls{}, + getObjectEtag: getObjectEtagCalls{}, + getObject: getObjectCalls{}, + } + + physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) + snaps.WithConfig(snaps.Filename(t.Name()+"/"+tt.name)).MatchSnapshot(t, clients.getObject, clients.getObjectEtag, clients.putParameter, clients.putSecretValue) + + assert.NoError(t, err) + assert.NotEmpty(t, physicalResourceID) + assert.NotNil(t, data) + }) } } diff --git a/lambda/mocks.go b/lambda/mocks.go deleted file mode 100644 index 15ed7bd8..00000000 --- a/lambda/mocks.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "crypto/sha256" - "fmt" - "io" - "testing" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - - "github.com/aws/aws-sdk-go/service/s3" - "github.com/aws/aws-sdk-go/service/s3/s3iface" - "github.com/aws/aws-sdk-go/service/s3/s3manager" - "github.com/aws/aws-sdk-go/service/s3/s3manager/s3manageriface" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" - "github.com/gkampitakis/go-snaps/snaps" -) - -type SecretsManagerMockClient struct { - secretsmanageriface.SecretsManagerAPI - t *testing.T -} - -type PutSecretValueInputNotSecure struct { - - // A unique identifier for the new version of the secret. - // - // If you use the Amazon Web Services CLI or one of the Amazon Web Services - // SDKs to call this operation, then you can leave this parameter empty. The - // CLI or SDK generates a random UUID for you and includes it as the value for - // this parameter in the request. - // - // If you generate a raw HTTP request to the Secrets Manager service endpoint, - // then you must generate a ClientRequestToken and include it in the request. - // - // This value helps ensure idempotency. Secrets Manager uses this value to prevent - // the accidental creation of duplicate versions if there are failures and retries - // during a rotation. We recommend that you generate a UUID-type (https://wikipedia.org/wiki/Universally_unique_identifier) - // value to ensure uniqueness of your versions within the specified secret. - // - // * If the ClientRequestToken value isn't already associated with a version - // of the secret then a new version of the secret is created. - // - // * If a version with this value already exists and that version's SecretString - // or SecretBinary values are the same as those in the request then the request - // is ignored. The operation is idempotent. - // - // * If a version with this value already exists and the version of the SecretString - // and SecretBinary values are different from those in the request, then - // the request fails because you can't modify a secret version. You can only - // create new versions to store new secret values. - // - // This value becomes the VersionId of the new version. - ClientRequestToken *string `min:"32" type:"string" idempotencyToken:"true"` - - // The binary data to encrypt and store in the new version of the secret. To - // use this parameter in the command-line tools, we recommend that you store - // your binary data in a file and then pass the contents of the file as a parameter. - // - // You must include SecretBinary or SecretString, but not both. - // - // You can't access this value from the Secrets Manager console. - // - // SecretBinary is a sensitive parameter and its value will be - // replaced with "sensitive" in string returned by PutSecretValueInput's - // String and GoString methods. - // - // SecretBinary is automatically base64 encoded/decoded by the SDK. - SecretBinary []byte `min:"1" type:"blob"` - - // The ARN or name of the secret to add a new version to. - // - // For an ARN, we recommend that you specify a complete ARN rather than a partial - // ARN. See Finding a secret from a partial ARN (https://docs.aws.amazon.com/secretsmanager/latest/userguide/troubleshoot.html#ARN_secretnamehyphen). - // - // If the secret doesn't already exist, use CreateSecret instead. - // - // SecretId is a required field - SecretId *string `min:"1" type:"string" required:"true"` - - // The text to encrypt and store in the new version of the secret. - // - // You must include SecretBinary or SecretString, but not both. - // - // We recommend you create the secret string as JSON key/value pairs, as shown - // in the example. - // - // SecretString is a sensitive parameter and its value will be - // replaced with "sensitive" in string returned by PutSecretValueInput's - // String and GoString methods. - SecretString *string `min:"1" type:"string"` - - // A list of staging labels to attach to this version of the secret. Secrets - // Manager uses staging labels to track versions of a secret through the rotation - // process. - // - // If you specify a staging label that's already associated with a different - // version of the same secret, then Secrets Manager removes the label from the - // other version and attaches it to this version. If you specify AWSCURRENT, - // and it is already attached to another version, then Secrets Manager also - // moves the staging label AWSPREVIOUS to the version that AWSCURRENT was removed - // from. - // - // If you don't include VersionStages, then Secrets Manager automatically moves - // the staging label AWSCURRENT to this version. - VersionStages []*string `min:"1" type:"list"` -} - -type putSecretValueInputNotSecure secretsmanager.PutSecretValueInput - -func (m *SecretsManagerMockClient) PutSecretValue(input *secretsmanager.PutSecretValueInput) (*secretsmanager.PutSecretValueOutput, error) { - versionId := fmt.Sprintf("%x", sha256.Sum256([]byte(*input.SecretString))) - - snaps.MatchSnapshot(m.t, ">>>SecretsManagerMockClient.PutSecretValue.Input", putSecretValueInputNotSecure(*input)) - - name := fmt.Sprintf("%x", sha256.Sum256([]byte(*input.SecretId))) - - return &secretsmanager.PutSecretValueOutput{ - ARN: input.SecretId, - Name: &name, - VersionStages: []*string{&name}, - VersionId: &versionId, - }, nil -} - -type S3ManagerMockClient struct { - s3manageriface.DownloaderAPI - t *testing.T -} - -func (d S3ManagerMockClient) Download(w io.WriterAt, input *s3.GetObjectInput, options ...func(*s3manager.Downloader)) (n int64, err error) { - dat := ReadFile(*input.Key) - snaps.MatchSnapshot(d.t, ">>>S3MAnagerMockClient.Download.Input", input) - _, err = w.WriteAt(dat, int64(0)) - check(err) - return int64(len(dat)), err -} - -type MockSSMClient struct { - ssmiface.SSMAPI - t *testing.T -} - -type putParameterValueInputNotSecure ssm.PutParameterInput - -func (m *MockSSMClient) PutParameter(input *ssm.PutParameterInput) (*ssm.PutParameterOutput, error) { - snaps.MatchSnapshot(m.t, ">>>SecretsManagerMockClient.PutParameterValue.Input", putParameterValueInputNotSecure(*input)) - - var version int64 - version = 1 - - tier := ssm.ParameterTierStandard - return &ssm.PutParameterOutput{ - Tier: &tier, - Version: &version, - }, nil -} - -type MocksS3Api struct { - s3iface.S3API - t *testing.T -} - -func (m *MocksS3Api) GetObjectAttributes(input *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error) { - snaps.MatchSnapshot(m.t, ">>>S3ApiMockClient.GetObjectAttributes.Input", *input) - - return &s3.GetObjectAttributesOutput{ - Checksum: nil, - DeleteMarker: nil, - ETag: aws.String("some-32-character-long-string-ab"), - LastModified: nil, - ObjectParts: nil, - ObjectSize: nil, - RequestCharged: nil, - StorageClass: nil, - VersionId: nil, - }, nil -} diff --git a/lambda/testhelper.go b/lambda/testhelper.go deleted file mode 100644 index 99f04f57..00000000 --- a/lambda/testhelper.go +++ /dev/null @@ -1,92 +0,0 @@ -package main - -import ( - "context" - "encoding/base64" - "encoding/json" - "io/ioutil" - "os" - "testing" - "time" - - "github.com/aws/aws-lambda-go/cfn" - "github.com/aws/aws-lambda-go/lambdacontext" -) - -func check(e error) { - if e != nil { - panic(e) - } -} - -func UnmarshalAny(input []byte) map[string]interface{} { - var returnValue map[string]interface{} - err := json.Unmarshal(input, &returnValue) - check(err) - return returnValue -} - -func ReadFile(path string) []byte { - ret, err := os.ReadFile(path) - check(err) - return ret -} - -func ReadJSONFromFile(t *testing.T, inputFile string) []byte { - inputJSON, err := ioutil.ReadFile(inputFile) - if err != nil { - t.Errorf("could not open test file. details: %v", err) - } - - return inputJSON -} - -func base64FromFile(file string) string { - inputData, err := ioutil.ReadFile(file) - check(err) - return base64.StdEncoding.EncodeToString(inputData) -} - -func fileToInline(event cfn.Event) cfn.Event { - sopsProps, err := toSopsSyncResourcePropertys(&event.ResourceProperties) - check(err) - - inlineProps := SopsInline{ - Content: base64FromFile(sopsProps.SopsS3File.Key), - Hash: "MyHash", - } - event.ResourceProperties["SopsInline"] = inlineProps - delete(event.ResourceProperties, "SopsS3File") - return event -} -func getMocks(t *testing.T) *AWS { - return &AWS{ - secretsmanager: &SecretsManagerMockClient{ - t: t, - }, - s3Downloader: &S3ManagerMockClient{ - t: t, - }, - ssm: &MockSSMClient{ - t: t, - }, - s3Api: &MocksS3Api{ - t: t, - }, - } -} -func prepareHandler(t *testing.T, eventFile string) (*AWS, context.Context, cfn.Event) { - os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") - mocks := getMocks(t) - d := time.Now().Add(50 * time.Millisecond) - ctx, _ := context.WithDeadline(context.Background(), d) - ctx = lambdacontext.NewContext(ctx, &lambdacontext.LambdaContext{ - AwsRequestID: "AwsRequestID", - InvokedFunctionArn: "arn:aws:lambda:us-east-2:123456789012:function:cdk-sops-secrets", - }) - inputJson := ReadJSONFromFile(t, eventFile) - var event cfn.Event - err := json.Unmarshal(inputJson, &event) - check(err) - return mocks, ctx, event -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 11885db3..00000000 --- a/package-lock.json +++ /dev/null @@ -1,11335 +0,0 @@ -{ - "name": "cdk-sops-secrets", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "cdk-sops-secrets", - "version": "0.0.0", - "bundleDependencies": [ - "yaml" - ], - "license": "Apache-2.0", - "dependencies": { - "yaml": "^2.5.0" - }, - "devDependencies": { - "@types/jest": "^27", - "@types/node": "^16 <= 16.18.78", - "@typescript-eslint/eslint-plugin": "^7", - "@typescript-eslint/parser": "^7", - "aws-cdk": "^2", - "aws-cdk-lib": "2.144.0", - "commit-and-tag-version": "^12", - "constructs": "10.0.5", - "eslint": "^8", - "eslint-config-prettier": "^8.10.0", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^4.2.1", - "jest": "^27", - "jest-junit": "^15", - "jsii": "1.x", - "jsii-diff": "^1.103.1", - "jsii-docgen": "^10.5.0", - "jsii-pacmak": "^1.103.1", - "jsii-rosetta": "1.x", - "prettier": "^2.8.8", - "projen": "^0.88.1", - "ts-jest": "^27", - "ts-node": "^10.9.2", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "aws-cdk-lib": "^2.144.0", - "constructs": "^10.0.5" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.202", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.202.tgz", - "integrity": "sha512-JqlF0D4+EVugnG5dAsNZMqhu3HW7ehOXm5SDMxMbXNDMdsF0pxtQKNHRl52z1U9igsHmaFpUgSGjbhAJ+0JONg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", - "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.0.3.tgz", - "integrity": "sha512-twhuEG+JPOYCYPx/xy5uH2+VUsIEhPTzDY0F1KuB+ocjWWB/KEDiOVL19nHvbPCB6fhWnkykXEMJ4HHcKvjtvg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.10", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/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==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsii/check-node": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.103.1.tgz", - "integrity": "sha512-Vi6ONm5WXEim98a2DJ6WMlrP/w5AGzXrrQBpGcfVV7cu86DPx1L0OAZnqzGAJE8ly0VfcSXkmxJ9LFcn3jylBQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "semver": "^7.6.3" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/@jsii/spec": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.103.1.tgz", - "integrity": "sha512-14OGYM3DjEBjUOUaih+bwPgkhFnR8L9TSNSM0oE0L0hjWscTapvClqOgMDJ1ID52qkROCAgKl1d71Vmm4v0Buw==", - "dev": true, - "dependencies": { - "ajv": "^8.17.1" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/@jsii/spec/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@jsii/spec/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "16.18.78", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.78.tgz", - "integrity": "sha512-2poPMDdsGfvhcLmgJZ85QrIfN6z3PijYRMiV0FWIEUiQW/t/lzH7BEm4vN+HMhjZXbtIKssMcAxTcgu4Rm83YA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", - "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "16.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", - "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals/node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "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/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-cdk": { - "version": "2.150.0", - "dev": true, - "license": "Apache-2.0", - "bin": { - "cdk": "bin/cdk" - }, - "engines": { - "node": ">= 14.15.0" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/aws-cdk-lib": { - "version": "2.144.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz", - "integrity": "sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA==", - "bundleDependencies": [ - "@balena/dockerignore", - "case", - "fs-extra", - "ignore", - "jsonschema", - "minimatch", - "punycode", - "semver", - "table", - "yaml", - "mime-types" - ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.202", - "@aws-cdk/asset-kubectl-v20": "^2.1.2", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.3", - "@balena/dockerignore": "^1.0.2", - "case": "1.6.3", - "fs-extra": "^11.2.0", - "ignore": "^5.3.1", - "jsonschema": "^1.4.1", - "mime-types": "^2.1.35", - "minimatch": "^3.1.2", - "punycode": "^2.3.1", - "semver": "^7.6.0", - "table": "^6.8.2", - "yaml": "1.10.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "constructs": "^10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", - "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.13.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/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==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/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==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/aws-cdk-lib/node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/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==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/aws-cdk-lib/node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aws-cdk-lib/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/aws-cdk-lib/node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.6.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aws-cdk-lib/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/aws-cdk-lib/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/browserslist": { - "version": "4.23.2", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001643", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/codemaker": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.103.1.tgz", - "integrity": "sha512-y3Ru0bZV6qiuPAt8c/Hik1dCI0dVb6lj/6gAIWckvNYVu5FS51avr3FU/mRtuPrY3b1bW/EA0pszGB/P54Bl5A==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "decamelize": "^5.0.1", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/codemaker/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commit-and-tag-version": { - "version": "12.4.4", - "resolved": "https://registry.npmjs.org/commit-and-tag-version/-/commit-and-tag-version-12.4.4.tgz", - "integrity": "sha512-sK+69usdfluwRO6DtXs8wpRvyM9OAuV6y8kTgMj+ncRG3KrXeKjNcxFsWnnwH/KZU9k8ErKu5uQ1ptX6/pPk7A==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "conventional-changelog": "4.0.0", - "conventional-changelog-config-spec": "2.1.0", - "conventional-changelog-conventionalcommits": "6.1.0", - "conventional-recommended-bump": "7.0.1", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "dotgitignore": "^2.1.0", - "figures": "^3.1.0", - "find-up": "^5.0.0", - "git-semver-tags": "^5.0.0", - "jsdom": "^25.0.0", - "semver": "^7.6.3", - "w3c-xmlserializer": "^5.0.0", - "yaml": "^2.4.1", - "yargs": "^17.7.2" - }, - "bin": { - "commit-and-tag-version": "bin/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz", - "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==", - "dev": true, - "dependencies": { - "conventional-changelog-angular": "^6.0.0", - "conventional-changelog-atom": "^3.0.0", - "conventional-changelog-codemirror": "^3.0.0", - "conventional-changelog-conventionalcommits": "^6.0.0", - "conventional-changelog-core": "^5.0.0", - "conventional-changelog-ember": "^3.0.0", - "conventional-changelog-eslint": "^4.0.0", - "conventional-changelog-express": "^3.0.0", - "conventional-changelog-jquery": "^4.0.0", - "conventional-changelog-jshint": "^3.0.0", - "conventional-changelog-preset-loader": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-atom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz", - "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-codemirror": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz", - "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz", - "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==", - "dev": true, - "dependencies": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^6.0.0", - "conventional-commits-parser": "^4.0.0", - "dateformat": "^3.0.3", - "get-pkg-repo": "^4.2.1", - "git-raw-commits": "^3.0.0", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^5.0.0", - "normalize-package-data": "^3.0.3", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-ember": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz", - "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-eslint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz", - "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-express": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz", - "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-jquery": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz", - "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-jshint": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz", - "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-preset-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", - "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-writer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", - "dev": true, - "dependencies": { - "conventional-commits-filter": "^3.0.0", - "dateformat": "^3.0.3", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^8.1.2", - "semver": "^7.0.0", - "split": "^1.0.1" - }, - "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", - "dev": true, - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-recommended-bump": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", - "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", - "dev": true, - "dependencies": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^3.0.0", - "conventional-commits-filter": "^3.0.0", - "conventional-commits-parser": "^4.0.0", - "git-raw-commits": "^3.0.0", - "git-semver-tags": "^5.0.0", - "meow": "^8.1.2" - }, - "bin": { - "conventional-recommended-bump": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/cssstyle": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", - "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", - "dev": true, - "dependencies": { - "rrweb-cssom": "^0.7.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/commit-and-tag-version/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/commit-and-tag-version/node_modules/git-raw-commits": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", - "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", - "dev": true, - "dependencies": { - "dargs": "^7.0.0", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/git-semver-tags": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", - "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", - "dev": true, - "dependencies": { - "meow": "^8.1.2", - "semver": "^7.0.0" - }, - "bin": { - "git-semver-tags": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/commit-and-tag-version/node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", - "dev": true, - "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/commit-and-tag-version/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/commit-and-tag-version/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/commit-and-tag-version/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/commit-and-tag-version/node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/commit-and-tag-version/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==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/tough-cookie": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", - "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", - "dev": true, - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/commit-and-tag-version/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "dev": true, - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/commit-and-tag-version/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/commonmark": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.31.2.tgz", - "integrity": "sha512-2fRLTyb9r/2835k5cwcAwOj0DEc44FARnMp5veGsJ+mEAZdi52sNopLu07ZyElQUz058H43whzlERDIaaSw4rg==", - "dev": true, - "dependencies": { - "entities": "~3.0.1", - "mdurl": "~1.0.1", - "minimist": "~1.2.8" - }, - "bin": { - "commonmark": "bin/commonmark" - }, - "engines": { - "node": "*" - } - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/constructs": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.0.5.tgz", - "integrity": "sha512-IwOwekzrASFC3qt4ozCtV09rteAIAesuCGsW0p+uBfqHd2XcvA5CXqJjgf4eUqm6g8e/noXlVCMDWwC8GaLtrg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 10.17.0" - } - }, - "node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", - "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotgitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", - "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", - "dev": true, - "license": "ISC", - "dependencies": { - "find-up": "^3.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.1", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", - "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "debug": "^4.3.4", - "glob": "^7.2.0", - "is-glob": "^4.0.3", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/eslint/node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "dev": true, - "license": "MIT", - "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "get-pkg-repo": "src/cli.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-pkg-repo/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-pkg-repo/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/get-pkg-repo/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/get-pkg-repo/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-remote-origin-url/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", - "dev": true, - "license": "BSD", - "dependencies": { - "ini": "^1.3.2" - } - }, - "node_modules/gitconfiglocal/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "license": "ISC", - "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-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "license": "ISC", - "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-haste-map/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-haste-map/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-junit": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-15.0.0.tgz", - "integrity": "sha512-Z5sVX0Ag3HZdMUnD5DFlG+1gciIFSy7yIVPhOdGUi8YJaI9iLvvBb530gtQL2CHmv0JJeiwRZenr0VrSR7frvg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jsii": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii/-/jsii-1.103.1.tgz", - "integrity": "sha512-SjS/g9iq8UJIEPBcaGUIYUJ3/oCboBKpDlJOOzMj2w4MpXQbXP3eyRO6NWBWkWsrIczyJ7HZiRWUJ7J4rUJ0sg==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "case": "^1.6.3", - "chalk": "^4", - "fast-deep-equal": "^3.1.3", - "fs-extra": "^10.1.0", - "log4js": "^6.9.1", - "semver": "^7.6.3", - "semver-intersect": "^1.5.0", - "sort-json": "^2.0.1", - "spdx-license-list": "^6.9.0", - "typescript": "~3.9.10", - "yargs": "^16.2.0" - }, - "bin": { - "jsii": "bin/jsii" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-diff": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.103.1.tgz", - "integrity": "sha512-JceGFJkOsTEFjtubTsDTDIw+3PrAVx0lpUtHSvFUZ+aeFYpnbWLcOGcX7vuxwnvZO2oDbm7qE+ymmov53exKqQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "fs-extra": "^10.1.0", - "jsii-reflect": "^1.103.1", - "log4js": "^6.9.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-diff": "bin/jsii-diff" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-docgen": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/jsii-docgen/-/jsii-docgen-10.5.5.tgz", - "integrity": "sha512-xPlCmtR0HEVLTIv2dkXL7NZ0l6G7AWbmYZDRQvIie1AjHDwTEszlyivG1zXqP4jx180bQl5ezOf9BWGJLxHyTA==", - "dev": true, - "dependencies": { - "@jsii/spec": "^1.103.1", - "case": "^1.6.3", - "fs-extra": "^10.1.0", - "glob": "^8.1.0", - "glob-promise": "^6.0.7", - "jsii-reflect": "^1.103.1", - "semver": "^7.6.3", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-docgen": "bin/jsii-docgen" - }, - "peerDependencies": { - "jsii-rosetta": "^1.85.0 || ~5.0.14 || ~5.1.2 || ~5.2.0 || ~5.3.0 || ~5.4.0 || ~5.5.0" - } - }, - "node_modules/jsii-docgen/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jsii-docgen/node_modules/glob-promise": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-6.0.7.tgz", - "integrity": "sha512-DEAe6br1w8ZF+y6KM2pzgdfhpreladtNvyNNVgSkxxkFWzXTJFXxQrJQQbAnc7kL0EUd7w5cR8u4K0P4+/q+Gw==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/ahmadnassri" - }, - "peerDependencies": { - "glob": "^8.0.3" - } - }, - "node_modules/jsii-docgen/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsii-pacmak": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.103.1.tgz", - "integrity": "sha512-2zzm/OYsdbxcaYuq4n0o2lQAPQ5Fo+T+sQJPGFeMXD0kgDZTNqXv21FdsKBKuQ/DutxTATOaZ7gTXEDK1n7/RQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "clone": "^2.1.2", - "codemaker": "^1.103.1", - "commonmark": "^0.31.1", - "escape-string-regexp": "^4.0.0", - "fs-extra": "^10.1.0", - "jsii-reflect": "^1.103.1", - "semver": "^7.6.3", - "spdx-license-list": "^6.9.0", - "xmlbuilder": "^15.1.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-pacmak": "bin/jsii-pacmak" - }, - "engines": { - "node": ">= 14.17.0" - }, - "peerDependencies": { - "jsii-rosetta": "^1.103.1 || ~5.2.0 || ~5.3.0 || ~5.4.0 || ~5.5.0" - } - }, - "node_modules/jsii-pacmak/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jsii-reflect": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.103.1.tgz", - "integrity": "sha512-kFm09KL9dlxyxesf7mtm12+4vVaRin5YI4Eca2OOa0X28HNVpr62/n21T3BuAAhFaI0nkiUoJuBWtdOz475BSQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "chalk": "^4", - "fs-extra": "^10.1.0", - "oo-ascii-tree": "^1.103.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-tree": "bin/jsii-tree" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-rosetta": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.103.1.tgz", - "integrity": "sha512-LzLtFqQXOXdvYxDeq2OzaiR+Xhq7q9+NfUEWTpNVsvVh3N7E7w3G/75shsl8BfacJVvrH0hYVMkOH4Lyd0np2g==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "1.103.1", - "@xmldom/xmldom": "^0.8.10", - "commonmark": "^0.31.1", - "fast-glob": "^3.3.2", - "jsii": "1.103.1", - "semver": "^7.6.3", - "semver-intersect": "^1.5.0", - "stream-json": "^1.8.0", - "typescript": "~3.9.10", - "workerpool": "^6.5.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-rosetta": "bin/jsii-rosetta" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-rosetta/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/jsii/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimatch/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", - "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/oo-ascii-tree": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.103.1.tgz", - "integrity": "sha512-X0nmbb8xUUi637JXzCxY/K4AtO/I0fB5b7iiGaHJHu8IXBWV8TnQ4xqa0Igb/NoAg3OP2uXNhSeiTsErETOA/g==", - "dev": true, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/projen": { - "version": "0.88.1", - "resolved": "https://registry.npmjs.org/projen/-/projen-0.88.1.tgz", - "integrity": "sha512-LAv/kUAcCSTXH7/E+eeAJln3NvVFvhHgx9ezGPudcEPUOhr98M+Uojt6lniGvKESmk6rDO8AcVvzIhFH3kcz1g==", - "bundleDependencies": [ - "@iarna/toml", - "case", - "chalk", - "comment-json", - "conventional-changelog-config-spec", - "fast-json-patch", - "glob", - "ini", - "semver", - "shx", - "xmlbuilder2", - "yaml", - "yargs" - ], - "dev": true, - "dependencies": { - "@iarna/toml": "^2.2.5", - "case": "^1.6.3", - "chalk": "^4.1.2", - "comment-json": "4.2.2", - "constructs": "^10.0.0", - "conventional-changelog-config-spec": "^2.1.0", - "fast-json-patch": "^3.1.1", - "glob": "^8", - "ini": "^2.0.0", - "semver": "^7.6.3", - "shx": "^0.3.4", - "xmlbuilder2": "^3.1.1", - "yaml": "^2.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "projen": "bin/projen" - }, - "engines": { - "node": ">= 16.0.0" - }, - "peerDependencies": { - "constructs": "^10.0.0" - } - }, - "node_modules/projen/node_modules/@iarna/toml": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/@oozcitak/dom": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", - "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/url": "1.0.4", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/infra": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", - "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/url": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", - "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/util": { - "version": "8.3.8", - "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", - "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/projen/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/projen/node_modules/array-timsort": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", - "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/projen/node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/projen/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/projen/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/projen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/projen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/comment-json": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.2.tgz", - "integrity": "sha512-H8T+kl3nZesZu41zO2oNXIJWojNeK3mHxCLrsBNu6feksBXsgb+PtYz5daP5P86A0F3sz3840KVYehr04enISQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/projen/node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/constructs": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.3.0.tgz", - "integrity": "sha512-vbK8i3rIb/xwZxSpTjz3SagHn1qq9BChLEfy5Hf6fB3/2eFbrwt2n9kHwQcS0CPTRBesreeAcsJfMq2229FnbQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 16.14.0" - } - }, - "node_modules/projen/node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/projen/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/projen/node_modules/fast-json-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/projen/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/projen/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/has-own-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/projen/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/projen/node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/projen/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/projen/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/projen/node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "inBundle": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/projen/node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/projen/node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/projen/node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.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/projen/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/projen/node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "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/projen/node_modules/shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/projen/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/projen/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/projen/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==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/xmlbuilder2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.1.1.tgz", - "integrity": "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/dom": "1.15.10", - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8", - "js-yaml": "3.14.1" - }, - "engines": { - "node": ">=12.0" - } - }, - "node_modules/projen/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/projen/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/projen/node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT" - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.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/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-intersect": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.5.0.tgz", - "integrity": "sha512-BDjWX7yCC0haX4W/zrnV2JaMpVirwaEkGOBmgRQtH++F1N3xl9v7k9H44xfTqwl+yLNNSbMKosoVSTIiJVQ2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.3.0" - } - }, - "node_modules/semver-intersect/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sort-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sort-json/-/sort-json-2.0.1.tgz", - "integrity": "sha512-s8cs2bcsQCzo/P2T/uoU6Js4dS/jnX8+4xunziNoq9qmSpZNCrRIAIvp4avsz0ST18HycV4z/7myJ7jsHWB2XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-indent": "^5.0.0", - "detect-newline": "^2.1.0", - "minimist": "^1.2.0" - }, - "bin": { - "sort-json": "app/cmd.js" - } - }, - "node_modules/sort-json/node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/sort-json/node_modules/detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "license": "BSD-3-Clause", - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.18", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/spdx-license-list": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/spdx-license-list/-/spdx-license-list-6.9.0.tgz", - "integrity": "sha512-L2jl5vc2j6jxWcNCvcVj/BW9A8yGIG02Dw+IUw0ZxDM70f7Ylf5Hq39appV1BI9yxyWQRpq2TQ1qaXvf+yjkqA==", - "dev": true, - "license": "CC0-1.0", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stream-chain": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", - "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stream-json": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.8.0.tgz", - "integrity": "sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "stream-chain": "^2.2.5" - } - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/streamroller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/streamroller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/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==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tldts": { - "version": "6.1.50", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.50.tgz", - "integrity": "sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==", - "dev": true, - "dependencies": { - "tldts-core": "^6.1.50" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.50", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.50.tgz", - "integrity": "sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uglify-js": { - "version": "3.19.0", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "dev": true, - "license": "MIT" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", - "dev": true, - "license": "MIT" - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", - "inBundle": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/package.json b/package.json index d49447b5..31d0a299 100644 --- a/package.json +++ b/package.json @@ -15,26 +15,21 @@ "docgen": "npx projen docgen", "eject": "npx projen eject", "eslint": "npx projen eslint", - "integ:secret-asset:assert": "npx projen integ:secret-asset:assert", - "integ:secret-asset:deploy": "npx projen integ:secret-asset:deploy", - "integ:secret-asset:destroy": "npx projen integ:secret-asset:destroy", - "integ:secret-asset:snapshot": "npx projen integ:secret-asset:snapshot", - "integ:secret-asset:watch": "npx projen integ:secret-asset:watch", - "integ:secret-inline:assert": "npx projen integ:secret-inline:assert", - "integ:secret-inline:deploy": "npx projen integ:secret-inline:deploy", - "integ:secret-inline:destroy": "npx projen integ:secret-inline:destroy", - "integ:secret-inline:snapshot": "npx projen integ:secret-inline:snapshot", - "integ:secret-inline:watch": "npx projen integ:secret-inline:watch", - "integ:secret-manual:assert": "npx projen integ:secret-manual:assert", - "integ:secret-manual:deploy": "npx projen integ:secret-manual:deploy", - "integ:secret-manual:destroy": "npx projen integ:secret-manual:destroy", - "integ:secret-manual:snapshot": "npx projen integ:secret-manual:snapshot", - "integ:secret-manual:watch": "npx projen integ:secret-manual:watch", - "integ:secret-multikms:assert": "npx projen integ:secret-multikms:assert", - "integ:secret-multikms:deploy": "npx projen integ:secret-multikms:deploy", - "integ:secret-multikms:destroy": "npx projen integ:secret-multikms:destroy", - "integ:secret-multikms:snapshot": "npx projen integ:secret-multikms:snapshot", - "integ:secret-multikms:watch": "npx projen integ:secret-multikms:watch", + "integ:PARAMETER_MULTI:assert": "npx projen integ:PARAMETER_MULTI:assert", + "integ:PARAMETER_MULTI:deploy": "npx projen integ:PARAMETER_MULTI:deploy", + "integ:PARAMETER_MULTI:destroy": "npx projen integ:PARAMETER_MULTI:destroy", + "integ:PARAMETER_MULTI:snapshot": "npx projen integ:PARAMETER_MULTI:snapshot", + "integ:PARAMETER_MULTI:watch": "npx projen integ:PARAMETER_MULTI:watch", + "integ:PARAMETER:assert": "npx projen integ:PARAMETER:assert", + "integ:PARAMETER:deploy": "npx projen integ:PARAMETER:deploy", + "integ:PARAMETER:destroy": "npx projen integ:PARAMETER:destroy", + "integ:PARAMETER:snapshot": "npx projen integ:PARAMETER:snapshot", + "integ:PARAMETER:watch": "npx projen integ:PARAMETER:watch", + "integ:SECRET:assert": "npx projen integ:SECRET:assert", + "integ:SECRET:deploy": "npx projen integ:SECRET:deploy", + "integ:SECRET:destroy": "npx projen integ:SECRET:destroy", + "integ:SECRET:snapshot": "npx projen integ:SECRET:snapshot", + "integ:SECRET:watch": "npx projen integ:SECRET:watch", "integ:snapshot-all": "npx projen integ:snapshot-all", "package": "npx projen package", "package-all": "npx projen package-all", @@ -59,12 +54,12 @@ "organization": false }, "devDependencies": { - "@types/jest": "^27", - "@types/node": "^16 <= 16.18.78", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.78", "@typescript-eslint/eslint-plugin": "^8", "@typescript-eslint/parser": "^8", "aws-cdk": "^2", - "aws-cdk-lib": "2.144.0", + "aws-cdk-lib": "2.177.0", "commit-and-tag-version": "^12", "constructs": "10.0.5", "eslint": "^9", @@ -72,21 +67,22 @@ "eslint-import-resolver-typescript": "^2.7.1", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^4.2.1", - "jest": "^27", + "jest": "^27.5.1", "jest-junit": "^16", "jsii": "~5.6.0", "jsii-diff": "^1.106.0", "jsii-docgen": "^10.5.0", "jsii-pacmak": "^1.106.0", "jsii-rosetta": "~5.6.0", + "json-schema-to-typescript": "^15.0.4", "prettier": "^2.8.8", "projen": "^0.91.7", - "ts-jest": "^27", + "ts-jest": "^27.1.5", "ts-node": "^10.9.2", "typescript": "^4.9.5" }, "peerDependencies": { - "aws-cdk-lib": "^2.144.0", + "aws-cdk-lib": "^2.177.0", "constructs": "^10.0.5" }, "dependencies": { diff --git a/src/LambdaInterface.ts b/src/LambdaInterface.ts new file mode 100644 index 00000000..28a6d027 --- /dev/null +++ b/src/LambdaInterface.ts @@ -0,0 +1,25 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface SopsSyncResourcePropertys { + ResourceType: "SECRET" | "SECRET_RAW" | "SECRET_BINARY" | "PARAMETER_MULTI" | "PARAMETER"; + Format: "json" | "yaml" | "dotenv" | "binary"; + Target: string; + EncryptionKey?: string; + SopsS3File?: SopsS3File; + SopsInline?: SopsInline; + FlattenSeparator?: string; + ServiceToken?: string; +} +export interface SopsS3File { + Bucket: string; + Key: string; +} +export interface SopsInline { + Content: string; + Hash: string; +} diff --git a/src/MultiStringParameter.ts b/src/MultiStringParameter.ts index a2c98478..31ba1c87 100644 --- a/src/MultiStringParameter.ts +++ b/src/MultiStringParameter.ts @@ -4,15 +4,25 @@ import { ParameterTier, StringParameter } from 'aws-cdk-lib/aws-ssm'; import { ResourceEnvironment, Stack } from 'aws-cdk-lib/core'; import { Construct } from 'constructs'; import * as YAML from 'yaml'; -import { SopsStringParameterProps } from './SopsStringParameter'; +import { SopsCommonParameterProps } from './SopsStringParameter'; import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; interface JSONObject { [key: string]: any; } -export interface MultiStringParameterProps extends SopsStringParameterProps { +export interface MultiStringParameterProps extends SopsCommonParameterProps { + /** + * The seperator used to seperate keys + * + * @default - '/' + */ readonly keySeparator?: string; + /** + * The prefix used for all parameters + * + * @default - '/' + */ readonly keyPrefix?: string; } @@ -66,11 +76,40 @@ export class MultiStringParameter extends Construct { const keys = this.parseFile(props.sopsFilePath!, this.keySeparator) .filter((key) => !key.startsWith('sops')) - .map((value) => `${this.keyPrefix}${value}`); + .map((value) => { + // Ass we flatten array to [number] path notations, we have to fix this for parameter store + let fixedKey = value.replace('[', this.keySeparator); + fixedKey = fixedKey.replace(']', this.keySeparator); + if (fixedKey.endsWith(this.keySeparator)) { + fixedKey = fixedKey.slice(0, -1); + } + fixedKey = fixedKey.replace( + this.keySeparator + this.keySeparator, + this.keySeparator, + ); + + // The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@- + const allowedChars = '/_+=.@-'; + for (let i = 0; i < fixedKey.length; i++) { + const char = fixedKey[i]; + if ( + !( + (char >= 'a' && char <= 'z') || + (char >= 'A' && char <= 'Z') || + (char >= '0' && char <= '9') || + allowedChars.includes(char) + ) + ) { + fixedKey = fixedKey.slice(0, i) + '_' + fixedKey.slice(i + 1); + } + } + return `${this.keyPrefix}${fixedKey}`; + }); keys.forEach((key) => { new StringParameter(this, 'Resource' + key, { parameterName: key, + description: props.description, tier: ParameterTier.STANDARD, stringValue: ' ', }); @@ -79,10 +118,9 @@ export class MultiStringParameter extends Construct { this.sync = new SopsSync(this, 'SopsSync', { encryptionKey: this.encryptionKey, resourceType: ResourceType.PARAMETER_MULTI, - flatten: true, flattenSeparator: this.keySeparator, - parameterKeyPrefix: this.keyPrefix, parameterNames: keys, + target: this.keyPrefix, ...(props as SopsSyncOptions), }); } diff --git a/src/SopsSecret.ts b/src/SopsSecret.ts index ba574851..50098898 100644 --- a/src/SopsSecret.ts +++ b/src/SopsSecret.ts @@ -8,6 +8,7 @@ import { IKey } from 'aws-cdk-lib/aws-kms'; import { ISecret, ISecretAttachmentTarget, + ReplicaRegion, RotationSchedule, RotationScheduleOptions, Secret, @@ -22,10 +23,58 @@ import { import { Construct } from 'constructs'; import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; +export enum RawOutput { + /** + * Parse the secret as a string + */ + STRING = 'STRING', + /** + * Parse the secret as a binary + */ + BINARY = 'BINARY', +} + /** * The configuration options of the SopsSecret */ -export interface SopsSecretProps extends SecretProps, SopsSyncOptions {} +export interface SopsSecretProps extends SopsSyncOptions { + /** + * Should the secret parsed and transformed to json? + * @default - undefined - no raw output + */ + readonly rawOutput?: RawOutput; + /** + * An optional, human-friendly description of the secret. + * + * @default - No description. + */ + readonly description?: string; + /** + * The customer-managed encryption key to use for encrypting the secret value. + * + * @default - A default KMS key for the account and region is used. + */ + readonly encryptionKey?: IKey; + /** + * A name for the secret. Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to + * 30 days blackout period. During that period, it is not possible to create another secret that shares the same name. + * + * @default - A name is generated by CloudFormation. + */ + readonly secretName?: string; + /** + * Policy to apply when the secret is removed from this stack. + * + * @default - Not set. + */ + readonly removalPolicy?: RemovalPolicy; + /** + * A list of regions where to replicate this secret. + * + * @default - Secret is not replicated + */ + readonly replicaRegions?: ReplicaRegion[]; +} /** * A drop in replacement for the normal Secret, that is populated with the encrypted @@ -43,7 +92,7 @@ export class SopsSecret extends Construct implements ISecret { readonly sync: SopsSync; public constructor(scope: Construct, id: string, props: SopsSecretProps) { super(scope, id); - this.secret = new Secret(this, 'Resource', props as SecretProps); + this.secret = new Secret(this, 'Resource', props satisfies SecretProps); // Fullfill secret Interface this.encryptionKey = this.secret.encryptionKey; @@ -55,10 +104,19 @@ export class SopsSecret extends Construct implements ISecret { region: this.stack.region, }; + let resourceType = ResourceType.SECRET; + if (props.rawOutput === RawOutput.BINARY) { + resourceType = ResourceType.SECRET_BINARY; + } + if (props.rawOutput === RawOutput.STRING) { + resourceType = ResourceType.SECRET_RAW; + } + this.sync = new SopsSync(this, 'SopsSync', { - secret: this.secret, - resourceType: ResourceType.SECRET, + target: this.secret.secretArn, + resourceType, flattenSeparator: '.', + secret: this.secret, ...(props as SopsSyncOptions), }); } diff --git a/src/SopsStringParameter.ts b/src/SopsStringParameter.ts index 42321106..704877b1 100644 --- a/src/SopsStringParameter.ts +++ b/src/SopsStringParameter.ts @@ -2,8 +2,8 @@ import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; import { IKey } from 'aws-cdk-lib/aws-kms'; import { IStringParameter, + ParameterTier, StringParameter, - StringParameterProps, } from 'aws-cdk-lib/aws-ssm'; import { RemovalPolicy, ResourceEnvironment, Stack } from 'aws-cdk-lib/core'; import { Construct } from 'constructs'; @@ -12,12 +12,36 @@ import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; /** * The configuration options of the StringParameter */ -export interface SopsStringParameterProps - extends SopsSyncOptions, - StringParameterProps { +export interface SopsCommonParameterProps extends SopsSyncOptions { + /** + * The tier of the string parameter + * + * @default - undefined + */ + readonly tier?: ParameterTier; + /** + * Information about the parameter that you want to add to the system. + * + * @default none + */ + readonly description?: string; + /** + * The customer-managed encryption key to use for encrypting the secret value. + * + * @default - A default KMS key for the account and region is used. + */ readonly encryptionKey: IKey; } +export interface SopsStringParameterProps extends SopsCommonParameterProps { + /** + * The name of the parameter. + * + * @default - a name will be generated by CloudFormation + */ + readonly parameterName?: string; +} + /** * A drop in replacement for the normal String Parameter, that is populated with the encrypted * content of the given sops file. @@ -48,9 +72,12 @@ export class SopsStringParameter extends Construct implements IStringParameter { }; this.parameter = new StringParameter(this, 'Resource', { - ...(props as StringParameterProps), + parameterName: props.parameterName, + description: props.description, + tier: props.tier, stringValue: ' ', }); + this.parameterArn = this.parameter.parameterArn; this.parameterName = this.parameter.parameterName; this.parameterType = this.parameter.parameterType; @@ -58,8 +85,9 @@ export class SopsStringParameter extends Construct implements IStringParameter { this.sync = new SopsSync(this, 'SopsSync', { encryptionKey: this.parameter.encryptionKey, - parameterNames: [this.parameter.parameterName], + target: this.parameter.parameterName, resourceType: ResourceType.PARAMETER, + parameterNames: [props.parameterName ?? this.parameter.parameterName], ...(props as SopsSyncOptions), }); } diff --git a/src/SopsSync.ts b/src/SopsSync.ts index 969d9b15..7c57d7fe 100644 --- a/src/SopsSync.ts +++ b/src/SopsSync.ts @@ -21,6 +21,7 @@ import { Code, Runtime, SingletonFunction } from 'aws-cdk-lib/aws-lambda'; import { Asset } from 'aws-cdk-lib/aws-s3-assets'; import { ISecret } from 'aws-cdk-lib/aws-secretsmanager'; import { Construct } from 'constructs'; +import { SopsSyncResourcePropertys } from './LambdaInterface'; export enum UploadType { /** @@ -35,6 +36,8 @@ export enum UploadType { export enum ResourceType { SECRET = 'SECRET', + SECRET_RAW = 'SECRET_RAW', + SECRET_BINARY = 'SECRET_BINARY', PARAMETER = 'PARAMETER', PARAMETER_MULTI = 'PARAMETER_MULTI', } @@ -96,41 +99,6 @@ export interface SopsSyncOptions { */ readonly sopsAgeKey?: SecretValue; - /** - * Should the encrypted sops value should be converted to JSON? - * Only JSON can be handled by cloud formations dynamic references. - * - * @default true - */ - readonly convertToJSON?: boolean; - - /** - * Should the structure be flattened? The result will be a flat structure and all - * object keys will be replaced with the full jsonpath as key. - * This is usefull for dynamic references, as those don't support nested objects. - * - * @default true - */ - readonly flatten?: boolean; - - /** - * If the structure should be flattened use the provided separator between keys. - * - * @default '.' - */ - readonly flattenSeparator?: string; - - /** - * Add this prefix to parameter names. - */ - readonly parameterKeyPrefix?: string; - - /** - * Shall all values be flattened? This is usefull for dynamic references, as there - * are lookup errors for certain float types - */ - readonly stringifyValues?: boolean; - /** * Should this construct automatically create IAM permissions? * @@ -150,14 +118,19 @@ export interface SopsSyncOptions { */ export interface SopsSyncProps extends SopsSyncOptions { /** - * The secret that will be populated with the encrypted sops file content. + * The target to populate with the sops file content. + * - for secret, it's the name or arn of the secret + * - for parameter, it's the name of the parameter + * - for parameter multi, it's the prefix of the parameters */ - readonly secret?: ISecret; + readonly target: string; /** - * The parameter names. If set this creates encrypted SSM Parameters instead of a secret. + * If the structure should be flattened use the provided separator between keys. + * + * @default - undefined */ - readonly parameterNames?: string[]; + readonly flattenSeparator?: string; /** * The encryption key used for encrypting the ssm parameter if `parameterName` is set. @@ -167,7 +140,10 @@ export interface SopsSyncProps extends SopsSyncOptions { /** * Will this Sync deploy a Secret or Parameter(s) */ - readonly resourceType?: ResourceType; + readonly resourceType: ResourceType; + + readonly secret?: ISecret; + readonly parameterNames?: string[]; } /** @@ -245,28 +221,9 @@ export class SopsSync extends Construct { */ readonly versionId: string; - /** - * Was the format converted to json? - */ - readonly converToJSON: boolean; - - /** - * Was the structure flattened? - */ - readonly flatten: boolean; - - /** - * Were the values stringified? - */ - readonly stringifiedValues: boolean; - constructor(scope: Construct, id: string, props: SopsSyncProps) { super(scope, id); - this.converToJSON = props.convertToJSON ?? true; - this.flatten = props.flatten ?? true; - this.stringifiedValues = props.stringifyValues ?? true; - const provider = props.sopsProvider ?? new SopsSyncProvider(scope); let uploadType = props.uploadType ?? UploadType.INLINE; @@ -289,35 +246,38 @@ export class SopsSync extends Construct { } if (props.sopsFilePath !== undefined) { - const _sopsFileFormat = - props.sopsFileFormat ?? props.sopsFilePath.split('.').pop(); - switch (_sopsFileFormat) { - case 'json': { - sopsFileFormat = 'json'; - break; - } - case 'yaml': { - sopsFileFormat = 'yaml'; - break; - } - case 'yml': { - sopsFileFormat = 'yaml'; - break; - } - case 'dotenv': { - sopsFileFormat = 'dotenv'; - break; - } - case 'env': { - sopsFileFormat = 'dotenv'; - break; - } - case 'binary': { - sopsFileFormat = 'binary'; - break; - } - default: { - throw new Error(`Unsupported sopsFileFormat ${_sopsFileFormat}`); + if (sopsFileFormat === undefined) { + const _sopsFileFormat = props.sopsFilePath.split('.').pop(); + switch (_sopsFileFormat) { + case 'json': { + sopsFileFormat = 'json'; + break; + } + case 'yaml': { + sopsFileFormat = 'yaml'; + break; + } + case 'yml': { + sopsFileFormat = 'yaml'; + break; + } + case 'dotenv': { + sopsFileFormat = 'dotenv'; + break; + } + case 'env': { + sopsFileFormat = 'dotenv'; + break; + } + case 'binary': { + sopsFileFormat = 'binary'; + break; + } + default: { + Annotations.of(this).addError( + "Failed to determine sops file format. Please specify 'sopsFileFormat'!", + ); + } } } @@ -402,26 +362,14 @@ export class SopsSync extends Construct { serviceToken: provider.functionArn, resourceType: 'Custom::SopsSync', properties: { - SecretARN: props.secret?.secretArn, SopsS3File: sopsS3File, SopsInline: sopsInline, - ConvertToJSON: this.converToJSON, - Flatten: this.flatten, - FlattenSeparator: props.flattenSeparator ?? '.', - ParameterKeyPrefix: props.parameterKeyPrefix, + FlattenSeparator: props.flattenSeparator, Format: sopsFileFormat, - StringifiedValues: this.stringifiedValues, - ParameterName: - // Dirty Workaround, refactor ... - props.parameterNames && props.parameterNames.length == 1 - ? props.parameterNames[0] - : undefined, - EncryptionKey: - props.secret !== undefined ? undefined : props.encryptionKey?.keyId, - ResourceType: props.resourceType - ? props.resourceType.toString() - : ResourceType.SECRET.toString(), - }, + EncryptionKey: props.encryptionKey?.keyId, + ResourceType: props.resourceType, + Target: props.target, + } satisfies SopsSyncResourcePropertys, }); this.versionId = cr.getAttString('VersionId'); } diff --git a/test-secrets/README.gz.sops.binary b/test-secrets/README.gz.sops.binary new file mode 100644 index 00000000..bb252627 --- /dev/null +++ b/test-secrets/README.gz.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:EjjTw976sTEpeSvA0cMYF4VruJFLRpi4Hfk3+eEb6i545QOyHUEkknnrjsr3DN1RpvyppbAmVq33WHnB3FL9CKuXfNc9k0hhTjWFAgGjYVZqLzRZJIyjbKFkxYVdpFjbCxk6L5hII1d/SRh61/WmKktEZ18eBNf88f5E5WrznPOjJfq4Zto50kkOcnn6zL7U/LuWh6iqb9Zfnc2aQpSX5JPMhc6wVp8xOMFfBT2n0bOeUHVMZzf0/jiNTcKURy+ENyqibc8zEtAGqFHVGsK/uC3YsE0zGntr3Tn40gcAkfmewz8YEU2YrnOA+KJgHoBA6hjLdCsjAdYdQ5kQRL2iZKA1AK3TosKGwjIQfS/kOi2xY5Q43tNuEkPuTjvY4ugEeuXGXxfQRz8RyoRsKIk+xbP6Pv6SoYvM5tWGwd5pzb0NDXJx7oJpilX40YFFdFegqYa9gfOhSQ==,iv:vLpG2x1eJ+HUj/VAyEnTzQYku+Tu7E+Ea2qnYMMJy00=,tag:41WDFsgPC7AEJzy49kOwGQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvcUpWa0IvQjc4Zk1jaXEz\nVFF1TURUSkdxdkp6QUpKSWkrL21pWGZjajJZClVaOGJTd0FOMU5yanRMOHJ5REdS\nS0RoOC9PcUEyWmZ5NERqRFl0UjhyREUKLS0tIGJrc3lINVFsZDNSUjZjS2lwdnpV\nbXFzd1gvSnVUKzZTcHJiemNRTEEwOUEKZ+L9VZbrFOw1qWjUFX9YCOawR/WqPXEp\n167H2YaedW7JfgEX6LZNwrccMQEEzKS1aogrqdM0xrq8gy9wmlRf0g==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-10T09:56:02Z", + "mac": "ENC[AES256_GCM,data:ctF4yVtqwUoo69pqguDM51pTeD1v+oF5vjhxygIuWGlXllM+eTnhtv1KMf6bXqveEcHhbI7eNmqbOI2Ts+v+1a3Tekj32yk0YjyQ9YGxqdkJo8HW6/J4rwmobe8EFujAMs7K7vT0BOFB/KOWbk1De3VWlLC7R3FRsVFGV0hcyGw=,iv:A/sVJc4+bmWVzRT7kHgRn/zbwJfHeCsnXt9VhH4+AwE=,tag:eXWJKToJDMUYg/WLeMLfvg==,type:str]", + "pgp": null, + "encrypted_regex": "^(data|stringData)$", + "version": "3.9.1" + } +} \ No newline at end of file diff --git a/test-secrets/README.md b/test-secrets/README.md index 4745d778..029b9b99 100644 --- a/test-secrets/README.md +++ b/test-secrets/README.md @@ -7,4 +7,4 @@ The following keys were used: ```yaml public: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu private: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3 -``` \ No newline at end of file +``` diff --git a/test-secrets/README.sops.binary b/test-secrets/README.sops.binary new file mode 100644 index 00000000..ce5d437b --- /dev/null +++ b/test-secrets/README.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:M9gzDsRd9oCruM1DhYiUA4YCAGvSuAWORbpXepreT3NxIfD8Y63pz00LHh/t9Y+WrTBApJuOOD3UYhU1Jrvu638HedrB1A5sq1tOuAVsYz9+KUaOjaoyeyMhvwrNzvlzaH6J06S2qb2q/G1pUHWVPkoEOUhiGNyXTbQch4nHUBbUZpUSkmqwtvzkIYOx0FbxRhf0FwZXay4S+XOMcDuKbfQx8hA1gXXdgZal2nleujE4kXWah7gB/q0AcfjIjhytPaeieElPXrNcJdyIRKllOWtpmowDxaRmqU4iqUYg5k/OybtKwPvbg2mjYxLwJZr57xjzEX2tFJi9kuoxl4HP04qVERPbaPuy3q61Zb9+FwtW85ebnViOAITp//R78KkmrQVzGx6VKY+2JxbPGsQ6HfeSm7WWWGCXteuTDYAgpoEKlZHMd/6hY07D92tlna8vadBPOcLAl7+cxVfCJaZ7Ob63jFgzPo6/LOTzYjqDKvLIEKdFGj08PwiED3vUiX4hO4oi2MUkfNuI1jyjP9Aqwj/H2QwvqpbtGDjD2+CdyOdw5pBEQQ==,iv:ntwa7TSFVDDAhd79X5GLD2B61FM19QajO2BKROjF7sk=,tag:4NfwoTRNzKK1UP2GxaQRXw==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXNUEyT09PR3pZYmN1ZU9S\neURCWUdZYnhmMzBiSm1FcENYNGliNGtNZzFRCk52TVZCSDRBOWk5TTB2dGRGTFgz\nMklsZUV0ZForUkxaM0ZiSTRIcW5id3MKLS0tIHdFMHFMMUdEYllUaGRRSEl6UGZw\ndFF2ODBPZGRrTnBGbWJvdVZvdWVGUW8Km5PYXRuTBvjmMDYmg6NEKhIbUU/SHPSZ\nTtgwos8id+MYTpudG+aKVTKSx91Gnx9ekLcTkafEw/YULU9crybYtg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:50:25Z", + "mac": "ENC[AES256_GCM,data:NjLPZL5bdkc+ebNrpT9sjsOZjUE/Z1t/Oq1q4CEs731jgbW0lolLZ3Dr7EFVNLoC5eunhQxvn7E6ZA1bpmqpijtMNSkqqVQdG1JszF7YGhF9Yj+Tyz9RHhvNFuH8AFcl4f1ksD7GmnV7dYsj1r1YP3wwFY+UhEqlq4+Kd87Vna0=,iv:8IMB37V4kxLHrNiIV0cVZtB2VCfuq8SYANsyDyl3m1o=,tag:EGBXVOIayzn2lh5Zi5+Gxg==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/_testsecret.env b/test-secrets/_testsecret.env new file mode 100644 index 00000000..703d0ea0 --- /dev/null +++ b/test-secrets/_testsecret.env @@ -0,0 +1,17 @@ +apiKey=sk-1234567890abcdef +database:host=db.example.com +database:password=P@ssw0rd! +database:user=admin +someOtherKey=base64:aGFsbG8gd2VsdAo= +specific:boolean=True +specific:SpecialCharacters="ajkscbuiuXA34%%&&= +specific:HTLMEncodingTest3=@ +specific:HTMLEncodingTest1=test +specific:HTMLEncodingTest2=& +specific:null= +specific:number1=123 +specific:number2=123.456 +tokens:0:service=service1 +tokens:0:token=token1 +tokens:1:service=service2 +tokens:1:token=token2 diff --git a/test-secrets/_testsecret.json b/test-secrets/_testsecret.json new file mode 100644 index 00000000..89659261 --- /dev/null +++ b/test-secrets/_testsecret.json @@ -0,0 +1,29 @@ +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "user": "admin", + "password": "P@ssw0rd!", + "host": "db.example.com" + }, + "tokens": [ + { + "service": "service1", + "token": "token1" + }, + { + "service": "service2", + "token": "token2" + } + ], + "someOtherKey": "base64:aGFsbG8gd2VsdAo=", + "specific": { + "SpecialCharacters": "\"ajkscbuiuXA34%%&&=", + "HTMLEncodingTest1": "test ", + "HTMLEncodingTest2": "&", + "HTLMEncodingTest3": "@", + "null": null, + "boolean": true, + "number1": 123, + "number2": 123.456 + } +} \ No newline at end of file diff --git a/test-secrets/_testsecret.yaml b/test-secrets/_testsecret.yaml new file mode 100644 index 00000000..71cc8a85 --- /dev/null +++ b/test-secrets/_testsecret.yaml @@ -0,0 +1,21 @@ +--- +apiKey: sk-1234567890abcdef +database: + user: admin + password: P@ssw0rd! + host: db.example.com +tokens: +- service: service1 + token: token1 +- service: service2 + token: token2 +someOtherKey: base64:aGFsbG8gd2VsdAo= +specific: + SpecialCharacters: '"ajkscbuiuXA34%%&&=' + HTMLEncodingTest1: test + HTMLEncodingTest2: "&" + HTLMEncodingTest3: "@" + 'null': + boolean: true + number1: 123 + number2: 123.456 diff --git a/test-secrets/binary/sopsfile.binary b/test-secrets/binary/sopsfile.binary deleted file mode 100644 index 73e6592d..00000000 --- a/test-secrets/binary/sopsfile.binary +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q -W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA -AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB -AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ -AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g -JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u -Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF -YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY -bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 -ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C -ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO -jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN -23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/test-secrets/binary/sopsfile.enc-age.binary b/test-secrets/binary/sopsfile.enc-age.binary deleted file mode 100644 index f1805d71..00000000 --- a/test-secrets/binary/sopsfile.enc-age.binary +++ /dev/null @@ -1,20 +0,0 @@ -{ - "data": "ENC[AES256_GCM,data:1szZY1Vg1DsmbynG4Dw9qvHVuzXh6vWngLoUMEnR87VFB7/Nu/SfnD2s0n/KvhQuz7bZie1wvtJoFZD6hgjdA/kzMOOJTSWH40drn/Cx6mmFSDlVCD3f3K3jn6Xg8uZGQaW/X9jmYkTTyRGQhrLuhLEmgHeM+BK3gF12zMSDyjij9BkGh+GgXo07Md2Z7F84UO6PQdEebc8YteIVk1zN/IQVFTNUa9tu9TDNSL6xfMWjBF1hmKQuH0OS/6B/RohBExPjxxIT5yA0LjVG1kijCdwcfDfuWMA/wv0jrdWGABBipju5VDXU8lepc5w+WIHq59yNDqMYXkb2s7YgHY9Uwt+nUEqn68pXA4IqXL4pdnnZjyEGCqnG0ltt+7bcjNORIwPTMRxl6bXCXRNSFtANUxVvBvyV3rvFee4G6SZMfG2QThraIKdx3p1C+ZnmJCwldFooCVXCW33n2jTiTcNlgEQfoGAyKL95ZOlct+pedAjFkGuDlpn9DGvbBQgGbLx7IdCX/RvCuYATLaUjf118/W2djStJOio2qr6ql06J6nZamDIBoxdQ2NHNHWTJsKMDF8Ya0mzUlfdTzJtn/ZQFtY5R+u10iCPiZOF9dY3jSBy8Oa6XHicKnpl6iXfw2SwGMJ0MXvS+TPfjsgLIFboDHD/1aFbaceMS57D83z8FHqU03xnb3HWs6J2G00Oj0Ow6AA7+/oo9hEdDC4pGQSjXLwbZilwoKRjamaJ35EMOkywiMeIvtQggyaf0g37lS4Hlflrop3vlvh5pInY2qb4fROHmE76nhIQ4Ek1AXPOLPkd3Wu6bIqGm+WsNYtsTn4c5btuLYFP+XXHkhrE5Z9oRX2U+go4tdlGy4nCTsUVhOIFDJPJQndjppSwBGUXDyf4qJSzSfYVHXboBD6glV+2iEBvq5Ewfr7s9vOgAu8U/mJ1eYEVauigDxcup/t85EpXPeFZIIn/g1aPXHtvujW/B7HuaAWcAmSb+t/YZ7MHEcJnQgHRNstIdiVuJWVoielvR6+7/SZzcmkTahTu+3g99R4pLEeNB4poj3kv+/A/TihnUWhyLuGpKRAAgscMqxBo/wgD4f7mcG8OAfQcGVKerc5pwDhTEbcjlXPcuMTJ8pbBJFebxIl2eL8LbcbcG/Fu1WstdA93leQ2NwPmX3SSNclwTf7yR/A==,iv:QLfsbEB7wLwwXT2+1Tf92L/abYF6ewC2658e0CxlRvE=,tag:Z4BdO/nT8HukvgTHi8sLFg==,type:str]", - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBONWJSL2xVOFVablVpbFBr\nZ3cxVzVEZ2ZxVTRzWU1NVjdua1hEczBhNmdRCmFEYS9YS1AweWVDVXFRRTV2c01T\nZVBoa3ZRelJXOUNCVk9VNGtLWnlrRG8KLS0tIFdtT0tjMjA4Y2NkMVpyOFdKY2Nm\nbld4RjRraDlrYkJHRm9PRjUxVm0wUk0KLWT517HtucD/VDU08s4zNqQ8rVhmQaaQ\nLfgVbIjVFsQb0MUdIMHQovJ4OLIXaKSo+PMHswU/uxMvaEjD+ulTyA==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2024-05-31T18:07:09Z", - "mac": "ENC[AES256_GCM,data:qmwxSfIs+OlIxq7LlG2vZPLelEtXylOLuLBBJoZn6ZGaV9I75umIb+vHYcbmtYUHZRMiEAvv1kMLprVR66burD/pxa4oNjXuVhSXR1nxpb7bhimgqKmw5mN2Kk4Dx7cq4lqIfLfEZhPqRKgPOdCBpEMYbqGNsOOMXqDRRyroeC0=,iv:Fsmb0IGbjCYc3tKIEF17rcPZfe5QeyJ+ZMpYjiSofyI=,tag:TMfwecLKdL1MDisnQioB2Q==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.8.1" - } -} \ No newline at end of file diff --git a/test-secrets/dotenv/best-secret.env b/test-secrets/dotenv/best-secret.env deleted file mode 100644 index c2619162..00000000 --- a/test-secrets/dotenv/best-secret.env +++ /dev/null @@ -1,2 +0,0 @@ -banane=yellow -crypt="ajkscbuiuXA34%%&&= \ No newline at end of file diff --git a/test-secrets/dotenv/encrypted-best-secret.env b/test-secrets/dotenv/encrypted-best-secret.env deleted file mode 100644 index 9e9ba6a6..00000000 --- a/test-secrets/dotenv/encrypted-best-secret.env +++ /dev/null @@ -1,8 +0,0 @@ -banane=ENC[AES256_GCM,data:KfCbo7Z8,iv:ewDKVZH7/fL4wRksCySb4M9HIhZ4+w43mXgmYUtKzU8=,tag:KuoFFUA47LJLWpDJJwb7cA==,type:str] -crypt=ENC[AES256_GCM,data:2BpWV4wG7Go59fyxTmQaqKnIug==,iv:IfEHwS+Re2G8IHcOuyomvWfgb0G6X6slRSNoNclDNj4=,tag:541QTPLUJcunvp8LZIv+xQ==,type:str] -sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVEJBcXBqMEt6L3lQTFZM\nYUplSGRPRDVsL2Y0NFBNYWF5cmZLcXphcjFFCmFyUTUvRjRRRVhsOVdmd09nbkZr\ndG5wTjdCYlZxTnlMQWNFd3FaT3FtK00KLS0tIEIyS2pjYTlSSDN5R0FrejZMdUZk\nMlpmRDVjZk1SZUVGR0NDdnVhWjhvVTgKsB2MvVrUiJU2qvN8x8kUhZdvKP1Rqqfd\nuHvaXnVZ0puLCyW6bJPPH408N+nsmzcZIS9XPw9aRptQvUV53O5NVw==\n-----END AGE ENCRYPTED FILE-----\n -sops_age__list_0__map_recipient=age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu -sops_lastmodified=2024-04-29T11:58:27Z -sops_mac=ENC[AES256_GCM,data:WEYgLvSAiZpbgTq67oawPYie3vujHViYFR51q1KNYCvptZ9XVm6wUCfuVenD79MgSSySTEFxV7BXcbqMIKTP+aG7K5PKeHuuA91uEPwKuv/X2ErcQ0ttHVd+RDDlov97w8NOKWrgqNhWlQ8PM4uCoyspt0DRTLDFmEdLy9/LJnY=,iv:UDIQJDWn0mggYZStz9x0zJ9OJQQ7GLq0eur8M4K1u0o=,tag:kpYoKN9AuX+I6XpRQfWODQ==,type:str] -sops_unencrypted_suffix=_unencrypted -sops_version=3.8.1 diff --git a/test-secrets/json/complex.sops.binary b/test-secrets/json/complex.sops.binary new file mode 100644 index 00000000..7bf22bf8 --- /dev/null +++ b/test-secrets/json/complex.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:zomC/advyRjbi+7BhnHjYGPiRKGgpsY2GbBVUi/7A4EKYOXOf4870xhRkxAHBUA+CllzjfLsVc3GbYPsdJ1VzymbQL5dCNOMMbn/KgMIq1eSYpnYWZ3kOMPpVJZi9HVMEOVa4rRQbmjqnY640XEvv1mjN0/8AmJdp1vPABLmCiLCka++sIrkdFzFOwI3GlKa7mfrn137Q5VaDb3RnOzfT9lvC2ymuvFVu/Wpk6WANpID0PwGa8AZD5EHBqTYG2LbFY3CDkKMgRRurrRsRr8dih4KyF4CckyE1mo2WoxpaN9JFAS985IEYvVZZbzxSfVxved2K4qLp5xCBlE8mp3rvkDIdtGywQlm56B8Vra7sXije4/RuS8yhxW3HG3K0mZ1rvxKdZigZaWM/1De6H842QmkuIHABkbi8G60HtIiGkTCoqeS0MrqmoFS+c5+Fb3wA/cfTgstcFWbYVafhZUOkO8KfoEbWFnvCnKhCBsJWq0bve2rGKMSCFcXX5I1DDJ/XC7WQBc5PcsImKnuByu+4pgrMimz1Ah50SJM3eM/GYpcJvvhfZyEf5ustnzKvVSK04RKIXIX+G2hFawgj8gm2uw079vF2WkWslrJepA7xh338D5f0DMurvTkujiLq9DtkrW4FrxB1dsplpcl7CHyUdXPK7/Ii1V9BTvpdvLqPR7by75s64xClJt5GijkWBWUJitxrwG+Szufnv3Bbj++MRUrhEiSvGoR052bpmk=,iv:ei7B9c6t9hLtnDYJWnkRl1Wf7SWDUPlKkisDjYORZds=,tag:sMBkA3dZ8hMZWA6dF7EOyQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFMVBqMWNaanp1MktqRXBE\nYlVWWWxjUW1NZS9oVmMwMDdnWko5UzRjMGlJCjJaS0FWVDQvS2RoMHBHMEV3VG1M\nTml0dVhlUGdENzk2bzFTS05CSE5OYXcKLS0tIDRLRHBHYTQ3aXROV3VwMis3UVlZ\nZnNZQkZqWENjaGRwcWJ6SDB2VmJOcHMKlqxMDLaL4vdsmpKZct986r5CqlnwROXB\neYzxlSDP/48hTej56BzCsVYOHHOcFBud255HaVINXu9mHjsov0XYGA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:07:37Z", + "mac": "ENC[AES256_GCM,data:dJGBOZbUlZ1TCq2ZCzl7Giwwkjvh9nCaqkj4ZfSSxbsstOg1cUPUhwYzyxBLwj0tl/tmPjMiyz0MlY8ZtL/CFfjktWJbzZL3AGGU+Eq2WRt0sH6skpymy07w381HiWJfzz10GC0+yRXCQWWSmdQ3bNlyGIrXIT9eAtU83VnvTmE=,iv:tIe0mulg3snFbpfW7Qk1W7tSkM3tOIFv5OQwK3wVLz4=,tag:pRkSBsjR/1WZ5QLKITd2Mg==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/json/complex.sops.json b/test-secrets/json/complex.sops.json new file mode 100644 index 00000000..39deadfa --- /dev/null +++ b/test-secrets/json/complex.sops.json @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:9PHZv0Okb/u2GbUKLtimcD+e/j+QbV8f5F7GBaE7BYmFX0Ft1p58b83AyBALjcKmldUQTQVLvkVEROHyZvQXM5HMEgGMJqu2aaCJgvaUVd7d0c8L4WppylxvzfPLzZFtE+m+H07Ab6FgmL/EtEmzLaNJX+d31gyfCNXO7svY8VnctDMMHWflXNGMmQbo5UPTsKasx9U5xmQJRFEPJXWJPXBWtpYXRiMYn0t5ZTrrPJf9I2suKzCFx0I+t2yga4iJEdTPiW8Xcdu2P8VTY3YboEBgvMMqj9W2ZlWYy0uPt9ACcmec1EhNB1IfB6lQM+siLlGZyrI/4gBtmX+Z5fIMYYBcm2oj2VSdSFErAHtmbQVJ3vYKVuT/ztGHx42SNExpeS5pIHYlKkCFsbvHo222r1d4FelbxLOcIaXs9a0bdIco4s5tYDy92vRTjYp6MjozzWixpou/bZzY3kwHVTSFXv7MxD/o+vN/W+Cgw/XnYY/VdLjyWmdYWOc+zKncZC0NuCxSWOGmS3C/nH1w3lnm8HQ4trksrm0/XFzyqbsDLfGaxz1LQJiEnTC3QS8plcWit2SZYIWH9azc/PGa4095/gCUcvGDfCqoswNAuKPyFDEPHqQPkh4x3qLQY6xHLC9IO2kWWyxsFWM5EGXMTxeKFW3q5N+3xbr5KuK3yyoFf9Rk/2wd2qDEhWPx0RwuGxXv+rjadwIkZxWAVLY8iKHAiKqrCTDt67cO/T/eTm8=,iv:CQtbsFV0L+VkrsG2HyYDqMyXZiaAPDLCyYYJjUMw2mY=,tag:GfZwBt/vJim2jZX9WYEdNA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvcDcrc0pFbXJkbHk0K00x\nNkRMcmlQQVlVRGlDTEoyeVFwMWdUSHU5cTM0CmxhWGdGVDZndzlxYzNlS0xuSElv\nOU9JM1I2WERIY3hmcTdFTzRoSTgreEEKLS0tIGJJUkdMeUluMGJ5Z3dUM3lrakJh\nMVd4UENwQ1dvNFdkeWVFL05uU3I2cGcKuM1BUeQilKGIVstjC6wU368ovRx9upJr\nTga8aeE62fxDrp4gRRHqAw6KhT5OOnDdaZs5Ze5pFxkeO90csLj55Q==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:07:08Z", + "mac": "ENC[AES256_GCM,data:8ztXnA+XO8v74aLFeeCOn2VBIeXvk4vMiASOPftwQgZFTaesVvQRszAPNpVrdr0JmMiTHNfyMOeJd4pEOSClzcynYLkEurxJIAXIWgFaGg2pZS9yO0Ybg/gJLsApV+s4FPtFSLSJjd42QlNwCUex6noUIR/kSchXOMs9qbyxdrc=,iv:5L71jZk+jVrK8vNCCKESj4mBavZ0RCTqio445TKkr8I=,tag:PVBvVFXtgt0SetwjxUy2fw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/json/sopsfile-complex.enc-age.json b/test-secrets/json/sopsfile-complex.enc-age.json index c865fd96..22a401fb 100644 --- a/test-secrets/json/sopsfile-complex.enc-age.json +++ b/test-secrets/json/sopsfile-complex.enc-age.json @@ -2,33 +2,38 @@ "some": { "deep": { "nested": { - "object": "ENC[AES256_GCM,data:yukHuGsD0wgY,iv:Ughn8OgNcdIPSz1hXCpcnJODSDrk19y0UMcwQzTRJFc=,tag:wOpa03Pdp63eeVL1t9GPwA==,type:str]", + "object": "ENC[AES256_GCM,data:KqcODVlKoN+h,iv:0cIx2pZoTzfGq6JaSD72yVYLbzThijiEyDCnle7m8Bo=,tag:m4HgUT9//lEjgxxWKcwTlQ==,type:str]", "arrays": [ - "ENC[AES256_GCM,data:M3+8vg==,iv:GDrQlRnH0P32mlD9eZMovhJ4Nk6rMb/E79GQ5uPba04=,tag:abOv3ysU1Yk96muxLGyOHQ==,type:str]", - "ENC[AES256_GCM,data:0NC0GL5pRA==,iv:+JH62RSknw6AXN6vMPDB2gm9RRtnChxPz8tw99X/6y0=,tag:ZPKzHCY66HK0BaukjvZlvQ==,type:str]", + "ENC[AES256_GCM,data:cwdZGg==,iv:nHtR+SK2qPPwvkWIuLSQR0NOy7vm53KXHg8A7WOjVyM=,tag:EW/JaUnr3n43H3ZNC4AAbA==,type:str]", + "ENC[AES256_GCM,data:zqWmSAyFuw==,iv:M/0wJ2xjwWdlNJ4XSMOHpUT6bPlh21jl3inR19qj8qc=,tag:60Hb9dVqXphkHl48cU+skA==,type:str]", { "values": { - "and": "ENC[AES256_GCM,data:PVjnZ2Zm9g==,iv:WAeNDT4xl9XKXnkGArsDKaN6TxRTI8uWOtn8x+G0hnM=,tag:SyLib8RPN65pyqkFgPhlVA==,type:str]" + "and": "ENC[AES256_GCM,data:9q+bY2/Fxg==,iv:oGUlni+NO9BE1FSvVhp3mGs64DhNErVES3tMVY1geFU=,tag:9a//E2BWpBnzJNBkshNVPQ==,type:str]" } } ] } }, - "notsodeep": "ENC[AES256_GCM,data:KSf6pl1e,iv:OKR5+hw6GCzbm750sAlAXW8/G4Se8Bu1FWHHtEenYeU=,tag:5hlF03Om7qVcJUG3U95uvQ==,type:str]" + "notsodeep": "ENC[AES256_GCM,data:sSIRj3Fd,iv:hvi5Yygsf+czctpvuvAItgioIIfGBhFuvse9CsF7BVM=,tag:drZ9yZCsQZ+N9f78gYe/sg==,type:str]" + }, + "with": { + "TestValue": "ENC[AES256_GCM,data:bto965a3UQy4xhGhrnLHp6UOlLVY,iv:jfyb6zm1S4DxsEDnwNx17PjpNoLoM1GjWycNAYLIiTo=,tag:p5NKNN/4gfPK4wbxalrMgg==,type:str]", + "TestValue2": "ENC[AES256_GCM,data:2A==,iv:5pptPCrBWBdZ2dyEE7fb53kdF9AXSBO3U2zQJ36SEFo=,tag:R4p7PdwCQVJzkFtpHcWzyA==,type:str]", + "TestValue3": "ENC[AES256_GCM,data:pg==,iv:qAzebSlwqDH75A4ptv0b5u2nX01Q+K+I22lyHXfOGg8=,tag:TS/dSzzkIXsoNyyqfu9dbw==,type:str]" }, "and now": { "some": [ { - "basic": "ENC[AES256_GCM,data:KBo4/k0=,iv:kp4gxhCpWnP/VvInFBNlwXTE6sk48N322sAaGsNeebk=,tag:E45zw12lkRgKdEIH/ARnyA==,type:bool]" + "basic": "ENC[AES256_GCM,data:LLfe+cU=,iv:KK/akV0TnHIKxi+ZVRRuqGW9/BZeaVq+bVoWjbw8V94=,tag:fZKNID18dnK+TTcUC02iBQ==,type:bool]" }, { - "nested": "ENC[AES256_GCM,data:rzJs1m8=,iv:+oRnXYPa6Jbv/iNt1QknyhdR7Z67fVHVq2nvq3GZOTU=,tag:AWLhtD4E/+EHIDJgipqM1A==,type:float]" + "nested": "ENC[AES256_GCM,data:94TT9qM=,iv:suWnfGAoEJ8oRbh6guaX5ZmaBJii9k9s+1Rktn3PeUQ=,tag:eAgf5Id1PiU2nVo3Q+h67w==,type:float]" }, { - "type": "ENC[AES256_GCM,data:nahV3BNE,iv:iddjiztjRaUqTaS6uVTPPDiXHNYRDC+oIPD819/GCRs=,tag:qD4bztCGw9C4wi0Kl7vLUw==,type:float]" + "type": "ENC[AES256_GCM,data:9MGS4J8e,iv:LIza4w0iCTY13SBtIkL/zXXvcot1NRkhQoXQCO6YI1E=,tag:U3tdtG7sCOgJuX0HNwd6Bw==,type:float]" }, { - "tests": "ENC[AES256_GCM,data:8ofXTHND6w==,iv:DrKo4rv3vV/N8b1S5dTiJGyLHNlvnrX8gIZDqNzq1eg=,tag:gFPndV96rOk1R0dAzefmuA==,type:str]" + "tests": "ENC[AES256_GCM,data:ZywWxDM6mQ==,iv:cbJtn9JN7UvB7qcvu6/x+BAE6IKZR28ec1295tvbo3g=,tag:9T8Q3PiisNnwKbJyGXsI/w==,type:str]" } ] }, @@ -40,13 +45,13 @@ "age": [ { "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxT3NGU0JET0NiY1NQcm9n\nZFZQSCs1NzdZaEkvSGhmTDV6bFBHY2VZa2djCklCZkJ4Vy9STlBud2prSm5KR1hr\nN0hpaDdoWGtxakR6MWg5UjI0SXBibUUKLS0tIHdtR29SWTIxWmhMenlaeU5xem9u\nKzhKa3NKbGp2dFVxMTVuWi9VdXJ3MW8Kanz3DpIgPXO9u44TUsTPtgwTLbP6YpUf\nJov4T2oLy4Uo668RNCB1fbKnt5nycmRJxe+rYmOvn2VeL9vWcw0kZw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3RzBneS9sWnFmWnl3NDBO\nV0FFQ3lhYzZTZmQ1U3dmbUgrR2dUaTEybzJZCmxyaEhQT2hLalM5WWlXMjVCdWpS\nWHI5dUE5MjhyM2VlWjRWY1FMd3Zub0EKLS0tIGFiZlhrMTlJY1MrMXJGMS9xbUVQ\nY2d1czhGOGdsdzIzVjNsSDNRWE93bWMKTBl/gzy3HxvBfdwBkTQ8x0zaAHflC+DU\nDZu42K3OgMSJ16s7Abbk7Bp5uzUx+UEIJB+Fb5IzVIFAvovFq2fhNA==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2022-04-03T17:24:24Z", - "mac": "ENC[AES256_GCM,data:mUSKFyYqbxQWirfzNvyNMvrJ9+j+3Q9s/ARjOWJZOJrAypJYPtbZa/duSL4CzBW6KdLf9YRfI7HjiKX5G8SUL9f5BzAXIGBq/DAEfaXZ8ArzHfK4ttx9Pe2tL+DjO//mHGEJ88JYEVjrEMLG+NDa9arpDKK8+O4LuECSoCaaaqI=,iv:2W2VtCVGfskooWMAiLoLLcDgu9Puw2Cf3di2iTYvPcU=,tag:5epn8SaE8DE2EKRmbIo1gg==,type:str]", + "lastmodified": "2025-02-07T10:08:49Z", + "mac": "ENC[AES256_GCM,data:HYmEvL9BQFp8AQNzRP6QoY8/7lsYpceP5qCPmgL/SCokgVqazV7BJp58b/6eHI5yUSxBOsvtqse0fo7R4POoOEqzVh6oSLGfT7hB0sXjn9G34MQCz6aQZiOyz41uV6/tzsOoivH+/xSLV0I5sosY8jHxa6HdD/d3V7ke+wJOSXs=,iv:VEYU+FMfdAZMha1ny9rD7GeimMyiB/E6uM3mXpaYvVU=,tag:mGwHGZFLem7Xz0dDzj0rvQ==,type:str]", "pgp": null, "unencrypted_suffix": "_unencrypted", - "version": "3.7.2" + "version": "3.9.4" } } \ No newline at end of file diff --git a/test-secrets/json/sopsfile-complex.json b/test-secrets/json/sopsfile-complex.json index c0fb8aa2..8b8f8be8 100644 --- a/test-secrets/json/sopsfile-complex.json +++ b/test-secrets/json/sopsfile-complex.json @@ -16,6 +16,11 @@ }, "notsodeep": "struct" }, + "with": { + "TestValue": "test ", + "TestValue2": "&", + "TestValue3": "@" + }, "and now": { "some": [ { diff --git a/test-secrets/testsecret.notsupported b/test-secrets/testsecret.notsupported new file mode 100644 index 00000000..e69de29b diff --git a/test-secrets/testsecret.sops.env b/test-secrets/testsecret.sops.env new file mode 100644 index 00000000..d9a2d1ff --- /dev/null +++ b/test-secrets/testsecret.sops.env @@ -0,0 +1,23 @@ +apiKey=ENC[AES256_GCM,data:yMjVmvg8ngplsw6A2Ed/L9xrFg==,iv:CqIREmvd4vtMmXR0sKFW4BzZVa9g0rTj558RfwBAyp8=,tag:uDdkA/HTENFIaFzqlHUTdw==,type:str] +database:host=ENC[AES256_GCM,data:NQGBJcEmb3Mk96XLPKs=,iv:lhkq8kcH/axV+wR8d/qcXD0isSn+BAFT+j4gD1kCqVc=,tag:WK9Cd9xQo20C726TYNBwbw==,type:str] +database:password=ENC[AES256_GCM,data:o6Cw6lRCKwW3,iv:ab1xLcrf9XWrjXAddW/vFhzOQHqbOyRiMT1WDZ2E94U=,tag:xay4qqpXVFG5SAXswtKuWg==,type:str] +database:user=ENC[AES256_GCM,data:YakZvFU=,iv:/UkM6EE2v9miMngg5hrFW+TNC6O9SHgJvpEpbBS4iZk=,tag:cQ7BgN/rlfppBaI2eXNB4A==,type:str] +someOtherKey=ENC[AES256_GCM,data:jbrUQ2ZN3G+2ms1ktUbB4n4GKMhzs1Q=,iv:nxBr7hYaKWIQ+w2R9ydqRgE8WY3wWJYHRLEML4oXvCE=,tag:h8xX0ENw30JvPUBVbn3RcA==,type:str] +specific:boolean=ENC[AES256_GCM,data:6hJZpA==,iv:Jn7vcGhG/KHuIvnWtLm4KutBcXOMGGa03VexDEfoELw=,tag:yVYbrdDc8lZQcr5M90hLpA==,type:str] +specific:SpecialCharacters=ENC[AES256_GCM,data:iVnV8R4wUo4Hmj+hNBgVhqsK/Q==,iv:2qnJFP07q+bidV6QHva8xg/6Kut01vySqoUbrJiVdd4=,tag:ODPHGLs3yU9BKAXjvH8aaQ==,type:str] +specific:HTLMEncodingTest3=ENC[AES256_GCM,data:Og==,iv:OsijRbaUtX2fNNzsI02Bm81Bx9ZpMCLl9oEYfEgoygM=,tag:W5yrTTCt8xpEyDWpmCrSbg==,type:str] +specific:HTMLEncodingTest1=ENC[AES256_GCM,data:Gtc5yOSZrpRQZRWpbFP9QCk52Dpq,iv:zs/FMO5S92w/DOmT/RhEuWQ4WXDtHYWmglyp8bmW6SQ=,tag:4nQCdkMJLnRK5RAWTmbNVA==,type:str] +specific:HTMLEncodingTest2=ENC[AES256_GCM,data:Kg==,iv:RQRy8LWFvoKd4UaWSIKL/5js6I8Wvi+r+T7uF/ox+rA=,tag:TKMdUm/83MkBnP9VtPAHWg==,type:str] +specific:null= +specific:number1=ENC[AES256_GCM,data:236O,iv:/X1jDyMOvcqfve673BjCP5r1zjj0h1KtVjMD+4rbIZI=,tag:rWBT0Rs5hhlKBTyvNwBqiw==,type:str] +specific:number2=ENC[AES256_GCM,data:iIqKlmwRCA==,iv:usF+X0flWIg9Ki7O18K01x8m/WT/kQd/aVWBSdXabww=,tag:BPHFXTeq7qru6OWG3DfUsQ==,type:str] +tokens:0:service=ENC[AES256_GCM,data:MlgbuTr1d4s=,iv:e/YjEvEtEhMQdu4obTW3BzkStSk843krefETISmxxVw=,tag:cg4E2clFJ5GWUc+iFm78Tw==,type:str] +tokens:0:token=ENC[AES256_GCM,data:Kde9qHN8,iv:HWGei+RhxWfEY+YgKT75QfwWh1piE1UJ8q4lVc4Gu7M=,tag:DLYPwmYlhRlJK6COxd9waw==,type:str] +tokens:1:service=ENC[AES256_GCM,data:d0AWlJz+nt4=,iv:BQzKHbBDTlR+8z1LTkhBLLo/7vAcOjLTfB/9qR7MdGg=,tag:s2NeOPlR1IwZiUnCs4E1eg==,type:str] +tokens:1:token=ENC[AES256_GCM,data:G4vIDVtl,iv:ihV/tjPSwSazsc/Df+dXpnepwSkP6n1KccDG8GKWRMg=,tag:RDl9c3P9kok1zWWUbifEcA==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRcTUrRWtwSHdPOTNGVXVp\nemJQWlY4aXg0ZEVSSGxsUzl4MW9ydlVYR2lBCkFDdkl4bjVVYWpja3FObC9nVFVK\nMks5ck5mSXI4QUk5R1R0c2JCVC9ZK0EKLS0tIERNODdLaWJmZ1R3NFZET3F1YVMy\nRitBcEVhNGt6UUNlc2szZUJjd1RTT1kKAYk+D7gqF+prdNAF7OdOHima/A92Njpw\nqh57Rk5C7NXvVeeJk0xKdS2zFm86IIST/KgSw7QK80IUx8iGCHf6kg==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu +sops_lastmodified=2025-02-07T14:46:04Z +sops_mac=ENC[AES256_GCM,data:vmJOTGI56UNeTSU5f3OFQ2Kqgl6N51TKHpCZ2eGD9W0sBzvri4usD9cOiiOsr1cOIVk9tjfdpjcs8/SMVLPY2D4nMfBdUO6e32tNo3V0DpR1BUPYcUykPogDF4psrJ3h1WG8+n1Y1KgVDo0+RawHp4WxeBi8/myxFvE+m067rso=,iv:MeiPPTwepzHU0rrtiVpOIngVMrGO/LGXu/5FDKe+k6A=,tag:vYSKk1/g7TPaNrninFx1Gg==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/test-secrets/testsecret.sops.json b/test-secrets/testsecret.sops.json new file mode 100644 index 00000000..fef6f6e6 --- /dev/null +++ b/test-secrets/testsecret.sops.json @@ -0,0 +1,46 @@ +{ + "apiKey": "ENC[AES256_GCM,data:lLbXVEhBRKXiGGkBh5KltgUBoA==,iv:luayJniiXHwA3Z0rZyxeF00xlHfMwrYMiYh+ahP6Ayo=,tag:l3k3pSnzRTAKeAHOxw+fGw==,type:str]", + "database": { + "user": "ENC[AES256_GCM,data:kQtkQas=,iv:+qyJ9FUXoMtcpcfdT7ZTONHf3SsGbAfJznJFt5e/pVE=,tag:2CinmzVeqn654MfYdhkqxg==,type:str]", + "password": "ENC[AES256_GCM,data:jHwCEJh02A8s,iv:imwHW4U7DV09m5NCzO5k0AuRZdY/TK2+F28VbWFH6yg=,tag:pcQ3h40D9AvBFQEniRxMow==,type:str]", + "host": "ENC[AES256_GCM,data:U3Jx/GkByKLPnebsp5U=,iv:cCuW99ktyAI4dVQzDt1/jsgLP5pMdYYCsi6AhqsgVXs=,tag:v16zyYu5A1TVBP4baOxB1g==,type:str]" + }, + "tokens": [ + { + "service": "ENC[AES256_GCM,data:MLQW8tocgCc=,iv:+/foQyR7q0hvbOkGivauUAWdihfoHKzwgSYdv1Gq29c=,tag:O2ebmT2u9NfVqoo0q4J97w==,type:str]", + "token": "ENC[AES256_GCM,data:pcrFQQDk,iv:+q/3i7niTwn/jyOqeHJ8hUVA4jN8CqPXufWsIRkkpJA=,tag:buIs8G4OfiuJPf108/sDhQ==,type:str]" + }, + { + "service": "ENC[AES256_GCM,data:gyRnIigPXh8=,iv:oTNrXTZKX77yynvcQwhzXio2rEJXsIBMUD6DOCRr4fA=,tag:2OchZmbqdcHdljC6CKkulA==,type:str]", + "token": "ENC[AES256_GCM,data:EwGCYT3k,iv:1HMzUDqmXrI3bhGaxknMftwEZ8Cc1szxaMV6A164mfc=,tag:0b5eRwxZD4j9ujixTjfFZg==,type:str]" + } + ], + "someOtherKey": "ENC[AES256_GCM,data:vVlp3EE1mgTQP9JSDGdPf/+h2FSqajY=,iv:xYGIoTYPEn+4ax2LTKixlQb5NaotVw+0QVfFSm9QNWo=,tag:+U4JQbm/8mFWAmlMryg7LA==,type:str]", + "specific": { + "SpecialCharacters": "ENC[AES256_GCM,data:uPqFOSjUMgVdroUBIM6qernOsA==,iv:rSScNgl3g66+ITAYYjjyU2HzBWYDy8lBcCGGXFvHIgo=,tag:JEw3yYdiLK+F+MCyWcth6w==,type:str]", + "HTMLEncodingTest1": "ENC[AES256_GCM,data:ksCu3G0rG2Nf5+c/9vSs0aol+xnv,iv:7+PJt3Q91CHmvRHqDIbApSMaYLoZq3D1/BnaA3CfsMw=,tag:S/At2clSsGAvHSkjLwetqQ==,type:str]", + "HTMLEncodingTest2": "ENC[AES256_GCM,data:Zw==,iv:jH3RkRJsMDL+gPPzpLv1gPX/TLy9U1zSPqIpF97wTb4=,tag:3Xaf7JWYYxIQQR88eb+FDg==,type:str]", + "HTLMEncodingTest3": "ENC[AES256_GCM,data:UA==,iv:ZYqChMLBfQoKHclu94sbcI98sVGvymM37Esshvz0Iuw=,tag:UV1zFimcgETD0ncTjpgDvg==,type:str]", + "null": null, + "boolean": "ENC[AES256_GCM,data:w2sY/A==,iv:K+2AL8Da70+1mBVzuq2eOgzkEFwembEcyX8HXKIAqR8=,tag:KYCw3m6PT8rcu1i/mGZJ5g==,type:bool]", + "number1": "ENC[AES256_GCM,data:3Y1f,iv:MCCT+EwNnpVLeu/KkiQNlIGGokimh6U7PNEFEyr1u4A=,tag:jZVaMNn4rgh+5kWgNziIig==,type:float]", + "number2": "ENC[AES256_GCM,data:EPgTD7ZxVQ==,iv:+ZJgfD2V/s3XBjQuzq0ysS5fYtS2P2hX72dj9qmuHCE=,tag:fM9g+wtubjAfjXPHCvsXVA==,type:float]" + }, + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjSCttMFlYZE9FZjdHS2gw\nQjdjeFNmRmlQVnVYMHIvUzlLTEJFZVFxZ1E0CmFxWnRwejNMZXpBNnplaUVDdzZt\nQWZGVEJ5QzMzUUhud0hkSW5vdGFiU00KLS0tIDVpRTJHMlhqTGJZSytranZaSW1a\nclA0YWFUNXIrY2x2emh5dGFTd1VjYzAKA9R9C+42bZ2bKDUn8K6SDfQ5KkrICY3r\n0N27V58ZPAo48tqkhea/o0DBtkdllrBHOxGeOIJm/wFOfnETrZ68Vw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:47:14Z", + "mac": "ENC[AES256_GCM,data:7CuCj7sJeKFZFpFp6ji3BfGzDY+X6Z5efccpTsbDj4ck/QYu+x3iLkirhhrGH0hEuN6xHKAjry/jmCRJpGh+7EGm3ffQoSYu9oC+ujSX3+7aWfhOv8ROt7R38Z9jzEn1qphKEX9lK3O+IruXHfUE+6t/zqwlIVjMGaI1ARbLBKA=,iv:n8ceHb4WwXy4VIx/mJNWNMwGbF6IvMuOw/YQa7JxRiY=,tag:hfU3SbZE7cAJ9QTXRGZj7w==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/testsecret.sops.yaml b/test-secrets/testsecret.sops.yaml new file mode 100644 index 00000000..036c1ee5 --- /dev/null +++ b/test-secrets/testsecret.sops.yaml @@ -0,0 +1,40 @@ +apiKey: ENC[AES256_GCM,data:r6YfrwGkVFxBF8mHEcsPaxMtUQ==,iv:/8rr4K5mBxLi3jR2lHfeeyVO/wQY00pc//Ow5vqY17Q=,tag:+dgLaKeSxNNBuOEFIftOZw==,type:str] +database: + user: ENC[AES256_GCM,data:sdsUyvo=,iv:IVioJCVyROehAtG6xbmAZzd52HQvk0eZItMBjBAvqx8=,tag:0pumzdyH5wiEArMmmra3UQ==,type:str] + password: ENC[AES256_GCM,data:CSQ8jFrxnLQY,iv:hXLENmG8qLGsGdWv3wbrj5Lf2zbF1ToNIwS4y1uWEXg=,tag:8QDCMyA69dYl58xIuP1DcA==,type:str] + host: ENC[AES256_GCM,data:xfU2eC+/+uvCkHY8QHY=,iv:ULWdvoa6r8F1g2+ZF3xPwak1EdhDWmndsO5RUxAVPE8=,tag:KGlJG1IMSWn4nEtMaOSsdg==,type:str] +tokens: + - service: ENC[AES256_GCM,data:tRSUpGKIEmc=,iv:hi/38iC/Glc4nxUkRYBV2cy946k+azXFtEdJONP1g/w=,tag:GQ0/WEhteyqCpsEv/SFrbA==,type:str] + token: ENC[AES256_GCM,data:CGnSO4HE,iv:LH0xVWNTbBmHPQ1OiP5+uRFfG/E7K7OGYqKHXOKje8Q=,tag:sOYhgKKV1ogOs7PJrBrsjw==,type:str] + - service: ENC[AES256_GCM,data:ohqXvZ/7HWw=,iv:CpjUdTbGL4TGRIWtEJxZ8923tw/Qomw+kCtiHuFiGQc=,tag:95TQUa3NSW1qGT8LNsEgbQ==,type:str] + token: ENC[AES256_GCM,data:I0I/XgWl,iv:87E/c7DiGKT22tddCFqBuPOC736yv5YD9M/+g3PiZX4=,tag:Z1prIHfH39m2U6i2KeV22Q==,type:str] +someOtherKey: ENC[AES256_GCM,data:HSMFwMXHni18tTOPw2DAE0g5XQR9oUw=,iv:4xTRO8TYhbla01gzathf7UBHh8Gthd97GIxX/0kCXwg=,tag:4psEFW3O2RqqYN68U23Pxw==,type:str] +specific: + SpecialCharacters: ENC[AES256_GCM,data:E/jqkPvUSbhZPbm0vrCjX1soLA==,iv:Rto0EyQT2ozFmk1tvk3xRDwVnNprA5xjpCNGTZieb0A=,tag:pRvhsXnVrb2qGG1ocu5mKw==,type:str] + HTMLEncodingTest1: ENC[AES256_GCM,data:Zdc5vZOBIQR8mclrPytvmyg4HQeD,iv:WGzS0+LSP9XaFeqh1aZmmgO54ZDn8Tf2YIOiwmJHp0I=,tag:ZdA/xX72JzBYxGVcV2a2RA==,type:str] + HTMLEncodingTest2: ENC[AES256_GCM,data:Xw==,iv:blYJXwT+wErgVswaCW8oWYnny88oL1yvFx8e3JcE09Q=,tag:+YUy02xaJhqqatBtkj972A==,type:str] + HTLMEncodingTest3: ENC[AES256_GCM,data:/w==,iv:/4eSVtFQ7cGoNI7UOMw8ly0+aiX7WivU4ihMlVKUD5k=,tag:cLSO8CR0IM+Y5LZfdM43BQ==,type:str] + "null": null + boolean: ENC[AES256_GCM,data:D1iaUA==,iv:SurUABhqM+UYiCZaEmjyGKZai2jDJL3nnZJ41tMNHBQ=,tag:gewFlccUdb3IyX7kP+SP3w==,type:bool] + number1: ENC[AES256_GCM,data:McBM,iv:VjYEpdVgLsjXGm2VRD9Lu0BXyOMFjkUMQIjvuVod5cs=,tag:7EfnK0qcITRg1Obriu7Egg==,type:int] + number2: ENC[AES256_GCM,data:wLcu0XjyJg==,iv:tZT/AMYMToZi5nuo6jUxwB01HPX4HhHpdt6v7uzZ9SE=,tag:fgK4Gfi5YBA1LupJBX2sBA==,type:float] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYc3F6ZFY4RFllbStpMzEz + WmxuNzduMytjRkh1Y24xMUNoVndCYUNhaGtJCjJwZ1AzZlBVcVd6Y2NFbGR4MmVF + bW9OWWh2bmRjaFRrOFoyeWVWbnJTeWMKLS0tIExyVDNFRXpFTEpRMzYvWG1PaWNz + TW96d0tqajBLc01paVlEZHFXR1F2bXcKLIJg7yTm0uCiiPiKsnsAyRM/aDZ/fNvw + iilKTB5wP1qds7StcVLJ18RGUo9vuAA9iP0NZCP6kKLVgZbcJ/aSdw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-02-07T14:47:09Z" + mac: ENC[AES256_GCM,data:Sx2D6SF+pQHQ+oux7lNexshPodcge3w2g6ixLTjK/NkEgyBMmgsVyBGWMl+kSk6PY58HT4AQpyBtuiUKj3jSJ4pZmepgWIAdxKpB3slqy38gghYP2/AHSbHYRzhLQIOxxDO0inUwroHa13HttJCzDfXKNiKrbMRAQKk+FWF6x3w=,iv:7sBjShVWrW177wZBv+rxW6eqK0VQcjjGWVtHw9dbGTY=,tag:Bo3oYFgbATbNVwDtP2RAaw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json similarity index 60% rename from test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json rename to test/PARAMETER.integ.snapshot/PARAMETER.assets.json index dcb5e985..ca029ee5 100644 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json @@ -1,28 +1,28 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { "source": { - "path": "asset.6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "ceae4c5aae51b63349d9022671dd663ff353a630338cc08e7f00096b4cc05706": { + "fe230a59724068b8e22b0ddbff5b46984961c41efe347bc575998ad868551ee6": { "source": { - "path": "SecretIntegrationAsset.template.json", + "path": "PARAMETER.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "ceae4c5aae51b63349d9022671dd663ff353a630338cc08e7f00096b4cc05706.json", + "objectKey": "fe230a59724068b8e22b0ddbff5b46984961c41efe347bc575998ad868551ee6.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.template.json b/test/PARAMETER.integ.snapshot/PARAMETER.template.json new file mode 100644 index 00000000..4f0d6e0b --- /dev/null +++ b/test/PARAMETER.integ.snapshot/PARAMETER.template.json @@ -0,0 +1,388 @@ +{ + "Resources": { + "Json7D959341": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json", + "Type": "String", + "Value": " " + } + }, + "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "JsonSopsSync13335C85": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "Format": "json", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Json7D959341" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Ref": "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62" + }, + { + "Ref": "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629" + }, + { + "Ref": "DotEnvSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess096D6CB67" + }, + { + "Ref": "BinarySopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0957B5711" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "Yaml8A8E441C": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml", + "Type": "String", + "Value": " " + } + }, + "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "YamlSopsSync65050259": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "Format": "yaml", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Yaml8A8E441C" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv36F67242": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/DotEnv", + "Type": "String", + "Value": " " + } + }, + "DotEnvSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess096D6CB67": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/DotEnv" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DotEnvSopsSyncBB91B728": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5PUVOQ1tBRVMyNTZfR0NNLGRhdGE6eU1qVm12ZzhuZ3Bsc3c2QTJFZC9MOXhyRmc9PSxpdjpDcUlSRW12ZDR2dE1tWFIwc0tGVzRCelpWYTlnMHJUajU1OFJmd0JBeXA4PSx0YWc6dURka0EvSFRFTkZJYUZ6cWxIVVRkdz09LHR5cGU6c3RyXQpkYXRhYmFzZTpob3N0PUVOQ1tBRVMyNTZfR0NNLGRhdGE6TlFHQkpjRW1iM01rOTZYTFBLcz0saXY6bGhrcThrY0gvYXhWK3dSOGQvcWNYRDBpc1NuK0JBRlQrajRnRDFrQ3FWYz0sdGFnOldLOUNkOXhRbzIwQzcyNlRZTkJ3Ync9PSx0eXBlOnN0cl0KZGF0YWJhc2U6cGFzc3dvcmQ9RU5DW0FFUzI1Nl9HQ00sZGF0YTpvNkN3NmxSQ0t3VzMsaXY6YWIxeExjcmY5WFdyalhBZGRXL3ZGaHpPUUhxYk95UmlNVDFXRFoyRTk0VT0sdGFnOnhheTRxcXBYVkZHNVNBWHN3dEt1V2c9PSx0eXBlOnN0cl0KZGF0YWJhc2U6dXNlcj1FTkNbQUVTMjU2X0dDTSxkYXRhOllha1p2RlU9LGl2Oi9Va002RUUydjltaU1uZ2c1aHJGVytUTkM2TzlTSGdKdnBFcGJCUzRpWms9LHRhZzpjUTdCZ04vcmxmcHBCYUkyZVhOQjRBPT0sdHlwZTpzdHJdCnNvbWVPdGhlcktleT1FTkNbQUVTMjU2X0dDTSxkYXRhOmpiclVRMlpOM0crMm1zMWt0VWJCNG40R0tNaHpzMVE9LGl2Om54QnI3aFlhS1dJUSt3MlI5eWRxUmdFOFdZM3dXSllIUkxFTUw0b1h2Q0U9LHRhZzpoOHhYMEVOdzMwSnZQVUJWYm4zUmNBPT0sdHlwZTpzdHJdCnNwZWNpZmljOmJvb2xlYW49RU5DW0FFUzI1Nl9HQ00sZGF0YTo2aEpacEE9PSxpdjpKbjd2Y0doRy9LSHVJdm5XdExtNEt1dEJjWE9NR0dhMDNWZXhERWZvRUx3PSx0YWc6eVZZYnJkRGM4bFpRY3I1TTkwaExwQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpTcGVjaWFsQ2hhcmFjdGVycz1FTkNbQUVTMjU2X0dDTSxkYXRhOmlWblY4UjR3VW80SG1qK2hOQmdWaHFzSy9RPT0saXY6MnFuSkZQMDdxK2JpZFY2UUh2YTh4Zy82S3V0MDF2eVNxb1VickppVmRkND0sdGFnOk9EUEhHTHMzeVU5QktBWGp2SDhhYVE9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6SFRMTUVuY29kaW5nVGVzdDM9RU5DW0FFUzI1Nl9HQ00sZGF0YTpPZz09LGl2Ok9zaWpSYmFVdFgyZk5OenNJMDJCbTgxQng5WnBNQ0xsOW9FWWZFZ295Z009LHRhZzpXNXlyVFRDdDh4cEV5RFdwbUNyU2JnPT0sdHlwZTpzdHJdCnNwZWNpZmljOkhUTUxFbmNvZGluZ1Rlc3QxPUVOQ1tBRVMyNTZfR0NNLGRhdGE6R3RjNXlPU1pycFJRWlJXcGJGUDlRQ2s1MkRwcSxpdjp6cy9GTU81Uzkydy9ET21UL1JoRXVXUTRXWER0SFlXbWdseXA4Ym1XNlNRPSx0YWc6NG5RQ2RrTUpMblJLNVJBV1RtYk5WQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpIVE1MRW5jb2RpbmdUZXN0Mj1FTkNbQUVTMjU2X0dDTSxkYXRhOktnPT0saXY6UlFSeThMV0Z2b0tkNFVhV1NJS0wvNWpzNkk4V3ZpK3IrVDd1Ri9veCtyQT0sdGFnOlRLTWRVbS84M01rQm5QOVZ0UEFIV2c9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVsbD0Kc3BlY2lmaWM6bnVtYmVyMT1FTkNbQUVTMjU2X0dDTSxkYXRhOjIzNk8saXY6L1gxakR5TU92Y3FmdmU2NzNCakNQNXIxempqMGgxS3RWak1EKzRyYklaST0sdGFnOnJXQlQwUnM1aGhsS0JUeXZOd0JxaXc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVtYmVyMj1FTkNbQUVTMjU2X0dDTSxkYXRhOmlJcUtsbXdSQ0E9PSxpdjp1c0YrWDBmbFdJZzlLaTdPMThLMDF4OG0vV1Qva1FkL2FWV0JTZFhhYnd3PSx0YWc6QlBIRlhUZXE3cXJ1Nk9XRzNEZlVzUT09LHR5cGU6c3RyXQp0b2tlbnM6MDpzZXJ2aWNlPUVOQ1tBRVMyNTZfR0NNLGRhdGE6TWxnYnVUcjFkNHM9LGl2OmUvWWpFdkV0RWhNUWR1NG9iVFczQnprU3RTazg0M2tyZWZFVElTbXh4Vnc9LHRhZzpjZzRFMmNsRko1R1dVYytpRm03OFR3PT0sdHlwZTpzdHJdCnRva2VuczowOnRva2VuPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2RlOXFITjgsaXY6SFdHZWkrUmh4V2ZFWStZZ0tUNzVRZndXaDFwaUUxVUo4cTRsVmM0R3U3TT0sdGFnOkRMWVB3bVlsaFJsSks2Q094ZDl3YXc9PSx0eXBlOnN0cl0KdG9rZW5zOjE6c2VydmljZT1FTkNbQUVTMjU2X0dDTSxkYXRhOmQwQVdsSnorbnQ0PSxpdjpCUXpLSGJCRFRsUis4ejFMVGtoQkxMby83dkFjT2pMVGZCLzlxUjdNZEdnPSx0YWc6czJOZU9QbFIxSXdaaVVuQ3M0RTFlZz09LHR5cGU6c3RyXQp0b2tlbnM6MTp0b2tlbj1FTkNbQUVTMjU2X0dDTSxkYXRhOkc0dklEVnRsLGl2OmloVi90alBTd1NhenNjL0RmK2RYcG5lcHdTa1A2bjFLY2NERzhHS1dSTWc9LHRhZzpSRGw5YzNQOWtvazF6V1dVYmlmRWNBPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlJjVFVyUld0d1NIZFBPVE5HVlhWcFxuZW1KUVdsWTRhWGcwWkVWU1NHeHNVemw0TVc5eWRsVllSMmxCQ2tGRGRrbDRialZWWVdwamEzRk9iQzluVkZWS1xuTWtzNWNrNW1TWEk0UVVrNVIxUjBjMkpDVkM5WkswRUtMUzB0SUVSTk9EZExhV0ptWjFSM05GWkVUM0YxWVZNeVxuUml0QmNFVmhOR3Q2VVVObGMyc3paVUpqZDFSVFQxa0tBWWsrRDdncUYrcHJkTkFGN09kT0hpbWEvQTkyTmpwd1xucWg1N1JrNUM3Tlh2VmVlSmsweEtkUzJ6Rm04NklJU1QvS2dTdzdRSzgwSVV4OGlHQ0hmNmtnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI1LTAyLTA3VDE0OjQ2OjA0Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOnZtSk9UR0k1NlVOZVRTVTVmM09GUTJLcWdsNk41MVRLSHBDWjJlR0Q5VzBzQnp2cmk0dXNEOWNPaWlPc3IxY09JVms5dGpmZHBqY3M4L1NNVkxQWTJENG5NZkJkVU82ZTMydE5vM1YwRHBSMUJVUFljVXlrUG9nREY0cHNySjNoMVdHOCtuMVkxS2dWRG8wK1Jhd0hwNFd4ZUJpOC9teXhGdkUrbTA2N3Jzbz0saXY6TWVpUFBUd2VwekhVMHJydGlWcE9JbmdWTXJHTy9MR1h1LzVGREtlK2s2QT0sdGFnOnZZU0trMS9nN1RQYU5ybmluRngxR2c9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjkuNAo=", + "Hash": "8503036ebdb63922730f2d820336b67f3a28a6713b1d92133fc311b2a04ff62c" + }, + "Format": "dotenv", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "DotEnv36F67242" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary266F49CD": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Binary", + "Type": "String", + "Value": " " + } + }, + "BinarySopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0957B5711": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Binary" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "BinarySopsSyncC6FD2267": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "Format": "binary", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Binary266F49CD" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/test/PARAMETER.integ.ts b/test/PARAMETER.integ.ts new file mode 100644 index 00000000..20ab88d4 --- /dev/null +++ b/test/PARAMETER.integ.ts @@ -0,0 +1,49 @@ +import * as cdk from 'aws-cdk-lib'; +import { Key } from 'aws-cdk-lib/aws-kms'; +import { SopsStringParameter } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'PARAMETER'); + +interface TestCase { + name: string; + sopsFilePath: string; +} + +const tc = [ + { + name: 'Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + }, + { + name: 'Yaml', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + }, + { + name: 'DotEnv', + sopsFilePath: 'test-secrets/testsecret.sops.env', + }, + { + name: 'Binary', + sopsFilePath: 'test-secrets/README.sops.binary', + }, +] satisfies TestCase[]; + +const encryptionKey = Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb', +); + +tc.forEach((t) => { + new SopsStringParameter(stack, t.name, { + parameterName: `/${t.name}`, + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + encryptionKey, + }); +}); + +app.synth(); diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json similarity index 60% rename from test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json rename to test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json index ed2116ad..839f0b6a 100644 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json @@ -1,28 +1,28 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { "source": { - "path": "asset.6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "3b0bdb64bee0336eb36cc464c1af9cf58a1c325998209d00ee6a7d112c38ad41": { + "13ee38eb33b1b85e4b825987f0ed7035df11b30a8fa50b41ff32239fcf380a8b": { "source": { - "path": "SecretIntegrationInline.template.json", + "path": "PARAMETERMULTI.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3b0bdb64bee0336eb36cc464c1af9cf58a1c325998209d00ee6a7d112c38ad41.json", + "objectKey": "13ee38eb33b1b85e4b825987f0ed7035df11b30a8fa50b41ff32239fcf380a8b.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json new file mode 100644 index 00000000..7ce7f25e --- /dev/null +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json @@ -0,0 +1,1060 @@ +{ + "Resources": { + "JsonResourceJsonapiKeyEB6B5C10": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/apiKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabaseuserD88F8D25": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/user", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabasepassword12EBC48E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/password", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabasehost37888D7D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/host", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens0service92C0D936": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/0/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens0token105295EA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/0/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens1service387D7891": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/1/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens1token4D4522D2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/1/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonsomeOtherKey8C556C1F": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/someOtherKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificSpecialCharacters340895B2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/SpecialCharacters", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTMLEncodingTest101B8C7B8": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTMLEncodingTest1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTMLEncodingTest2479B055F": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTMLEncodingTest2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTLMEncodingTest3773A92F2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTLMEncodingTest3", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnullEFE6F24D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/null", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificbooleanDCCAF95E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/boolean", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnumber120FA2919": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/number1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnumber2B2EBD3ED": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/number2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/apiKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/user" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/password" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/host" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/0/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/0/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/1/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/1/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/someOtherKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/SpecialCharacters" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTMLEncodingTest1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTMLEncodingTest2" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTLMEncodingTest3" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/null" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/boolean" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/number1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/number2" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "JsonSopsSync13335C85": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": "/", + "Format": "json", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER_MULTI", + "Target": "/Json/" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Ref": "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62" + }, + { + "Ref": "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "YamlResourceYamlapiKey6387C0EA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/apiKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabaseuser0BD59C5D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/user", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabasepassword99035603": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/password", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabasehostB5A0FE91": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/host", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens0service8AE519C3": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/0/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens0token8810E18D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/0/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens1service870E3CC4": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/1/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens1tokenAC2DFE7E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/1/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlsomeOtherKey98D03965": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/someOtherKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificSpecialCharacters5B206BEA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/SpecialCharacters", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTMLEncodingTest10D2233FA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTMLEncodingTest1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTMLEncodingTest2761B8FA7": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTMLEncodingTest2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTLMEncodingTest32407BA78": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTLMEncodingTest3", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnull5A2012DC": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/null", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificboolean377BB393": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/boolean", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnumber1E294648B": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/number1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnumber28F676023": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/number2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/apiKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/user" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/password" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/host" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/0/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/0/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/1/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/1/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/someOtherKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/SpecialCharacters" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTMLEncodingTest1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTMLEncodingTest2" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTLMEncodingTest3" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/null" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/boolean" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/number1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/number2" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "YamlSopsSync65050259": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": "/", + "Format": "yaml", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER_MULTI", + "Target": "/Yaml/" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/test/PARAMETER_MULTI.integ.ts b/test/PARAMETER_MULTI.integ.ts new file mode 100644 index 00000000..1fc76764 --- /dev/null +++ b/test/PARAMETER_MULTI.integ.ts @@ -0,0 +1,46 @@ +import * as cdk from 'aws-cdk-lib'; +import { Key } from 'aws-cdk-lib/aws-kms'; +import { MultiStringParameter } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'PARAMETERMULTI'); + +interface TestCase { + name: string; + sopsFilePath: string; +} + +const tc = [ + { + name: 'Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + }, + { + name: 'Yaml', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + }, + // { NotSupported right now + // name: 'DotEnv', + // sopsFilePath: 'test-secrets/testsecret.sops.env', + // }, +] satisfies TestCase[]; + +const encryptionKey = Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb', +); + +tc.forEach((t) => { + new MultiStringParameter(stack, t.name, { + keyPrefix: `/${t.name}/`, + keySeparator: '/', + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + encryptionKey, + }); +}); + +app.synth(); diff --git a/test/SECRET.integ.snapshot/SECRET.assets.json b/test/SECRET.integ.snapshot/SECRET.assets.json new file mode 100644 index 00000000..004fba44 --- /dev/null +++ b/test/SECRET.integ.snapshot/SECRET.assets.json @@ -0,0 +1,32 @@ +{ + "version": "39.0.0", + "files": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { + "source": { + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "6242ad5b6accf4725b672e5e1b6969d282ff2e191bef99f14cabf39f4988aa1a": { + "source": { + "path": "SECRET.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6242ad5b6accf4725b672e5e1b6969d282ff2e191bef99f14cabf39f4988aa1a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/test/SECRET.integ.snapshot/SECRET.template.json b/test/SECRET.integ.snapshot/SECRET.template.json new file mode 100644 index 00000000..807d1458 --- /dev/null +++ b/test/SECRET.integ.snapshot/SECRET.template.json @@ -0,0 +1,450 @@ +{ + "Resources": { + "Json2JsonAD09CFF1": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Json2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Json2JsonSopsSync5CFFDB9D": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": ".", + "Format": "json", + "ResourceType": "SECRET", + "Target": { + "Ref": "Json2JsonAD09CFF1" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Json2JsonAD09CFF1" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Json2RawString0FD9054F" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Yaml2Json4AC73F66" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Yaml2RawStringBB57E2A1" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DotEnv2Json0B50F63B" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DotEnv2RawString8AFC290F" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Binary2RawString41D1BBEA" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Binary2RawBinary9379AA24" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "Json2RawString0FD9054F": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Json2RawString" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Json2RawStringSopsSync8C4F878C": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": ".", + "Format": "json", + "ResourceType": "SECRET_RAW", + "Target": { + "Ref": "Json2RawString0FD9054F" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2Json4AC73F66": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Yaml2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2JsonSopsSync33E502C1": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": ".", + "Format": "yaml", + "ResourceType": "SECRET", + "Target": { + "Ref": "Yaml2Json4AC73F66" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2RawStringBB57E2A1": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Yaml2RawString" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2RawStringSopsSyncCD57EBFA": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": ".", + "Format": "yaml", + "ResourceType": "SECRET_RAW", + "Target": { + "Ref": "Yaml2RawStringBB57E2A1" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2Json0B50F63B": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "DotEnv2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2JsonSopsSyncE88E8A73": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5PUVOQ1tBRVMyNTZfR0NNLGRhdGE6eU1qVm12ZzhuZ3Bsc3c2QTJFZC9MOXhyRmc9PSxpdjpDcUlSRW12ZDR2dE1tWFIwc0tGVzRCelpWYTlnMHJUajU1OFJmd0JBeXA4PSx0YWc6dURka0EvSFRFTkZJYUZ6cWxIVVRkdz09LHR5cGU6c3RyXQpkYXRhYmFzZTpob3N0PUVOQ1tBRVMyNTZfR0NNLGRhdGE6TlFHQkpjRW1iM01rOTZYTFBLcz0saXY6bGhrcThrY0gvYXhWK3dSOGQvcWNYRDBpc1NuK0JBRlQrajRnRDFrQ3FWYz0sdGFnOldLOUNkOXhRbzIwQzcyNlRZTkJ3Ync9PSx0eXBlOnN0cl0KZGF0YWJhc2U6cGFzc3dvcmQ9RU5DW0FFUzI1Nl9HQ00sZGF0YTpvNkN3NmxSQ0t3VzMsaXY6YWIxeExjcmY5WFdyalhBZGRXL3ZGaHpPUUhxYk95UmlNVDFXRFoyRTk0VT0sdGFnOnhheTRxcXBYVkZHNVNBWHN3dEt1V2c9PSx0eXBlOnN0cl0KZGF0YWJhc2U6dXNlcj1FTkNbQUVTMjU2X0dDTSxkYXRhOllha1p2RlU9LGl2Oi9Va002RUUydjltaU1uZ2c1aHJGVytUTkM2TzlTSGdKdnBFcGJCUzRpWms9LHRhZzpjUTdCZ04vcmxmcHBCYUkyZVhOQjRBPT0sdHlwZTpzdHJdCnNvbWVPdGhlcktleT1FTkNbQUVTMjU2X0dDTSxkYXRhOmpiclVRMlpOM0crMm1zMWt0VWJCNG40R0tNaHpzMVE9LGl2Om54QnI3aFlhS1dJUSt3MlI5eWRxUmdFOFdZM3dXSllIUkxFTUw0b1h2Q0U9LHRhZzpoOHhYMEVOdzMwSnZQVUJWYm4zUmNBPT0sdHlwZTpzdHJdCnNwZWNpZmljOmJvb2xlYW49RU5DW0FFUzI1Nl9HQ00sZGF0YTo2aEpacEE9PSxpdjpKbjd2Y0doRy9LSHVJdm5XdExtNEt1dEJjWE9NR0dhMDNWZXhERWZvRUx3PSx0YWc6eVZZYnJkRGM4bFpRY3I1TTkwaExwQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpTcGVjaWFsQ2hhcmFjdGVycz1FTkNbQUVTMjU2X0dDTSxkYXRhOmlWblY4UjR3VW80SG1qK2hOQmdWaHFzSy9RPT0saXY6MnFuSkZQMDdxK2JpZFY2UUh2YTh4Zy82S3V0MDF2eVNxb1VickppVmRkND0sdGFnOk9EUEhHTHMzeVU5QktBWGp2SDhhYVE9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6SFRMTUVuY29kaW5nVGVzdDM9RU5DW0FFUzI1Nl9HQ00sZGF0YTpPZz09LGl2Ok9zaWpSYmFVdFgyZk5OenNJMDJCbTgxQng5WnBNQ0xsOW9FWWZFZ295Z009LHRhZzpXNXlyVFRDdDh4cEV5RFdwbUNyU2JnPT0sdHlwZTpzdHJdCnNwZWNpZmljOkhUTUxFbmNvZGluZ1Rlc3QxPUVOQ1tBRVMyNTZfR0NNLGRhdGE6R3RjNXlPU1pycFJRWlJXcGJGUDlRQ2s1MkRwcSxpdjp6cy9GTU81Uzkydy9ET21UL1JoRXVXUTRXWER0SFlXbWdseXA4Ym1XNlNRPSx0YWc6NG5RQ2RrTUpMblJLNVJBV1RtYk5WQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpIVE1MRW5jb2RpbmdUZXN0Mj1FTkNbQUVTMjU2X0dDTSxkYXRhOktnPT0saXY6UlFSeThMV0Z2b0tkNFVhV1NJS0wvNWpzNkk4V3ZpK3IrVDd1Ri9veCtyQT0sdGFnOlRLTWRVbS84M01rQm5QOVZ0UEFIV2c9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVsbD0Kc3BlY2lmaWM6bnVtYmVyMT1FTkNbQUVTMjU2X0dDTSxkYXRhOjIzNk8saXY6L1gxakR5TU92Y3FmdmU2NzNCakNQNXIxempqMGgxS3RWak1EKzRyYklaST0sdGFnOnJXQlQwUnM1aGhsS0JUeXZOd0JxaXc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVtYmVyMj1FTkNbQUVTMjU2X0dDTSxkYXRhOmlJcUtsbXdSQ0E9PSxpdjp1c0YrWDBmbFdJZzlLaTdPMThLMDF4OG0vV1Qva1FkL2FWV0JTZFhhYnd3PSx0YWc6QlBIRlhUZXE3cXJ1Nk9XRzNEZlVzUT09LHR5cGU6c3RyXQp0b2tlbnM6MDpzZXJ2aWNlPUVOQ1tBRVMyNTZfR0NNLGRhdGE6TWxnYnVUcjFkNHM9LGl2OmUvWWpFdkV0RWhNUWR1NG9iVFczQnprU3RTazg0M2tyZWZFVElTbXh4Vnc9LHRhZzpjZzRFMmNsRko1R1dVYytpRm03OFR3PT0sdHlwZTpzdHJdCnRva2VuczowOnRva2VuPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2RlOXFITjgsaXY6SFdHZWkrUmh4V2ZFWStZZ0tUNzVRZndXaDFwaUUxVUo4cTRsVmM0R3U3TT0sdGFnOkRMWVB3bVlsaFJsSks2Q094ZDl3YXc9PSx0eXBlOnN0cl0KdG9rZW5zOjE6c2VydmljZT1FTkNbQUVTMjU2X0dDTSxkYXRhOmQwQVdsSnorbnQ0PSxpdjpCUXpLSGJCRFRsUis4ejFMVGtoQkxMby83dkFjT2pMVGZCLzlxUjdNZEdnPSx0YWc6czJOZU9QbFIxSXdaaVVuQ3M0RTFlZz09LHR5cGU6c3RyXQp0b2tlbnM6MTp0b2tlbj1FTkNbQUVTMjU2X0dDTSxkYXRhOkc0dklEVnRsLGl2OmloVi90alBTd1NhenNjL0RmK2RYcG5lcHdTa1A2bjFLY2NERzhHS1dSTWc9LHRhZzpSRGw5YzNQOWtvazF6V1dVYmlmRWNBPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlJjVFVyUld0d1NIZFBPVE5HVlhWcFxuZW1KUVdsWTRhWGcwWkVWU1NHeHNVemw0TVc5eWRsVllSMmxCQ2tGRGRrbDRialZWWVdwamEzRk9iQzluVkZWS1xuTWtzNWNrNW1TWEk0UVVrNVIxUjBjMkpDVkM5WkswRUtMUzB0SUVSTk9EZExhV0ptWjFSM05GWkVUM0YxWVZNeVxuUml0QmNFVmhOR3Q2VVVObGMyc3paVUpqZDFSVFQxa0tBWWsrRDdncUYrcHJkTkFGN09kT0hpbWEvQTkyTmpwd1xucWg1N1JrNUM3Tlh2VmVlSmsweEtkUzJ6Rm04NklJU1QvS2dTdzdRSzgwSVV4OGlHQ0hmNmtnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI1LTAyLTA3VDE0OjQ2OjA0Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOnZtSk9UR0k1NlVOZVRTVTVmM09GUTJLcWdsNk41MVRLSHBDWjJlR0Q5VzBzQnp2cmk0dXNEOWNPaWlPc3IxY09JVms5dGpmZHBqY3M4L1NNVkxQWTJENG5NZkJkVU82ZTMydE5vM1YwRHBSMUJVUFljVXlrUG9nREY0cHNySjNoMVdHOCtuMVkxS2dWRG8wK1Jhd0hwNFd4ZUJpOC9teXhGdkUrbTA2N3Jzbz0saXY6TWVpUFBUd2VwekhVMHJydGlWcE9JbmdWTXJHTy9MR1h1LzVGREtlK2s2QT0sdGFnOnZZU0trMS9nN1RQYU5ybmluRngxR2c9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjkuNAo=", + "Hash": "8503036ebdb63922730f2d820336b67f3a28a6713b1d92133fc311b2a04ff62c" + }, + "FlattenSeparator": ".", + "Format": "dotenv", + "ResourceType": "SECRET", + "Target": { + "Ref": "DotEnv2Json0B50F63B" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2RawString8AFC290F": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "DotEnv2RawString" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2RawStringSopsSyncC5213FA3": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "FlattenSeparator": ".", + "Format": "binary", + "ResourceType": "SECRET_RAW", + "Target": { + "Ref": "DotEnv2RawString8AFC290F" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawString41D1BBEA": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Binary2RawString" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawStringSopsSyncB4561EC6": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "FlattenSeparator": ".", + "Format": "binary", + "ResourceType": "SECRET_RAW", + "Target": { + "Ref": "Binary2RawString41D1BBEA" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawBinary9379AA24": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Binary2RawBinary" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawBinarySopsSyncBB670AFE": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFampUdzk3NnNURXBlU3ZBMGNNWUY0VnJ1SkZMUnBpNEhmazMrZUViNmk1NDVRT3lIVUVra25ucmpzcjNETjFScHZ5cHBiQW1WcTMzV0huQjNGTDlDS3VYZk5jOWswaGhUaldGQWdHallWWnFMelJaSkl5amJLRmt4WVZkcEZqYkN4azZMNWhJSTFkL1NSaDYxL1dtS2t0RVoxOGVCTmY4OGY1RTVXcnpuUE9qSmZxNFp0bzUwa2tPY25uNnpMN1UvTHVXaDZpcWI5WmZuYzJhUXBTWDVKUE1oYzZ3VnA4eE9NRmZCVDJuMGJPZVVIVk1aemYwL2ppTlRjS1VSeStFTnlxaWJjOHpFdEFHcUZIVkdzSy91QzNZc0UwekdudHIzVG40MGdjQWtmbWV3ejhZRVUyWXJuT0ErS0pnSG9CQTZoakxkQ3NqQWRZZFE1a1FSTDJpWktBMUFLM1Rvc0tHd2pJUWZTL2tPaTJ4WTVRNDN0TnVFa1B1VGp2WTR1Z0VldVhHWHhmUVJ6OFJ5b1JzS0lrK3hiUDZQdjZTb1l2TTV0V0d3ZDVwemIwTkRYSng3b0pwaWxYNDBZRkZkRmVncVlhOWdmT2hTUT09LGl2OnZMcEcyeDFlSitIVWovVkF5RW5UelFZa3UrVHU3RStFYTJxbllNTUp5MDA9LHRhZzo0MVdERnNnUEM3QUVKenk0OWtPd0dRPT0sdHlwZTpzdHJdIiwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0J2Y1VwV2EwSXZRamM0WmsxamFYRXpcblZGRjFUVVJVU2tkeGRrcDZRVXBLU1drckwyMXBXR1pqYWpKWkNsVmFPR0pUZDBGT01VNXlhblJNT0hKNVJFZFNcblMwUm9PQzlQY1VFeVdtWjVORVJxUkZsMFVqaHlSRVVLTFMwdElHSnJjM2xJTlZGc1pETlNValpqUzJsd2RucFZcbmJYRnpkMWd2U25WVUt6WlRjSEppZW1OUlRFRXdPVUVLWitMOVZaYnJGT3cxcVdqVUZYOVlDT2F3Ui9XcVBYRXBcbjE2N0gyWWFlZFc3SmZnRVg2TFpOd3JjY01RRUV6S1MxYW9ncnFkTTB4cnE4Z3k5d21sUmYwZz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMTBUMDk6NTY6MDJaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6Y3RGNHlWdHF3VW9vNjlwcWd1RE01MXBUZUQxditvRjV2amh4eWdJdVdHbFhsbE0rZVRuaHR2MUtNZjZiWHF2ZUVjSGhiSTdlTm1xYk9JMlRzK3YrMWEzVGVrajMyeWswWWp5UTlZR3hxZGtKbzhIVzYvSjRyd21vYmU4RUZ1akFNczdLN3ZUMEJPRkIvS09XYmsxRGUzVldsTEM3UjNGUnNWRkdWMGhjeUd3PSxpdjpBL3NWSmM0K2JtV1Z6UlQ3a0hnUm4vemJ3SmZIZUNzblh0OVZoSDQrQXdFPSx0YWc6ZVhXSktUb0pETVVZZy9XTGVNTGZ2Zz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJImVuY3J5cHRlZF9yZWdleCI6ICJeKGRhdGF8c3RyaW5nRGF0YSkkIiwKCQkidmVyc2lvbiI6ICIzLjkuMSIKCX0KfQ==", + "Hash": "28384fe2a27b34268efc6eef99b23999a6cd1bfc84a10937fc592f39c4e93b28" + }, + "FlattenSeparator": ".", + "Format": "binary", + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "Binary2RawBinary9379AA24" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/test/SECRET.integ.ts b/test/SECRET.integ.ts new file mode 100644 index 00000000..562550df --- /dev/null +++ b/test/SECRET.integ.ts @@ -0,0 +1,77 @@ +import * as cdk from 'aws-cdk-lib'; +import { RawOutput, SopsSecret } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'SECRET'); + +interface TestCase { + name: string; + sopsFilePath: string; + additionalProperties: Record; +} + +const tc = [ + { + name: 'Json2Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + additionalProperties: {}, + }, + { + name: 'Json2RawString', + sopsFilePath: 'test-secrets/testsecret.sops.json', + additionalProperties: { + rawOutput: RawOutput.STRING, + }, + }, + { + name: 'Yaml2Json', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + additionalProperties: {}, + }, + { + name: 'Yaml2RawString', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + additionalProperties: { + rawOutput: RawOutput.STRING, + }, + }, + { + name: 'DotEnv2Json', + sopsFilePath: 'test-secrets/testsecret.sops.env', + additionalProperties: {}, + }, + { + name: 'DotEnv2RawString', + sopsFilePath: 'test-secrets/README.sops.binary', + additionalProperties: { + rawOutput: RawOutput.STRING, + }, + }, + { + name: 'Binary2RawString', + sopsFilePath: 'test-secrets/README.sops.binary', + additionalProperties: { + rawOutput: RawOutput.STRING, + }, + }, + { + name: 'Binary2RawBinary', + sopsFilePath: 'test-secrets/README.gz.sops.binary', + additionalProperties: { + rawOutput: RawOutput.BINARY, + }, + }, +] satisfies TestCase[]; + +tc.forEach((t) => { + new SopsSecret(stack, t.name, { + secretName: t.name, + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + ...t.additionalProperties, + }); +}); + +app.synth(); diff --git a/test/__snapshots__/permissions.test.ts.snap b/test/__snapshots__/permissions.test.ts.snap index 3c64327c..64184f60 100644 --- a/test/__snapshots__/permissions.test.ts.snap +++ b/test/__snapshots__/permissions.test.ts.snap @@ -31,6 +31,9 @@ Object { ], "Version": "2012-10-17", }, + "Roles": Array [ + "test-role", + ], }, "Type": "AWS::IAM::ManagedPolicy", }, diff --git a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json deleted file mode 100644 index 319ca7e8..00000000 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "version": "36.0.0", - "files": { - "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e": { - "source": { - "path": "asset.6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649": { - "source": { - "path": "asset.2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f": { - "source": { - "path": "asset.c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282": { - "source": { - "path": "asset.313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2": { - "source": { - "path": "asset.4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b": { - "source": { - "path": "asset.a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - }, - "f38430ae989f7328d34b16732c6932c35e9314625fe461dfa174222af079cae3": { - "source": { - "path": "SecretIntegrationAsset.template.json", - "packaging": "file" - }, - "destinations": { - "123456789-us-east-1": { - "bucketName": "cdk-integ-assets-123456789-us-east-1", - "objectKey": "f38430ae989f7328d34b16732c6932c35e9314625fe461dfa174222af079cae3.json", - "region": "us-east-1", - "assumeRoleArn": "arn:${AWS::Partition}:iam::123456789:role/cdk-integ-file-publishing-role-123456789-us-east-1" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json deleted file mode 100644 index 8b40d860..00000000 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json +++ /dev/null @@ -1,987 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::cdk-integ-assets-123456789-us-east-1" - ] - ] - }, - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::cdk-integ-assets-123456789-us-east-1/*" - ] - ] - } - ] - }, - { - "Action": "kms:Decrypt", - "Effect": "Allow", - "Resource": "arn:aws:kms:us-east-1:123456789:key/my-key-id" - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretJSON72040543" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsBinaryAsBinary6FB08519" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": "cdk-integ-assets-123456789-us-east-1", - "S3Key": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "ConvertToJSON": false, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsBinaryAsBinary6FB08519": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsBinaryAsBinarySopsSyncEC998F91": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsBinaryAsBinary6FB08519" - }, - "SopsS3File": { - "Bucket": "cdk-integ-assets-123456789-us-east-1", - "Key": "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "binary", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs20.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/integ/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/test/secret-asset.integ.ts b/test/secret-asset.integ.ts deleted file mode 100644 index 809acc89..00000000 --- a/test/secret-asset.integ.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { App, DefaultStackSynthesizer, SecretValue, Stack } from 'aws-cdk-lib'; -import { Key } from 'aws-cdk-lib/aws-kms'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret, UploadType } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationAsset', { - synthesizer: new DefaultStackSynthesizer({ - qualifier: 'integ', - }), - env: { - account: '123456789', - region: 'us-east-1', - }, -}); - -const assetKey = Key.fromKeyArn( - stack, - 'KmsKey', - 'arn:aws:kms:us-east-1:123456789:key/my-key-id', -); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: false, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: false, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - uploadType: UploadType.ASSET, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - uploadType: UploadType.ASSET, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - uploadType: UploadType.ASSET, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, - uploadType: UploadType.ASSET, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - uploadType: UploadType.ASSET, - convertToJSON: true, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, - }, -); - -new SopsSecret(stack, 'SopsBinaryAsBinary', { - sopsFilePath: 'test-secrets/binary/sopsfile.enc-age.binary', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - assetEncryptionKey: assetKey, -}); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_20_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json b/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json deleted file mode 100644 index 6434f5ad..00000000 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json +++ /dev/null @@ -1,994 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, - "SopsInline": { - "Content": "ewoJImtleTEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpBclNqQzBWZCxpdjpORnJJajFla00yZFU4SkNVNk5wbW5IRm13Y0ZhRVFhZ0N3L2Z4S1YyYjZBPSx0YWc6R3JHZ2VObXRxRnV5aVRqS0ovNzhrdz09LHR5cGU6c3RyXSIsCgkia2V5MiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOk5lb2FuZFk9LGl2OjJvQ2NCazBSL1h4dkgvTythYUNJYTdWOXBGc3k3ZGhDS1o3MGViamM1RHM9LHRhZzpHVlpYVUZGd2JwTVZZL0tDTE5FTkFRPT0sdHlwZTpmbG9hdF0iLAoJImtleTMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp5NHRCYU5nPSxpdjptSHVZcnRmMEtlL29IQmN1bnBnZFBwemFZa0J4N1VqTWNPUWdwbVZjOC9RPSx0YWc6Y3VFZzJVRTE3UG82b3BmcEg4aWtvZz09LHR5cGU6Ym9vbF0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQk9XbEF4ZWtWTk5YZGplblY1Y21kUlxuWkRsUVUzTjVXQzlvZUVOVWJVcFljV3hrZVU5a1ZTOVRlVVIzQ201emJHaElMMEo2V0c5VFdpOUtSM1pVVFZwaFxuYmxwaVVEWnRRa2xuV2xSclNHWnpUWGxaTjJaNldqZ0tMUzB0SURJM1pITkhSME5tV1RNemRUZzBkRXRYY1U5M1xuYkVkTlduZEtkV1JPV0dkTGRIQXdUR0Z0Ukdsc2FEUUtWN0hKRzYyOXJQV0RCWTA0Nkh4ajR1dHhVa2V4M1N3VVxuVlVRUlgwMHA2cjlmZmMraUM1REdVbS9LT2tldEFIdW5PNEtuMHVPUzRXSGcrSmcyQ3d1NzJRPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyMi0wMy0yOVQyMTowMjozMloiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YToydm16d1c3NE9TSnExOEdFY1NjcE1INzZBV3JoSmRFTmxLdzJ2UnpHclFmUGl4VE5jcndKMG5lVEgrQnZHS2ZSOU9sTFIyRVpUaGVScGhRMElrYjRTZGhmSW5vRGpIbyswalhON1JRNG5lVGxrbzRqL1lSVmVrNjFvZVBnQUtBcWNtdkwySWh6UkdPMlZSOG5EUHVKdXZSQ21QNXdPTU9Ca2VyeWRSS0hlRGM9LGl2Ok5IV1BOV0RtdWhla0pVSUpwQzFjREo1MWxMS1RzWExFNmRDNHRwdy9xU0k9LHRhZzp5VjVuZ1JkSVlaZlVnajZudHNZNUNRPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy43LjIiCgl9Cn0=", - "Hash": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretJSON72040543" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretDOTENV13EC93B6" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretDOTENVasJSONC46F5173" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, - "SopsInline": { - "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, - "SopsInline": { - "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENV13EC93B6": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVSopsSyncCF15A60A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretDOTENV13EC93B6" - }, - "SopsInline": { - "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", - "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "dotenv", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVasJSONC46F5173": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVasJSONSopsSync598B1279": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretDOTENVasJSONC46F5173" - }, - "SopsInline": { - "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", - "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "dotenv", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, - "SopsInline": { - "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", - "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - "SopsInline": { - "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", - "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "ConvertToJSON": false, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/test/secret-inline.integ.ts b/test/secret-inline.integ.ts deleted file mode 100644 index b6fcdd29..00000000 --- a/test/secret-inline.integ.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationInline'); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretDOTENV', { - sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - convertToJSON: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretDOTENVasJSON', { - sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - convertToJSON: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_14_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json deleted file mode 100644 index 3e27f576..00000000 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json +++ /dev/null @@ -1,799 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "ConvertToJSON": false, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "ConvertToJSON": false, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "ConvertToJSON": true, - "Flatten": false, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/test/secret-manual.integ.ts b/test/secret-manual.integ.ts deleted file mode 100644 index efde44c0..00000000 --- a/test/secret-manual.integ.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationAsset'); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - convertToJSON: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'yaml', - convertToJSON: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - convertToJSON: false, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - convertToJSON: false, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - convertToJSON: true, - flatten: false, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - convertToJSON: true, - flatten: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_14_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json deleted file mode 100644 index c9198986..00000000 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "36.0.0", - "files": { - "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e": { - "source": { - "path": "asset.6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649": { - "source": { - "path": "asset.2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "03f53bba5301d6df7d9be45c3a6e68e59652eed2b74f63b1d21c147468d8b0b9": { - "source": { - "path": "SecretMultiKms.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "03f53bba5301d6df7d9be45c3a6e68e59652eed2b74f63b1d21c147468d8b0b9.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json deleted file mode 100644 index ed14e217..00000000 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json +++ /dev/null @@ -1,433 +0,0 @@ -{ - "Resources": { - "CustomKey1E6D0D07": { - "Type": "AWS::KMS::Key", - "Properties": { - "KeyPolicy": { - "Statement": [ - { - "Action": "kms:*", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:CreateGrant", - "kms:DescribeKey" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "SopsSecretOwnKmsMey0B320436": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {}, - "KmsKeyId": { - "Fn::GetAtt": [ - "CustomKey1E6D0D07", - "Arn" - ] - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretOwnKmsMeySopsSync52A94247": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretOwnKmsMey0B320436" - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } - ] - ] - }, - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "CustomKey1E6D0D07", - "Arn" - ] - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretOwnKmsMey0B320436" - } - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Resource": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretForeignKmsMey8C3BA0B7" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "6b7324d3cfcf3382ce5efed880245dc232ee5e4ccc0affec91bfce961fb36b9e.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretForeignKmsMey8C3BA0B7": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {}, - "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretForeignKmsMeySopsSync7493861B": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SecretARN": { - "Ref": "SopsSecretForeignKmsMey8C3BA0B7" - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "ConvertToJSON": true, - "Flatten": true, - "FlattenSeparator": ".", - "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/test/secret-multikms.integ.ts b/test/secret-multikms.integ.ts deleted file mode 100644 index 313fadb3..00000000 --- a/test/secret-multikms.integ.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Caution - this test can only be used for snapshots - you can't deploy this - */ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Key } from 'aws-cdk-lib/aws-kms'; -import { SopsSecret, UploadType } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretMultiKms'); - -new SopsSecret(stack, 'SopsSecretOwnKmsMey', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - encryptionKey: new Key(stack, 'CustomKey'), -}); - -new SopsSecret(stack, 'SopsSecretForeignKmsMey', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - encryptionKey: Key.fromKeyArn( - stack, - 'ForeignKey', - 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012', - ), -}); diff --git a/test/secret.test.ts b/test/secret.test.ts index 92cfcdcd..f70308a0 100644 --- a/test/secret.test.ts +++ b/test/secret.test.ts @@ -14,6 +14,7 @@ import { SopsSyncProvider, UploadType, MultiStringParameter, + RawOutput, } from '../src'; const keyStatements = [ @@ -32,6 +33,7 @@ test('Upload type ASSET', () => { new SopsSecret(stack, 'SopsSecret', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-kms.yaml', uploadType: UploadType.ASSET, + rawOutput: RawOutput.STRING, }); Template.fromStack(stack).hasResource('Custom::SopsSync', { Properties: Match.objectLike({ @@ -219,9 +221,9 @@ test('Exception when derive format: notsupported', () => { expect( () => new SopsSecret(stack, 'SopsSecret', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.notsupported', + sopsFilePath: 'test-secrets/testsecret.notsupported', }), - ).toThrowError('Unsupported sopsFileFormat notsupported'); + ).toThrowError('You have to specify sopsFileFormat!'); }); test('Set format: json', () => { @@ -529,14 +531,12 @@ test('Multiple parameters from yaml file', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml', encryptionKey: Key.fromKeyArn( stack, 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); @@ -608,7 +608,6 @@ test('Multiple parameters from yaml file with custom key structure', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml', keyPrefix: '_', keySeparator: '.', @@ -617,7 +616,6 @@ test('Multiple parameters from yaml file with custom key structure', () => { 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); @@ -689,7 +687,6 @@ test('Large set of parameters to split in multiple policies', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-parameters-large.yaml', keyPrefix: '_', keySeparator: '.', @@ -698,7 +695,6 @@ test('Large set of parameters to split in multiple policies', () => { 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); diff --git a/yarn.lock b/yarn.lock index 4438ea25..cb428774 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,6 +10,15 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" +"@apidevtools/json-schema-ref-parser@^11.5.5": + version "11.9.0" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.0.tgz#863c1c15f0b87ec442f1c932b31823ea1d17ab51" + integrity sha512-8Q/r5mXLa8Rfyh6r4SgEEFJgISVN5cDNFlcfSWLgFn3odzQhTfHAqzI3hMGdcROViL+8NrDNVVFQtEUrYOksDg== + dependencies: + "@jsdevtools/ono" "^7.1.3" + "@types/json-schema" "^7.0.15" + js-yaml "^4.1.0" + "@asamuzakjp/css-color@^2.8.2": version "2.8.3" resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-2.8.3.tgz#665f0f5e8edb95d8f543847529e30fe5cc437ef7" @@ -21,21 +30,29 @@ "@csstools/css-tokenizer" "^3.0.3" lru-cache "^10.4.3" -"@aws-cdk/asset-awscli-v1@^2.2.202": - version "2.2.221" - resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.221.tgz#747506051071610dbe054d7266208fd9afb2fff2" - integrity sha512-+Vu2cMvgtkaHwNezrTVng4+FAMAWKJTkC/2ZQlgkbY05k0lHHK/2eWKqBhTeA7EpxVrx9uFN7GdBFz3mcThpxg== +"@aws-cdk/asset-awscli-v1@^2.2.208": + version "2.2.222" + resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.222.tgz#a1f912b93a038b4779ed04d63afcf8df20cb50ed" + integrity sha512-9qjd91FwBYmxjfF3ckieTKrmmvIBZdSe1Daf/hRGxAPnhtH9Fm5Y3Oi0dJD2tRw0ufyM6AbvX9zgejcTqXc+LQ== -"@aws-cdk/asset-kubectl-v20@^2.1.2": +"@aws-cdk/asset-kubectl-v20@^2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.3.tgz#80e09004be173995e91614e34d947da11dd9ff4d" integrity sha512-cDG1w3ieM6eOT9mTefRuTypk95+oyD7P5X/wRltwmYxU7nZc3+076YEVS6vrjDKr3ADYbfn0lDKpfB1FBtO9CQ== -"@aws-cdk/asset-node-proxy-agent-v6@^2.0.3": +"@aws-cdk/asset-node-proxy-agent-v6@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz#6d3c7860354d4856a7e75375f2f0ecab313b4989" integrity sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A== +"@aws-cdk/cloud-assembly-schema@^39.2.0": + version "39.2.15" + resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-39.2.15.tgz#e869dd3c76c9d093ecf27fe3378fbae64b7d958e" + integrity sha512-roeUKO5QR9JLnNEULg0RiS1ac6PZ9qsPaOcAJXCP0D1NLLECdxwwqJvLbhV91pCWrGTeWY5OhLtlL5OPS6Ycvg== + dependencies: + jsonschema "~1.4.1" + semver "^7.7.1" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.2": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" @@ -656,6 +673,11 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jsdevtools/ono@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" + integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== + "@jsii/check-node@1.106.0": version "1.106.0" resolved "https://registry.yarnpkg.com/@jsii/check-node/-/check-node-1.106.0.tgz#5deb20b0bbe0a506c4bd9edf60b17b0a93f83834" @@ -829,7 +851,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27": +"@types/jest@^27.5.2": version "27.5.2" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== @@ -847,6 +869,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.17.7": + version "4.17.15" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.15.tgz#12d4af0ed17cc7600ce1f9980cec48fc17ad1e89" + integrity sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw== + "@types/minimist@^1.2.0": version "1.2.5" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" @@ -859,10 +886,10 @@ dependencies: undici-types "~6.20.0" -"@types/node@^16 <= 16.18.78": - version "16.18.78" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.78.tgz#3d97264128712f2eb59f1f8456bcfc5d56d8105c" - integrity sha512-2poPMDdsGfvhcLmgJZ85QrIfN6z3PijYRMiV0FWIEUiQW/t/lzH7BEm4vN+HMhjZXbtIKssMcAxTcgu4Rm83YA== +"@types/node@^16.18.78": + version "16.18.126" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.126.tgz#27875faa2926c0f475b39a8bb1e546c0176f8d4b" + integrity sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw== "@types/normalize-package-data@^2.4.0": version "2.4.4" @@ -1220,23 +1247,24 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.144.0: - version "2.144.0" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz#0e224634d361cea0a8019b4677a517752600609b" - integrity sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA== +aws-cdk-lib@2.177.0: + version "2.177.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.177.0.tgz#dd161eb9b3fca56d0677c903ff758780a3eeb974" + integrity sha512-nTnHAwjZaPJ5gfJjtzE/MyK6q0a66nWthoJl7l8srucRb+I30dczhbbXor6QCdVpJaTRAEliMOMq23aglsAQbg== dependencies: - "@aws-cdk/asset-awscli-v1" "^2.2.202" - "@aws-cdk/asset-kubectl-v20" "^2.1.2" - "@aws-cdk/asset-node-proxy-agent-v6" "^2.0.3" + "@aws-cdk/asset-awscli-v1" "^2.2.208" + "@aws-cdk/asset-kubectl-v20" "^2.1.3" + "@aws-cdk/asset-node-proxy-agent-v6" "^2.1.0" + "@aws-cdk/cloud-assembly-schema" "^39.2.0" "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^11.2.0" - ignore "^5.3.1" + ignore "^5.3.2" jsonschema "^1.4.1" mime-types "^2.1.35" minimatch "^3.1.2" punycode "^2.3.1" - semver "^7.6.0" + semver "^7.6.3" table "^6.8.2" yaml "1.10.2" @@ -2415,6 +2443,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fdir@^6.4.2: + version "6.4.3" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" + integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== + figures@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -2891,7 +2924,7 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ignore@^5.2.0, ignore@^5.3.1: +ignore@^5.2.0, ignore@^5.3.1, ignore@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -3646,7 +3679,7 @@ jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^27: +jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== @@ -3848,6 +3881,21 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-schema-to-typescript@^15.0.4: + version "15.0.4" + resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz#a530c7f17312503b262ae12233749732171840f3" + integrity sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ== + dependencies: + "@apidevtools/json-schema-ref-parser" "^11.5.5" + "@types/json-schema" "^7.0.15" + "@types/lodash" "^4.17.7" + is-glob "^4.0.3" + js-yaml "^4.1.0" + lodash "^4.17.21" + minimist "^1.2.8" + prettier "^3.2.5" + tinyglobby "^0.2.9" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3906,6 +3954,11 @@ jsonschema@^1.4.1: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.5.0.tgz#f6aceb1ab9123563dd901d05f81f9d4883d3b7d8" integrity sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw== +jsonschema@~1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" + integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== + keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -4001,7 +4054,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.7.0: +lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4162,7 +4215,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.8: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8, minimist@~1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -4468,6 +4521,11 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4512,6 +4570,11 @@ prettier@^2.8.8: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.2.5: + version "3.4.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.2.tgz#a5ce1fb522a588bf2b78ca44c6e6fe5aa5a2b13f" + integrity sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ== + pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" @@ -4849,6 +4912,11 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.7.1: + version "7.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -5265,6 +5333,14 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tinyglobby@^0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== + dependencies: + fdir "^6.4.2" + picomatch "^4.0.2" + tldts-core@^6.1.76: version "6.1.76" resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.76.tgz#1ea632bbf11b288645dd7e2f3fb9cb6fa41e6bd7" @@ -5330,7 +5406,7 @@ ts-api-utils@^2.0.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd" integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w== -ts-jest@^27: +ts-jest@^27.1.5: version "27.1.5" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==