├── .eslintignore
├── .eslintrc
├── .github
├── actions
│ └── setup
│ │ └── action.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.json
├── .release-it.json
├── .yarn
└── releases
│ └── yarn-4.3.1.cjs
├── .yarnrc.yml
├── README.md
├── __fixtures__
└── output.md
├── __tests__
├── __file_snapshots__
│ ├── matches-binary-content-of-file-on-disk-0
│ ├── matches-content-of-file-on-disk-with-file-extension-0.md
│ ├── matches-content-of-file-on-disk-without-filename-0
│ ├── works-with-.not-0
│ ├── works-with-.not-for-binary-files-0
│ └── works-with-non-binary-buffer-content-0
├── index.test.js
└── minimal.pdf
├── commitlint.config.js
├── index.d.ts
├── index.js
├── lefthook.yml
├── package.json
├── tsconfig.json
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | extends: "satya164",
3 | env: {
4 | node: true,
5 | jest: true,
6 | },
7 | rules: {
8 | 'import/no-commonjs': 'off',
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/actions/setup/action.yml:
--------------------------------------------------------------------------------
1 | name: Setup
2 | description: Setup Node.js and install dependencies
3 |
4 | runs:
5 | using: composite
6 | steps:
7 | - name: Setup Node.js
8 | uses: actions/setup-node@v3
9 | with:
10 | node-version-file: .nvmrc
11 |
12 | - name: Cache dependencies
13 | id: yarn-cache
14 | uses: actions/cache@v3
15 | with:
16 | path: |
17 | **/node_modules
18 | .yarn/install-state.gz
19 | key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }}
20 | restore-keys: |
21 | ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
22 | ${{ runner.os }}-yarn-
23 |
24 | - name: Install dependencies
25 | if: steps.yarn-cache.outputs.cache-hit != 'true'
26 | run: yarn install --immutable
27 | shell: bash
28 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | branches:
8 | - main
9 |
10 | jobs:
11 | lint:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v3
16 |
17 | - name: Setup
18 | uses: ./.github/actions/setup
19 |
20 | - name: Lint files
21 | run: yarn lint
22 |
23 | - name: Typecheck files
24 | run: yarn typecheck
25 |
26 | test:
27 | runs-on: ubuntu-latest
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v3
31 |
32 | - name: Setup
33 | uses: ./.github/actions/setup
34 |
35 | - name: Run unit tests
36 | run: yarn test --maxWorkers=2 --coverage
37 |
38 | - name: Store test coverage
39 | uses: actions/upload-artifact@v4
40 | with:
41 | name: coverage
42 | path: coverage
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode
3 |
4 | /node_modules/
5 |
6 |
7 | # Yarn
8 | .yarn/*
9 | !.yarn/patches
10 | !.yarn/plugins
11 | !.yarn/releases
12 | !.yarn/sdks
13 | !.yarn/versions
14 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "tabWidth": 2,
4 | "trailingComma": "es5",
5 | "useTabs": false
6 | }
7 |
--------------------------------------------------------------------------------
/.release-it.json:
--------------------------------------------------------------------------------
1 | {
2 | "git": {
3 | "commitMessage": "chore: release ${version}",
4 | "tagName": "v${version}"
5 | },
6 | "npm": {
7 | "publish": true
8 | },
9 | "github": {
10 | "release": true
11 | },
12 | "plugins": {
13 | "@release-it/conventional-changelog": {
14 | "preset": "angular"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-4.3.1.cjs
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jest-file-snapshot
2 |
3 | [![Build Status][build-badge]][build]
4 | [![Code Coverage][coverage-badge]][coverage]
5 | [![MIT License][license-badge]][license]
6 | [![Version][version-badge]][package]
7 |
8 | Jest matcher to write snapshots to a separate file instead of the default snapshot file used by Jest. Writing a snapshot to a separate file means you have proper syntax highlighting in the output file, and better readability without those pesky escape characters. It's also useful if you have binary content.
9 |
10 | ## Installation
11 |
12 | ```sh
13 | npm install --save-dev jest-file-snapshot
14 | ```
15 |
16 | or
17 |
18 | ```sh
19 | yarn add --dev jest-file-snapshot
20 | ```
21 |
22 | ## Usage
23 |
24 | Extend Jest's `expect`:
25 |
26 | ```js
27 | import { toMatchFile } from 'jest-file-snapshot';
28 |
29 | expect.extend({ toMatchFile });
30 | ```
31 |
32 | Then use it in your tests:
33 |
34 | ```js
35 | it('matches content of file on disk', () => {
36 | expect(content).toMatchFile();
37 | });
38 | ```
39 |
40 | The content passed can be of type `string` or a `Buffer`. The comparison be done using `Buffer.equals()` instead of `===` if a `Buffer` is passed.
41 |
42 | The matcher takes two optional arguments:
43 |
44 | - `filepath`: path to the file whose content should be matched, e.g. `expect(content).toMatchFile(path.join(__dirname, 'output.md'))`
45 | - `options`: additional options object for the matcher, with following properties:
46 | - `diff`: options for [`jest-diff`](https://github.com/facebook/jest/tree/master/packages/jest-diff)
47 | - `fileExtension`: optional file extension to use for the snapshot file.
48 |
49 | You should also [exclude the output files from Jest's watcher](https://jestjs.io/docs/en/configuration#watchpathignorepatterns-arraystring) so that updating the snapshot doesn't re-run the tests again.
50 |
51 | For example, by default `toMatchFile` uses a folder named `__file_snapshots__` which you can exclude by adding the following under the `jest` key in `package.json`:
52 |
53 | ```json
54 | "watchPathIgnorePatterns": [
55 | "__file_snapshots__"
56 | ]
57 | ```
58 |
59 | ## Credits
60 |
61 | - [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot)
62 |
63 | ## Contributing
64 |
65 | Make sure your code passes the unit tests, ESLint and TypeScript. Run the following to verify:
66 |
67 | ```sh
68 | yarn test
69 | yarn lint
70 | yarn typescript
71 | ```
72 |
73 | To fix formatting errors, run the following:
74 |
75 | ```sh
76 | yarn lint -- --fix
77 | ```
78 |
79 |
80 |
81 | [build-badge]: https://img.shields.io/circleci/project/github/satya164/jest-file-snapshot/main.svg?style=flat-square
82 | [build]: https://circleci.com/gh/satya164/jest-file-snapshot
83 | [coverage-badge]: https://img.shields.io/codecov/c/github/satya164/jest-file-snapshot.svg?style=flat-square
84 | [coverage]: https://codecov.io/github/satya164/jest-file-snapshot
85 | [license-badge]: https://img.shields.io/npm/l/jest-file-snapshot.svg?style=flat-square
86 | [license]: https://opensource.org/licenses/MIT
87 | [version-badge]: https://img.shields.io/npm/v/jest-file-snapshot.svg?style=flat-square
88 | [package]: https://www.npmjs.com/package/jest-file-snapshot
89 |
--------------------------------------------------------------------------------
/__fixtures__/output.md:
--------------------------------------------------------------------------------
1 | # this is a test
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/matches-binary-content-of-file-on-disk-0:
--------------------------------------------------------------------------------
1 | %PDF-1.1
2 | %¥±ë
3 |
4 | 1 0 obj
5 | << /Type /Catalog
6 | /Pages 2 0 R
7 | >>
8 | endobj
9 |
10 | 2 0 obj
11 | << /Type /Pages
12 | /Kids [3 0 R]
13 | /Count 1
14 | /MediaBox [0 0 300 144]
15 | >>
16 | endobj
17 |
18 | 3 0 obj
19 | << /Type /Page
20 | /Parent 2 0 R
21 | /Resources
22 | << /Font
23 | << /F1
24 | << /Type /Font
25 | /Subtype /Type1
26 | /BaseFont /Times-Roman
27 | >>
28 | >>
29 | >>
30 | /Contents 4 0 R
31 | >>
32 | endobj
33 |
34 | 4 0 obj
35 | << /Length 55 >>
36 | stream
37 | BT
38 | /F1 18 Tf
39 | 0 0 Td
40 | (Hello World) Tj
41 | ET
42 | endstream
43 | endobj
44 |
45 | xref
46 | 0 5
47 | 0000000000 65535 f
48 | 0000000018 00000 n
49 | 0000000077 00000 n
50 | 0000000178 00000 n
51 | 0000000457 00000 n
52 | trailer
53 | << /Root 1 0 R
54 | /Size 5
55 | >>
56 | startxref
57 | 565
58 | %%EOF
59 |
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/matches-content-of-file-on-disk-with-file-extension-0.md:
--------------------------------------------------------------------------------
1 | # this is a another test
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/matches-content-of-file-on-disk-without-filename-0:
--------------------------------------------------------------------------------
1 | # this is a another test
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/works-with-.not-0:
--------------------------------------------------------------------------------
1 | # this is a ugly test
2 |
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/works-with-.not-for-binary-files-0:
--------------------------------------------------------------------------------
1 | %PDF-1.1
2 | %¥±ë
3 |
4 | % MIT License
5 | %
6 | % Copyright (c) 2010 Brendan Zagaeski
7 | %
8 | % Permission is hereby granted, free of charge, to any person obtaining a copy
9 | % of this software and associated documentation files (the "Software"), to deal
10 | % in the Software without restriction, including without limitation the rights
11 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | % copies of the Software, and to permit persons to whom the Software is
13 | % furnished to do so, subject to the following conditions:
14 | %
15 | % The above copyright notice and this permission notice shall be included in all
16 | % copies or substantial portions of the Software.
17 | %
18 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | % SOFTWARE.
25 |
26 | 1 0 obj
27 | << /Type /Catalog
28 | /Pages 2 0 R
29 | >>
30 | endobj
31 |
32 | 2 0 obj
33 | << /Type /Pages
34 | /Kids [3 0 R]
35 | /Count 1
36 | /MediaBox [0 0 300 144]
37 | >>
38 | endobj
39 |
40 | 3 0 obj
41 | << /Type /Page
42 | /Parent 2 0 R
43 | /Resources
44 | << /Font
45 | << /F1
46 | << /Type /Font
47 | /Subtype /Type1
48 | /BaseFont /Times-Roman
49 | >>
50 | >>
51 | >>
52 | /Contents 4 0 R
53 | >>
54 | endobj
55 |
56 | 4 0 obj
57 | << /Length 55 >>
58 | stream
59 | BT
60 | /F1 18 Tf
61 | 0 0 Td
62 | (Hello World) Tj
63 | ET
64 | endstream
65 | endobj
66 |
67 | xref
68 | 0 5
69 | 0000000000 65535 f
70 | 0000001130 00000 n
71 | 0000001189 00000 n
72 | 0000001290 00000 n
73 | 0000001569 00000 n
74 | trailer
75 | << /Root 1 0 R
76 | /Size 5
77 | >>
78 | startxref
79 | 1677
80 | %%EOF
81 |
--------------------------------------------------------------------------------
/__tests__/__file_snapshots__/works-with-non-binary-buffer-content-0:
--------------------------------------------------------------------------------
1 | # this is a buffer test
--------------------------------------------------------------------------------
/__tests__/index.test.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 | const { toMatchFile } = require('../index');
4 |
5 | expect.extend({ toMatchFile });
6 |
7 | it('matches content of file on disk with specified filename', () => {
8 | expect(`# this is a test`).toMatchFile(
9 | path.join(__dirname, '..', '__fixtures__', 'output.md')
10 | );
11 | });
12 |
13 | it('matches content of file on disk without filename', () => {
14 | expect(`# this is a another test`).toMatchFile();
15 | });
16 |
17 | it('matches content of file on disk with file extension', () => {
18 | expect(`# this is a another test`).toMatchFile(undefined, {
19 | fileExtension: '.md',
20 | });
21 | });
22 |
23 | it('matches binary content of file on disk', () => {
24 | expect(
25 | fs.readFileSync(path.join(__dirname, 'minimal.pdf'), 'binary')
26 | ).toMatchFile();
27 | });
28 |
29 | it('works with non-binary buffer content', () => {
30 | expect(Buffer.from('# this is a buffer test')).toMatchFile();
31 | });
32 |
33 | it('works with .not', () => {
34 | expect(`# this is a nice test`).not.toMatchFile();
35 | });
36 |
37 | it('works with .not for binary files', () => {
38 | expect(
39 | fs.readFileSync(path.join(__dirname, 'minimal.pdf'), 'binary')
40 | ).not.toMatchFile();
41 | });
42 |
--------------------------------------------------------------------------------
/__tests__/minimal.pdf:
--------------------------------------------------------------------------------
1 | %PDF-1.1
2 | %¥±ë
3 |
4 | 1 0 obj
5 | << /Type /Catalog
6 | /Pages 2 0 R
7 | >>
8 | endobj
9 |
10 | 2 0 obj
11 | << /Type /Pages
12 | /Kids [3 0 R]
13 | /Count 1
14 | /MediaBox [0 0 300 144]
15 | >>
16 | endobj
17 |
18 | 3 0 obj
19 | << /Type /Page
20 | /Parent 2 0 R
21 | /Resources
22 | << /Font
23 | << /F1
24 | << /Type /Font
25 | /Subtype /Type1
26 | /BaseFont /Times-Roman
27 | >>
28 | >>
29 | >>
30 | /Contents 4 0 R
31 | >>
32 | endobj
33 |
34 | 4 0 obj
35 | << /Length 55 >>
36 | stream
37 | BT
38 | /F1 18 Tf
39 | 0 0 Td
40 | (Hello World) Tj
41 | ET
42 | endstream
43 | endobj
44 |
45 | xref
46 | 0 5
47 | 0000000000 65535 f
48 | 0000000018 00000 n
49 | 0000000077 00000 n
50 | 0000000178 00000 n
51 | 0000000457 00000 n
52 | trailer
53 | << /Root 1 0 R
54 | /Size 5
55 | >>
56 | startxref
57 | 565
58 | %%EOF
59 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | };
4 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import { DiffOptions } from 'jest-diff';
4 |
5 | export const toMatchFile: (
6 | content: string | Buffer,
7 | filename?: string,
8 | options?: FileMatcherOptions
9 | ) => jest.CustomMatcherResult;
10 |
11 | declare interface FileMatcherOptions {
12 | diff?: DiffOptions;
13 | fileExtension?: string;
14 | }
15 |
16 | declare global {
17 | namespace jest {
18 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
19 | interface Matchers {
20 | toMatchFile: (filename?: string, options?: FileMatcherOptions) => void;
21 | }
22 |
23 | interface Expect {
24 | toMatchFile: (filename?: string, options?: FileMatcherOptions) => void;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /* istanbul ignore file */
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const chalk = require('chalk');
6 | const { diff } = require('jest-diff');
7 | const mkdirp = require('mkdirp');
8 | const filenamify = require('filenamify');
9 |
10 | /**
11 | * Check if 2 strings or buffer are equal
12 | * @param {string | Buffer} a
13 | * @param {string | Buffer} b
14 | */
15 | const isEqual = (a, b) => {
16 | // @ts-ignore: TypeScript gives error if we pass string to buffer.equals
17 | return Buffer.isBuffer(a) ? a.equals(b) : a === b;
18 | };
19 |
20 | /**
21 | * Match given content against content of the specified file.
22 | *
23 | * @param {string | Buffer} content Output content to match
24 | * @param {string} [filepath] Path to the file to match against
25 | * @param {{
26 | * diff?: import('jest-diff').DiffOptions,
27 | * diffMethod?: (a: string, b: string, options: import('jest-diff').DiffOptions) => string,
28 | * fileExtension?: string,
29 | * }} options
30 | * @this {{ testPath: string, currentTestName: string, assertionCalls: number, isNot: boolean, snapshotState: { added: number, updated: number, unmatched: number, _updateSnapshot: 'none' | 'new' | 'all' } }}
31 | */
32 | exports.toMatchFile = function toMatchFile(content, filepath, options = {}) {
33 | const { isNot, snapshotState } = this;
34 |
35 | const fileExtension = options.fileExtension || '';
36 |
37 | const filename =
38 | filepath === undefined
39 | ? // If file name is not specified, generate one from the test title
40 | path.join(
41 | path.dirname(this.testPath),
42 | '__file_snapshots__',
43 | `${filenamify(
44 | this.currentTestName,
45 | {
46 | replacement: '-',
47 | },
48 | { maxLength: Infinity }
49 | ).replace(/\s/g, '-')}-${this.assertionCalls}`
50 | ) + fileExtension
51 | : filepath;
52 |
53 | options = {
54 | // Options for jest-diff
55 | diff: Object.assign(
56 | {
57 | expand: false,
58 | contextLines: 5,
59 | aAnnotation: 'Snapshot',
60 | },
61 | options.diff
62 | ),
63 | };
64 |
65 | if (snapshotState._updateSnapshot === 'none' && !fs.existsSync(filename)) {
66 | // We're probably running in CI environment
67 |
68 | snapshotState.unmatched++;
69 |
70 | return {
71 | pass: isNot,
72 | message: () =>
73 | `New output file ${chalk.blue(
74 | path.basename(filename)
75 | )} was ${chalk.bold.red('not written')}.\n\n` +
76 | 'The update flag must be explicitly passed to write a new snapshot.\n\n' +
77 | `This is likely because this test is run in a ${chalk.blue(
78 | 'continuous integration (CI) environment'
79 | )} in which snapshots are not written by default.\n\n`,
80 | };
81 | }
82 |
83 | if (fs.existsSync(filename)) {
84 | const output = fs.readFileSync(
85 | filename,
86 | Buffer.isBuffer(content) ? null : 'utf8'
87 | );
88 |
89 | if (isNot) {
90 | // The matcher is being used with `.not`
91 |
92 | if (!isEqual(content, output)) {
93 | // The value of `pass` is reversed when used with `.not`
94 | return { pass: false, message: () => '' };
95 | } else {
96 | snapshotState.unmatched++;
97 |
98 | return {
99 | pass: true,
100 | message: () =>
101 | `Expected received content ${chalk.red(
102 | 'to not match'
103 | )} the file ${chalk.blue(path.basename(filename))}.`,
104 | };
105 | }
106 | } else {
107 | if (isEqual(content, output)) {
108 | return { pass: true, message: () => '' };
109 | } else {
110 | if (snapshotState._updateSnapshot === 'all') {
111 | mkdirp.sync(path.dirname(filename));
112 | fs.writeFileSync(filename, content);
113 |
114 | snapshotState.updated++;
115 |
116 | return { pass: true, message: () => '' };
117 | } else {
118 | snapshotState.unmatched++;
119 |
120 | const diffMethod = options.diffMethod || diff;
121 | const difference =
122 | Buffer.isBuffer(content) || Buffer.isBuffer(output)
123 | ? ''
124 | : `\n\n${diffMethod(output, content, options.diff)}`;
125 |
126 | return {
127 | pass: false,
128 | message: () =>
129 | `Received content ${chalk.red(
130 | "doesn't match"
131 | )} the file ${chalk.blue(path.basename(filename))}.${difference}`,
132 | };
133 | }
134 | }
135 | }
136 | } else {
137 | if (
138 | !isNot &&
139 | (snapshotState._updateSnapshot === 'new' ||
140 | snapshotState._updateSnapshot === 'all')
141 | ) {
142 | mkdirp.sync(path.dirname(filename));
143 | fs.writeFileSync(filename, content);
144 |
145 | snapshotState.added++;
146 |
147 | return { pass: true, message: () => '' };
148 | } else {
149 | snapshotState.unmatched++;
150 |
151 | return {
152 | pass: true,
153 | message: () =>
154 | `The output file ${chalk.blue(
155 | path.basename(filename)
156 | )} ${chalk.bold.red("doesn't exist")}.`,
157 | };
158 | }
159 | }
160 | };
161 |
--------------------------------------------------------------------------------
/lefthook.yml:
--------------------------------------------------------------------------------
1 | pre-commit:
2 | parallel: true
3 | commands:
4 | lint:
5 | glob: "*.{js,ts,tsx}"
6 | run: yarn lint {staged_files}
7 | types:
8 | glob: "*.{json,js,ts,tsx}"
9 | run: yarn tsc --noEmit
10 | test:
11 | glob: "*.{json,js,ts,tsx}"
12 | run: yarn test
13 | commit-msg:
14 | parallel: true
15 | commands:
16 | commitlint:
17 | run: yarn commitlint --edit
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jest-file-snapshot",
3 | "version": "0.7.0",
4 | "description": "Jest matcher to write snapshots to a separate file instead of the default snapshot file used by Jest",
5 | "keywords": [
6 | "test",
7 | "jest",
8 | "snapshot"
9 | ],
10 | "main": "index.js",
11 | "files": [
12 | "index.js",
13 | "index.d.ts"
14 | ],
15 | "types": "index.d.ts",
16 | "license": "MIT",
17 | "repository": {
18 | "type": "git",
19 | "url": "git+https://github.com/satya164/jest-file-snapshot.git"
20 | },
21 | "author": "Satyajit Sahoo (https://github.com/satya164/)",
22 | "scripts": {
23 | "test": "jest",
24 | "lint": "eslint .",
25 | "typecheck": "tsc --noEmit",
26 | "release": "release-it"
27 | },
28 | "publishConfig": {
29 | "registry": "https://registry.npmjs.org/"
30 | },
31 | "devDependencies": {
32 | "@babel/core": "^7.24.7",
33 | "@commitlint/cli": "^19.3.0",
34 | "@commitlint/config-conventional": "^19.2.2",
35 | "@release-it/conventional-changelog": "^8.0.1",
36 | "@types/jest": "^29.5.12",
37 | "@types/jest-diff": "^24.3.0",
38 | "@types/mkdirp": "^2.0.0",
39 | "conventional-changelog-cli": "^5.0.0",
40 | "eslint": "^8.56.0",
41 | "eslint-config-satya164": "^3.2.1",
42 | "jest": "^29.7.0",
43 | "lefthook": "^1.7.0",
44 | "prettier": "^3.3.2",
45 | "release-it": "^17.4.1",
46 | "typescript": "^5.5.3"
47 | },
48 | "dependencies": {
49 | "chalk": "^4.1.2",
50 | "filenamify": "^4.3.0",
51 | "jest-diff": "^29.7.0",
52 | "mkdirp": "^3.0.1"
53 | },
54 | "jest": {
55 | "testEnvironment": "node",
56 | "testMatch": [
57 | "**/__tests__/**/*.test.js"
58 | ],
59 | "watchPathIgnorePatterns": [
60 | "(__fixtures__|__file_snapshots__)"
61 | ]
62 | },
63 | "packageManager": "yarn@4.3.1"
64 | }
65 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowUnreachableCode": false,
4 | "allowUnusedLabels": false,
5 | "esModuleInterop": true,
6 | "forceConsistentCasingInFileNames": true,
7 | "lib": ["esnext", "dom"],
8 | "module": "esnext",
9 | "moduleResolution": "node",
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitReturns": true,
12 | "noImplicitUseStrict": false,
13 | "noStrictGenericChecks": false,
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "resolveJsonModule": true,
17 | "skipLibCheck": true,
18 | "strict": true,
19 | "target": "esnext",
20 | "verbatimModuleSyntax": true
21 | }
22 | }
23 |
--------------------------------------------------------------------------------