summaryrefslogtreecommitdiff
path: root/node_modules/@jet/environment/json
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /node_modules/@jet/environment/json
init commit
Diffstat (limited to 'node_modules/@jet/environment/json')
-rw-r--r--node_modules/@jet/environment/json/index.js19
-rw-r--r--node_modules/@jet/environment/json/reader/coercion.js139
-rw-r--r--node_modules/@jet/environment/json/reader/index.js20
-rw-r--r--node_modules/@jet/environment/json/reader/key-path.js143
-rw-r--r--node_modules/@jet/environment/json/reader/object-cursor.js119
-rw-r--r--node_modules/@jet/environment/json/reader/object-reader.js428
-rw-r--r--node_modules/@jet/environment/json/reader/traverse.js36
-rw-r--r--node_modules/@jet/environment/json/validation.js250
8 files changed, 1154 insertions, 0 deletions
diff --git a/node_modules/@jet/environment/json/index.js b/node_modules/@jet/environment/json/index.js
new file mode 100644
index 0000000..285e4bb
--- /dev/null
+++ b/node_modules/@jet/environment/json/index.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/coercion.js b/node_modules/@jet/environment/json/reader/coercion.js
new file mode 100644
index 0000000..6f84fcf
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/coercion.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/index.js b/node_modules/@jet/environment/json/reader/index.js
new file mode 100644
index 0000000..3f23caa
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/index.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/key-path.js b/node_modules/@jet/environment/json/reader/key-path.js
new file mode 100644
index 0000000..1bb25ff
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/key-path.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/object-cursor.js b/node_modules/@jet/environment/json/reader/object-cursor.js
new file mode 100644
index 0000000..8ac84f2
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/object-cursor.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/object-reader.js b/node_modules/@jet/environment/json/reader/object-reader.js
new file mode 100644
index 0000000..f31a222
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/object-reader.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/reader/traverse.js b/node_modules/@jet/environment/json/reader/traverse.js
new file mode 100644
index 0000000..9f5d1ad
--- /dev/null
+++ b/node_modules/@jet/environment/json/reader/traverse.js
@@ -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 \ No newline at end of file
diff --git a/node_modules/@jet/environment/json/validation.js b/node_modules/@jet/environment/json/validation.js
new file mode 100644
index 0000000..b338c4e
--- /dev/null
+++ b/node_modules/@jet/environment/json/validation.js
@@ -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 \ No newline at end of file