├── src ├── layers │ ├── yup-utils │ │ └── nodejs │ │ │ ├── yup-utils.ts │ │ │ ├── package.json │ │ │ └── package-lock.json │ └── calc │ │ └── nodejs │ │ └── calc.ts └── my-lambda │ └── index.ts ├── .prettierignore ├── .npmignore ├── cdk.json ├── jest.config.js ├── .prettierrc.js ├── tsconfig.eslint.json ├── bin └── cdk-starter.ts ├── README.md ├── tsconfig.json ├── package.json ├── .gitignore ├── lib └── cdk-starter-stack.ts └── .eslintrc.js /src/layers/yup-utils/nodejs/yup-utils.ts: -------------------------------------------------------------------------------- 1 | export * from 'yup'; 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | cdk.out 4 | template.yaml -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/cdk-starter.ts", 3 | "context": {} 4 | } 5 | -------------------------------------------------------------------------------- /src/layers/calc/nodejs/calc.ts: -------------------------------------------------------------------------------- 1 | export function double(a: number): number { 2 | return a * 2; 3 | } 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/test'], 3 | testMatch: ['**/*.test.ts'], 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | arrowParens: 'avoid', 4 | tabWidth: 2, 5 | useTabs: false, 6 | singleQuote: true, 7 | trailingComma: 'all', 8 | bracketSpacing: false, 9 | proseWrap: 'always', 10 | }; 11 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.js", 6 | "global-types/**/*", 7 | "**/*.js", 8 | "**/*.ts", 9 | "infra/**/*" 10 | ], 11 | "exclude": ["node_modules", "**/node_modules/*", "cdk.out"] 12 | } 13 | -------------------------------------------------------------------------------- /src/layers/yup-utils/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "yup": "^0.32.9" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bin/cdk-starter.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as cdk from 'aws-cdk-lib'; 3 | import {CdkStarterStack} from '../lib/cdk-starter-stack'; 4 | 5 | const app = new cdk.App(); 6 | new CdkStarterStack(app, 'cdk-stack', { 7 | stackName: 'cdk-stack', 8 | env: { 9 | region: process.env.CDK_DEFAULT_REGION, 10 | account: process.env.CDK_DEFAULT_ACCOUNT, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to use Lambda Layers in AWS CDK - Complete Guide 2 | 3 | A repository for an article on 4 | [bobbyhadz.com](https://bobbyhadz.com/blog/aws-cdk-lambda-layers) 5 | 6 | > If you use CDK v1, switch to the cdk-v1 branch 7 | 8 | ## How to Use 9 | 10 | 1. Clone the repository 11 | 12 | 2. Install the dependencies 13 | 14 | ```bash 15 | cd aws-cdk-lambda-layers 16 | npm install && npm install --prefix src/layers/yup-utils/nodejs 17 | ``` 18 | 19 | 3. Create the CDK stack 20 | 21 | ```bash 22 | npx aws-cdk deploy 23 | ``` 24 | 25 | 4. Open the AWS Console and the stack should be created in your default region 26 | 27 | 5. Cleanup 28 | 29 | ```bash 30 | npx aws-cdk destroy 31 | ``` 32 | -------------------------------------------------------------------------------- /src/my-lambda/index.ts: -------------------------------------------------------------------------------- 1 | import {APIGatewayProxyEventV2, APIGatewayProxyResultV2} from 'aws-lambda'; 2 | /* eslint-disable import/extensions, import/no-absolute-path */ 3 | import {double} from '/opt/nodejs/calc'; 4 | /* eslint-disable import/extensions, import/no-absolute-path */ 5 | import {number, object, string} from '/opt/nodejs/yup-utils'; 6 | 7 | // 👇 using yup layer 8 | const schema = object().shape({ 9 | name: string().required(), 10 | age: number().required(), 11 | }); 12 | 13 | export async function main( 14 | event: APIGatewayProxyEventV2, 15 | ): Promise { 16 | console.log(event); 17 | 18 | await schema.isValid({name: 'Tom', age: 24}); 19 | 20 | return { 21 | // 👇 using calc layer 22 | body: JSON.stringify({num: double(15)}), 23 | statusCode: 200, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": ["es2018", "ESNext.AsyncIterable"], 6 | "allowJs": true, 7 | "checkJs": true, 8 | "removeComments": true, 9 | "resolveJsonModule": true, 10 | "declaration": true, 11 | "strict": true, 12 | "noImplicitAny": true, 13 | "strictNullChecks": true, 14 | "strictPropertyInitialization": true, 15 | "noImplicitThis": true, 16 | "alwaysStrict": true, 17 | "noUnusedLocals": false, 18 | "noUnusedParameters": false, 19 | "noImplicitReturns": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "esModuleInterop": true, 22 | "allowSyntheticDefaultImports": true, 23 | "inlineSourceMap": true, 24 | "inlineSources": true, 25 | "skipLibCheck": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "experimentalDecorators": true, 28 | "typeRoots": ["./node_modules/@types"], 29 | "isolatedModules": true, 30 | "baseUrl": "./", 31 | "paths": { 32 | "/opt/nodejs/yup-utils": ["src/layers/yup-utils/nodejs/yup-utils"], 33 | "/opt/nodejs/calc": ["src/layers/calc/nodejs/calc"] 34 | } 35 | }, 36 | "exclude": ["node_modules", "**/node_modules/*", "cdk.out"] 37 | } 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cdk-starter", 3 | "version": "0.1.0", 4 | "bin": { 5 | "cdk-starter": "bin/cdk-starter.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "test": "jest", 11 | "cdk": "cdk", 12 | "type-check": "tsc --project tsconfig.json --pretty --noEmit", 13 | "lint": "eslint . --ext js,jsx,ts,tsx --fix" 14 | }, 15 | "dependencies": { 16 | "aws-cdk-lib": "^2.124.0", 17 | "constructs": "^10.3.0", 18 | "source-map-support": "^0.5.21" 19 | }, 20 | "devDependencies": { 21 | "@types/aws-lambda": "^8.10.132", 22 | "@types/jest": "^29.5.11", 23 | "@types/node": "^20.11.7", 24 | "@typescript-eslint/eslint-plugin": "^6.19.1", 25 | "@typescript-eslint/parser": "^6.19.1", 26 | "aws-cdk": "^2.124.0", 27 | "aws-lambda": "^1.0.7", 28 | "esbuild": "^0.19.12", 29 | "eslint-config-airbnb-base": "^15.0.0", 30 | "eslint-config-prettier": "^9.1.0", 31 | "eslint-import-resolver-typescript": "^3.6.1", 32 | "eslint-plugin-import": "^2.29.1", 33 | "eslint-plugin-jest": "^27.6.3", 34 | "eslint-plugin-prettier": "^5.1.3", 35 | "jest": "^29.7.0", 36 | "prettier": "^3.2.4", 37 | "ts-jest": "^29.1.2", 38 | "ts-node": "^10.9.2", 39 | "typescript": "^5.3.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (https://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | 43 | # TypeScript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | .env.test 64 | 65 | # parcel-bundler cache (https://parceljs.org/) 66 | .cache 67 | 68 | # next.js build output 69 | .next 70 | 71 | # Serverless directories 72 | .serverless/ 73 | 74 | # DynamoDB Local files 75 | .dynamodb/ 76 | 77 | 78 | infra/*.js 79 | *.d.ts 80 | !environment.d.ts 81 | 82 | # CDK asset staging directory 83 | .cdk.staging 84 | cdk.out 85 | 86 | cdk-exports-dev.json 87 | 88 | .env 89 | env.js 90 | env.ts -------------------------------------------------------------------------------- /lib/cdk-starter-stack.ts: -------------------------------------------------------------------------------- 1 | import * as lambda from 'aws-cdk-lib/aws-lambda'; 2 | import {NodejsFunction} from 'aws-cdk-lib/aws-lambda-nodejs'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import * as path from 'path'; 5 | 6 | export class CdkStarterStack extends cdk.Stack { 7 | constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { 8 | super(scope, id, props); 9 | 10 | // 👇 layer we've written 11 | const calcLayer = new lambda.LayerVersion(this, 'calc-layer', { 12 | compatibleRuntimes: [ 13 | lambda.Runtime.NODEJS_16_X, 14 | lambda.Runtime.NODEJS_18_X, 15 | lambda.Runtime.NODEJS_20_X, 16 | ], 17 | code: lambda.Code.fromAsset('src/layers/calc'), 18 | description: 'multiplies a number by 2', 19 | }); 20 | 21 | // 👇 3rd party library layer 22 | const yupLayer = new lambda.LayerVersion(this, 'yup-layer', { 23 | compatibleRuntimes: [ 24 | lambda.Runtime.NODEJS_16_X, 25 | lambda.Runtime.NODEJS_18_X, 26 | lambda.Runtime.NODEJS_20_X, 27 | ], 28 | code: lambda.Code.fromAsset('src/layers/yup-utils'), 29 | description: 'Uses a 3rd party library called yup', 30 | }); 31 | 32 | // 👇 Lambda function 33 | new NodejsFunction(this, 'my-function', { 34 | memorySize: 1024, 35 | timeout: cdk.Duration.seconds(5), 36 | runtime: lambda.Runtime.NODEJS_18_X, 37 | handler: 'main', 38 | entry: path.join(__dirname, `/../src/my-lambda/index.ts`), 39 | bundling: { 40 | minify: false, 41 | // 👇 don't bundle `yup` layer 42 | // layers are already available in the lambda env 43 | externalModules: ['aws-sdk', 'yup'], 44 | }, 45 | layers: [calcLayer, yupLayer], 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | ignorePatterns: [ 4 | 'node_modules/*', 5 | '**/node_modules/', 6 | 'cdk.out/', 7 | '.prettierrc.js', 8 | '.eslintrc.js', 9 | ], 10 | parser: '@typescript-eslint/parser', 11 | parserOptions: { 12 | project: './tsconfig.eslint.json', 13 | tsconfigRootDir: './', 14 | }, 15 | plugins: ['import', '@typescript-eslint', 'jest', 'prettier'], 16 | extends: [ 17 | 'eslint:recommended', 18 | 'airbnb-base', 19 | 'prettier', 20 | 'plugin:prettier/recommended', 21 | 'plugin:@typescript-eslint/recommended', 22 | 'plugin:@typescript-eslint/recommended-requiring-type-checking', 23 | ], 24 | rules: { 25 | 'no-use-before-define': [ 26 | 'error', 27 | {functions: false, classes: true, variables: true}, 28 | ], 29 | 'import/no-extraneous-dependencies': [ 30 | 'error', 31 | { 32 | devDependencies: true, 33 | optionalDependencies: false, 34 | peerDependencies: false, 35 | }, 36 | ], 37 | // for lambda layer imports starting with /opt/nodejs/ directory 38 | 'import/no-unresolved': ['warn', {ignore: ['/opt/*']}], 39 | 'import/prefer-default-export': 'off', 40 | 'lines-between-class-members': [ 41 | 'error', 42 | 'always', 43 | {exceptAfterSingleLine: true}, 44 | ], 45 | 'no-shadow': 'off', 46 | '@typescript-eslint/no-shadow': ['error'], 47 | 'no-new': 'off', 48 | 'no-console': 'off', 49 | 'no-unused-vars': 'off', 50 | '@typescript-eslint/no-unused-vars': 'error', 51 | 'no-useless-constructor': 'off', 52 | '@typescript-eslint/no-useless-constructor': 'error', 53 | 'jest/no-disabled-tests': 'warn', 54 | 'jest/no-focused-tests': 'error', 55 | 'jest/no-identical-title': 'error', 56 | 'jest/prefer-to-have-length': 'warn', 57 | 'jest/valid-expect': 'error', 58 | 'prettier/prettier': ['error'], 59 | 'import/extensions': [ 60 | 'error', 61 | 'ignorePackages', 62 | { 63 | js: 'never', 64 | jsx: 'never', 65 | ts: 'never', 66 | tsx: 'never', 67 | }, 68 | ], 69 | }, 70 | env: { 71 | 'jest/globals': true, 72 | }, 73 | globals: { 74 | page: true, 75 | browser: true, 76 | context: true, 77 | jestPuppeteer: true, 78 | document: true, 79 | localStorage: true, 80 | }, 81 | settings: { 82 | 'import/core-modules': ['aws-sdk'], 83 | 'import/parsers': { 84 | '@typescript-eslint/parser': ['.ts', '.tsx'], 85 | }, 86 | 'import/resolver': { 87 | typescript: {}, 88 | node: { 89 | paths: ['src'], 90 | moduleDirectory: ['node_modules', 'src/'], 91 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], 92 | }, 93 | }, 94 | }, 95 | }; 96 | -------------------------------------------------------------------------------- /src/layers/yup-utils/nodejs/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "nodejs", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "yup": "^0.32.9" 13 | } 14 | }, 15 | "node_modules/@babel/runtime": { 16 | "version": "7.13.17", 17 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz", 18 | "integrity": "sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==", 19 | "dependencies": { 20 | "regenerator-runtime": "^0.13.4" 21 | } 22 | }, 23 | "node_modules/@types/lodash": { 24 | "version": "4.14.168", 25 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", 26 | "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" 27 | }, 28 | "node_modules/lodash": { 29 | "version": "4.17.21", 30 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 31 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 32 | }, 33 | "node_modules/lodash-es": { 34 | "version": "4.17.21", 35 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 36 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" 37 | }, 38 | "node_modules/nanoclone": { 39 | "version": "0.2.1", 40 | "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", 41 | "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" 42 | }, 43 | "node_modules/property-expr": { 44 | "version": "2.0.4", 45 | "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", 46 | "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" 47 | }, 48 | "node_modules/regenerator-runtime": { 49 | "version": "0.13.7", 50 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", 51 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" 52 | }, 53 | "node_modules/toposort": { 54 | "version": "2.0.2", 55 | "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", 56 | "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" 57 | }, 58 | "node_modules/yup": { 59 | "version": "0.32.9", 60 | "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", 61 | "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", 62 | "dependencies": { 63 | "@babel/runtime": "^7.10.5", 64 | "@types/lodash": "^4.14.165", 65 | "lodash": "^4.17.20", 66 | "lodash-es": "^4.17.15", 67 | "nanoclone": "^0.2.1", 68 | "property-expr": "^2.0.4", 69 | "toposort": "^2.0.2" 70 | }, 71 | "engines": { 72 | "node": ">=10" 73 | } 74 | } 75 | }, 76 | "dependencies": { 77 | "@babel/runtime": { 78 | "version": "7.13.17", 79 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz", 80 | "integrity": "sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==", 81 | "requires": { 82 | "regenerator-runtime": "^0.13.4" 83 | } 84 | }, 85 | "@types/lodash": { 86 | "version": "4.14.168", 87 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", 88 | "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==" 89 | }, 90 | "lodash": { 91 | "version": "4.17.21", 92 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 93 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 94 | }, 95 | "lodash-es": { 96 | "version": "4.17.21", 97 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 98 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" 99 | }, 100 | "nanoclone": { 101 | "version": "0.2.1", 102 | "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", 103 | "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" 104 | }, 105 | "property-expr": { 106 | "version": "2.0.4", 107 | "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz", 108 | "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" 109 | }, 110 | "regenerator-runtime": { 111 | "version": "0.13.7", 112 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", 113 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" 114 | }, 115 | "toposort": { 116 | "version": "2.0.2", 117 | "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", 118 | "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" 119 | }, 120 | "yup": { 121 | "version": "0.32.9", 122 | "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz", 123 | "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==", 124 | "requires": { 125 | "@babel/runtime": "^7.10.5", 126 | "@types/lodash": "^4.14.165", 127 | "lodash": "^4.17.20", 128 | "lodash-es": "^4.17.15", 129 | "nanoclone": "^0.2.1", 130 | "property-expr": "^2.0.4", 131 | "toposort": "^2.0.2" 132 | } 133 | } 134 | } 135 | } 136 | --------------------------------------------------------------------------------