├── .devcontainer
├── devcontainer.json
└── post-create-command.sh
├── .eslintignore
├── .eslintrc.js
├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── .husky
├── pre-commit
└── pre-merge-commit
├── .ncurc.json
├── .nvmrc
├── .prettierignore
├── .vscode
├── launch.json
└── settings.json
├── CONTRIBUTING.md
├── Dockerfile.dev
├── LICENSE
├── README.md
├── gulpfile.js
├── package-lock.json
├── package.json
├── scripts
└── bundle-declaration-references.js
├── src
├── index.spec.ts
└── nodes
│ └── DataValidation
│ ├── DataValidation.node.json
│ └── DataValidation.node.ts
├── tsconfig.base.json
├── tsconfig.json
├── tsconfig.release.json
├── tsconfig.watch.json
└── update-project-boilerplate.sh
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/docker-existing-dockerfile
3 | {
4 | "name": "Existing Dockerfile",
5 |
6 | // Sets the run context to one level up instead of the .devcontainer folder.
7 | "context": "..",
8 |
9 | // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
10 | "dockerFile": "../Dockerfile.dev",
11 |
12 | // Set *default* container specific settings.json values on container create.
13 | "settings": {},
14 |
15 | // Add the IDs of extensions you want installed when the container is created.
16 | "extensions": ["dbaeumer.vscode-eslint"],
17 |
18 | // Use 'forwardPorts' to make a list of ports inside the container available locally.
19 | // "forwardPorts": [],
20 |
21 | // Uncomment the next line to run commands after the container is created - for example installing curl.
22 | "postCreateCommand": "/workspaces/n8n-nodes-data-validation/.devcontainer/post-create-command.sh",
23 |
24 | // Uncomment when using a ptrace-based debugger like C++, Go, and Rust
25 | "runArgs": ["--network", "host"],
26 |
27 | // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
28 | // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
29 |
30 | // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
31 | "remoteUser": "node"
32 | }
33 |
--------------------------------------------------------------------------------
/.devcontainer/post-create-command.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | cd /workspaces/n8n-nodes-data-validation
6 | npm link
7 |
8 | cd ~/.npm-global/lib/node_modules/n8n
9 | npm link n8n-nodes-data-validation
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .git
3 |
4 | /lib/
5 |
6 | /coverage
7 |
8 | *.json
9 | *.js
10 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: "@typescript-eslint/parser",
3 | parserOptions: {
4 | project: "tsconfig.json",
5 | sourceType: "module",
6 | },
7 | plugins: [
8 | "@typescript-eslint/eslint-plugin",
9 | "node",
10 | "eslint-plugin-n8n-nodes-base",
11 | ],
12 | extends: [
13 | "eslint:recommended",
14 | "plugin:@typescript-eslint/recommended",
15 | "plugin:@typescript-eslint/recommended-requiring-type-checking",
16 | "prettier",
17 | "plugin:n8n-nodes-base/nodes",
18 | ],
19 | root: true,
20 | env: {
21 | node: true,
22 | jest: true,
23 | },
24 | settings: {
25 | "import/parsers": {
26 | "@typescript-eslint/parser": [".ts", ".tsx"],
27 | },
28 | },
29 | rules: {
30 | "@typescript-eslint/interface-name-prefix": "off",
31 | "@typescript-eslint/explicit-module-boundary-types": "error",
32 | "@typescript-eslint/require-await": "off",
33 | "@typescript-eslint/no-unused-vars": ["error", { args: "after-used" }],
34 | "@typescript-eslint/ban-types": "off",
35 | "@typescript-eslint/no-inferrable-types": "off",
36 | "@typescript-eslint/no-explicit-any": "error",
37 | "@typescript-eslint/no-unsafe-assignment": "error",
38 | "@typescript-eslint/no-unsafe-call": "error",
39 | "@typescript-eslint/no-unsafe-member-access": "error",
40 | "@typescript-eslint/no-unsafe-return": "error",
41 | "@typescript-eslint/no-unsafe-argument": "error",
42 | "@typescript-eslint/restrict-template-expressions": [
43 | "error",
44 | { allowNumber: true, allowNullish: false },
45 | ],
46 | "@typescript-eslint/no-floating-promises": [
47 | "error",
48 | { ignoreVoid: false, ignoreIIFE: false },
49 | ],
50 | "@typescript-eslint/no-misused-promises": "error",
51 | "@typescript-eslint/no-unnecessary-condition": "error",
52 | "@typescript-eslint/unbound-method": "error",
53 | "no-console": "error",
54 | "no-debugger": "error",
55 | "node/no-process-env": "error",
56 | },
57 | };
58 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 | on:
3 | release:
4 | types: [created]
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | - uses: actions/setup-node@v3
11 | with:
12 | node-version: "14.x"
13 | registry-url: "https://registry.npmjs.org"
14 | - run: npm ci
15 | - run: npm run build
16 | - run: npm publish
17 | env:
18 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | /lib/
3 |
4 | /coverage
5 |
6 | .npmrc
7 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run precommit
5 |
--------------------------------------------------------------------------------
/.husky/pre-merge-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npm run pre-merge-commit
5 |
--------------------------------------------------------------------------------
/.ncurc.json:
--------------------------------------------------------------------------------
1 | {
2 | "dep": ["prod", "dev", "bundle", "optional", "peer"],
3 | "reject": ["@types/node"]
4 | }
5 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 14
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .git
3 |
4 | /lib/
5 |
6 | /coverage
7 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "type": "node",
6 | "request": "attach",
7 | "name": "Attach to debugger",
8 | "port": 9229
9 | },
10 | {
11 | "type": "node",
12 | "request": "launch",
13 | "name": "Debug n8n",
14 | "program": "n8n",
15 | "args": ["start"],
16 | "cwd": "/home/node/.npm-global/lib/node_modules/n8n/bin",
17 | "outFiles": ["${workspaceFolder}/lib/*.js"],
18 | "env": {
19 | "EXECUTIONS_PROCESS": "main"
20 | }
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib"
3 | }
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to this project
2 |
3 | - [Issues and Bugs](#issues-and-bugs)
4 | - [Suggesting or merging new Features](#new-features)
5 |
6 | ## Issues and Bugs
7 |
8 | If you found a bug and know how to fix it, just open a Pull Request and we'll gladly evaluate it and merge it. If you cannot fix it, just open an issue with a [Code Sandbox](https://codesandbox.io/) or similar reproducing the bug.
9 |
10 | ## New Features
11 |
12 | Right now, we're not expecting suggestions or Pull Requests for new features.
13 |
--------------------------------------------------------------------------------
/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM node:14-buster
2 |
3 | VOLUME /home/node
4 |
5 | ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
6 | ENV PATH="${PATH}:/home/node/.npm-global/bin"
7 |
8 | RUN apt-get update \
9 | && apt-get install -y nano
10 |
11 | USER node
12 |
13 | RUN npm install n8n -g
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Bartolomeu Rodrigues
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## How to
2 |
3 | This n8n community node validates input data using JSON Schemas.
4 |
5 | Visit or to learn how to describe your validation rules in JSON Schemas.
6 |
7 | ## Library development
8 |
9 | ### Changing the supported Node version
10 |
11 | - Files to be changed
12 | - .nvmrc
13 | - Dockerfile.dev
14 | - package.json
15 | - `engine` field
16 | - `@types/node` version
17 | - tsconfig.base.json
18 | - .github/workflows/main.yml and other CI config files
19 | - delete all `node_modules` directories and `package-lock.json` files
20 | - run `npm run install`
21 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const { src, dest } = require("gulp");
2 |
3 | function copyAssets() {
4 | return src("src/**/*.{png,svg,json}").pipe(dest("lib"));
5 | }
6 |
7 | exports.default = copyAssets;
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "n8n-nodes-data-validation",
3 | "version": "1.0.1",
4 | "description": "",
5 | "keywords": [
6 | "n8n-community-node-package"
7 | ],
8 | "main": "lib/index.js",
9 | "types": "lib/types.d.ts",
10 | "files": [
11 | "lib",
12 | "assets"
13 | ],
14 | "n8n": {
15 | "n8nNodesApiVersion": 1,
16 | "credentials": [],
17 | "nodes": [
18 | "lib/nodes/DataValidation/DataValidation.node.js"
19 | ]
20 | },
21 | "engines": {
22 | "node": ">=14"
23 | },
24 | "scripts": {
25 | "build": "npm run clean && gulp && tsc --project tsconfig.release.json && node scripts/bundle-declaration-references.js",
26 | "build:watch": "gulp && tsc --project tsconfig.watch.json --watch",
27 | "clean": "rimraf lib",
28 | "typecheck": "tsc --noEmit",
29 | "test": "jest",
30 | "test:watch": "jest --watch",
31 | "test:cov": "jest --coverage",
32 | "test:cov:changed": "npm run test:cov -- --onlyChanged",
33 | "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand --testTimeout=86400000",
34 | "test:debug:watch": "npm run test:debug -- --watch",
35 | "format": "prettier --write .",
36 | "lint": "eslint --ext .ts,.tsx --max-warnings 0 .",
37 | "lint:fix": "eslint --ext .ts,.tsx --max-warnings 0 --fix .",
38 | "integrity-check": "npm run typecheck && npm run lint && npm run test",
39 | "precommit": "lint-staged && npm run integrity-check",
40 | "update-all-dependencies": "npm-check-updates --upgrade && rimraf package-lock.json node_modules && npm install",
41 | "reset-repository": "git clean -Xdf",
42 | "prepare": "husky install",
43 | "pre-merge-commit": "npm install && npm run integrity-check"
44 | },
45 | "author": "Bartolomeu Rodrigues",
46 | "license": "MIT",
47 | "publishConfig": {
48 | "access": "public"
49 | },
50 | "dependencies": {
51 | "ajv": "^8.11.0"
52 | },
53 | "devDependencies": {
54 | "@types/express": "^4.17.13",
55 | "@types/jest": "^27.4.1",
56 | "@types/request-promise-native": "^1.0.18",
57 | "@typescript-eslint/eslint-plugin": "^5.15.0",
58 | "@typescript-eslint/parser": "^5.15.0",
59 | "eslint": "^8.11.0",
60 | "eslint-config-prettier": "^8.5.0",
61 | "eslint-plugin-n8n-nodes-base": "^1.6.5",
62 | "eslint-plugin-node": "^11.1.0",
63 | "glob": "^7.2.0",
64 | "gulp": "^4.0.2",
65 | "husky": "^7.0.4",
66 | "jest": "^27.5.1",
67 | "lint-staged": "^12.3.7",
68 | "n8n-core": "^0.132.0",
69 | "n8n-workflow": "^0.114.0",
70 | "npm-check-updates": "^12.5.4",
71 | "prettier": "^2.6.0",
72 | "rimraf": "^3.0.2",
73 | "ts-jest": "^27.1.3",
74 | "typescript": "^4.6.2"
75 | },
76 | "jest": {
77 | "moduleFileExtensions": [
78 | "js",
79 | "json",
80 | "ts",
81 | "tsx"
82 | ],
83 | "rootDir": ".",
84 | "testMatch": [
85 | "**/*.spec.ts",
86 | "**/*.spec.tsx"
87 | ],
88 | "transform": {
89 | "\\.tsx?$": "ts-jest"
90 | },
91 | "globals": {
92 | "ts-jest": {
93 | "isolatedModules": true,
94 | "tsconfig": "tsconfig.json"
95 | }
96 | },
97 | "testEnvironment": "node",
98 | "roots": [
99 | "/src/"
100 | ],
101 | "moduleDirectories": [
102 | "node_modules",
103 | ""
104 | ]
105 | },
106 | "lint-staged": {
107 | "*.{js,jsx,json,ts,tsx,scss,sass,css,md,yml,yaml}": "prettier --write"
108 | },
109 | "repository": {
110 | "type": "git",
111 | "url": "https://github.com/Bartmr/n8n-nodes-data-validation.git"
112 | },
113 | "bugs": {
114 | "url": "https://github.com/Bartmr/n8n-nodes-data-validation/issues"
115 | },
116 | "homepage": "https://github.com/Bartmr/n8n-nodes-data-validation"
117 | }
118 |
--------------------------------------------------------------------------------
/scripts/bundle-declaration-references.js:
--------------------------------------------------------------------------------
1 | const glob = require("glob");
2 | const fs = require("fs");
3 |
4 | const declarationFiles = glob.sync("lib/**/*.d.ts");
5 |
6 | const typesFile = "lib/types.d.ts";
7 |
8 | const declarationReferences = declarationFiles.reduce((content, current) => {
9 | if (current === typesFile) {
10 | return content;
11 | }
12 |
13 | const relativePath = current.substring(4);
14 |
15 | return content + `/// ` + "\n";
16 | }, "");
17 |
18 | fs.writeFileSync(typesFile, declarationReferences);
19 |
--------------------------------------------------------------------------------
/src/index.spec.ts:
--------------------------------------------------------------------------------
1 | describe("Sample test. REMOVE IT", () => {
2 | it("Sample test. REMOVE IT", () => {
3 | expect("world").toBe("world");
4 | });
5 | });
6 |
7 | export {};
8 |
--------------------------------------------------------------------------------
/src/nodes/DataValidation/DataValidation.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "node": "n8n-nodes-base.data-validation",
3 | "nodeVersion": "1.0",
4 | "codexVersion": "1.0",
5 | "categories": ["Utility"]
6 | }
7 |
--------------------------------------------------------------------------------
/src/nodes/DataValidation/DataValidation.node.ts:
--------------------------------------------------------------------------------
1 | import { IExecuteFunctions } from "n8n-core";
2 | import {
3 | INodeExecutionData,
4 | INodeType,
5 | INodeTypeDescription,
6 | NodeApiError,
7 | NodeOperationError,
8 | } from "n8n-workflow";
9 | import Ajv, { Schema } from "ajv";
10 |
11 | export class DataValidation implements INodeType {
12 | description: INodeTypeDescription = {
13 | displayName: "Data Validation",
14 | name: "dataValidation",
15 | group: ["transform"],
16 | version: 1,
17 | description: "Validate input data before continuing the workflow",
18 | defaults: {
19 | name: "Data Validation",
20 | color: "#000000",
21 | },
22 | inputs: ["main"],
23 | outputs: ["main"],
24 | properties: [
25 | {
26 | displayName: "JSON Schema",
27 | name: "jsonSchema",
28 | type: "json",
29 | typeOptions: {
30 | alwaysOpenEditWindow: true,
31 | },
32 | default: JSON.stringify(
33 | {
34 | type: "object",
35 | properties: {
36 | foo: { type: "integer" },
37 | bar: { type: "string" },
38 | },
39 | required: ["foo"],
40 | additionalProperties: false,
41 | },
42 | undefined,
43 | 2
44 | ),
45 | placeholder: "",
46 | // eslint-disable-next-line n8n-nodes-base/node-param-description-miscased-json
47 | description:
48 | "Visit https://ajv.js.org/ or https://json-schema.org/ to learn how to describe your validation rules in JSON Schemas",
49 | },
50 | ],
51 | };
52 |
53 | async execute(this: IExecuteFunctions): Promise {
54 | const items = this.getInputData();
55 | const returnData: INodeExecutionData[] = [];
56 |
57 | const jsonSchemaString = this.getNodeParameter("jsonSchema", 0);
58 |
59 | if (typeof jsonSchemaString !== "string") {
60 | throw new NodeOperationError(this.getNode(), "Invalid JSON Schema");
61 | }
62 |
63 | let jsonSchema: Schema;
64 |
65 | try {
66 | jsonSchema = JSON.parse(jsonSchemaString) as Schema;
67 | } catch (err) {
68 | throw new NodeOperationError(this.getNode(), "Invalid JSON Schema");
69 | }
70 |
71 | const ajv = new Ajv();
72 | let validate: ReturnType;
73 |
74 | try {
75 | validate = ajv.compile(jsonSchema);
76 | } catch (err) {
77 | throw new NodeOperationError(this.getNode(), "Invalid JSON Schema");
78 | }
79 |
80 | for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
81 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
82 | const item = items[itemIndex]!;
83 |
84 | const json = item["json"];
85 |
86 | const valid = validate(json);
87 |
88 | if (!valid) {
89 | throw new NodeApiError(
90 | this.getNode(),
91 | {
92 | errors: JSON.stringify(validate.errors, undefined, 4),
93 | },
94 | {
95 | itemIndex,
96 | message: "Invalid data",
97 | description: JSON.stringify(validate.errors, undefined, 4),
98 | httpCode: "400",
99 | }
100 | );
101 | }
102 |
103 | returnData.push({
104 | json,
105 | pairedItem: {
106 | item: itemIndex,
107 | },
108 | });
109 | }
110 |
111 | return this.prepareOutputData(returnData);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src"],
3 | "compilerOptions": {
4 | "lib": ["es2020"],
5 | "module": "commonjs",
6 | "target": "es2020",
7 | "isolatedModules": true,
8 | "declaration": true,
9 | "removeComments": false,
10 | "sourceMap": true,
11 | "outDir": "./lib",
12 | "rootDir": "./src",
13 | "strict": true,
14 | "noUncheckedIndexedAccess": true,
15 | "noImplicitReturns": true,
16 | "forceConsistentCasingInFileNames": true,
17 | "esModuleInterop": true,
18 | "experimentalDecorators": true,
19 | "emitDecoratorMetadata": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "incremental": true,
5 | "tsBuildInfoFile": "./lib/default.tsbuildinfo"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.release.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "exclude": [
4 | "**/*.*spec.ts",
5 | "**/*.*spec.tsx",
6 | "**/spec/**/*.ts",
7 | "**/spec/**/*.tsx"
8 | ],
9 | "compilerOptions": {
10 | "incremental": false
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig.watch.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "exclude": [
4 | "**/*.*spec.ts",
5 | "**/*.*spec.tsx",
6 | "**/spec/**/*.ts",
7 | "**/spec/**/*.tsx"
8 | ],
9 | "compilerOptions": {
10 | "incremental": true,
11 | "tsBuildInfoFile": "./lib/watch.tsbuildinfo"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/update-project-boilerplate.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ ! -d "./.git/" ] && [ ! -f "./.git" ]
4 | then
5 | echo -e "This command is only to be used when the project is in the root directory of a Git repository"
6 | else
7 | echo "-----
8 | WARNING!!! This will erase any uncommited changes that you have right now.
9 | To cancel the update press Ctrl+C. Commit and push your changes first and then run this update command again.
10 | To continue with the update write yes and press Enter.
11 | -----"
12 | read user_has_continued
13 |
14 | if [ "$user_has_continued" != "yes" ]; then
15 | echo "Update canceled"
16 | exit 0
17 | fi
18 |
19 | echo "Paste the URL of the git repository where the boilerplate is"
20 | read git_url
21 |
22 | echo "What is the name of the git branch where the updates are?"
23 | read git_branch
24 |
25 | echo "Updating..."
26 |
27 | git add .
28 | git reset --hard
29 |
30 | git remote remove boilerplate
31 | git remote add boilerplate $git_url
32 |
33 | git fetch boilerplate $git_branch
34 |
35 | git merge "boilerplate/${git_branch}" --no-commit
36 |
37 | echo "
38 | -----
39 | -----
40 | -----
41 | ----- FURTHER INSTRUCTIONS
42 |
43 | - Review and pick the updates you want to add to the project
44 |
45 | - Run 'npm install', in case any dependencies were changed or added
46 |
47 | - Check if any of the changes made by the updates require a new migration to be written
48 |
49 | - Run 'git add .' to stage all the accepted updates
50 |
51 | - IF YOU WANT TO ABORT the update, run 'git merge --abort'
52 |
53 | - To finalize the update, run 'git merge --continue'"
54 | fi
55 |
--------------------------------------------------------------------------------