├── .github
├── FUNDING.yml
├── SPONSORS.yml
└── workflows
│ └── test.yml
├── .gitignore
├── .prettierrc.js
├── LICENSE
├── README.md
├── dist
├── index.d.ts
└── index.js
├── eslint.config.js
├── package-lock.json
├── package.json
├── src
└── index.ts
├── test
└── index.test.ts
└── tsconfig.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: mesqueeb
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/SPONSORS.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: mesqueeb
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on:
3 | push:
4 | branches: main
5 | paths:
6 | - src/**
7 | - test/**
8 | - '*.js'
9 | - '*.ts'
10 | - '*.json'
11 | - .github/workflows/test.yml
12 | pull_request:
13 | branches: main
14 | paths:
15 | - src/**
16 | - test/**
17 | - '*.js'
18 | - '*.ts'
19 | - '*.json'
20 | - .github/workflows/test.yml
21 | concurrency:
22 | group: test-${{ github.ref }}
23 | cancel-in-progress: true
24 | jobs:
25 | test:
26 | strategy:
27 | matrix:
28 | node-version: ['18', '20']
29 | runs-on: ubuntu-latest
30 | steps:
31 | - uses: actions/checkout@v4
32 | - uses: actions/setup-node@v4
33 | with:
34 | node-version: ${{ matrix.node-version }}
35 | cache: npm
36 | - run: npm ci
37 | - run: npm test
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .vscode
3 | .cache
4 | .env
5 | .env.js
6 | .rpt2_cache
7 | .DS_Store
8 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | import prettier from "@cycraft/eslint/prettier"
2 |
3 | export default prettier
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Luca Ban - Mesqueeb
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Find and replace anything 🎣
2 |
3 |
4 |
5 |
6 | ```
7 | npm i find-and-replace-anything
8 | ```
9 |
10 | Replace one val with another or all occurrences in an object recursively. A simple & small integration.
11 |
12 | There are two methods you can import and use:
13 |
14 | - **findAndReplace** find `a` replace with `b` (recursively on an object)
15 | - **findAndReplaceIf** execute a function on every prop in an object recursively, and replace the prop with what the function returns
16 |
17 | ## Meet the family (more tiny utils with TS support)
18 |
19 | - [is-what 🙉](https://github.com/mesqueeb/is-what)
20 | - [is-where 🙈](https://github.com/mesqueeb/is-where)
21 | - [merge-anything 🥡](https://github.com/mesqueeb/merge-anything)
22 | - [check-anything 👁](https://github.com/mesqueeb/check-anything)
23 | - [remove-anything ✂️](https://github.com/mesqueeb/remove-anything)
24 | - [getorset-anything 🐊](https://github.com/mesqueeb/getorset-anything)
25 | - [map-anything 🗺](https://github.com/mesqueeb/map-anything)
26 | - [filter-anything ⚔️](https://github.com/mesqueeb/filter-anything)
27 | - [copy-anything 🎭](https://github.com/mesqueeb/copy-anything)
28 | - [case-anything 🐫](https://github.com/mesqueeb/case-anything)
29 | - [flatten-anything 🏏](https://github.com/mesqueeb/flatten-anything)
30 | - [nestify-anything 🧅](https://github.com/mesqueeb/nestify-anything)
31 |
32 | ## find and replace
33 |
34 | This will find a value inside an object and replace it with another:
35 |
36 | - `findAndReplace(object, find, replace)`
37 |
38 | ```js
39 | import { findAndReplace } from 'find-and-replace-anything'
40 |
41 | findAndReplace({deep: {nested: {prop: 'a'}}}, 'a', 'b')
42 | // returns
43 | {deep: {nested: {prop: 'b'}}}
44 |
45 | findAndReplace('works on "exact" strings as well', 'a', 'b')
46 | // returns
47 | 'works on "exact" strings as well'
48 |
49 | findAndReplace('a', 'a', 'b')
50 | // returns
51 | 'b'
52 |
53 | // works with other types as well:
54 | findAndReplace({nr: 1}, 1, 100)
55 | // returns
56 | {nr: 100}
57 | ```
58 |
59 | ## find and replace IF
60 |
61 | This will execute a provided function to every prop in the object recursively. The "check" function provided will receive the prop's value as param:
62 |
63 | - `findAndReplaceIf(object, checkFn)` checkFn receives each `propVal` of the object recursively
64 |
65 | ```js
66 | import { findAndReplaceIf } from 'find-and-replace-anything'
67 |
68 | // function that replaces 'a' with 'b'
69 | function checkFn (foundVal) {
70 | if (foundVal === 'a') return 'b'
71 | return foundVal
72 | // always return original foundVal when no replacement occurs
73 | }
74 |
75 | findAndReplaceIf({deep: {nested: {prop: 'a'}}}, checkFn)
76 | // returns
77 | {deep: {nested: {prop: 'b'}}}
78 |
79 | // this is what gets executed in order:
80 | checkFn({deep: {nested: {prop: 'a'}}})
81 | checkFn({nested: {prop: 'a'}})
82 | checkFn({prop: 'a'})
83 | checkFn('a')
84 | // the final execution replaces 'a' with 'b'
85 | // and then returns the entire object
86 |
87 | // also works on non-objects
88 | findAndReplace('a', checkFn)
89 | // returns
90 | 'b'
91 | ```
92 |
93 | ## A note on plain objects vs classes
94 |
95 | > only for `findAndReplace()`
96 |
97 | Please note that it will also recursively look inside special objects like JavaScript classes etc. So make sure you test the behaviour properly in those cases! (especially when your classes have read-only properties etc.)
98 |
99 | ```js
100 | class MyClass {
101 | constructor () {
102 | this.prop = 1
103 | }
104 | }
105 | const target = {
106 | prop: 1,
107 | class: new MyClass()
108 | }
109 | findAndReplace(target, 1, 2)
110 | // this will replace 1 with 2 in the class as well and returns:
111 | {prop: 2, class: {prop: 2}}
112 | ```
113 |
114 | If you need it to only recursively go through plain JavaScript object and avoid going in custom classes etc. you can pass a 4th parameter like so:
115 |
116 | ```js
117 | findAndReplace(target, 1, 2, {onlyPlainObjects: true})
118 | // this will replace 1 with 2 only in the plain object and returns:
119 | {prop: 2, class: {prop: 1}}
120 | ```
121 |
122 | > Also be careful with circular references! It will cause this library to crash.
123 |
124 | ## Source code
125 |
126 | It's literally just this:
127 |
128 | ```js
129 | /**
130 | * @param {*} target Target can be anything
131 | * @param {*} find val to find
132 | * @param {*} replaceWith val to replace
133 | * @returns the target with replaced values
134 | */
135 | function findAndReplaceRecursively (target, find, replaceWith) {
136 | if (!isObject(target)) {
137 | if (target === find) return replaceWith
138 | return target
139 | }
140 | return Object.keys(target)
141 | .reduce((carry, key) => {
142 | const val = target[key]
143 | carry[key] = findAndReplaceRecursively(val, find, replaceWith)
144 | return carry
145 | }, {})
146 | }
147 | ```
148 |
--------------------------------------------------------------------------------
/dist/index.d.ts:
--------------------------------------------------------------------------------
1 | type Config = {
2 | onlyPlainObjects?: boolean;
3 | checkArrayValues?: boolean;
4 | };
5 | /**
6 | * Goes through an object recursively and replaces all occurences of the `find` value with `replaceWith`. Also works no non-objects.
7 | *
8 | * @export
9 | * @param target Target can be anything
10 | * @param find val to find
11 | * @param replaceWith val to replace
12 | * @param [config={onlyPlainObjects: false, checkArrayValues: false}]
13 | * @returns the target with replaced values
14 | */
15 | export declare function findAndReplace(target: any, find: any, replaceWith: any, config?: Config): unknown;
16 | export declare function _findAndReplaceIf(target: any, checkFn: (foundVal: any, propKey: string | undefined) => any, propKey: string | undefined, config?: Config): unknown;
17 | /**
18 | * Goes through an object recursively and replaces all props with what's is returned in the `checkFn`. Also works on non-objects. `checkFn` is triggered on every single level of any value/object.
19 | *
20 | * @export
21 | * @param target Target can be anything
22 | * @param checkFn a function that will receive the `foundVal`
23 | * @param [config={onlyPlainObjects: true, checkArrayValues: false}]
24 | * @returns the target with replaced values
25 | */
26 | export declare function findAndReplaceIf(target: any, checkFn: (foundVal: any, propKey: string | undefined) => any, config?: Config): unknown;
27 | export {};
28 |
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | import { isAnyObject, isArray, isNaNValue, isPlainObject } from 'is-what';
2 | /**
3 | * Goes through an object recursively and replaces all occurences of the `find` value with `replaceWith`. Also works no non-objects.
4 | *
5 | * @export
6 | * @param target Target can be anything
7 | * @param find val to find
8 | * @param replaceWith val to replace
9 | * @param [config={onlyPlainObjects: false, checkArrayValues: false}]
10 | * @returns the target with replaced values
11 | */
12 | export function findAndReplace(target, find, replaceWith, config = { onlyPlainObjects: false, checkArrayValues: false }) {
13 | const _target = target;
14 | // arrays
15 | if (config.checkArrayValues && isArray(_target) && !isAnyObject(_target)) {
16 | return _target.map((value) => findAndReplace(value, find, replaceWith, config));
17 | }
18 | // non-objects
19 | if ((!config.onlyPlainObjects && !isAnyObject(_target)) ||
20 | (config.onlyPlainObjects === true && !isPlainObject(_target))) {
21 | if (_target === find || (isNaNValue(_target) && isNaNValue(find))) {
22 | return replaceWith;
23 | }
24 | return _target;
25 | }
26 | // objects
27 | return Object.entries(target).reduce((carry, [key, val]) => {
28 | carry[key] = findAndReplace(val, find, replaceWith, config);
29 | return carry;
30 | }, {});
31 | }
32 | export function _findAndReplaceIf(target, checkFn, propKey, config = { onlyPlainObjects: true, checkArrayValues: false }) {
33 | const _target = checkFn(target, propKey);
34 | if (config.checkArrayValues && isArray(_target) && !isAnyObject(_target)) {
35 | return _target.map((value) => _findAndReplaceIf(value, checkFn, undefined, config));
36 | }
37 | if (!isPlainObject(_target))
38 | return _target;
39 | return Object.entries(_target).reduce((carry, [key, val]) => {
40 | carry[key] = _findAndReplaceIf(val, checkFn, key, config);
41 | return carry;
42 | }, {});
43 | }
44 | /**
45 | * Goes through an object recursively and replaces all props with what's is returned in the `checkFn`. Also works on non-objects. `checkFn` is triggered on every single level of any value/object.
46 | *
47 | * @export
48 | * @param target Target can be anything
49 | * @param checkFn a function that will receive the `foundVal`
50 | * @param [config={onlyPlainObjects: true, checkArrayValues: false}]
51 | * @returns the target with replaced values
52 | */
53 | export function findAndReplaceIf(target, checkFn, config = { onlyPlainObjects: true, checkArrayValues: false }) {
54 | return _findAndReplaceIf(target, checkFn, undefined, config);
55 | }
56 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import config from '@cycraft/eslint/config'
2 |
3 | export default [
4 | ...config,
5 | {
6 | rules: {
7 | '@typescript-eslint/no-explicit-any': 'warn',
8 | },
9 | },
10 | ]
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "find-and-replace-anything",
3 | "version": "4.0.3",
4 | "description": "Replace one val with another or all occurrences in an object recursively. A simple & small integration.",
5 | "type": "module",
6 | "sideEffects": false,
7 | "exports": {
8 | ".": "./dist/index.js"
9 | },
10 | "engines": {
11 | "node": ">=18"
12 | },
13 | "scripts": {
14 | "test": "vitest run",
15 | "lint": "tsc --noEmit && eslint ./src",
16 | "build": "del-cli dist && tsc",
17 | "release": "npm run lint && npm run build && np"
18 | },
19 | "dependencies": {
20 | "is-what": "^5.2.0"
21 | },
22 | "devDependencies": {
23 | "@cycraft/eslint": "^0.4.3",
24 | "@cycraft/tsconfig": "^0.1.2",
25 | "del-cli": "^6.0.0",
26 | "np": "^10.2.0",
27 | "vitest": "^3.0.6"
28 | },
29 | "files": [
30 | "dist"
31 | ],
32 | "keywords": [
33 | "find-and-replace",
34 | "find-replace",
35 | "find-and-replace-if",
36 | "javascript",
37 | "recursively",
38 | "has-prop",
39 | "find-prop",
40 | "replace-prop-value",
41 | "replace-value",
42 | "search-prop",
43 | "search-object-prop",
44 | "replace-if"
45 | ],
46 | "author": "Luca Ban - Mesqueeb (https://cycraft.co)",
47 | "funding": "https://github.com/sponsors/mesqueeb",
48 | "license": "MIT",
49 | "repository": {
50 | "type": "git",
51 | "url": "https://github.com/mesqueeb/find-and-replace-anything.git"
52 | },
53 | "homepage": "https://github.com/mesqueeb/find-and-replace-anything#readme",
54 | "bugs": "https://github.com/mesqueeb/find-and-replace-anything/issues"
55 | }
56 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { isAnyObject, isArray, isNaNValue, isPlainObject } from 'is-what'
2 |
3 | type Config = {
4 | onlyPlainObjects?: boolean
5 | checkArrayValues?: boolean
6 | }
7 |
8 | /**
9 | * Goes through an object recursively and replaces all occurences of the `find` value with `replaceWith`. Also works no non-objects.
10 | *
11 | * @export
12 | * @param target Target can be anything
13 | * @param find val to find
14 | * @param replaceWith val to replace
15 | * @param [config={onlyPlainObjects: false, checkArrayValues: false}]
16 | * @returns the target with replaced values
17 | */
18 | export function findAndReplace(
19 | target: any,
20 | find: any,
21 | replaceWith: any,
22 | config: Config = { onlyPlainObjects: false, checkArrayValues: false },
23 | ): unknown {
24 | const _target = target
25 | // arrays
26 | if (config.checkArrayValues && isArray(_target) && !isAnyObject(_target)) {
27 | return (_target as any[]).map((value) => findAndReplace(value, find, replaceWith, config))
28 | }
29 | // non-objects
30 | if (
31 | (!config.onlyPlainObjects && !isAnyObject(_target)) ||
32 | (config.onlyPlainObjects === true && !isPlainObject(_target))
33 | ) {
34 | if (_target === find || (isNaNValue(_target) && isNaNValue(find))) {
35 | return replaceWith
36 | }
37 | return _target
38 | }
39 | // objects
40 | return Object.entries(target).reduce((carry, [key, val]) => {
41 | carry[key] = findAndReplace(val, find, replaceWith, config)
42 | return carry
43 | }, {})
44 | }
45 |
46 | export function _findAndReplaceIf(
47 | target: any,
48 | checkFn: (foundVal: any, propKey: string | undefined) => any,
49 | propKey: string | undefined,
50 | config: Config = { onlyPlainObjects: true, checkArrayValues: false },
51 | ): unknown {
52 | const _target = checkFn(target, propKey)
53 | if (config.checkArrayValues && isArray(_target) && !isAnyObject(_target)) {
54 | return (_target as any[]).map((value) => _findAndReplaceIf(value, checkFn, undefined, config))
55 | }
56 | if (!isPlainObject(_target)) return _target
57 | return Object.entries(_target).reduce((carry, [key, val]) => {
58 | carry[key] = _findAndReplaceIf(val, checkFn, key, config)
59 | return carry
60 | }, {})
61 | }
62 |
63 | /**
64 | * Goes through an object recursively and replaces all props with what's is returned in the `checkFn`. Also works on non-objects. `checkFn` is triggered on every single level of any value/object.
65 | *
66 | * @export
67 | * @param target Target can be anything
68 | * @param checkFn a function that will receive the `foundVal`
69 | * @param [config={onlyPlainObjects: true, checkArrayValues: false}]
70 | * @returns the target with replaced values
71 | */
72 | export function findAndReplaceIf(
73 | target: any,
74 | checkFn: (foundVal: any, propKey: string | undefined) => any,
75 | config: Config = { onlyPlainObjects: true, checkArrayValues: false },
76 | ): unknown {
77 | return _findAndReplaceIf(target, checkFn, undefined, config)
78 | }
79 |
--------------------------------------------------------------------------------
/test/index.test.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from 'vitest'
2 | import { findAndReplace, findAndReplaceIf } from '../src/index'
3 |
4 | test('findAndReplace in arrays', () => {
5 | const res = findAndReplace({ a: [{ b: 'c' }] }, 'c', 'd', { checkArrayValues: true })
6 | expect(res).toEqual({
7 | a: [{ b: 'd' }],
8 | })
9 | })
10 |
11 | test('findAndReplaceIf in arrays', () => {
12 | const replacer = (foundVal: any) => (foundVal === 'c' ? 'd' : foundVal)
13 | expect(findAndReplaceIf({ a: ['c'] }, replacer, { checkArrayValues: true })).toEqual({
14 | a: ['d'],
15 | })
16 | })
17 |
18 | test('findAndReplaceIf in arrays double nested', () => {
19 | const replacer = (foundVal: any) => (foundVal === 'c' ? 'd' : foundVal)
20 | expect(findAndReplaceIf({ a: [{ b: 'c' }, 'c'] }, replacer, { checkArrayValues: true })).toEqual({
21 | a: [{ b: 'd' }, 'd'],
22 | })
23 | })
24 |
25 | test('findAndReplace nested strings', () => {
26 | expect(findAndReplace({ a: { b: { c: 'a' } } }, 'a', 'b')).toEqual({ a: { b: { c: 'b' } } })
27 | })
28 |
29 | test('findAndReplace strings', () => {
30 | expect(findAndReplace('a', 'a', 'b')).toEqual('b')
31 | expect(findAndReplace('_', 'a', 'b')).toEqual('_')
32 | })
33 |
34 | test('findAndReplace undefined', () => {
35 | expect(findAndReplace({ undefined: undefined }, undefined, 'undefined')).toEqual({
36 | undefined: 'undefined',
37 | })
38 | })
39 | test('findAndReplace NaN', () => {
40 | expect(findAndReplace({ NaN: NaN }, NaN, 'NaN')).toEqual({ NaN: 'NaN' })
41 | })
42 | test('findAndReplace null', () => {
43 | expect(findAndReplace({ null: null }, null, 'null')).toEqual({ null: 'null' })
44 | })
45 |
46 | test('findAndReplace does not modify objects', () => {
47 | let res, ori
48 | ori = { a: { b: { c: 'a' }, d: 1 } }
49 | res = findAndReplace(ori, 'a', 'b')
50 | expect(res).toEqual({ a: { b: { c: 'b' }, d: 1 } })
51 | expect(ori).toEqual({ a: { b: { c: 'a' }, d: 1 } })
52 | res.a.b = 1
53 | expect(res).toEqual({ a: { b: 1, d: 1 } })
54 | expect(ori).toEqual({ a: { b: { c: 'a' }, d: 1 } })
55 | res.a.d = 2
56 | expect(res).toEqual({ a: { b: 1, d: 2 } })
57 | expect(ori).toEqual({ a: { b: { c: 'a' }, d: 1 } })
58 | ori.a.d = 3
59 | expect(res).toEqual({ a: { b: 1, d: 2 } })
60 | expect(ori).toEqual({ a: { b: { c: 'a' }, d: 3 } })
61 | })
62 |
63 | test('findAndReplace does not work with objects', () => {
64 | let res, ori
65 | ori = { a: { b: { c: 'a' } } }
66 | res = findAndReplace(ori, { c: 'a' }, { c: 'b' })
67 | expect(res).toEqual({ a: { b: { c: 'a' } } })
68 | expect(ori).toEqual({ a: { b: { c: 'a' } } })
69 | })
70 |
71 | test('findAndReplaceIf', () => {
72 | let res
73 | function checkFn(foundVal: any) {
74 | if (foundVal === 'a') return 'b'
75 | return foundVal
76 | }
77 | res = findAndReplaceIf({ a: { b: { c: 'a' } } }, checkFn)
78 | expect(res).toEqual({ a: { b: { c: 'b' } } })
79 | res = findAndReplaceIf('_', checkFn)
80 | expect(res).toEqual('_')
81 | res = findAndReplaceIf('a', checkFn)
82 | expect(res).toEqual('b')
83 | })
84 |
85 | test('should work on classes', () => {
86 | let res, target
87 | class MyClass {
88 | prop = 0
89 | constructor() {
90 | this.prop = 1
91 | }
92 | }
93 | const myClass = new MyClass()
94 | target = {
95 | prop: 1,
96 | class: myClass,
97 | }
98 | res = findAndReplace(target, 1, 2)
99 | expect(res.prop).toEqual(2)
100 | expect(res.class.prop).toEqual(2)
101 | })
102 |
103 | test('should prevent classes', () => {
104 | let res, target
105 | class MyClass {
106 | prop = 0
107 | constructor() {
108 | this.prop = 1
109 | }
110 | }
111 | const myClass = new MyClass()
112 | target = {
113 | prop: 1,
114 | class: myClass,
115 | }
116 | res = findAndReplace(target, 1, 2, { onlyPlainObjects: true })
117 | expect(res.prop).toEqual(2)
118 | expect(res.class.prop).toEqual(1)
119 | })
120 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@cycraft/tsconfig",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "outDir": "dist"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------