mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 23:00:32 +00:00
init commit
This commit is contained in:
19
node_modules/@jet/environment/json/index.js
generated
vendored
Normal file
19
node_modules/@jet/environment/json/index.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./reader"), exports);
|
||||
__exportStar(require("./validation"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
139
node_modules/@jet/environment/json/reader/coercion.js
generated
vendored
Normal file
139
node_modules/@jet/environment/json/reader/coercion.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.valueAsNumber = exports.valueAsString = exports.valueAsBoolean = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
const validation = require("../validation");
|
||||
/**
|
||||
* Attempt to coerce the given value to a boolean.
|
||||
*
|
||||
* @see asBoolean
|
||||
* @param value - the value to coerce
|
||||
* @param policy - determines when validation errors are added to the current validation context
|
||||
* @param path - an optional string appended to validation errors to identify where this value originated
|
||||
* @returns a boolean if the value was a boolean or coercible to a boolean, otherwise null
|
||||
*/
|
||||
function valueAsBoolean(value, policy = "coercible", path) {
|
||||
if (!(0, optional_1.isSome)(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "boolean") {
|
||||
return value;
|
||||
}
|
||||
// Handle string coercion
|
||||
if (typeof value === "string") {
|
||||
if (value === "true") {
|
||||
return true;
|
||||
}
|
||||
else if (value === "false") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Else coerce.
|
||||
const coercedValue = Boolean(value);
|
||||
switch (policy) {
|
||||
case "strict": {
|
||||
validation.context("asBoolean", () => {
|
||||
validation.unexpectedType("coercedValue", "boolean", value, path);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "coercible": {
|
||||
if ((0, optional_1.isNothing)(coercedValue)) {
|
||||
validation.context("asBoolean", () => {
|
||||
validation.unexpectedType("coercedValue", "boolean", value, path);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "none":
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return coercedValue;
|
||||
}
|
||||
exports.valueAsBoolean = valueAsBoolean;
|
||||
/**
|
||||
* Attempt to coerce the given value to a string.
|
||||
*
|
||||
* @see asString
|
||||
* @param value - the value to coerce
|
||||
* @param policy - determines when validation errors are added to the current validation context
|
||||
* @param path - an optional string appended to validation errors to identify where this value originated
|
||||
* @returns a string if the value was a string or coercible to a string, otherwise null
|
||||
*/
|
||||
function valueAsString(value, policy = "coercible", path) {
|
||||
if (!(0, optional_1.isSome)(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value;
|
||||
}
|
||||
// We don't consider arbitrary objects as convertable to strings even through they will result in some value
|
||||
const coercedValue = typeof value === "object" ? null : String(value);
|
||||
switch (policy) {
|
||||
case "strict": {
|
||||
validation.context("asString", () => {
|
||||
validation.unexpectedType("coercedValue", "string", value, path);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "coercible": {
|
||||
if ((0, optional_1.isNothing)(coercedValue)) {
|
||||
validation.context("asString", () => {
|
||||
validation.unexpectedType("coercedValue", "string", value, path);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "none":
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return coercedValue;
|
||||
}
|
||||
exports.valueAsString = valueAsString;
|
||||
/**
|
||||
* Attempt to coerce the given value to a number.
|
||||
*
|
||||
* @see asNumber
|
||||
* @param value - the value to coerce
|
||||
* @param policy - determines when validation errors are added to the current validation context
|
||||
* @param path - an optional string appended to validation errors to identify where this value originated
|
||||
* @returns a number if the value was a number or coercible to a number, otherwise null
|
||||
*/
|
||||
function valueAsNumber(value, policy = "coercible", path) {
|
||||
if (!(0, optional_1.isSome)(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number") {
|
||||
return value;
|
||||
}
|
||||
const coercedValue = Number(value);
|
||||
switch (policy) {
|
||||
case "strict": {
|
||||
validation.context("asNumber", () => {
|
||||
validation.unexpectedType("coercedValue", "number", value, path);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "coercible": {
|
||||
if (isNaN(coercedValue)) {
|
||||
validation.context("asNumber", () => {
|
||||
validation.unexpectedType("coercedValue", "number", value, path);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "none":
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return coercedValue;
|
||||
}
|
||||
exports.valueAsNumber = valueAsNumber;
|
||||
//# sourceMappingURL=coercion.js.map
|
||||
20
node_modules/@jet/environment/json/reader/index.js
generated
vendored
Normal file
20
node_modules/@jet/environment/json/reader/index.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./object-reader"), exports);
|
||||
__exportStar(require("./key-path"), exports);
|
||||
__exportStar(require("./coercion"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
143
node_modules/@jet/environment/json/reader/key-path.js
generated
vendored
Normal file
143
node_modules/@jet/environment/json/reader/key-path.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.keyPathContains = exports.keyPathEndsWith = exports.keyPathStartsWith = exports.keyPathsEqual = exports.isKeyPathThis = exports.thisKeyPath = exports.keysOf = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
/**
|
||||
* A global cache containing parsed string key paths
|
||||
* with components separated by a dot.
|
||||
*/
|
||||
const parsedKeyPaths = {};
|
||||
/**
|
||||
* Extract the individual keys from a key path in order
|
||||
* to traverse into an object to access a specific value.
|
||||
*
|
||||
* @param keyPath - A key path to extract the keys from.
|
||||
* @returns An array containing the keys making up `keyPath`.
|
||||
*/
|
||||
function keysOf(keyPath) {
|
||||
// TODO: Normalizing into an array is potentially a bottleneck.
|
||||
// Do we want to do this differently for slower environments?
|
||||
if (Array.isArray(keyPath)) {
|
||||
return keyPath;
|
||||
}
|
||||
else {
|
||||
switch (typeof keyPath) {
|
||||
case "string": {
|
||||
const existingKeyPath = parsedKeyPaths[keyPath];
|
||||
if ((0, optional_1.isSome)(existingKeyPath)) {
|
||||
return existingKeyPath;
|
||||
}
|
||||
else {
|
||||
const newKeyPath = Object.freeze(keyPath.split("."));
|
||||
parsedKeyPaths[keyPath] = newKeyPath;
|
||||
return newKeyPath;
|
||||
}
|
||||
}
|
||||
case "number": {
|
||||
return [keyPath];
|
||||
}
|
||||
case "symbol": {
|
||||
return [keyPath];
|
||||
}
|
||||
default: {
|
||||
throw new TypeError(`${keyPath.toString()} is not a KeyPath`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.keysOf = keysOf;
|
||||
/**
|
||||
* A key path representing an object itself.
|
||||
*/
|
||||
exports.thisKeyPath = Object.freeze([]);
|
||||
/**
|
||||
* Determine whether a given key path is the `this` (identity) key path.
|
||||
* @param keyPath - A key path to test.
|
||||
*/
|
||||
function isKeyPathThis(keyPath) {
|
||||
return Array.isArray(keyPath) && keyPath.length === 0;
|
||||
}
|
||||
exports.isKeyPathThis = isKeyPathThis;
|
||||
/**
|
||||
* Determines whether two key paths are equivalent taking into account
|
||||
* that the key paths may have different representations.
|
||||
*
|
||||
* @param lhs - A key path to compare.
|
||||
* @param rhs - Another key path to compare.
|
||||
*/
|
||||
function keyPathsEqual(lhs, rhs) {
|
||||
// 1. Are the key paths equal through value semantics?
|
||||
if (lhs === rhs) {
|
||||
return true;
|
||||
}
|
||||
const lhsKeys = keysOf(lhs);
|
||||
const rhsKeys = keysOf(rhs);
|
||||
// 2. Do we have the same number of keys in each path?
|
||||
if (lhsKeys.length !== rhsKeys.length) {
|
||||
return false;
|
||||
}
|
||||
// 3. Do any of the keys in our paths differ?
|
||||
for (let index = 0, length = lhsKeys.length; index < length; index += 1) {
|
||||
if (lhsKeys[index] !== rhsKeys[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 4. We have passed all checks and are considered equal.
|
||||
return true;
|
||||
}
|
||||
exports.keyPathsEqual = keyPathsEqual;
|
||||
/**
|
||||
* Determine whether a given key path starts with a specified key.
|
||||
*
|
||||
* @param haystack - A key path to perform a prefix check on.
|
||||
* @param needle - The key to check for.
|
||||
*/
|
||||
function keyPathStartsWith(haystack, needle) {
|
||||
if (haystack === needle) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
const keys = keysOf(haystack);
|
||||
if (keys.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return keys[0] === needle;
|
||||
}
|
||||
}
|
||||
exports.keyPathStartsWith = keyPathStartsWith;
|
||||
/**
|
||||
* Determine whether a given key path ends with a specified key.
|
||||
*
|
||||
* @param haystack - A key path to perform a suffix check on.
|
||||
* @param needle - The key to check for.
|
||||
*/
|
||||
function keyPathEndsWith(haystack, needle) {
|
||||
if (haystack === needle) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
const keys = keysOf(haystack);
|
||||
if (keys.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return keys[keys.length - 1] === needle;
|
||||
}
|
||||
}
|
||||
exports.keyPathEndsWith = keyPathEndsWith;
|
||||
/**
|
||||
* Determine whether a given key path contains a specified key.
|
||||
*
|
||||
* @param haystack - A key path to search.
|
||||
* @param needle - The key to search for.
|
||||
*/
|
||||
function keyPathContains(haystack, needle) {
|
||||
if (haystack === needle) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
const keys = keysOf(haystack);
|
||||
return keys.includes(needle);
|
||||
}
|
||||
}
|
||||
exports.keyPathContains = keyPathContains;
|
||||
//# sourceMappingURL=key-path.js.map
|
||||
119
node_modules/@jet/environment/json/reader/object-cursor.js
generated
vendored
Normal file
119
node_modules/@jet/environment/json/reader/object-cursor.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ObjectCursor = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
const clone_1 = require("../../util/clone");
|
||||
const key_path_1 = require("./key-path");
|
||||
const traverse_1 = require("./traverse");
|
||||
class ObjectCursor {
|
||||
/**
|
||||
* Create a cursor for an object.
|
||||
*
|
||||
* @param root - An object to traverse.
|
||||
*/
|
||||
constructor(root) {
|
||||
this.values = [root];
|
||||
this.keyPaths = [key_path_1.thisKeyPath];
|
||||
this.savedDepths = [];
|
||||
}
|
||||
/**
|
||||
* The current value this cursor is pointing at.
|
||||
*/
|
||||
get currentValue() {
|
||||
return this.values[this.values.length - 1];
|
||||
}
|
||||
/**
|
||||
* The key path of the value this cursor is pointing at.
|
||||
*/
|
||||
get currentKeyPath() {
|
||||
return this.keyPaths[this.keyPaths.length - 1];
|
||||
}
|
||||
/**
|
||||
* Advance this cursor to a given value and the key path which
|
||||
* was used to reach it.
|
||||
*
|
||||
* Use this method to override the internal traversal logic of
|
||||
* the cursor as needed. Like `moveTo`, calls to this method can
|
||||
* be balanced with calls to `back`.
|
||||
*
|
||||
* @param value - The new value for the cursor to represent.
|
||||
* @param keyPath - The key path used to reach the value.
|
||||
*/
|
||||
interject(value, keyPath) {
|
||||
this.values.push(value);
|
||||
this.keyPaths.push(keyPath);
|
||||
}
|
||||
/**
|
||||
* Reconfigure this cursor to traverse a given object.
|
||||
*
|
||||
* @param newRoot - The new root object to traverse.
|
||||
* @param keyPath - The key path specifying where the root object came from.
|
||||
* Typically this should be `thisKeyPath` (the default value for this parameter.)
|
||||
*/
|
||||
reuse(newRoot, keyPath = key_path_1.thisKeyPath) {
|
||||
this.values.length = 0;
|
||||
this.values.push(newRoot);
|
||||
this.keyPaths.length = 0;
|
||||
this.keyPaths.push(keyPath);
|
||||
this.savedDepths.length = 0;
|
||||
}
|
||||
/**
|
||||
* Advance this cursor to a new position in the object it is traversing,
|
||||
* saving its previous position so that the cursor may be moved back.
|
||||
*
|
||||
* @param keyPath - A key path referring to a location in the cursor's current value.
|
||||
* @returns The new current value of the cursor.
|
||||
*/
|
||||
moveTo(keyPath) {
|
||||
const newValue = (0, traverse_1.traverse)(this.currentValue, keyPath);
|
||||
this.values.push(newValue);
|
||||
this.keyPaths.push(keyPath);
|
||||
return newValue;
|
||||
}
|
||||
/**
|
||||
* Rewind this cursor to its previous position in the object it is traversing.
|
||||
*/
|
||||
moveBack() {
|
||||
const currentDepth = this.values.length;
|
||||
if (currentDepth === 1) {
|
||||
throw new Error("Cannot move back past the root of a cursor");
|
||||
}
|
||||
const numberOfSaves = this.savedDepths.length;
|
||||
if (numberOfSaves > 0 && currentDepth <= this.savedDepths[numberOfSaves - 1]) {
|
||||
throw new Error("Cannot move back past the most recent saved state");
|
||||
}
|
||||
this.values.pop();
|
||||
this.keyPaths.pop();
|
||||
}
|
||||
/**
|
||||
* Save the current position of this cursor so that it may be restored later.
|
||||
*
|
||||
* Calls to this method must be balanced with a call to `restoreState`.
|
||||
*/
|
||||
saveState() {
|
||||
this.savedDepths.push(this.values.length);
|
||||
}
|
||||
/**
|
||||
* Restore this cursor's position to a previously saved state.
|
||||
*
|
||||
* Use this method to balance a previous call to `saveState`.
|
||||
*/
|
||||
restoreState() {
|
||||
const savedLength = this.savedDepths.pop();
|
||||
if ((0, optional_1.isNothing)(savedLength)) {
|
||||
throw new Error("Calls to restoreState must balance previous calls to saveState");
|
||||
}
|
||||
this.values.length = savedLength;
|
||||
this.keyPaths.length = savedLength;
|
||||
}
|
||||
// section Cloneable
|
||||
clone() {
|
||||
const copy = (0, clone_1.shallowCloneOf)(this);
|
||||
copy.values = this.values.slice();
|
||||
copy.keyPaths = this.keyPaths.slice();
|
||||
copy.savedDepths = this.savedDepths.slice();
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
exports.ObjectCursor = ObjectCursor;
|
||||
//# sourceMappingURL=object-cursor.js.map
|
||||
428
node_modules/@jet/environment/json/reader/object-reader.js
generated
vendored
Normal file
428
node_modules/@jet/environment/json/reader/object-reader.js
generated
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ObjectReader = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
const clone_1 = require("../../util/clone");
|
||||
const coercion_1 = require("./coercion");
|
||||
const key_path_1 = require("./key-path");
|
||||
const object_cursor_1 = require("./object-cursor");
|
||||
const traverse_1 = require("./traverse");
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/**
|
||||
* Map which holds any object readers recycled, divided by constructor.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const scrapReaders = new Map();
|
||||
/**
|
||||
* A type which allows efficient and type-safe traversal of untyped objects.
|
||||
*/
|
||||
class ObjectReader {
|
||||
/**
|
||||
* Create a reader to traverse the contents of an untyped
|
||||
* object safely and efficiently.
|
||||
*
|
||||
* @param object - An object to efficiently traverse with a reader.
|
||||
*/
|
||||
constructor(object) {
|
||||
this._cursor = new object_cursor_1.ObjectCursor(object);
|
||||
}
|
||||
// endsection
|
||||
// section Structure
|
||||
/**
|
||||
* Current key path which operations on this reader are relative to.
|
||||
*/
|
||||
get currentKeyPath() {
|
||||
return this._cursor.currentKeyPath;
|
||||
}
|
||||
/**
|
||||
* Determines whether a value exists for a given key
|
||||
* relative to the reader's current location.
|
||||
*
|
||||
* @param key - The key to test for the existence of.
|
||||
* @returns `true` if a value exists for `key`; `false` otherwise.
|
||||
*/
|
||||
has(key) {
|
||||
return (0, key_path_1.keyPathEndsWith)(this._cursor.currentKeyPath, key) || (0, optional_1.isSome)(this.get(key));
|
||||
}
|
||||
/**
|
||||
* Make all operations on this reader be relative to a given key path.
|
||||
*
|
||||
* Consecutive calls to `select` with the same key path are idempotent.
|
||||
* You may repeatedly call this method with the same key path and only
|
||||
* the first call will change what operations are relative to on this reader.
|
||||
*
|
||||
* To allow repeated paths in consecutive `select` calls set the optional
|
||||
* `allowRepeatedKeyPath` argument to `true`.
|
||||
*
|
||||
* You must balance calls to this method with matching calls to `deselect`.
|
||||
*
|
||||
* @param keyPath - The key path to make this reader's operations relative to.
|
||||
* @param allowRepeatedKeyPath - The Boolean indicating whether repeated key path
|
||||
* like 'value.value' should be accepted by the reader.
|
||||
* Some JSON objects can have nested properties stored under the same key path.
|
||||
* @returns The reader this method was called on.
|
||||
*/
|
||||
select(keyPath, allowRepeatedKeyPath = false) {
|
||||
if (allowRepeatedKeyPath || !(0, key_path_1.keyPathsEqual)(this._cursor.currentKeyPath, keyPath)) {
|
||||
this._cursor.moveTo(keyPath);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Make all operations on this reader be relative to the previously selected key path.
|
||||
*
|
||||
* If no key path was previously selected, this method has the effect of making
|
||||
* operations relative to the media response the reader was created to work on.
|
||||
*
|
||||
* Use this method to balance previous calls to a method in the `select` family.
|
||||
*
|
||||
* @returns The reader this method was called on.
|
||||
*/
|
||||
deselect() {
|
||||
this._cursor.moveBack();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Save the current selection of this reader so that it can be restored later.
|
||||
*
|
||||
* Calls to this method should be balanced with a call to `restoreSelection`.
|
||||
*/
|
||||
saveSelection() {
|
||||
this._cursor.saveState();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Restore a previous selection of this reader.
|
||||
*
|
||||
* Use this method to balance a previous call to `saveSelection`.
|
||||
*/
|
||||
restoreSelection() {
|
||||
this._cursor.restoreState();
|
||||
return this;
|
||||
}
|
||||
// endsection
|
||||
// section Scalars
|
||||
/**
|
||||
* Access an untyped value in this reader's contents.
|
||||
*
|
||||
* @param keyPath - A key path specifying where to find the value in this reader's contents.
|
||||
* @returns An optional untyped value.
|
||||
*/
|
||||
get(keyPath = key_path_1.thisKeyPath) {
|
||||
if ((0, key_path_1.isKeyPathThis)(keyPath)) {
|
||||
return this._cursor.currentValue;
|
||||
}
|
||||
else {
|
||||
return (0, traverse_1.traverse)(this._cursor.currentValue, keyPath);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Access a boolean value in this reader's contents.
|
||||
*
|
||||
* @param keyPath - A key path specifying where to find the value in this reader's contents.
|
||||
* @returns An optional boolean value.
|
||||
*/
|
||||
asBoolean(keyPath = key_path_1.thisKeyPath, policy = "coercible") {
|
||||
return (0, coercion_1.valueAsBoolean)(this.get(keyPath), policy, String(keyPath));
|
||||
}
|
||||
/**
|
||||
* Access a number value in this reader's contents.
|
||||
*
|
||||
* @param keyPath - A key path specifying where to find the value in this reader's contents.
|
||||
* @returns An optional number value.
|
||||
*/
|
||||
asNumber(keyPath = key_path_1.thisKeyPath, policy = "coercible") {
|
||||
return (0, coercion_1.valueAsNumber)(this.get(keyPath), policy, String(keyPath));
|
||||
}
|
||||
/**
|
||||
* Access a string value in this reader's contents.
|
||||
*
|
||||
* @param keyPath - A key path specifying where to find the value in this reader's contents.
|
||||
* @returns An optional string value.
|
||||
*/
|
||||
asString(keyPath = key_path_1.thisKeyPath, policy = "coercible") {
|
||||
return (0, coercion_1.valueAsString)(this.get(keyPath), policy, String(keyPath));
|
||||
}
|
||||
// endsection
|
||||
// section Sequences
|
||||
/**
|
||||
* Create an iterator for the contents of this reader.
|
||||
*
|
||||
* If the current reader's contents are `undefined` or `null`,
|
||||
* the returned iterator yields nothing.
|
||||
*
|
||||
* If the current reader's contents is an array, the returned
|
||||
* iterator will yield a reader for each element in that array.
|
||||
*
|
||||
* Otherwise, the iterator will yield a single reader for
|
||||
* the current reader's contents.
|
||||
*
|
||||
* __Important:__ The readers yielded by this iterator must not
|
||||
* be allowed to escape your `for`-loop. For efficiency, readers
|
||||
* may be reused.
|
||||
*
|
||||
* An iterator consumer (`for...of` loop) may safely call select
|
||||
* methods on the reader without balancing them with deselect
|
||||
* calls before the getting the next reader from the iterator.
|
||||
*/
|
||||
*[Symbol.iterator]() {
|
||||
const iteratee = this.get();
|
||||
if ((0, optional_1.isNothing)(iteratee)) {
|
||||
return;
|
||||
}
|
||||
const iterationReader = ObjectReader._clone(this);
|
||||
if (Array.isArray(iteratee)) {
|
||||
let index = 0;
|
||||
for (const value of iteratee) {
|
||||
iterationReader.saveSelection();
|
||||
iterationReader._cursor.interject(value, index);
|
||||
yield iterationReader;
|
||||
iterationReader.restoreSelection();
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
yield iterationReader;
|
||||
}
|
||||
ObjectReader._recycle(iterationReader);
|
||||
}
|
||||
/**
|
||||
* Returns the result of combining the contents of this reader
|
||||
* using a given function.
|
||||
*
|
||||
* If the current reader's contents are `undefined` or `null`,
|
||||
* the `initialValue` is returned unchanged.
|
||||
*
|
||||
* If the current reader's contents is an array, the `reducer`
|
||||
* will be called with a reader for each element in that array.
|
||||
*
|
||||
* Otherwise, the `reducer` function will be called once with
|
||||
* a reader for the current reader's contents.
|
||||
*
|
||||
* __Important:__ The `reducer` function must not allow the passed in
|
||||
* reader to escape its body. For efficiency, readers may be reused.
|
||||
* The function may safely perform call select methods without balancing
|
||||
* them with matching deselect calls.
|
||||
*
|
||||
* @param initialValue - The value to use as the initial accumulating value.
|
||||
* @param reducer - A function that combines an accumulating value and an element from this reader's contents
|
||||
* into a new accumulating value, to be used in the next call of this function or returned to the caller.
|
||||
*/
|
||||
reduce(initialValue, reducer) {
|
||||
const iteratee = this.get();
|
||||
if ((0, optional_1.isNothing)(iteratee)) {
|
||||
return initialValue;
|
||||
}
|
||||
if (Array.isArray(iteratee)) {
|
||||
try {
|
||||
let value = initialValue;
|
||||
for (let index = 0, length = iteratee.length; index < length; index += 1) {
|
||||
this.saveSelection();
|
||||
this._cursor.interject(iteratee[index], index);
|
||||
value = reducer(value, this);
|
||||
this.restoreSelection();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
catch (e) {
|
||||
this.restoreSelection();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return reducer(initialValue, this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create an array by applying a function to the contents of this reader.
|
||||
*
|
||||
* If the current reader's contents are `undefined` or `null`,
|
||||
* an empty array will be returned without calling `transformer`.
|
||||
*
|
||||
* If the current reader's contents is an array, the function will
|
||||
* be called with a reader for each element from that array.
|
||||
*
|
||||
* Otherwise, the function will be called once with a reader for
|
||||
* the current reader's contents.
|
||||
*
|
||||
* __Important:__ The function must not allow the passed in reader
|
||||
* to escape its body. For efficiency, readers may be reused.
|
||||
* The function may safely perform call select methods without balancing
|
||||
* them with matching deselect calls.
|
||||
*
|
||||
* @param transformer - A function which derives a value from a reader.
|
||||
* @returns An array containing the accumulated results of calling `transformer`.
|
||||
*/
|
||||
map(transformer) {
|
||||
return this.reduce(new Array(), (acc, reader) => {
|
||||
acc.push(transformer(reader));
|
||||
return acc;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create an array by applying a function to the contents of this reader,
|
||||
* discarding `undefined` and `null` values returned by the function.
|
||||
*
|
||||
* If the current reader's contents are `undefined` or `null`,
|
||||
* an empty array will be returned without calling `transformer`.
|
||||
*
|
||||
* If the current reader's contents is an array, the function will
|
||||
* be called with a reader for each element from that array.
|
||||
*
|
||||
* Otherwise, the function will be called once with a reader for
|
||||
* the current reader's contents.
|
||||
*
|
||||
* __Important:__ The function must not allow the passed in reader
|
||||
* to escape its body. For efficiency, readers may be reused.
|
||||
* The function may safely perform call select methods without balancing
|
||||
* them with matching deselect calls.
|
||||
*
|
||||
* @param transformer - A function which derives a value from a reader,
|
||||
* or returns a nully value if none can be derived.
|
||||
* @returns An array containing the accumulated results of calling `transformer`.
|
||||
*/
|
||||
compactMap(transformer) {
|
||||
return this.reduce(new Array(), (acc, reader) => {
|
||||
const value = transformer(reader);
|
||||
if ((0, optional_1.isSome)(value)) {
|
||||
acc.push(value);
|
||||
}
|
||||
return acc;
|
||||
});
|
||||
}
|
||||
// endsection
|
||||
// section Builders
|
||||
/**
|
||||
* Call a function with this reader and any number of additional parameters,
|
||||
* rolling back any reader selection changes the function makes.
|
||||
*
|
||||
* Use this method to work with closures and top level functions which use
|
||||
* an object reader to do work. Prefer `#callOn` for object methods.
|
||||
*
|
||||
* @param body - A function which takes a reader and any number of additional parameters.
|
||||
* @param rest - The parameters to pass to `body` after this reader.
|
||||
* @returns The result of `body`, if any.
|
||||
*/
|
||||
applyTo(body, ...rest) {
|
||||
this.saveSelection();
|
||||
try {
|
||||
const result = body(this, ...rest);
|
||||
this.restoreSelection();
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
this.restoreSelection();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Call an object method with this reader and any number of additional parameters,
|
||||
* rolling back any reader selection changes the method makes.
|
||||
*
|
||||
* Use this method to work with object methods which use an object reader to do work.
|
||||
* Prefer `#applyTo` for closures and top level functions.
|
||||
*
|
||||
* @param method - A method which takes a reader and any number of additional parameters.
|
||||
* @param thisArg - The object to be used as the current object.
|
||||
* @param rest - The parameters to pass to `method` after this reader.
|
||||
* @returns The result of `method`, if any.
|
||||
*/
|
||||
callOn(method, thisArg, ...rest) {
|
||||
this.saveSelection();
|
||||
try {
|
||||
const result = method.call(thisArg, this, ...rest);
|
||||
this.restoreSelection();
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
this.restoreSelection();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
// endsection
|
||||
// section Cloneable
|
||||
clone() {
|
||||
const copy = (0, clone_1.shallowCloneOf)(this);
|
||||
copy._cursor = this._cursor.clone();
|
||||
return copy;
|
||||
}
|
||||
// endsection
|
||||
// section Reuse
|
||||
/**
|
||||
* Reduce allocations required when iterating with this object reader
|
||||
* up to a specified depth.
|
||||
*
|
||||
* Each subclass of `ObjectReader` should call this method on itself
|
||||
* after the module containing the subclass is loaded.
|
||||
*
|
||||
* @param depth - The expected iteration depth of this object reader type.
|
||||
*/
|
||||
static optimizeIterationUpToDepth(depth) {
|
||||
for (let index = 0; index < depth; index += 1) {
|
||||
ObjectReader._recycle(new ObjectReader(undefined));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clone a given object reader, reusing a previously created instance
|
||||
* of the same constructor if one is available.
|
||||
*
|
||||
* @param reader - The object reader to efficiently clone.
|
||||
* @returns A new reader which can be treated as clone of `reader`.
|
||||
*/
|
||||
static _clone(reader) {
|
||||
const scrap = scrapReaders.get(reader.constructor);
|
||||
if ((0, optional_1.isSome)(scrap)) {
|
||||
const reclaimedReader = scrap.pop();
|
||||
if ((0, optional_1.isSome)(reclaimedReader)) {
|
||||
reclaimedReader.onReuseToIterate(reader);
|
||||
return reclaimedReader;
|
||||
}
|
||||
}
|
||||
return reader.clone();
|
||||
}
|
||||
/**
|
||||
* Informs an object reader it is about to be reused as the value
|
||||
* of another object reader which is being treated as an iterator.
|
||||
*
|
||||
* Subclasses _must_ call `super` when overriding this method.
|
||||
*
|
||||
* @param other - The reader this instance is being used to assist.
|
||||
*/
|
||||
onReuseToIterate(other) {
|
||||
const cursorToMirror = other._cursor;
|
||||
this._cursor.reuse(cursorToMirror.currentValue, cursorToMirror.currentKeyPath);
|
||||
}
|
||||
/**
|
||||
* Recycle an object reader which was used as the value of another
|
||||
* object reader being treated as an iterator.
|
||||
*
|
||||
* @param reader - A reader which was used for iteration and is no longer
|
||||
* needed for that role.
|
||||
*/
|
||||
static _recycle(reader) {
|
||||
const ctor = reader.constructor;
|
||||
const existingScrap = scrapReaders.get(ctor);
|
||||
if ((0, optional_1.isSome)(existingScrap)) {
|
||||
if (existingScrap.length >= 5) {
|
||||
return;
|
||||
}
|
||||
reader.onRecycleForIteration();
|
||||
existingScrap.push(reader);
|
||||
}
|
||||
else {
|
||||
reader.onRecycleForIteration();
|
||||
scrapReaders.set(ctor, [reader]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Informs an object reader it is being recycled after being used as
|
||||
* the value of another object reader which was treated as an iterator.
|
||||
*
|
||||
* Subclasses _must_ call `super` when overriding this method.
|
||||
*/
|
||||
onRecycleForIteration() {
|
||||
this._cursor.reuse(undefined);
|
||||
}
|
||||
}
|
||||
exports.ObjectReader = ObjectReader;
|
||||
//# sourceMappingURL=object-reader.js.map
|
||||
36
node_modules/@jet/environment/json/reader/traverse.js
generated
vendored
Normal file
36
node_modules/@jet/environment/json/reader/traverse.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.traverse = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
const key_path_1 = require("./key-path");
|
||||
function traverse(object, keyPath) {
|
||||
if (typeof object !== "object") {
|
||||
return object;
|
||||
}
|
||||
if (!(0, optional_1.isSome)(object)) {
|
||||
return object;
|
||||
}
|
||||
const keys = (0, key_path_1.keysOf)(keyPath);
|
||||
switch (keys.length) {
|
||||
case 0:
|
||||
return object;
|
||||
case 1:
|
||||
return object[keys[0]];
|
||||
default:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
let currentObject = object;
|
||||
for (const key of keys) {
|
||||
const currentValue = currentObject[key];
|
||||
if (typeof currentValue !== "object") {
|
||||
return currentValue;
|
||||
}
|
||||
if (!(0, optional_1.isSome)(currentValue)) {
|
||||
return currentValue;
|
||||
}
|
||||
currentObject = currentValue;
|
||||
}
|
||||
return currentObject;
|
||||
}
|
||||
}
|
||||
exports.traverse = traverse;
|
||||
//# sourceMappingURL=traverse.js.map
|
||||
250
node_modules/@jet/environment/json/validation.js
generated
vendored
Normal file
250
node_modules/@jet/environment/json/validation.js
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.unexpectedNull = exports.catchingContext = exports.context = exports.recordValidationIncidents = exports.endContext = exports.getContextNames = exports.beginContext = exports.messageForRecoveryAction = exports.isValidatable = exports.unexpectedType = exports.extendedTypeof = void 0;
|
||||
const optional_1 = require("../types/optional");
|
||||
/**
|
||||
* Returns a string containing the type of a given value.
|
||||
* This function augments the built in `typeof` operator
|
||||
* to return sensible values for arrays and null values.
|
||||
*
|
||||
* @privateRemarks
|
||||
* This function is exported for testing.
|
||||
*
|
||||
* @param value - The value to find the type of.
|
||||
* @returns A string containing the type of `value`.
|
||||
*/
|
||||
function extendedTypeof(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return "array";
|
||||
}
|
||||
else if (value === null) {
|
||||
return "null";
|
||||
}
|
||||
else {
|
||||
return typeof value;
|
||||
}
|
||||
}
|
||||
exports.extendedTypeof = extendedTypeof;
|
||||
/**
|
||||
* Reports a non-fatal validation failure, logging a message to the console.
|
||||
* @param recovery - The recovery action taken when the bad type was found.
|
||||
* @param expected - The expected type of the value.
|
||||
* @param actual - The actual value.
|
||||
* @param pathString - A string containing the path to the value on the object which failed type validation.
|
||||
*/
|
||||
function unexpectedType(recovery, expected, actual, pathString) {
|
||||
const actualType = extendedTypeof(actual);
|
||||
const prettyPath = (0, optional_1.isSome)(pathString) && pathString.length > 0 ? pathString : "<this>";
|
||||
trackIncident({
|
||||
type: "badType",
|
||||
expected: expected,
|
||||
// Our test assertions are matching the string interpolation of ${actual} value.
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
actual: `${actualType} (${actual})`,
|
||||
objectPath: prettyPath,
|
||||
contextNames: getContextNames(),
|
||||
recoveryAction: recovery,
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
exports.unexpectedType = unexpectedType;
|
||||
// endregion
|
||||
/**
|
||||
* Determines if a given object conforms to the Validatable interface
|
||||
* @param possibleValidatable - An object that might be considered validatable
|
||||
*
|
||||
* @returns `true` if it is an instance of Validatable, `false` if not
|
||||
*/
|
||||
function isValidatable(possibleValidatable) {
|
||||
if ((0, optional_1.isNothing)(possibleValidatable)) {
|
||||
return false;
|
||||
}
|
||||
// MAINTAINER'S NOTE: We must check for either the existence of a pre-existing incidents
|
||||
// property *or* the ability to add one. Failure to do so will cause
|
||||
// problems for clients that either a) use interfaces to define their
|
||||
// view models; or b) return collections from their service routes.
|
||||
return (Object.prototype.hasOwnProperty.call(possibleValidatable, "$incidents") ||
|
||||
Object.isExtensible(possibleValidatable));
|
||||
}
|
||||
exports.isValidatable = isValidatable;
|
||||
/**
|
||||
* Returns a developer-readable diagnostic message for a given recovery action.
|
||||
* @param action - The recovery action to get the message for.
|
||||
* @returns The message for `action`.
|
||||
*/
|
||||
function messageForRecoveryAction(action) {
|
||||
switch (action) {
|
||||
case "coercedValue":
|
||||
return "Coerced format";
|
||||
case "defaultValue":
|
||||
return "Default value used";
|
||||
case "ignoredValue":
|
||||
return "Ignored value";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
exports.messageForRecoveryAction = messageForRecoveryAction;
|
||||
// region Contexts
|
||||
/**
|
||||
* Shared validation context "stack".
|
||||
*
|
||||
* Because validation incidents propagate up the context stack,
|
||||
* the representation used here is optimized for memory usage.
|
||||
* A more literal representation of this would be a singly linked
|
||||
* list describing a basic stack, but that will produce a large
|
||||
* amount of unnecessary garbage and require copying `incidents`
|
||||
* arrays backwards.
|
||||
*/
|
||||
const contextState = {
|
||||
/// The names of each validation context on the stack.
|
||||
nameStack: Array(),
|
||||
/// All incidents reported so far. Cleared when the
|
||||
/// context stack is emptied.
|
||||
incidents: Array(),
|
||||
// TODO: Removal of this is being tracked here:
|
||||
// <rdar://problem/35015460> Intro Pricing: Un-suppress missing parent 'offers' error when server address missing key
|
||||
/// The paths for incidents we wish to forgo tracking.
|
||||
suppressedIncidentPaths: Array(),
|
||||
};
|
||||
/**
|
||||
* Begin a new validation context with a given name,
|
||||
* pushing it onto the validation context stack.
|
||||
* @param name - The name for the validation context.
|
||||
*/
|
||||
function beginContext(name) {
|
||||
contextState.nameStack.push(name);
|
||||
}
|
||||
exports.beginContext = beginContext;
|
||||
/**
|
||||
* Traverses the validation context stack and collects all of the context names.
|
||||
* @returns The names of all validation contexts on the stack, from oldest to newest.
|
||||
*/
|
||||
function getContextNames() {
|
||||
if (contextState.nameStack.length === 0) {
|
||||
return ["<empty stack>"];
|
||||
}
|
||||
return contextState.nameStack.slice(0);
|
||||
}
|
||||
exports.getContextNames = getContextNames;
|
||||
/**
|
||||
* Ends the current validation context
|
||||
*/
|
||||
function endContext() {
|
||||
if (contextState.nameStack.length === 0) {
|
||||
console.warn("endContext() called without active validation context, ignoring");
|
||||
}
|
||||
contextState.nameStack.pop();
|
||||
}
|
||||
exports.endContext = endContext;
|
||||
/**
|
||||
* Records validation incidents back into an object that implements Validatable.
|
||||
*
|
||||
* Note: This method has a side-effect that the incident queue and name stack are cleared
|
||||
* to prepare for the next thread's invocation.
|
||||
*
|
||||
* @param possibleValidatable - An object that may conform to Validatable, onto which we
|
||||
* want to stash our validation incidents
|
||||
*/
|
||||
function recordValidationIncidents(possibleValidatable) {
|
||||
if (isValidatable(possibleValidatable)) {
|
||||
possibleValidatable.$incidents = contextState.incidents;
|
||||
}
|
||||
contextState.incidents = [];
|
||||
contextState.nameStack = [];
|
||||
contextState.suppressedIncidentPaths = [];
|
||||
}
|
||||
exports.recordValidationIncidents = recordValidationIncidents;
|
||||
/**
|
||||
* Create a transient validation context, and call a function that will return a value.
|
||||
*
|
||||
* Prefer this function over manually calling begin/endContext,
|
||||
* it is exception safe.
|
||||
*
|
||||
* @param name - The name of the context
|
||||
* @param producer - A function that produces a result
|
||||
* @returns <Result> The resulting type
|
||||
*/
|
||||
function context(name, producer, suppressingPath) {
|
||||
let suppressingName = null;
|
||||
if ((0, optional_1.isSome)(suppressingPath) && suppressingPath.length > 0) {
|
||||
suppressingName = name;
|
||||
contextState.suppressedIncidentPaths.push(suppressingPath);
|
||||
}
|
||||
let result;
|
||||
try {
|
||||
beginContext(name);
|
||||
result = producer();
|
||||
}
|
||||
catch (e) {
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (!e.hasThrown) {
|
||||
unexpectedType("defaultValue", "no exception", e.message);
|
||||
e.hasThrown = true;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if (name === suppressingName) {
|
||||
contextState.suppressedIncidentPaths.pop();
|
||||
}
|
||||
endContext();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.context = context;
|
||||
/**
|
||||
* Create a transient validation context, that catches errors and returns null
|
||||
*
|
||||
* @param name - The name of the context
|
||||
* @param producer - A function that produces a result
|
||||
* @param caught - An optional handler to provide a value when an error is caught
|
||||
* @returns <Result> The resulting type
|
||||
*/
|
||||
function catchingContext(name, producer, caught) {
|
||||
let result = null;
|
||||
try {
|
||||
result = context(name, producer);
|
||||
}
|
||||
catch (e) {
|
||||
result = null;
|
||||
if ((0, optional_1.isSome)(caught)) {
|
||||
result = caught(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.catchingContext = catchingContext;
|
||||
/**
|
||||
* Track an incident within the current validation context.
|
||||
* @param incident - An incident object describing the problem.
|
||||
*/
|
||||
function trackIncident(incident) {
|
||||
if (contextState.suppressedIncidentPaths.includes(incident.objectPath)) {
|
||||
return;
|
||||
}
|
||||
contextState.incidents.push(incident);
|
||||
}
|
||||
// endregion
|
||||
// region Nullability
|
||||
/**
|
||||
* Reports a non-fatal error indicating a value was unexpectedly null.
|
||||
* @param recovery - The recovery action taken when the null value was found.
|
||||
* @param expected - The expected type of the value.
|
||||
* @param pathString - A string containing the path to the value on the object which was null.
|
||||
*/
|
||||
function unexpectedNull(recovery, expected, pathString) {
|
||||
const prettyPath = (0, optional_1.isSome)(pathString) && pathString.length > 0 ? pathString : "<this>";
|
||||
trackIncident({
|
||||
type: "nullValue",
|
||||
expected: expected,
|
||||
actual: "null",
|
||||
objectPath: prettyPath,
|
||||
contextNames: getContextNames(),
|
||||
recoveryAction: recovery,
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
exports.unexpectedNull = unexpectedNull;
|
||||
// endregion
|
||||
//# sourceMappingURL=validation.js.map
|
||||
Reference in New Issue
Block a user