Skip to content

Commit 9693691

Browse files
committed
Improve jrefTypeOf
1 parent b78a9d2 commit 9693691

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,20 +215,33 @@ Parse and stringify [JRef] values using the same API as the `JSON` built-in
215215
functions including reviver and replacer functions.
216216
217217
```javascript
218-
import { parse, stringify, Reference } from "@hyperjump/browser/jref";
218+
import { parse, stringify, jrefTypeOf } from "@hyperjump/browser/jref";
219219

220220
const blogPostJref = `{
221221
"title": "Working with JRef",
222222
"author": { "$href": "/author/jdesrosiers" },
223223
"content": "lorem ipsum dolor sit amet",
224224
}`;
225225
const blogPost = parse(blogPostJref);
226-
blogPost.author instanceof Reference; // => true
226+
jrefTypeOf(blogPost.author) // => "reference"
227227
blogPost.author.href; // => "/author/jdesrosiers"
228228

229229
stringify(blogPost, null, " ") === blogPostJref // => true
230230
```
231231
232+
### API
233+
export type Replacer = (key: string, value: unknown) => unknown;
234+
235+
* parse: (jref: string, reviver?: (key: string, value: unknown) => unknown) => JRef;
236+
237+
Same as `JSON.parse`, but converts `{ "$href": "..." }` to `Reference`
238+
objects.
239+
* stringify: (value: JRef, replacer?: (string | number)[] | null | Replacer, space?: string | number) => string;
240+
241+
Same as `JSON.stringify`, but converts `Reference` objects to `{ "$href":
242+
"... " }`
243+
* jrefTypeOf: (value: unknown) => "object" | "array" | "string" | "number" | "boolean" | "null" | "reference" | "undefined";
244+
232245
## Contributing
233246
234247
### Tests

lib/jref/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export const jrefTypeOf = (value) => {
3030
const jsType = typeof value;
3131

3232
switch (jsType) {
33+
case "bigint":
34+
return "number";
3335
case "number":
3436
case "string":
3537
case "boolean":
@@ -42,10 +44,11 @@ export const jrefTypeOf = (value) => {
4244
return "array";
4345
} else if (value === null) {
4446
return "null";
45-
} else if (value.constructor.prototype === Object.prototype) {
47+
} else if (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null) {
4648
return "object";
4749
}
4850
default:
49-
throw Error(`Not a JRef compatible type: ${value}`);
51+
const type = jsType === "object" ? Object.getPrototypeOf(value).constructor.name || "anonymous" : jsType;
52+
throw Error(`Not a JRef compatible type: ${type}`);
5053
}
5154
};

lib/browser/jref-typeof.spec.ts renamed to lib/jref/jref-typeof.spec.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ describe("JRef - jrefTypeOf", () => {
1919
expect(jrefTypeOf(42)).to.equal("number");
2020
});
2121

22+
it("bigint", () => {
23+
expect(jrefTypeOf(42n)).to.equal("number");
24+
});
25+
2226
it("string", () => {
2327
expect(jrefTypeOf("")).to.equal("string");
2428
});
@@ -31,6 +35,10 @@ describe("JRef - jrefTypeOf", () => {
3135
expect(jrefTypeOf({})).to.equal("object");
3236
});
3337

38+
it("null prototype object", () => {
39+
expect(jrefTypeOf(Object.create(null))).to.equal("object");
40+
});
41+
3442
it("reference", () => {
3543
expect(jrefTypeOf(new Reference("/"))).to.equal("reference");
3644
});
@@ -39,13 +47,23 @@ describe("JRef - jrefTypeOf", () => {
3947
expect(jrefTypeOf(undefined)).to.equal("undefined");
4048
});
4149

42-
it("function should error", () => {
50+
it("symbol", () => {
51+
const subject = Symbol("test");
52+
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type: symbol");
53+
});
54+
55+
it("function", () => {
4356
const subject = () => true;
44-
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type");
57+
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type: function");
4558
});
4659

47-
it("Set should error", () => {
60+
it("non-plain-object", () => {
4861
const subject = new Set();
49-
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type");
62+
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type: Set");
63+
});
64+
65+
it("anonymous non-plain-object", () => {
66+
const subject = new class {}();
67+
expect(() => jrefTypeOf(subject)).to.throw(Error, "Not a JRef compatible type: anonymous");
5068
});
5169
});

0 commit comments

Comments
 (0)