pathtrace 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-today Peter Placzek
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.
package/README.md ADDED
@@ -0,0 +1,325 @@
1
+ # pathtrace 🔍
2
+
3
+ [![main](https://github.com/tada5hi/pathtrace/actions/workflows/main.yml/badge.svg)](https://github.com/tada5hi/pathtrace/actions/workflows/main.yml)
4
+ [![CodeQL](https://github.com/tada5hi/pathtrace/actions/workflows/codeql.yml/badge.svg)](https://github.com/tada5hi/pathtrace/actions/workflows/codeql.yml)
5
+ [![Known Vulnerabilities](https://snyk.io/test/github/tada5hi/pathtrace/badge.svg)](https://snyk.io/test/github/tada5hi/pathtrace)
6
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
7
+
8
+ **Pathtrace** is a library for managing nested objects and arrays.
9
+ It offers straightforward methods for
10
+ retrieving ([getPathValue](#getPathValue)) and
11
+ setting ([setPathValue](#setPathValue)) values at any path.
12
+ Additionally, [getPathInfo](#getPathInfo) provides detailed path information,
13
+ making it ideal for handling complex data structures efficiently.
14
+
15
+ **Table of Contents**
16
+
17
+ - [Installation](#installation)
18
+ - [Usage](#usage)
19
+ - [getPathValue](#getpathvalue)
20
+ - [setPathValue](#setpathvalue)
21
+ - [getPathInfo](#getpathinfo)
22
+ - [License](#license)
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install pathtrace --save
28
+ ```
29
+
30
+ ## Usage
31
+ The following examples demonstrate how to use the library.
32
+
33
+ ### getPathValue
34
+
35
+ This method retrieves the value of a property at a given `path`
36
+ inside an `object`.
37
+
38
+ ```ts
39
+ const obj = {
40
+ user: {
41
+ name: 'Alice',
42
+ roles: ['admin', 'editor'],
43
+ contact: {
44
+ email: 'alice@example.com',
45
+ phone: '123-456-7890',
46
+ },
47
+ },
48
+ settings: [
49
+ { theme: 'dark' },
50
+ { notifications: true },
51
+ [{ privacy: 'high' }]
52
+ ]
53
+ };
54
+ ```
55
+
56
+ **Example 1: Retrieving a simple property value**
57
+ ```ts
58
+ import { getPathValue } from 'pathtrace';
59
+
60
+ var value = getPathValue(obj, 'user.name');
61
+ console.log(value); // 'Alice'
62
+ ```
63
+
64
+ **Example 2: Retrieving a nested property value**
65
+ ```ts
66
+ import { getPathValue } from 'pathtrace';
67
+
68
+ var value = getPathValue(obj, 'user.contact.email');
69
+ console.log(value); // 'alice@example.com'
70
+ ```
71
+
72
+ **Example 3: Retrieving an array element by index**
73
+ ```ts
74
+ import { getPathValue } from 'pathtrace';
75
+
76
+ var value = getPathValue(obj, 'user.roles[1]');
77
+ console.log(value); // 'editor'
78
+ ```
79
+
80
+ **Example 4: Retrieving a nested property within an array**
81
+ ```ts
82
+ import { getPathValue } from 'pathtrace';
83
+
84
+ var value = getPathValue(obj, 'settings[1].notifications');
85
+ console.log(value); // true
86
+ ```
87
+
88
+ **Example 5: Retrieving a value from a multi-dimensional array**
89
+ ```ts
90
+ import { getPathValue } from 'pathtrace';
91
+
92
+ var value = getPathValue(obj, 'settings[2][0].privacy');
93
+ console.log(value); // 'high'
94
+ ```
95
+
96
+ **Example 6: Handling undefined objects and properties**
97
+ ```ts
98
+ import { getPathValue } from 'pathtrace';
99
+
100
+ var value = getPathValue(undefined, 'user.name');
101
+ console.log(value); // undefined
102
+
103
+ var value = getPathValue(obj, 'user.address');
104
+ console.log(value); // undefined
105
+
106
+ var value = getPathValue('hello', 'length');
107
+ console.log(value); // 5
108
+ ```
109
+
110
+ ### setPathValue
111
+
112
+ This method sets the `value` of a property at a given `path`
113
+ inside an `object` and returns the object in which the property has been set.
114
+
115
+ ```ts
116
+ var obj = {
117
+ user: {
118
+ name: 'Alice',
119
+ roles: ['admin', 'editor'],
120
+ contact: {
121
+ email: 'alice@example.com',
122
+ phone: '123-456-7890',
123
+ },
124
+ },
125
+ settings: [
126
+ { theme: 'dark' },
127
+ { notifications: true },
128
+ [{ privacy: 'high' }]
129
+ ]
130
+ };
131
+ ```
132
+
133
+ **Example 1: Setting a simple property value**
134
+ ```ts
135
+ import { setPathValue } from 'pathtrace';
136
+
137
+ setPathValue(obj, 'user.name', 'Bob');
138
+ console.log(obj.user.name); // 'Bob'
139
+ ```
140
+
141
+ **Example 2: Setting a nested property value**
142
+ ```ts
143
+ import { setPathValue } from 'pathtrace';
144
+
145
+ setPathValue(obj, 'user.contact.email', 'bob@example.com');
146
+ console.log(obj.user.contact.email); // 'bob@example.com'
147
+ ```
148
+
149
+ **Example 3: Setting a nested array value**
150
+ ```ts
151
+ import { setPathValue } from 'pathtrace';
152
+
153
+ setPathValue(obj, 'user.roles[1]', 'viewer');
154
+ console.log(obj.user.roles[1]); // 'viewer'
155
+ ```
156
+
157
+ **Example 4: Setting a value in an array**
158
+ ```ts
159
+ import { setPathValue } from 'pathtrace';
160
+
161
+ setPathValue(obj, 'settings[2][0].privacy', 'low');
162
+ console.log(obj.settings[2][0].privacy); // 'low'
163
+ ```
164
+
165
+ **Example 5: Adding a new property to an object**
166
+ ```ts
167
+ import { setPathValue } from 'pathtrace';
168
+
169
+ setPathValue(obj, 'user.contact.address', '123 Main St');
170
+ console.log(obj.user.contact.address); // '123 Main St'
171
+ ```
172
+
173
+ **Example 6: Setting a value in an object within an array**
174
+ ```ts
175
+ import { setPathValue } from 'pathtrace';
176
+
177
+ setPathValue(obj, 'settings[1].notifications', false);
178
+ console.log(obj.settings[1].notifications); // false
179
+ ```
180
+
181
+ **Example 7: Creating a new array and setting values**
182
+ ```ts
183
+ import { setPathValue } from 'pathtrace';
184
+
185
+ setPathValue(obj, 'user.history[0]', 'logged in');
186
+ setPathValue(obj, 'user.history[2]', 'logged out');
187
+ console.log(obj.user.history[0]); // 'logged in'
188
+ console.log(obj.user.history[1]); // undefined
189
+ console.log(obj.user.history[2]); // 'logged out'
190
+ ```
191
+
192
+ **Example 8: Setting a value in a multi-dimensional array**
193
+ ```ts
194
+ import { setPathValue } from 'pathtrace';
195
+
196
+ setPathValue(obj, 'settings[2][1]', { secure: true });
197
+ console.log(obj.settings[2][1].secure); // true
198
+ ```
199
+
200
+ **Example 9: Setting a value in an object inside an array**
201
+ ```ts
202
+ import { setPathValue } from 'pathtrace';
203
+
204
+ setPathValue(obj, 'settings[2][0].description', 'private settings');
205
+ console.log(obj.settings[2][0].description); // 'private settings'
206
+ ```
207
+
208
+ **Example 10: Returning the modified object**
209
+ ```ts
210
+ import { setPathValue } from 'pathtrace';
211
+
212
+ var modifiedObj = setPathValue(obj, 'user.contact.phone', '987-654-3210');
213
+ console.log(modifiedObj === obj); // true
214
+ ```
215
+
216
+
217
+ ### getPathInfo
218
+
219
+ This method returns an object with information indicating the value
220
+ of the `parent` of that path, the `name` of the property being retrieved,
221
+ and its `value`.
222
+
223
+ ```ts
224
+ const obj = {
225
+ user: {
226
+ name: 'Alice',
227
+ roles: ['admin', 'editor'],
228
+ contact: {
229
+ email: 'alice@example.com',
230
+ phone: '123-456-7890',
231
+ },
232
+ },
233
+ 'user.roles': {
234
+ '[1]': 'editor',
235
+ },
236
+ };
237
+ ```
238
+
239
+ **Example 1: Handling a nested property**
240
+
241
+ ```ts
242
+ import { getPathInfo } from 'pathtrace';
243
+
244
+ const info = getPathInfo(obj, 'user.contact.email');
245
+
246
+ if (info.parent) {
247
+ console.log(info.parent.name); // 'contact'
248
+ console.log(info.parent.value);
249
+ // { email: 'alice@example.com', phone: '123-456-7890' }
250
+ console.log(info.parent.exists); // true
251
+ }
252
+ console.log(info.value); // 'alice@example.com'
253
+ console.log(info.exists); // true
254
+ console.log(info.name); // 'email'
255
+
256
+ ```
257
+ **Example 2: Handling an array index**
258
+
259
+ ```ts
260
+ import { getPathInfo } from 'pathtrace';
261
+
262
+ const info = getPathInfo(obj, 'user.roles[1]');
263
+
264
+ if (info.parent) {
265
+ console.log(info.parent.name); // 'roles'
266
+ console.log(info.parent.value); // ['admin', 'editor']
267
+ console.log(info.parent.exists); // true
268
+ }
269
+ console.log(info.value); // 'editor'
270
+ console.log(info.name); // '1'
271
+ console.log(info.exists); // true
272
+ ```
273
+
274
+ **Example 3: Handling a non-existent property**
275
+ ```ts
276
+ import { getPathInfo } from 'pathtrace';
277
+
278
+ const info = getPathInfo(obj, 'user.contact.address');
279
+
280
+ if (info.parent) {
281
+ console.log(info.parent.name); // 'contact'
282
+ console.log(info.parent.value);
283
+ // { email: 'alice@example.com', phone: '123-456-7890' }
284
+ console.log(info.parent.exists); // true
285
+ }
286
+ console.log(info.value); // undefined
287
+ console.log(info.name); // 'address'
288
+ console.log(info.exists); // false
289
+ ```
290
+
291
+ **Example 4: Handling an out-of-bounds array index**
292
+ ```ts
293
+ import { getPathInfo } from 'pathtrace';
294
+
295
+ const info = getPathInfo(obj, 'user.roles[5]');
296
+
297
+ if (info.parent) {
298
+ console.log(info.parent.name); // 'roles'
299
+ console.log(info.parent.value); // ['admin', 'editor']
300
+ console.log(info.parent.exists); // true
301
+ }
302
+ console.log(info.value); // undefined
303
+ console.log(info.name); // '5'
304
+ console.log(info.exists); // false
305
+ ```
306
+
307
+ **Example 5: Handling backslash-escaping for . and []**
308
+ ```ts
309
+ import { getPathInfo } from 'pathtrace';
310
+
311
+ const info = getPathInfo(obj, 'user\\.roles.\\[1\\]');
312
+
313
+ if (info.parent) {
314
+ console.log(info.parent.name); // '[1]'
315
+ console.log(info.parent.value); // 'editor'
316
+ console.log(info.exists); // true
317
+ }
318
+ console.log(info.value); // 'editor'
319
+ console.log(info.name); // '1'
320
+ console.log(info.exists); // true
321
+ ```
322
+
323
+ ## License
324
+
325
+ Made with 💚
@@ -0,0 +1,2 @@
1
+ import { PathInfo } from './path-info';
2
+ export declare function getPathInfo(data: Record<string, any>, path?: string): PathInfo;
@@ -0,0 +1 @@
1
+ export declare function getPathValue(data: unknown, path: string | string[]): unknown;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214
3
+ * @param parts
4
+ */
5
+ export declare function arrayToPath(parts: readonly string[]): string;
@@ -0,0 +1,2 @@
1
+ export * from './array-to-path';
2
+ export * from './path-to-array';
@@ -0,0 +1,10 @@
1
+ export declare const BRACKET_NUMBER_REGEX: RegExp;
2
+ /**
3
+ * Convert string to property path array.
4
+ *
5
+ * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts
6
+ * @see https://github.com/chaijs/pathval
7
+ *
8
+ * @param segment
9
+ */
10
+ export declare function pathToArray(segment: string): string[];
package/dist/index.cjs ADDED
@@ -0,0 +1,193 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ * Copyright (c) 2024.
5
+ * Author Peter Placzek (tada5hi)
6
+ * For the full copyright and license information,
7
+ * view the LICENSE file that was distributed with this source code.
8
+ */ /**
9
+ * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214
10
+ * @param parts
11
+ */ function arrayToPath(parts) {
12
+ return parts.reduce((prev, segment)=>{
13
+ let part = '';
14
+ segment = segment === '\\*' ? '*' : segment;
15
+ segment = segment.replace(/^\[(\d+)]$/g, '\\[$1]');
16
+ segment = segment.replace(/\./g, '\\.');
17
+ if (/^\d+$/.test(segment)) {
18
+ // Index access
19
+ part = `[${segment}]`;
20
+ } else if (prev) {
21
+ // Object key access
22
+ part = `.${segment}`;
23
+ } else {
24
+ // Top level key
25
+ part = segment;
26
+ }
27
+ return prev + part;
28
+ }, '');
29
+ }
30
+
31
+ /*
32
+ * Copyright (c) 2024-2024.
33
+ * Author Peter Placzek (tada5hi)
34
+ * For the full copyright and license information,
35
+ * view the LICENSE file that was distributed with this source code.
36
+ */ const BRACKET_NUMBER_REGEX = RegExp("(?<!\\\\)\\[(\\d+)]$");
37
+ /**
38
+ * Convert string to property path array.
39
+ *
40
+ * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts
41
+ * @see https://github.com/chaijs/pathval
42
+ *
43
+ * @param segment
44
+ */ function pathToArray(segment) {
45
+ const str = segment.replace(/([^\\])\[/g, '$1.[');
46
+ const parts = str.match(/(\\\.|[^.]+?)+/g);
47
+ if (!parts) {
48
+ return [];
49
+ }
50
+ const result = [];
51
+ for(let i = 0; i < parts.length; i++){
52
+ if (parts[i] === 'constructor' || parts[i] === '__proto__' || parts[i] === 'prototype') {
53
+ continue;
54
+ }
55
+ const regex = BRACKET_NUMBER_REGEX.exec(parts[i]);
56
+ if (regex) {
57
+ result.push(regex[1]);
58
+ } else {
59
+ result.push(parts[i].replace(/\\([.[\]])/g, '$1'));
60
+ }
61
+ }
62
+ return result;
63
+ }
64
+
65
+ function getPathValue(data, path) {
66
+ const parts = Array.isArray(path) ? path : pathToArray(path);
67
+ let res;
68
+ let temp = data;
69
+ let index = 0;
70
+ while(index < parts.length){
71
+ if (temp === null || typeof temp === 'undefined') {
72
+ break;
73
+ }
74
+ if (parts[index] in Object(temp)) {
75
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
76
+ // @ts-expect-error
77
+ temp = temp[parts[index]];
78
+ } else {
79
+ break;
80
+ }
81
+ if (index === parts.length - 1) {
82
+ res = temp;
83
+ }
84
+ index++;
85
+ }
86
+ return res;
87
+ }
88
+
89
+ class PathInfo {
90
+ get value() {
91
+ if (typeof this._value !== 'undefined') {
92
+ return this._value;
93
+ }
94
+ if (this.pathParts.length > 0) {
95
+ this._value = getPathValue(this.data, this.pathParts);
96
+ } else {
97
+ this._value = this.data;
98
+ }
99
+ return this._value;
100
+ }
101
+ get name() {
102
+ if (this.pathParts.length > 0) {
103
+ return this.pathParts[this.pathParts.length - 1];
104
+ }
105
+ return null;
106
+ }
107
+ get parent() {
108
+ if (typeof this._parent !== 'undefined') {
109
+ return this._parent;
110
+ }
111
+ if (this.pathParts.length === 0) {
112
+ this._parent = null;
113
+ return this._parent;
114
+ }
115
+ if (this.pathParts.length > 1) {
116
+ const parentPathParts = this.pathParts.slice(0, this.pathParts.length - 1);
117
+ this._parent = new PathInfo(this.data, arrayToPath(parentPathParts));
118
+ } else {
119
+ this._parent = new PathInfo(this.data);
120
+ }
121
+ return this._parent;
122
+ }
123
+ get exists() {
124
+ if (typeof this._exists !== 'undefined') {
125
+ return this._exists;
126
+ }
127
+ if (!this.name || !this.parent) {
128
+ this._exists = true;
129
+ return this._exists;
130
+ }
131
+ if (this.parent.value !== null && typeof this.parent.value !== 'undefined') {
132
+ this._exists = this.name in Object(this.parent.value);
133
+ } else {
134
+ this._exists = false;
135
+ }
136
+ return this._exists;
137
+ }
138
+ constructor(data, path){
139
+ this.data = data;
140
+ this.path = path;
141
+ this.pathParts = this.path ? pathToArray(this.path) : [];
142
+ }
143
+ }
144
+
145
+ function getPathInfo(data, path) {
146
+ return new PathInfo(data, path);
147
+ }
148
+
149
+ /*
150
+ * Copyright (c) 2024.
151
+ * Author Peter Placzek (tada5hi)
152
+ * For the full copyright and license information,
153
+ * view the LICENSE file that was distributed with this source code.
154
+ */ function isObject(input) {
155
+ return !!input && typeof input === 'object' && !Array.isArray(input);
156
+ }
157
+
158
+ const NUMBER_REGEX = /^\d+$/;
159
+ function setPathValue(data, path, value) {
160
+ const parts = Array.isArray(path) ? path : pathToArray(path);
161
+ let temp = data;
162
+ let index = 0;
163
+ while(index < parts.length){
164
+ /* istanbul ignore next */ if (!Array.isArray(temp) && !isObject(temp)) {
165
+ break;
166
+ }
167
+ const key = parts[index];
168
+ // [foo, '0']
169
+ if (typeof temp[key] === 'undefined') {
170
+ const match = NUMBER_REGEX.test(key);
171
+ if (match) {
172
+ temp[key] = [];
173
+ } else {
174
+ temp[key] = {};
175
+ }
176
+ }
177
+ if (index === parts.length - 1) {
178
+ temp[key] = value;
179
+ break;
180
+ }
181
+ index++;
182
+ temp = temp[key];
183
+ }
184
+ return data;
185
+ }
186
+
187
+ exports.BRACKET_NUMBER_REGEX = BRACKET_NUMBER_REGEX;
188
+ exports.arrayToPath = arrayToPath;
189
+ exports.getPathInfo = getPathInfo;
190
+ exports.getPathValue = getPathValue;
191
+ exports.pathToArray = pathToArray;
192
+ exports.setPathValue = setPathValue;
193
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/helpers/array-to-path.ts","../src/helpers/path-to-array.ts","../src/get-path-value.ts","../src/path-info.ts","../src/get-path-info.ts","../src/utils/is-object.ts","../src/set-path-value.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214\n * @param parts\n */\nexport function arrayToPath(parts: readonly string[]) : string {\n return parts.reduce((prev, segment) => {\n let part = '';\n segment = segment === '\\\\*' ? '*' : segment;\n\n segment = segment.replace(/^\\[(\\d+)]$/g, '\\\\[$1]');\n segment = segment.replace(/\\./g, '\\\\.');\n\n if (/^\\d+$/.test(segment)) {\n // Index access\n part = `[${segment}]`;\n } else if (prev) {\n // Object key access\n part = `.${segment}`;\n } else {\n // Top level key\n part = segment;\n }\n\n return prev + part;\n }, '');\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport const BRACKET_NUMBER_REGEX = /(?<!\\\\)\\[(\\d+)]$/;\n\n/**\n * Convert string to property path array.\n *\n * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts\n * @see https://github.com/chaijs/pathval\n *\n * @param segment\n */\nexport function pathToArray(segment: string) : string[] {\n const str = segment.replace(/([^\\\\])\\[/g, '$1.[');\n const parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n if (!parts) {\n return [];\n }\n\n const result : string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n if (\n parts[i] === 'constructor' ||\n parts[i] === '__proto__' ||\n parts[i] === 'prototype'\n ) {\n continue;\n }\n\n const regex = BRACKET_NUMBER_REGEX.exec(parts[i]);\n if (regex) {\n result.push(regex[1]);\n } else {\n result.push(parts[i].replace(/\\\\([.[\\]])/g, '$1'));\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from './helpers';\n\nexport function getPathValue(\n data: unknown,\n path: string | string[],\n): unknown {\n const parts = Array.isArray(path) ? path : pathToArray(path);\n\n let res : unknown | undefined;\n let temp = data;\n let index = 0;\n while (index < parts.length) {\n if (temp === null || typeof temp === 'undefined') {\n break;\n }\n\n if (parts[index] in Object(temp)) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n temp = temp[parts[index]];\n } else {\n break;\n }\n\n if (index === parts.length - 1) {\n res = temp;\n }\n\n index++;\n }\n\n return res;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { getPathValue } from './get-path-value';\nimport { arrayToPath, pathToArray } from './helpers';\n\nexport class PathInfo {\n protected data: unknown;\n\n protected path : string | undefined;\n\n protected pathParts: string[];\n\n protected _value: unknown;\n\n protected _parent: PathInfo | null | undefined;\n\n protected _exists: boolean | undefined;\n\n constructor(data: unknown, path?: string) {\n this.data = data;\n this.path = path;\n this.pathParts = this.path ?\n pathToArray(this.path) :\n [];\n }\n\n get value() {\n if (typeof this._value !== 'undefined') {\n return this._value;\n }\n\n if (this.pathParts.length > 0) {\n this._value = getPathValue(this.data, this.pathParts);\n } else {\n this._value = this.data;\n }\n\n return this._value;\n }\n\n get name() : string | null {\n if (this.pathParts.length > 0) {\n return this.pathParts[this.pathParts.length - 1];\n }\n\n return null;\n }\n\n get parent() : PathInfo | null {\n if (typeof this._parent !== 'undefined') {\n return this._parent;\n }\n\n if (this.pathParts.length === 0) {\n this._parent = null;\n return this._parent;\n }\n\n if (this.pathParts.length > 1) {\n const parentPathParts = this.pathParts.slice(0, this.pathParts.length - 1);\n this._parent = new PathInfo(\n this.data,\n arrayToPath(parentPathParts),\n );\n } else {\n this._parent = new PathInfo(this.data);\n }\n\n return this._parent;\n }\n\n get exists() : boolean {\n if (typeof this._exists !== 'undefined') {\n return this._exists;\n }\n\n if (!this.name || !this.parent) {\n this._exists = true;\n return this._exists;\n }\n\n if (\n this.parent.value !== null &&\n typeof this.parent.value !== 'undefined'\n ) {\n this._exists = this.name in Object(this.parent.value);\n } else {\n this._exists = false;\n }\n\n return this._exists;\n }\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { PathInfo } from './path-info';\n\nexport function getPathInfo(\n data: Record<string, any>,\n path?: string,\n) : PathInfo {\n return new PathInfo(data, path);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isObject(input: unknown) : input is Record<string, any> {\n return !!input &&\n typeof input === 'object' &&\n !Array.isArray(input);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from './helpers';\nimport { isObject } from './utils';\n\nconst NUMBER_REGEX = /^\\d+$/;\n\nexport function setPathValue(\n data: Record<string, any> | Record<string, any>[],\n path: string | string[],\n value: unknown,\n) {\n const parts = Array.isArray(path) ? path : pathToArray(path);\n\n let temp = data;\n let index = 0;\n while (index < parts.length) {\n /* istanbul ignore next */\n if (!Array.isArray(temp) && !isObject(temp)) {\n break;\n }\n\n const key = parts[index] as keyof typeof temp;\n\n // [foo, '0']\n if (typeof temp[key] === 'undefined') {\n const match = NUMBER_REGEX.test(key);\n if (match) {\n (temp as Record<string, any>)[key] = [];\n } else {\n temp[key] = {};\n }\n }\n\n if (index === parts.length - 1) {\n temp[key] = value;\n break;\n }\n\n index++;\n temp = temp[key];\n }\n\n return data;\n}\n"],"names":["arrayToPath","parts","reduce","prev","segment","part","replace","test","BRACKET_NUMBER_REGEX","pathToArray","str","match","result","i","length","regex","exec","push","getPathValue","data","path","Array","isArray","res","temp","index","Object","PathInfo","value","_value","pathParts","name","parent","_parent","parentPathParts","slice","exists","_exists","constructor","getPathInfo","isObject","input","NUMBER_REGEX","setPathValue","key"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './helpers';
2
+ export * from './get-path-value';
3
+ export * from './get-path-info';
4
+ export * from './set-path-value';
package/dist/index.mjs ADDED
@@ -0,0 +1,186 @@
1
+ /*
2
+ * Copyright (c) 2024.
3
+ * Author Peter Placzek (tada5hi)
4
+ * For the full copyright and license information,
5
+ * view the LICENSE file that was distributed with this source code.
6
+ */ /**
7
+ * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214
8
+ * @param parts
9
+ */ function arrayToPath(parts) {
10
+ return parts.reduce((prev, segment)=>{
11
+ let part = '';
12
+ segment = segment === '\\*' ? '*' : segment;
13
+ segment = segment.replace(/^\[(\d+)]$/g, '\\[$1]');
14
+ segment = segment.replace(/\./g, '\\.');
15
+ if (/^\d+$/.test(segment)) {
16
+ // Index access
17
+ part = `[${segment}]`;
18
+ } else if (prev) {
19
+ // Object key access
20
+ part = `.${segment}`;
21
+ } else {
22
+ // Top level key
23
+ part = segment;
24
+ }
25
+ return prev + part;
26
+ }, '');
27
+ }
28
+
29
+ /*
30
+ * Copyright (c) 2024-2024.
31
+ * Author Peter Placzek (tada5hi)
32
+ * For the full copyright and license information,
33
+ * view the LICENSE file that was distributed with this source code.
34
+ */ const BRACKET_NUMBER_REGEX = RegExp("(?<!\\\\)\\[(\\d+)]$");
35
+ /**
36
+ * Convert string to property path array.
37
+ *
38
+ * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts
39
+ * @see https://github.com/chaijs/pathval
40
+ *
41
+ * @param segment
42
+ */ function pathToArray(segment) {
43
+ const str = segment.replace(/([^\\])\[/g, '$1.[');
44
+ const parts = str.match(/(\\\.|[^.]+?)+/g);
45
+ if (!parts) {
46
+ return [];
47
+ }
48
+ const result = [];
49
+ for(let i = 0; i < parts.length; i++){
50
+ if (parts[i] === 'constructor' || parts[i] === '__proto__' || parts[i] === 'prototype') {
51
+ continue;
52
+ }
53
+ const regex = BRACKET_NUMBER_REGEX.exec(parts[i]);
54
+ if (regex) {
55
+ result.push(regex[1]);
56
+ } else {
57
+ result.push(parts[i].replace(/\\([.[\]])/g, '$1'));
58
+ }
59
+ }
60
+ return result;
61
+ }
62
+
63
+ function getPathValue(data, path) {
64
+ const parts = Array.isArray(path) ? path : pathToArray(path);
65
+ let res;
66
+ let temp = data;
67
+ let index = 0;
68
+ while(index < parts.length){
69
+ if (temp === null || typeof temp === 'undefined') {
70
+ break;
71
+ }
72
+ if (parts[index] in Object(temp)) {
73
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
74
+ // @ts-expect-error
75
+ temp = temp[parts[index]];
76
+ } else {
77
+ break;
78
+ }
79
+ if (index === parts.length - 1) {
80
+ res = temp;
81
+ }
82
+ index++;
83
+ }
84
+ return res;
85
+ }
86
+
87
+ class PathInfo {
88
+ get value() {
89
+ if (typeof this._value !== 'undefined') {
90
+ return this._value;
91
+ }
92
+ if (this.pathParts.length > 0) {
93
+ this._value = getPathValue(this.data, this.pathParts);
94
+ } else {
95
+ this._value = this.data;
96
+ }
97
+ return this._value;
98
+ }
99
+ get name() {
100
+ if (this.pathParts.length > 0) {
101
+ return this.pathParts[this.pathParts.length - 1];
102
+ }
103
+ return null;
104
+ }
105
+ get parent() {
106
+ if (typeof this._parent !== 'undefined') {
107
+ return this._parent;
108
+ }
109
+ if (this.pathParts.length === 0) {
110
+ this._parent = null;
111
+ return this._parent;
112
+ }
113
+ if (this.pathParts.length > 1) {
114
+ const parentPathParts = this.pathParts.slice(0, this.pathParts.length - 1);
115
+ this._parent = new PathInfo(this.data, arrayToPath(parentPathParts));
116
+ } else {
117
+ this._parent = new PathInfo(this.data);
118
+ }
119
+ return this._parent;
120
+ }
121
+ get exists() {
122
+ if (typeof this._exists !== 'undefined') {
123
+ return this._exists;
124
+ }
125
+ if (!this.name || !this.parent) {
126
+ this._exists = true;
127
+ return this._exists;
128
+ }
129
+ if (this.parent.value !== null && typeof this.parent.value !== 'undefined') {
130
+ this._exists = this.name in Object(this.parent.value);
131
+ } else {
132
+ this._exists = false;
133
+ }
134
+ return this._exists;
135
+ }
136
+ constructor(data, path){
137
+ this.data = data;
138
+ this.path = path;
139
+ this.pathParts = this.path ? pathToArray(this.path) : [];
140
+ }
141
+ }
142
+
143
+ function getPathInfo(data, path) {
144
+ return new PathInfo(data, path);
145
+ }
146
+
147
+ /*
148
+ * Copyright (c) 2024.
149
+ * Author Peter Placzek (tada5hi)
150
+ * For the full copyright and license information,
151
+ * view the LICENSE file that was distributed with this source code.
152
+ */ function isObject(input) {
153
+ return !!input && typeof input === 'object' && !Array.isArray(input);
154
+ }
155
+
156
+ const NUMBER_REGEX = /^\d+$/;
157
+ function setPathValue(data, path, value) {
158
+ const parts = Array.isArray(path) ? path : pathToArray(path);
159
+ let temp = data;
160
+ let index = 0;
161
+ while(index < parts.length){
162
+ /* istanbul ignore next */ if (!Array.isArray(temp) && !isObject(temp)) {
163
+ break;
164
+ }
165
+ const key = parts[index];
166
+ // [foo, '0']
167
+ if (typeof temp[key] === 'undefined') {
168
+ const match = NUMBER_REGEX.test(key);
169
+ if (match) {
170
+ temp[key] = [];
171
+ } else {
172
+ temp[key] = {};
173
+ }
174
+ }
175
+ if (index === parts.length - 1) {
176
+ temp[key] = value;
177
+ break;
178
+ }
179
+ index++;
180
+ temp = temp[key];
181
+ }
182
+ return data;
183
+ }
184
+
185
+ export { BRACKET_NUMBER_REGEX, arrayToPath, getPathInfo, getPathValue, pathToArray, setPathValue };
186
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/helpers/array-to-path.ts","../src/helpers/path-to-array.ts","../src/get-path-value.ts","../src/path-info.ts","../src/get-path-info.ts","../src/utils/is-object.ts","../src/set-path-value.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214\n * @param parts\n */\nexport function arrayToPath(parts: readonly string[]) : string {\n return parts.reduce((prev, segment) => {\n let part = '';\n segment = segment === '\\\\*' ? '*' : segment;\n\n segment = segment.replace(/^\\[(\\d+)]$/g, '\\\\[$1]');\n segment = segment.replace(/\\./g, '\\\\.');\n\n if (/^\\d+$/.test(segment)) {\n // Index access\n part = `[${segment}]`;\n } else if (prev) {\n // Object key access\n part = `.${segment}`;\n } else {\n // Top level key\n part = segment;\n }\n\n return prev + part;\n }, '');\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport const BRACKET_NUMBER_REGEX = /(?<!\\\\)\\[(\\d+)]$/;\n\n/**\n * Convert string to property path array.\n *\n * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts\n * @see https://github.com/chaijs/pathval\n *\n * @param segment\n */\nexport function pathToArray(segment: string) : string[] {\n const str = segment.replace(/([^\\\\])\\[/g, '$1.[');\n const parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n if (!parts) {\n return [];\n }\n\n const result : string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n if (\n parts[i] === 'constructor' ||\n parts[i] === '__proto__' ||\n parts[i] === 'prototype'\n ) {\n continue;\n }\n\n const regex = BRACKET_NUMBER_REGEX.exec(parts[i]);\n if (regex) {\n result.push(regex[1]);\n } else {\n result.push(parts[i].replace(/\\\\([.[\\]])/g, '$1'));\n }\n }\n\n return result;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from './helpers';\n\nexport function getPathValue(\n data: unknown,\n path: string | string[],\n): unknown {\n const parts = Array.isArray(path) ? path : pathToArray(path);\n\n let res : unknown | undefined;\n let temp = data;\n let index = 0;\n while (index < parts.length) {\n if (temp === null || typeof temp === 'undefined') {\n break;\n }\n\n if (parts[index] in Object(temp)) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n temp = temp[parts[index]];\n } else {\n break;\n }\n\n if (index === parts.length - 1) {\n res = temp;\n }\n\n index++;\n }\n\n return res;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { getPathValue } from './get-path-value';\nimport { arrayToPath, pathToArray } from './helpers';\n\nexport class PathInfo {\n protected data: unknown;\n\n protected path : string | undefined;\n\n protected pathParts: string[];\n\n protected _value: unknown;\n\n protected _parent: PathInfo | null | undefined;\n\n protected _exists: boolean | undefined;\n\n constructor(data: unknown, path?: string) {\n this.data = data;\n this.path = path;\n this.pathParts = this.path ?\n pathToArray(this.path) :\n [];\n }\n\n get value() {\n if (typeof this._value !== 'undefined') {\n return this._value;\n }\n\n if (this.pathParts.length > 0) {\n this._value = getPathValue(this.data, this.pathParts);\n } else {\n this._value = this.data;\n }\n\n return this._value;\n }\n\n get name() : string | null {\n if (this.pathParts.length > 0) {\n return this.pathParts[this.pathParts.length - 1];\n }\n\n return null;\n }\n\n get parent() : PathInfo | null {\n if (typeof this._parent !== 'undefined') {\n return this._parent;\n }\n\n if (this.pathParts.length === 0) {\n this._parent = null;\n return this._parent;\n }\n\n if (this.pathParts.length > 1) {\n const parentPathParts = this.pathParts.slice(0, this.pathParts.length - 1);\n this._parent = new PathInfo(\n this.data,\n arrayToPath(parentPathParts),\n );\n } else {\n this._parent = new PathInfo(this.data);\n }\n\n return this._parent;\n }\n\n get exists() : boolean {\n if (typeof this._exists !== 'undefined') {\n return this._exists;\n }\n\n if (!this.name || !this.parent) {\n this._exists = true;\n return this._exists;\n }\n\n if (\n this.parent.value !== null &&\n typeof this.parent.value !== 'undefined'\n ) {\n this._exists = this.name in Object(this.parent.value);\n } else {\n this._exists = false;\n }\n\n return this._exists;\n }\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { PathInfo } from './path-info';\n\nexport function getPathInfo(\n data: Record<string, any>,\n path?: string,\n) : PathInfo {\n return new PathInfo(data, path);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isObject(input: unknown) : input is Record<string, any> {\n return !!input &&\n typeof input === 'object' &&\n !Array.isArray(input);\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from './helpers';\nimport { isObject } from './utils';\n\nconst NUMBER_REGEX = /^\\d+$/;\n\nexport function setPathValue(\n data: Record<string, any> | Record<string, any>[],\n path: string | string[],\n value: unknown,\n) {\n const parts = Array.isArray(path) ? path : pathToArray(path);\n\n let temp = data;\n let index = 0;\n while (index < parts.length) {\n /* istanbul ignore next */\n if (!Array.isArray(temp) && !isObject(temp)) {\n break;\n }\n\n const key = parts[index] as keyof typeof temp;\n\n // [foo, '0']\n if (typeof temp[key] === 'undefined') {\n const match = NUMBER_REGEX.test(key);\n if (match) {\n (temp as Record<string, any>)[key] = [];\n } else {\n temp[key] = {};\n }\n }\n\n if (index === parts.length - 1) {\n temp[key] = value;\n break;\n }\n\n index++;\n temp = temp[key];\n }\n\n return data;\n}\n"],"names":["arrayToPath","parts","reduce","prev","segment","part","replace","test","BRACKET_NUMBER_REGEX","pathToArray","str","match","result","i","length","regex","exec","push","getPathValue","data","path","Array","isArray","res","temp","index","Object","PathInfo","value","_value","pathParts","name","parent","_parent","parentPathParts","slice","exists","_exists","constructor","getPathInfo","isObject","input","NUMBER_REGEX","setPathValue","key"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare class PathInfo {
2
+ protected data: unknown;
3
+ protected path: string | undefined;
4
+ protected pathParts: string[];
5
+ protected _value: unknown;
6
+ protected _parent: PathInfo | null | undefined;
7
+ protected _exists: boolean | undefined;
8
+ constructor(data: unknown, path?: string);
9
+ get value(): unknown;
10
+ get name(): string | null;
11
+ get parent(): PathInfo | null;
12
+ get exists(): boolean;
13
+ }
@@ -0,0 +1 @@
1
+ export declare function setPathValue(data: Record<string, any> | Record<string, any>[], path: string | string[], value: unknown): Record<string, any> | Record<string, any>[];
@@ -0,0 +1 @@
1
+ export * from './is-object';
@@ -0,0 +1 @@
1
+ export declare function isObject(input: unknown): input is Record<string, any>;
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "pathtrace",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Simplifies working with nested objects and arrays by providing easy methods to retrieve, set, and check values at any path.",
5
+ "exports": {
6
+ "./package.json": "./package.json",
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.cjs"
11
+ }
12
+ },
13
+ "main": "./dist/index.cjs",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build:types": "tsc --emitDeclarationOnly -p tsconfig.json",
21
+ "build:js": "rollup -c",
22
+ "build": "rimraf ./dist && cross-env NODE_ENV=production npm run build:js && npm run build:types",
23
+ "test": "cross-env NODE_ENV=test jest --config ./test/jest.config.js",
24
+ "test:coverage": "npm run test -- --coverage",
25
+ "lint": "eslint --ext .js,.vue,.ts ./src ./test",
26
+ "lint:fix": "npm run lint -- --fix"
27
+ },
28
+ "bin": {
29
+ "authup": "dist/index.cjs"
30
+ },
31
+ "keywords": [
32
+ "nested-objects",
33
+ "path",
34
+ "path-retrival",
35
+ "javascript",
36
+ "path-info",
37
+ "deep-access"
38
+ ],
39
+ "author": {
40
+ "name": "Peter Placzek",
41
+ "email": "contact@tada5hi.net",
42
+ "url": "https://github.com/tada5hi"
43
+ },
44
+ "license": "Apache-2.0",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/tada5hi/pathtrace.git"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/tada5hi/pathtrace/issues"
51
+ },
52
+ "homepage": "https://github.com/tada5hi/pathtrace#readme",
53
+ "devDependencies": {
54
+ "@rollup/plugin-node-resolve": "^15.2.3",
55
+ "@rollup/plugin-swc": "^0.3.1",
56
+ "@swc/jest": "^0.2.36",
57
+ "@tada5hi/commitlint-config": "^1.2.1",
58
+ "@tada5hi/eslint-config-typescript": "^1.2.11",
59
+ "@tada5hi/semantic-release": "^0.3.1",
60
+ "@tada5hi/tsconfig": "^0.5.1",
61
+ "@types/jest": "^29.5.12",
62
+ "@types/node": "^22.5.0",
63
+ "@types/pathval": "^1.1.2",
64
+ "cross-env": "^7.0.3",
65
+ "eslint": "^8.37.0",
66
+ "husky": "^9.0.11",
67
+ "jest": "^29.7.0",
68
+ "rollup": "^4.21.1",
69
+ "semantic-release": "^22.0.12",
70
+ "ts-jest": "^29.2.5",
71
+ "typescript": "^5.5.4"
72
+ }
73
+ }