Skip to content

Commit 360a9d9

Browse files
authored
fix: check that a replacement is not mapped to itself (#540)
* fix: check that a replacement is not mapped to itself * feat: add `dottie` to preferred manifest * update doc * Update preferred.json
1 parent 4c7cfd8 commit 360a9d9

File tree

3 files changed

+37
-27
lines changed

3 files changed

+37
-27
lines changed

docs/modules/dot-prop.md

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,18 @@ setProperty(obj, 'foo.bar.baz', 'value') // [!code --]
2020
dset(obj, 'foo.bar.baz', 'value') // [!code ++]
2121
```
2222

23-
## `object-path`
23+
## `String.prototype.split` + `Array.prototype.reduce` (native)
2424

25-
[`object-path`](https://github.com/mariocasciaro/object-path) provides get/set/has/delete operations plus array methods like push, insert, and empty.
25+
If you only need to get a nested value you can use a simple function:
2626

27-
```ts
28-
import { deleteProperty, getProperty, hasProperty, setProperty } from 'dot-prop' // [!code --]
29-
import objectPath from 'object-path' // [!code ++]
30-
31-
const value = getProperty(obj, 'foo.bar.baz') // [!code --]
32-
const value = objectPath.get(obj, 'foo.bar.baz') // [!code ++]
27+
```js
28+
function getProperty(obj, key) {
29+
return key.split('.').reduce((acc, k) => acc?.[k], obj)
30+
}
3331

34-
setProperty(obj, 'foo.bar.baz', 'value') // [!code --]
35-
objectPath.set(obj, 'foo.bar.baz', 'value') // [!code ++]
36-
37-
const exists = hasProperty(obj, 'foo.bar.baz') // [!code --]
38-
const exists = objectPath.has(obj, 'foo.bar.baz') // [!code ++]
39-
40-
deleteProperty(obj, 'foo.bar.baz') // [!code --]
41-
objectPath.del(obj, 'foo.bar.baz') // [!code ++]
32+
const value = getProperty(obj, 'foo.bar.baz')
4233
```
34+
35+
> [!NOTE]
36+
> This assumes that you do not consume dot paths as user input.
37+
> If you do, ensure you sanitize keys before accessing them (e.g. through `Object.hasOwn`).

manifests/preferred.json

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
"dot-prop": {
184184
"type": "module",
185185
"moduleName": "dot-prop",
186-
"replacements": ["dlv", "object-path"],
186+
"replacements": ["dlv"],
187187
"url": {"type": "e18e", "id": "dot-prop"}
188188
},
189189
"dotenv": {
@@ -192,6 +192,12 @@
192192
"replacements": ["--env-file"],
193193
"url": {"type": "e18e", "id": "dotenv"}
194194
},
195+
"dottie": {
196+
"type": "module",
197+
"moduleName": "dottie",
198+
"replacements": ["dlv", "dset"],
199+
"url": {"type": "e18e", "id": "dot-prop"}
200+
},
195201
"duplexer": {
196202
"type": "module",
197203
"moduleName": "duplexer",
@@ -351,7 +357,7 @@
351357
"get-value": {
352358
"type": "module",
353359
"moduleName": "get-value",
354-
"replacements": ["dlv", "object-path"],
360+
"replacements": ["dlv"],
355361
"url": {"type": "e18e", "id": "dot-prop"}
356362
},
357363
"glob": {
@@ -2445,7 +2451,7 @@
24452451
"object-path": {
24462452
"type": "module",
24472453
"moduleName": "object-path",
2448-
"replacements": ["dlv", "object-path"],
2454+
"replacements": ["dlv", "dset"],
24492455
"url": {"type": "e18e", "id": "dot-prop"}
24502456
},
24512457
"ora": {
@@ -2593,7 +2599,7 @@
25932599
"set-value": {
25942600
"type": "module",
25952601
"moduleName": "set-value",
2596-
"replacements": ["dlv", "object-path"],
2602+
"replacements": ["dset"],
25972603
"url": {"type": "e18e", "id": "dot-prop"}
25982604
},
25992605
"shortid": {
@@ -3008,6 +3014,12 @@
30083014
"url": {"type": "e18e", "id": "dot-prop"},
30093015
"replacementModule": "dlv"
30103016
},
3017+
"dset": {
3018+
"id": "dset",
3019+
"type": "documented",
3020+
"url": {"type": "e18e", "id": "dot-prop"},
3021+
"replacementModule": "dset"
3022+
},
30113023
"elysia": {
30123024
"id": "elysia",
30133025
"type": "documented",
@@ -3326,12 +3338,6 @@
33263338
"url": {"type": "e18e", "id": "npm-run-all"},
33273339
"replacementModule": "npm-run-all2"
33283340
},
3329-
"object-path": {
3330-
"id": "object-path",
3331-
"type": "documented",
3332-
"url": {"type": "e18e", "id": "dot-prop"},
3333-
"replacementModule": "object-path"
3334-
},
33353341
"obug": {
33363342
"id": "obug",
33373343
"type": "documented",

scripts/validate-manifests.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,20 @@ export async function validateManifests() {
6565
}
6666

6767
for (const replacementId of mapping.replacements) {
68-
if (!manifest.replacements[replacementId]) {
68+
const replacement = manifest.replacements[replacementId];
69+
70+
if (!replacement) {
6971
throw new Error(
7072
`${manifestPath}: mapping "${key}" references unknown replacement "${replacementId}"`
7173
);
7274
}
75+
76+
if (replacement.replacementModule === key) {
77+
throw new Error(
78+
`${manifestPath}: mapping "${key}" defines a replacementModule that is identical to itself.`
79+
);
80+
}
81+
7382
usedReplacementIds.add(replacementId);
7483
}
7584
}

0 commit comments

Comments
 (0)