Skip to content

Commit 3a18d5c

Browse files
authored
Merge pull request #40 from Foxy/release/1.10.0
chore: release v1.10.0
2 parents d7fb104 + 1d3e8df commit 3a18d5c

File tree

7 files changed

+46
-6
lines changed

7 files changed

+46
-6
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
"webpack-node-externals": "^2.5.2"
9696
},
9797
"engines": {
98-
"node": ">=10 <=18"
98+
"node": ">=10 <=20"
9999
},
100100
"eslintConfig": {
101101
"extends": [

src/core/API/Node.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ export class Node<TGraph extends Graph> {
128128

129129
if (filters !== undefined) {
130130
filters.forEach((filter: string) => {
131-
const params = new URLSearchParams(filter);
132-
[...params.entries()].forEach(([key, value]) => url.searchParams.append(key, value));
131+
const [key, value = ''] = filter.split('=');
132+
if (key) url.searchParams.append(key, value);
133133
});
134134
}
135135

src/core/getResourceId.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Returns the last path segment, which is usually an ID.
3+
* If it's a non-NaN numeric ID (true for most Foxy resources) then a `number` is returned.
4+
* Otherwise returns a string or `null` if the path is empty.
5+
*
6+
* @param uri `self` link on a resource, e.g. `https://api.foxy.io/stores/123`
7+
* @returns resource ID or `null` if not found
8+
*/
9+
export function getResourceId(uri: string): string | number | null {
10+
try {
11+
const idAsString = new URL(uri).pathname.split('/').pop() || undefined;
12+
if (idAsString === undefined) return null;
13+
const idAsInt = parseInt(idAsString);
14+
return isNaN(idAsInt) ? idAsString : idAsInt;
15+
} catch {
16+
return null;
17+
}
18+
}

src/core/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export type { Graph } from './Graph';
66
export * as Nucleon from './Nucleon/index.js';
77

88
export { BooleanSelector } from './BooleanSelector.js';
9+
export { getResourceId } from './getResourceId.js';
910
export { Rumour } from './Rumour/index.js';
1011
export { API } from './API/index.js';

tests/core/API/Node.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ describe('Core', () => {
119119

120120
testGET<{ child: never }>({
121121
label: 'GETs resolved URL with filters',
122-
query: { filters: ['foo=bar', 'baz=qux'] },
123-
target: 'https://example.com/?foo=bar&baz=qux',
122+
query: { filters: ['foo=bar', 'baz=qux[email protected]'] },
123+
target: 'https://example.com/?foo=bar&baz=qux%2Bone%40example.com',
124124
});
125125

126126
it('errors when .get() is called with incorrect query', async () => {

tests/core/getResourceId.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { getResourceId } from '../../src/core';
2+
3+
describe('Core', () => {
4+
describe('getResourceId', () => {
5+
it('supports numeric IDs', () => {
6+
expect(getResourceId('https://api.foxy.io/stores/123')).toEqual(123);
7+
});
8+
9+
it('supports string IDs', () => {
10+
expect(getResourceId('https://api.foxy.io/stores/AB1')).toEqual('AB1');
11+
});
12+
13+
it("returns null if there's no ID", () => {
14+
expect(getResourceId('https://api.foxy.io')).toBeNull();
15+
});
16+
17+
it('returns null if the provided URI is invalid', () => {
18+
expect(getResourceId('this is definitely not a URI')).toBeNull();
19+
});
20+
});
21+
});

0 commit comments

Comments
 (0)