-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
94 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
"@smithy/smithy-client": major | ||
"@smithy/smithy-client": minor | ||
--- | ||
|
||
remove String extension in LazyJsonString |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,44 @@ | ||
import { describe, expect, test as it } from "vitest"; | ||
|
||
import { LazyJsonString } from "./lazy-json"; | ||
|
||
describe("LazyJsonString", () => { | ||
it("returns identical values for toString(), valueOf(), and toJSON()", () => { | ||
const jsonValue = LazyJsonString.from({ foo: "bar" }); | ||
expect(jsonValue.valueOf()).toBe(JSON.stringify({ foo: "bar" })); | ||
expect(jsonValue.toString()).toBe(JSON.stringify({ foo: "bar" })); | ||
expect(jsonValue.toJSON()).toBe(JSON.stringify({ foo: "bar" })); | ||
it("should have string methods", () => { | ||
const jsonValue = new LazyJsonString('"foo"'); | ||
expect(jsonValue.length).toBe(5); | ||
expect(jsonValue.toString()).toBe('"foo"'); | ||
}); | ||
|
||
it("should deserialize json properly", () => { | ||
const jsonValue = new LazyJsonString('"foo"'); | ||
expect(jsonValue.deserializeJSON()).toBe("foo"); | ||
const wrongJsonValue = new LazyJsonString("foo"); | ||
expect(() => wrongJsonValue.deserializeJSON()).toThrow(); | ||
}); | ||
|
||
it("should get JSON string properly", () => { | ||
const jsonValue = new LazyJsonString('{"foo", "bar"}'); | ||
expect(jsonValue.toJSON()).toBe('{"foo", "bar"}'); | ||
}); | ||
|
||
it("can instantiate from LazyJsonString class", () => { | ||
const original = LazyJsonString.from('"foo"'); | ||
const original = new LazyJsonString('"foo"'); | ||
const newOne = LazyJsonString.from(original); | ||
expect(newOne.toString()).toBe('"foo"'); | ||
}); | ||
|
||
it("can instantiate from String class", () => { | ||
const jsonValue = LazyJsonString.from('"foo"'); | ||
const jsonValue = LazyJsonString.from(new String('"foo"')); | ||
expect(jsonValue.toString()).toBe('"foo"'); | ||
}); | ||
|
||
it("can instantiate from object", () => { | ||
const jsonValue = LazyJsonString.from({ foo: "bar" }); | ||
expect(jsonValue.toString()).toBe('{"foo":"bar"}'); | ||
}); | ||
|
||
it("passes instanceof String check", () => { | ||
const jsonValue = LazyJsonString.from({ foo: "bar" }); | ||
expect(jsonValue).toBeInstanceOf(String); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,73 @@ | ||
/** | ||
* @public | ||
* | ||
* A model field with this type means that you may provide a JavaScript | ||
* object in lieu of a JSON string, and it will be serialized to JSON | ||
* automatically before being sent in a request. | ||
* | ||
* For responses, you will receive a "LazyJsonString", which is a boxed String object | ||
* with additional mixin methods. | ||
* To get the string value, call `.toString()`, or to get the JSON object value, | ||
* call `.deserializeJSON()` or parse it yourself. | ||
*/ | ||
export type AutomaticJsonStringConversion = Parameters<typeof JSON.stringify>[0] | LazyJsonString; | ||
|
||
/** | ||
* @internal | ||
* | ||
* This class allows the usage of data objects in fields that expect | ||
* JSON strings. It serializes the data object into JSON | ||
* if needed during the request serialization step. | ||
*/ | ||
export interface LazyJsonString extends String { | ||
new (s: string): typeof LazyJsonString; | ||
|
||
/** | ||
* @returns the JSON parsing of the string value. | ||
*/ | ||
deserializeJSON(): any; | ||
|
||
/** | ||
* @returns the original string value rather than a JSON.stringified value. | ||
*/ | ||
toJSON(): string; | ||
} | ||
|
||
/** | ||
* @internal | ||
* | ||
* Extension of the native String class in the previous implementation | ||
* has negative global performance impact on method dispatch for strings, | ||
* and is generally discouraged. | ||
* | ||
* This current implementation may look strange, but is necessary to preserve the interface and | ||
* behavior of extending the String class. | ||
*/ | ||
export class LazyJsonString { | ||
private constructor(private value: string) {} | ||
export function LazyJsonString(val: string): void { | ||
const str = Object.assign(new String(val), { | ||
deserializeJSON() { | ||
return JSON.parse(String(val)); | ||
}, | ||
|
||
public toString(): string { | ||
return this.value; | ||
} | ||
toString() { | ||
return String(val); | ||
}, | ||
|
||
public valueOf(): string { | ||
return this.value; | ||
} | ||
toJSON() { | ||
return String(val); | ||
}, | ||
}); | ||
|
||
public toJSON(): string { | ||
return this.value; | ||
} | ||
return str as never; | ||
} | ||
|
||
public static from(object: any): LazyJsonString { | ||
if (object instanceof LazyJsonString) { | ||
return object; | ||
} else if (typeof object === "string") { | ||
return new LazyJsonString(object); | ||
} | ||
return new LazyJsonString(JSON.stringify(object)); | ||
LazyJsonString.from = (object: any): LazyJsonString => { | ||
if (object && typeof object === "object" && (object instanceof LazyJsonString || "deserializeJSON" in object)) { | ||
return object as any; | ||
} else if (typeof object === "string" || Object.getPrototypeOf(object) === String.prototype) { | ||
return LazyJsonString(String(object) as string) as any; | ||
} | ||
return LazyJsonString(JSON.stringify(object)) as any; | ||
}; | ||
|
||
/** | ||
* @deprecated call from() instead. | ||
*/ | ||
public static fromObject(object: any): LazyJsonString { | ||
return LazyJsonString.from(object); | ||
} | ||
} | ||
/** | ||
* @deprecated use from. | ||
*/ | ||
LazyJsonString.fromObject = LazyJsonString.from; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters