init commit

This commit is contained in:
rxliuli
2025-11-04 05:03:50 +08:00
commit bce557cc2d
1396 changed files with 172991 additions and 0 deletions

18
node_modules/@jet/environment/dependencies/index.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
"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-graph"), exports);
//# sourceMappingURL=index.js.map

106
node_modules/@jet/environment/dependencies/jet-proxy.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
"use strict";
/* eslint-disable @typescript-eslint/no-extraneous-class */
Object.defineProperty(exports, "__esModule", { value: true });
exports.LazyProxyFactory = void 0;
// LazyProxyFactory creates a Proxy which lazily loads its target once needed
class LazyProxyFactory {
static makeProxy(name, lazyProvider) {
const target = new ProxyTarget(lazyProvider);
const handler = {
get: (_, property, __) => {
// Create the lazy dependency if needed
if (target.createRealObjectIfNeeded(name) === undefined) {
// The dependency unexpectedly couldn't be created, so we have nothing to proxy to
return undefined;
}
// Get the property, which could be a function
const res = target.realObject[property];
// If it's a function, bind it to the real object
if (typeof res == "function") {
return res.bind(target.realObject);
}
return res;
},
set: (_, property, value) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.set(target.realObject, property, value, target.realObject);
},
has: (_, property) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.has(target.realObject, property);
},
deleteProperty: (_, property) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.deleteProperty(target.realObject, property);
},
ownKeys: (_) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return [];
}
return Reflect.ownKeys(target.realObject);
},
getOwnPropertyDescriptor: (_, property) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return undefined;
}
return Reflect.getOwnPropertyDescriptor(target.realObject, property);
},
defineProperty: (_, property, descriptor) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.defineProperty(target.realObject, property, descriptor);
},
preventExtensions: (_) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
/* We need to prevent extensions on the actual proxy target
otherwise the Proxy throws a TypeError */
Reflect.preventExtensions(target);
return Reflect.preventExtensions(target.realObject);
},
isExtensible: (_) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.isExtensible(target.realObject);
},
getPrototypeOf: (_) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return null;
}
return Reflect.getPrototypeOf(target.realObject);
},
setPrototypeOf: (_, prototype) => {
if (target.createRealObjectIfNeeded(name) === undefined) {
return false;
}
return Reflect.setPrototypeOf(target.realObject, prototype);
},
};
const res = new Proxy(target, handler);
return res;
}
}
exports.LazyProxyFactory = LazyProxyFactory;
/* The proxy target begins by holding nothing,
and eventually holds the real proxy target once needed */
class ProxyTarget {
constructor(lazyProvider) {
this.lazyProvider = lazyProvider;
}
createRealObjectIfNeeded(name) {
if (this.realObject === undefined) {
this.realObject = this.lazyProvider.lazyDependencyFor(name);
}
return this.realObject;
}
}
//# sourceMappingURL=jet-proxy.js.map

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inject = exports.ObjectGraph = void 0;
const optional_1 = require("../types/optional");
/* eslint-disable no-underscore-dangle */
class ObjectGraph {
constructor(name) {
this._members = {};
this.name = name;
}
adding(type, member) {
const clone = this.clone();
clone._members[type.name] = member;
return clone;
}
removing(type) {
const clone = this.clone();
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete clone._members[type.name];
return clone;
}
optional(type) {
return this._members[type.name];
}
required(type) {
const member = this._members[type.name];
if ((0, optional_1.isNothing)(member)) {
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
const candidates = Object.keys(this._members).sort().join(", ");
throw new Error(`No member with type ${type.name} found in ${this.name}. Candidates ${candidates}`);
}
return member;
}
clone() {
const ctor = this.constructor;
// eslint-disable-next-line new-cap
const clone = new ctor(this.name);
for (const [type, member] of Object.entries(this._members)) {
clone._members[type] = member;
}
return clone;
}
}
exports.ObjectGraph = ObjectGraph;
function inject(type, objectGraph) {
return objectGraph.required(type);
}
exports.inject = inject;
//# sourceMappingURL=object-graph.js.map

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isBaseActionProvider = void 0;
const optional_1 = require("../../types/optional");
/**
* Checks if an object conforms to `BaseActionProvider`.
* @remarks
* This function does not perform any checking for the generic types.
* @param provider - The object that may be an action provider.
*/
function isBaseActionProvider(provider) {
if (typeof provider !== "object") {
return false;
}
return (0, optional_1.isSome)(provider === null || provider === void 0 ? void 0 : provider["actionFor"]);
}
exports.isBaseActionProvider = isBaseActionProvider;
//# sourceMappingURL=action-provider.js.map

View File

@@ -0,0 +1,18 @@
"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("./action-provider"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=dispatchable.js.map

View File

@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntentDispatcher = void 0;
const optional_1 = require("../../types/optional");
const intent_controller_1 = require("./intent-controller");
const net_1 = require("../../types/globals/net");
const types_1 = require("../../types/globals/types");
/**
* A dispatcher is responsible for taking an intent and invoking the controller
* registered to handle the intent's kind.
*
* Adopters can create a project specific dispatcher that composes `IntentDispatcher`
* to add additional functionality.
*
* @example
* ```
* const intent: SomeIntent = {
* $kind: "SomeIntent",
* field: "some value"
* };
* const dispatcher = new IntentDispatcher();
* const promise = dispatcher.dispatch(intent)
* ```
*/
class IntentDispatcher {
constructor() {
this.dispatchableMap = {};
}
/**
* Registers a controller to handle the intent specified in the `$intentKind` property.
* Only one controller can be registered per intent. If register is called multiple times
* with controllers for the same intent kind, the dispatcher will use the last registered
* controller.
* @param intentController - The controller to register.
*/
register(dispatchable) {
if ((0, optional_1.isNothing)(dispatchable.$intentKind)) {
throw new Error(`Dispatcher cannot register a controller without an $intentKind`);
}
if (dispatchable.$intentKind in this.dispatchableMap) {
throw new Error(`Dispatcher already has a controller registered for ${dispatchable.$intentKind}`);
}
this.dispatchableMap[dispatchable.$intentKind] = dispatchable;
}
/**
* Performs an intent using the controller registered to handle the provided intent.
* Returns a rejected promise if no controller is registered to handle the intent.
* @param intent - The intent to perform.
* @param objectGraph - An object graph for dependency injection.
*/
async dispatch(intent, objectGraph) {
if (intent.$kind === "$static") {
// MAINTAINER'S NOTE: We specially handle static intents here to cover two cases:
// 1) static intents created and dispatched wholly inside an app's
// JavaScript business layer;
// 2) static intents created from JavaScript running on an older
// version of native JetEngine that does not support static intents
// where the intent is boxed in an opaque intent in the platform layer.
// Static intents are normally not dispatched across an app's layers.
const data = Reflect.get(intent, "$data");
if ((0, optional_1.isNothing)(data)) {
throw new Error("StaticIntent<R> contains no data");
}
return data;
}
const controller = this.dispatchableMap[intent.$kind];
if ((0, optional_1.isNothing)(controller) || !(0, intent_controller_1.isIntentController)(controller)) {
throw new Error(`No controller registered to handle ${intent.$kind}`);
}
// Replace the `net` dependency with a proxy which includes instrumentation.
const pageIntentInstrumentation = intent.$pageIntentInstrumentation;
const network = objectGraph.optional(types_1.net);
if ((0, optional_1.isSome)(pageIntentInstrumentation) && (0, optional_1.isSome)(network)) {
const proxiedNetwork = new net_1.ProxiedNetwork(network, pageIntentInstrumentation);
const modifiedObjectGraph = objectGraph.adding(types_1.net, proxiedNetwork);
return await controller.perform(intent, modifiedObjectGraph);
}
else {
return await controller.perform(intent, objectGraph);
}
}
/**
* Returns the controller registered for the provided intent.
* @param intent - An intent to find the controller for.
*/
controller(intent) {
return this.dispatchableMap[intent.$kind];
}
/**
* An array of all registered controllers.
*/
get registeredControllers() {
return Object.values(this.dispatchableMap);
}
}
exports.IntentDispatcher = IntentDispatcher;
//# sourceMappingURL=dispatcher.js.map

View File

@@ -0,0 +1,21 @@
"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("./intent-controller"), exports);
__exportStar(require("./dispatcher"), exports);
__exportStar(require("./dispatchable"), exports);
__exportStar(require("./intent"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isIntentController = void 0;
const optional_1 = require("../../types/optional");
function isIntentController(controller) {
if (typeof controller !== "object") {
return false;
}
return (0, optional_1.isSome)(controller === null || controller === void 0 ? void 0 : controller["perform"]);
}
exports.isIntentController = isIntentController;
//# sourceMappingURL=intent-controller.js.map

View File

@@ -0,0 +1,178 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Continuous = exports.makeSidepackedIntent = exports.makeStaticContinuousIntentsOf = exports.makeStaticIntent = void 0;
/**
* Create a static intent.
*
* @param data - The data to wrap.
* @returns A new static intent ready for use.
*/
function makeStaticIntent(data) {
const intent = {
$kind: "$static",
$data: data,
};
return intent;
}
exports.makeStaticIntent = makeStaticIntent;
/**
* Transform an array of data into an array of continuous static intents.
*
* @param elements - An array of data to wrap.
* @returns A new static intent ready for use.
*/
function makeStaticContinuousIntentsOf(elements) {
const intents = new Array();
for (const element of elements) {
intents.push(makeStaticIntent(Continuous.of(element)));
}
return intents;
}
exports.makeStaticContinuousIntentsOf = makeStaticContinuousIntentsOf;
/**
* Create a sidepacked intent.
*
* @param data - The initial value to use before the provided intent is dispatched.
* @param intent - The intent that JetEngine should resolve when rendered.
* @returns A new sidepacked intent ready for use.
*/
function makeSidepackedIntent(initial, intent) {
const sidepackedIntent = {
$kind: "$sidepacked",
$initial: initial,
$intent: intent,
};
return sidepackedIntent;
}
exports.makeSidepackedIntent = makeSidepackedIntent;
// MARK: - Continuous
/**
* A async iterable which allows an intent implementation to vend data
* which changes over time, such as the state of a buy button,
* or database-backed shelves on a page.
*
* Use `Continuous` to specify that an intent embedded in a model,
* or passed to a view, vends data which changes over time instead
* of being calculated once at the time the intent is dispatched.
*
* ```typescript
* export interface Page extends PageModel {
* readonly shelves: Intent<Continuous<Shelf>>[];
* }
* ```
*
* A continuous async iterable can be created with a single element.
* This allows a model built around continuous intents to still cleanly
* represent data which will not change after being displayed the first time.
*
* ```typescript
* const page: Page = {
* pageMetrics: notInstrumented(NotInstrumentedMetricsType.PageMetrics),
* shelves: [
* makeStaticIntent(Continuous.of(Shelf(...))),
* ]
* };
* ```
* A continuous async iterable can be created with another `AsyncIterable`
* as a backing data source:
*
* ```typescript
* async function* timer(
* interval: number,
* start: number = 0,
* limit: number? = undefined,
* ): AsyncIterator<number> {
* for (let next = start; next != limit; next++) {
* yield next;
* await setTimeout(interval);
* }
* }
*
* const countToTen = Continuous.contentsOf(timer(1000, 0, 10));
* ```
*
* A single element continuous async iterable can be stringified to JSON
* as long the element itself has a valid JSON representation. This is
* especially useful when combined with `StaticIntent`.
*
* ```typescript
* const shelfIntent = makeStaticIntent(Continuous.of(Shelf(...)));
* const jsonData = JSON.stringify(shelfIntent);
* ```
*
* __Important__: A continuous async iterable which wraps another
* async iterable cannot be directly JSON stringified.
*/
class Continuous {
// MARK: - Constructors
/**
* Create a continuous async iterable with a single pre-determined element.
*
* @param element - A single element to yield from the new async iterable.
* @returns A new continuous async iterable ready to use.
*/
static of(element) {
return new Continuous(new AsyncJust(element));
}
/**
* Create a continuous async iterable by wrapping an async iterable.
*
* __Important__: A continuous async iterable which wraps another
* async iterable cannot be directly JSON stringified.
*
* @param base - The async iterable to wrap.
* @returns A new continuous async iterable ready to use.
*/
static contentsOf(base) {
return new Continuous(base);
}
/**
* Construct a continuous async iterable by wrapping an async iterable.
*
* @param base - The async iterable to wrap.
*/
constructor(base) {
this.base = base;
// Indicate to native that the true content of this object is in the base field under direct bridging where toJSON is not called.
this["$wrappedField"] = "base";
}
// MARK: - JSON.stringify
toJSON() {
if (this.base instanceof AsyncJust) {
return this.base.toJSON();
}
else {
throw new TypeError("Continuous was not created with a single element");
}
}
// MARK: - AsyncIterable
async *[Symbol.asyncIterator]() {
yield* this.base;
}
}
exports.Continuous = Continuous;
/**
* An asynchronous iterable which yields a single element.
*/
class AsyncJust {
// MARK: - Constructors
/**
* Construct an async iterable containing just the given element.
*
* @param element - The only element to yield.
*/
constructor(element) {
this.element = element;
// Indicate to native that the true content of this object is in the element field under direct bridging where toJSON is not called.
this["$wrappedField"] = "element";
}
// MARK: - JSON.stringify
toJSON() {
return this.element;
}
// MARK: - AsyncIterable
async *[Symbol.asyncIterator]() {
yield this.element;
}
}
//# sourceMappingURL=intent.js.map

19
node_modules/@jet/environment/dispatching/index.js generated vendored Normal file
View 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("./base"), exports);
__exportStar(require("./actions"), exports);
//# sourceMappingURL=index.js.map

22
node_modules/@jet/environment/index.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
"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("./models"), exports);
__exportStar(require("./types"), exports);
__exportStar(require("./json"), exports);
__exportStar(require("./metrics"), exports);
__exportStar(require("./util"), exports);
//# sourceMappingURL=index.js.map

19
node_modules/@jet/environment/json/index.js generated vendored Normal file
View 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
View 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
View 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
View 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

View 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

View 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
View 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
View 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

456
node_modules/@jet/environment/metrics/builder.js generated vendored Normal file
View File

@@ -0,0 +1,456 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMetricsMediaClickData = exports.createMetricsMediaData = exports.createMetricsImpressionsData = exports.createMetricsSearchData = exports.createMetricsPageData = exports.createMetricsBackClickData = exports.createMetricsClickData = exports.MediaClickEventBuilder = exports.MediaEventBuilder = exports.ImpressionsEventBuilder = exports.SearchEventBuilder = exports.PageEventBuilder = exports.BackClickEventBuilder = exports.ClickEventBuilder = exports.EventBuilder = void 0;
const optional_1 = require("../types/optional");
// region Builders
/**
* Base event builder.
*/
class EventBuilder {
/**
* Create base event builder with metrics configuration.
*
* @param configuration - Metrics configuration used to build metrics events.
*/
constructor(configuration) {
this.configuration = configuration;
this.eventFields = {};
}
/**
* Updates event builder with given event fields.
* @param eventFields - The events fields to update in builder.
* @returns Event builder with updated event fields.
*/
withEventFields(eventFields) {
this.eventFields = eventFields;
return this;
}
/**
* Updates event builder with given configuration.
* @param configuration - The configuration to update in builder.
* @returns Event builder with updated configuration.
*/
withConfiguration(configuration) {
this.configuration = configuration;
return this;
}
/**
* Updates event builder with given default topic.
* @param topic - The default topic to update in builder.
* @returns Event builder with updated default topic.
*/
withDefaultTopic(topic) {
this.configuration = {
...this.configuration,
defaultTopic: topic,
};
return this;
}
/**
* Updates event builder with given include fields requests.
* @param includeRequests - The include fields requests to update in builder.
* @returns Event builder with updated include fields requests.
*/
withDefaultIncludeRequests(includeRequests) {
this.configuration = {
...this.configuration,
defaultIncludeRequests: includeRequests,
};
return this;
}
/**
* Updates event builder with given exclude fields requests.
* @param excludeRequests - The exclude fields requests to update in builder.
* @returns Event builder with updated exclude fields requests.
*/
withDefaultExcludeRequests(excludeRequests) {
this.configuration = {
...this.configuration,
defaultExcludeRequests: excludeRequests,
};
return this;
}
/**
* Updates event builder with given flush behavior.
* @param shouldFlush - The flush behavior to update in builder.
* @returns Event builder with updated flush behavior.
*/
withShouldFlush(shouldFlush) {
this.configuration = {
...this.configuration,
shouldFlush: shouldFlush,
};
return this;
}
}
exports.EventBuilder = EventBuilder;
/**
* Builder for click events.
*/
class ClickEventBuilder extends EventBuilder {
/**
* Create click metrics event builder with all required properties.
*
* @param options - Object containing options required to create the builder.
*
* Options:
* - targetId - Target ID used for building events.
* - targetType - Target type used for building events.
* - configuration - Metrics configuration used to build metrics events.
*/
constructor(options) {
super(options.configuration);
this.targetId = options.targetId;
this.targetType = options.targetType;
}
/**
* Updates event builder with given target ID.
* @param targetId - The target ID to update in builder.
* @returns Event builder with updated target ID.
*/
withTargetId(targetId) {
this.targetId = targetId;
return this;
}
/**
* Updates event builder with given target type.
* @param targetType - The target type to update in builder.
* @returns Event builder with updated target type.
*/
withTargetType(targetType) {
this.targetType = targetType;
return this;
}
build() {
return createMetricsClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
}
}
exports.ClickEventBuilder = ClickEventBuilder;
/**
* Builder for back click events.
*/
class BackClickEventBuilder extends EventBuilder {
build() {
return createMetricsBackClickData(this.eventFields, this.configuration);
}
}
exports.BackClickEventBuilder = BackClickEventBuilder;
/**
* Builder for page events.
*/
class PageEventBuilder extends EventBuilder {
/**
* Create page metrics event builder with all required properties.
*
* @param configuration - Metrics configuration used to build metrics events.
*/
constructor(configuration) {
super(configuration);
this.timingMetrics = {};
}
/**
* Updates event builder with given fetch timing metrics.
* @param timingMetrics - The fetch timing metrics to update in builder.
* @returns Event builder with updated fetch timing metrics.
*/
withTimingMetrics(timingMetrics) {
this.timingMetrics = timingMetrics;
return this;
}
build() {
return createMetricsPageData(this.eventFields, this.timingMetrics, this.configuration);
}
}
exports.PageEventBuilder = PageEventBuilder;
/**
* Builder for search metrics events.
*/
class SearchEventBuilder extends EventBuilder {
/**
* Create search metrics event builder with all required properties.
*
* @param options - Object containing options required to create the builder.
*
* Options:
* - term - Search term used to build metrics events.
* - targetType - Target type used to build metrics events.
* - actionType - Action type used to build metrics events.
* - configuration - Metrics configuration used to build metrics events.
*/
constructor(options) {
super(options.configuration);
this.term = options.term;
this.targetType = options.targetType;
this.actionType = options.actionType;
this.actionUrl = null;
}
/**
* Updates event builder with given search term.
* @param term - The search term to update in builder.
* @returns Event builder with updated search term.
*/
withTerm(term) {
this.term = term;
return this;
}
/**
* Updates event builder with given target type.
* @param targetType - The target type to update in builder.
* @returns Event builder with updated target type.
*/
withTargetType(targetType) {
this.targetType = targetType;
return this;
}
/**
* Updates event builder with given action type.
* @param actionType - The action type to update in builder.
* @returns Event builder with updated action type.
*/
withActionType(actionType) {
this.actionType = actionType;
return this;
}
/**
* Updates event builder with given action URL.
* @param actionUrl - The action URL to update in builder.
* @returns Event builder with updated action URL.
*/
withActionUrl(actionUrl) {
this.actionUrl = actionUrl;
return this;
}
build() {
return createMetricsSearchData(this.term, this.targetType, this.actionType, this.actionUrl, this.eventFields, this.configuration);
}
}
exports.SearchEventBuilder = SearchEventBuilder;
/**
* Builder for impressions events.
*/
class ImpressionsEventBuilder extends EventBuilder {
constructor() {
super(...arguments);
/**
* Impressions event version.
*/
this.impressionsEventVersion = 4;
}
/**
* Updates event builder with given impressions event version.
* @param version - The impressions event version to update in builder.
* @returns Event builder with updated impressions event version.
*/
withImpressionsEventVersion(version) {
this.impressionsEventVersion = version;
return this;
}
build() {
return createMetricsImpressionsData(this.eventFields, this.configuration, this.impressionsEventVersion);
}
}
exports.ImpressionsEventBuilder = ImpressionsEventBuilder;
/**
* Builder for media events.
*/
class MediaEventBuilder extends EventBuilder {
build() {
return createMetricsMediaData(this.eventFields, this.configuration);
}
}
exports.MediaEventBuilder = MediaEventBuilder;
/**
* Builder for media click events.
*/
class MediaClickEventBuilder extends EventBuilder {
/**
* Create media click event builder with all required properties.
*
* @param options - Object containing options required to create the builder.
*
* Options:
* - targetId - Target ID used for building events.
* - targetType - Target type used to build metrics events.
* - configuration - Metrics configuration used to build metrics events.
*/
constructor(options) {
super(options.configuration);
this.targetId = options.targetId;
this.targetType = options.targetType;
}
/**
* Updates event builder with given target ID.
* @param targetId - The target ID to update in builder.
* @returns Event builder with updated target ID.
*/
withTargetId(targetId) {
this.targetId = targetId;
return this;
}
/**
* Updates event builder with given target type.
* @param targetType - The target type to update in builder.
* @returns Event builder with updated target type.
*/
withTargetType(targetType) {
this.targetType = targetType;
return this;
}
build() {
return createMetricsMediaClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
}
}
exports.MediaClickEventBuilder = MediaClickEventBuilder;
// region Metrics Data
/**
* Create metrics data for the click event.
*
* @param targetId - The ID of the click event target.
* @param targetType - The type of the click target.
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsClickData(targetId, targetType, eventFields, configuration) {
const eventType = "click" /* MetricsEventType.click */;
const fields = {
...eventFields,
eventType: eventType,
targetType: targetType,
targetId: targetId,
};
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsClickData = createMetricsClickData;
/**
* Create metrics data for the Back button click event.
*
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsBackClickData(eventFields, configuration) {
const fields = {
...eventFields,
actionType: "back",
};
return createMetricsClickData("back", "button" /* MetricsClickTargetType.button */, fields, configuration);
}
exports.createMetricsBackClickData = createMetricsBackClickData;
/**
* Create metrics data for the page event.
* @param eventFields - Event fields to create metrics data from.
* @param timingMetrics - The timing metrics for page data fetching.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsPageData(eventFields, timingMetrics, configuration) {
const eventType = "page" /* MetricsEventType.page */;
const fields = {
...eventFields,
eventType: eventType,
...timingMetrics,
};
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsPageData = createMetricsPageData;
/**
* Create metrics data for search event.
*
* @param term - The search term.
* @param target - The type of the acton target.
* @param actionType - The type of the action.
* @param actionUrl - An optional action URL.
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsSearchData(term, targetType, actionType, actionUrl, eventFields, configuration) {
const eventType = "search" /* MetricsEventType.search */;
const fields = {
...eventFields,
eventType: eventType,
term: term,
targetType: targetType,
actionType: actionType,
};
if ((0, optional_1.isSome)(actionUrl)) {
// actionUrl is defined for `hints` but not for searches fired from elsewhere.
fields["actionUrl"] = actionUrl;
}
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsSearchData = createMetricsSearchData;
/**
* Create metrics data for impressions event.
*
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
* @param impressionsEventVersion - The version of the impressions event.
*/
function createMetricsImpressionsData(eventFields, configuration, impressionsEventVersion = 4) {
const eventType = "impressions" /* MetricsEventType.impressions */;
const fields = {
...eventFields,
eventType: eventType,
impressionQueue: "data-metrics",
eventVersion: impressionsEventVersion,
};
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsImpressionsData = createMetricsImpressionsData;
/**
* Create metrics data for media event.
*
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsMediaData(eventFields, configuration) {
const eventType = "media" /* MetricsEventType.media */;
const fields = {
...eventFields,
eventType: eventType,
};
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsMediaData = createMetricsMediaData;
/**
* Create metrics data for media event.
*
* @param targetId - The ID of the click target.
* @param targetType - The type of the click target.
* @param eventFields - Event fields to create metrics data from.
* @param configuration - Metrics configuration used to create metrics data.
*/
function createMetricsMediaClickData(targetId, targetType, eventFields, configuration) {
const eventType = "click" /* MetricsEventType.click */;
const fields = {
...eventFields,
eventType: eventType,
targetType: targetType,
targetId: targetId,
};
return createMetricsData(fields, configuration, eventType);
}
exports.createMetricsMediaClickData = createMetricsMediaClickData;
// endregion
// region Helpers
function createMetricsData(fields, configuration, eventType) {
return {
fields: fields,
includingFields: configuration.defaultIncludeRequests[eventType],
excludingFields: configuration.defaultExcludeRequests[eventType],
topic: topicFromEventFields(fields, configuration.defaultTopic),
shouldFlush: (0, optional_1.isSome)(configuration.shouldFlush) ? configuration.shouldFlush(fields) : false,
};
}
/**
* Returns event topic for the given event fields.
* @param eventFields - Event fields.
* @param defaultTopic - An optional default topic to use if event fields doesn't have one.
*/
function topicFromEventFields(eventFields, defaultTopic) {
const topic = eventFields["topic"];
if ((0, optional_1.isSome)(topic)) {
return topic;
}
return defaultTopic;
}
// endregion
//# sourceMappingURL=builder.js.map

46
node_modules/@jet/environment/metrics/cookies.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cookieValueForKey = exports.cookiesOf = void 0;
const optional_1 = require("../types/optional");
/**
* Iterate the cookies contained in a string.
*
* @param cookie - A string containing zero or more cookies.
*/
function* cookiesOf(cookie) {
if ((0, optional_1.isNothing)(cookie)) {
return;
}
const rawEntries = cookie.split(";");
for (const rawEntry of rawEntries) {
const keyEndIndex = rawEntry.indexOf("=");
if (keyEndIndex === -1) {
// If there's no splitter, treat the whole raw
// entry as the key and provide an empty value.
const key = decodeURIComponent(rawEntry).trim();
yield { key, value: "" };
}
else {
const key = decodeURIComponent(rawEntry.substring(0, keyEndIndex)).trim();
const value = decodeURIComponent(rawEntry.substring(keyEndIndex + 1)).trim();
yield { key, value };
}
}
}
exports.cookiesOf = cookiesOf;
/**
* Returns value of the cookie with the given key or `null` if there's no such cookie.
*
* @param cookies - Cookies.
* @param key - The key to return cookie value for.
*/
function cookieValueForKey(cookies, key) {
for (const cookie of cookies) {
if (cookie.key === key) {
return cookie.value;
}
}
return null;
}
exports.cookieValueForKey = cookieValueForKey;
//# sourceMappingURL=cookies.js.map

155
node_modules/@jet/environment/metrics/event-linter.js generated vendored Normal file
View File

@@ -0,0 +1,155 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventLinter = void 0;
const object_reader_1 = require("../json/reader/object-reader");
const optional_1 = require("../types/optional");
const numerics = require("./helpers/numerics");
/**
* A type which applies common business rules to metrics fields
* and generates events which are ready for posting to Figaro.
*
* The common business rules are:
* - Add base event fields provided by linter configuration provider object
* - Set clientBuiltType and resourceRevNum fields based on EventLinterEnvironment object values
* - Set xpSendMethod field to "jet-js"
* - Combine pageType and pageId using compound separator provided by linter configuration provider
* and set result to "page" field.
* - Apply event field de-resolution rules provided by linter configuration provider object
* - Set the "position" field for events of "media" type.
*/
class EventLinter {
/**
* Create an event linter.
*
* @param options - The options which specify various behaviors of the new linter.
* This object will be frozen.
*/
constructor(options) {
this.options = Object.freeze(options);
}
// MARK: Public Properties
/**
* Topic to use if an event fields blob does not specify one.
*/
get defaultTopic() {
return this.options.defaultTopic;
}
// MARK: Utilities
/**
* Reduce the accuracy of fields in a blob according to
* a given array of rules provided by linter configuration object.
*
* @param eventFields - The fields of an event to reduce the accuracy of.
* @param rules - An array of de-resolution rules to apply to event fields.
*/
applyDeResolutionRules(eventFields, rules) {
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
for (const rule of rules) {
const value = eventFieldsReader.asNumber(rule.fieldName);
if ((0, optional_1.isNothing)(value)) {
continue;
}
let magnitude = rule.magnitude;
if ((0, optional_1.isNothing)(magnitude)) {
magnitude = 1024 * 1024;
}
let significantDigits = rule.significantDigits;
if ((0, optional_1.isNothing)(significantDigits)) {
significantDigits = 2;
}
if (magnitude <= 0.0 || significantDigits < 0.0) {
// This is the failure mode from MetricsKit.
eventFields[rule.fieldName] = Number.NaN;
continue;
}
const scaledValue = value / magnitude;
eventFields[rule.fieldName] = numerics.reduceSignificantDigits(scaledValue, significantDigits);
}
}
// MARK: Rules
/**
* Apply the rules which are universal to all metrics events
* to a given metrics fields linter.
*
* @param eventFields - The fields which will be used to construct a built event.
* @param topic - The topic the built event will be submitted to.
*/
decorateCommonEventFields(eventFields, topic) {
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
const configurationProvider = this.options.configuration;
// - Base metrics fields.
const baseFields = configurationProvider.baseFields(topic);
if ((0, optional_1.isSome)(baseFields)) {
Object.assign(eventFields, baseFields);
}
// - Universal basic fields.
eventFields["clientBuildType"] = this.options.environment.buildType;
eventFields["resourceRevNum"] = this.options.environment.jsVersion;
eventFields["xpSendMethod"] = "jet-js";
// - Page.
const pageType = eventFieldsReader.asString("pageType");
const pageId = eventFieldsReader.asString("pageId");
if ((0, optional_1.isSome)(pageType) && (0, optional_1.isSome)(pageId) && (0, optional_1.isNothing)(eventFields["page"])) {
const bagValue = configurationProvider.compoundSeparator(topic);
const separator = (0, optional_1.isSome)(bagValue) ? (0, optional_1.unwrapOptional)(bagValue) : "_";
eventFields["page"] = `${pageType}${separator}${pageId}`;
}
// - Field value resolution reduction.
const rules = configurationProvider.deResolutionRules(topic);
this.applyDeResolutionRules(eventFields, rules);
}
/**
* Apply the rules specific to the `media` event.
*
* @param eventFields - The fields which will be used to construct a built event.
*/
decorateMediaEventEvents(eventFields) {
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
const position = eventFieldsReader.asNumber("position");
if ((0, optional_1.isSome)(position)) {
eventFields["position"] = Math.round(position);
}
}
// MARK: Decorating Event Fields
/**
* Lint metrics event fields by applying the common business rules to a given fields blob.
*
* @remarks
*
* Note: A deep copy of event fields is created by linter using `JSON.parse(JSON.stringify(eventFields))`.
* The original event fields are not modified.
*
* @param eventFields - The fields to decorate.
* @param context - The additional event linter context to be passed to all
* event linter rules. This is a free-form object so clients can pass custom
* context information.
* @returns Decorated fields ready for creating a metrics event.
*/
lint(eventFields, context = {}) {
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
const eventType = eventFieldsReader.asString("eventType");
if (this.options.isLoggingEnabled) {
console.log(`Building event for event type: ${eventType !== null && eventType !== void 0 ? eventType : "<null>"}`);
}
// Make sure we have a deep copy of an object.
const decoratedEventFields = JSON.parse(JSON.stringify(eventFields));
const value = eventFieldsReader.asString("topic");
const topic = (0, optional_1.isSome)(value) ? (0, optional_1.unwrapOptional)(value) : this.options.defaultTopic;
this.decorateCommonEventFields(decoratedEventFields, topic);
switch (eventType) {
case "media" /* MetricsEventType.media */:
this.decorateMediaEventEvents(decoratedEventFields);
break;
default:
break;
}
for (const rule of this.options.rules) {
rule.apply(decoratedEventFields, context);
}
return {
fields: decoratedEventFields,
};
}
}
exports.EventLinter = EventLinter;
//# sourceMappingURL=event-linter.js.map

View File

@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchTimingMetricsBuilderType = exports.FetchTimingMetricsBuilder = void 0;
const optional_1 = require("../types/optional");
const metatype_1 = require("../util/metatype");
const promise_1 = require("../util/promise");
/** Object to collect `FetchTimingMetrics`, in order to decorate a model object with these metrics. */
class FetchTimingMetricsBuilder {
constructor() {
this.metrics = [];
}
/**
* Collects the timing metrics from the response,
* then execute code for parsing while capturing timing points around it,
* adding those parse times to the first timing metrics.
*/
measureParsing(response, body) {
const responseTimingMetrics = response.metrics.length > 0 ? [...response.metrics] : [];
const parseStartTime = Date.now();
const result = body(response);
const parseEndTime = Date.now();
// MAINTAINERS NOTE:
// Follows app store approach to add additional timing points to the first item.
// This may not be strictly correct, and we should revisit this later.
if (responseTimingMetrics.length > 0) {
responseTimingMetrics[0].parseStartTime = parseStartTime;
responseTimingMetrics[0].parseEndTime = parseEndTime;
}
this.metrics.push(...responseTimingMetrics);
return result;
}
/**
* Execute code for model construction while capturing timing points around it,
* adding those model construction times to the first timing metrics.
*
* Use this method when model construction is a synchronous operation.
* Use `measureModelConstructionAsync()` when model construction is an asynchronous operation.
*/
measureModelConstruction(body) {
const buildModelStartTime = Date.now();
const result = body();
const buildModelEndTime = Date.now();
this.saveModelConstructionTimes(buildModelStartTime, buildModelEndTime);
return result;
}
/**
* Execute and await code for an asynchronous model construction operation while capturing timing points around it,
* adding those model construction times to the first timing metrics.
*
* Use this method when model construction is an asynchronous operation.
* Use `measureModelConstruction()` when model construction is a synchronous operation.
*/
async measureModelConstructionAsync(body) {
const buildModelStartTime = Date.now();
const result = await body();
const buildModelEndTime = Date.now();
this.saveModelConstructionTimes(buildModelStartTime, buildModelEndTime);
return result;
}
saveModelConstructionTimes(startTime, endTime) {
// MAINTAINERS NOTE:
// Follows app store approach to add additional timing points to the first item.
// This may not be strictly correct, and we should revisit this later.
if (this.metrics.length > 0) {
this.metrics[0].modelConstructionStartTime = startTime;
this.metrics[0].modelConstructionEndTime = endTime;
}
else {
this.metrics.push({
modelConstructionStartTime: startTime,
modelConstructionEndTime: endTime,
});
}
}
/** Add the recorded `FetchTimingMetrics` as an additional property on the model. */
decorate(model) {
if ((0, optional_1.isNothing)(model)) {
throw new Error("Cannot decorate null or undefined");
}
if (typeof model !== "object") {
throw new Error("View model to decorate must be an object");
}
if ((0, promise_1.isPromise)(model)) {
// TypeScript compiler may be able to enforce this at compile time.
// A newer version of TypeScript which supports `Awaited` type may help.
throw new Error("Cannot decorate a Promise object");
}
if (this.metrics.length > 0) {
model["$networkPerformance"] = this.metrics;
}
}
}
exports.FetchTimingMetricsBuilder = FetchTimingMetricsBuilder;
/** Metatype for the `FetchTimingMetricsBuilder`, for adding to an object graph. */
exports.fetchTimingMetricsBuilderType = (0, metatype_1.makeMetatype)("jet-engine:fetchTimingMetricsBuilder");
//# sourceMappingURL=fetch-timing-metrics-builder.js.map

21
node_modules/@jet/environment/metrics/helpers/index.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
"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("./location"), exports);
__exportStar(require("./models"), exports);
__exportStar(require("./numerics"), exports);
__exportStar(require("./util"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,213 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetricsLocationTracker = void 0;
const validation = require("../../json/validation");
const optional_1 = require("../../types/optional");
const metricsUtil = require("./util");
/**
* A type describing metrics location tracker.
*
* The tracker manages stack of metrics location items.
*/
class MetricsLocationTracker {
// endregion
// region Initialization
/**
* Create new metrics location tracker with all required attributes.
* @param rootPosition - Current root position of the tracker.
* @param locations - Array of metrics location to track.
*/
constructor(rootPosition = 0, locations = []) {
this.rootPosition = rootPosition;
this.locationStack = locations.map((location) => new MetricsLocationStackItem(location));
}
// endregion
// region Location Stack Management
/**
* Check whether location stack is empty or not.
*/
get isEmpty() {
return this.locationStack.length === 0;
}
/**
* Push new location to location tracker's stack.
* @param location - Location to push to stack.
*/
pushLocation(location) {
this.locationStack.push(new MetricsLocationStackItem(location));
}
/**
* Pop location from location tracker's stack.
*/
popLocation() {
var _a;
if (this.locationStack.length === 0) {
validation.unexpectedType("ignoredValue", "non-empty location stack", "empty location stack");
return null;
}
return (_a = this.locationStack.pop()) === null || _a === void 0 ? void 0 : _a.location;
}
/**
* Returns tracker's current position.
*/
get currentPosition() {
const stackItem = this.lastStackItem;
if ((0, optional_1.isSome)(stackItem)) {
return stackItem.position;
}
else {
return this.rootPosition;
}
}
/**
* Set current position of tracker.
* This is necessary when large today modules are broken apart into multipart shelves.
* We need to preserve the position of content within server-response, not our logical shelves.
* @param position - Position to set to.
*/
setCurrentPosition(position) {
const stackItem = this.lastStackItem;
if ((0, optional_1.isSome)(stackItem)) {
stackItem.position = position;
}
else {
this.rootPosition = position;
}
}
/**
* Advance tracker's position.
*/
nextPosition() {
const stackItem = this.lastStackItem;
if ((0, optional_1.isSome)(stackItem)) {
stackItem.position += 1;
}
else {
this.rootPosition += 1;
}
}
/**
* Convert location tracker's stack items to array of metric location objects.
*/
get stackItemsToLocations() {
return this.locationStack.map((stackItem) => stackItem.location);
}
/**
* Returns last stack item in location stack or `null` if stack is empty.
*/
get lastStackItem() {
const length = this.locationStack.length;
if (length === 0) {
return null;
}
return this.locationStack[length - 1];
}
// endregion
// region Adding Location
/**
* Create new basic location and add it to existing locations of the location tracker
* and return resulting array of locations.
* @param options - Base metrics options which include location tracker to get current locations from.
* @param title - New location title.
*/
static locationsByAddingBasicLocation(options, title) {
const locations = options.locationTracker.stackItemsToLocations;
locations.push(MetricsLocationTracker.buildBasicLocation(options, title));
return locations;
}
/**
* Create new content location and add it to existing locations of the location tracker
* and return resulting array of locations.
* @param options - Content metrics options which include location tracker to get current locations from.
* @param title - New location title.
*/
static locationsByAddingContentLocation(options, title) {
const locations = options.locationTracker.stackItemsToLocations;
locations.push(MetricsLocationTracker.buildContentLocation(options, title));
return locations;
}
// endregion
// region Metrics Options
/**
* Create new basic location from base metrics options
* and push it to the stack of location tracker included into options.
* @param options - Base metrics options which include location tracker to push new location to.
* @param title - Location title.
*/
static pushBasicLocation(options, title) {
options.locationTracker.pushLocation(MetricsLocationTracker.buildBasicLocation(options, title));
}
/**
* Create new content location from content metrics options
* and push it to the stack of location tracker included into options.
* @param options - Content metrics options which include location tracker to push new location to.
* @param title - Location title.
*/
static pushContentLocation(options, title) {
options.locationTracker.pushLocation(MetricsLocationTracker.buildContentLocation(options, title));
}
/**
* Pop last location from location tracker contained in metrics options.
* @param options - Metrics options containing the location tracker.
*/
static popLocation(options) {
return options.locationTracker.popLocation();
}
// endregion
// region Location Builders
static buildBasicLocation(options, title) {
let name = title;
if ((0, optional_1.isSome)(options.anonymizationOptions)) {
name = options.anonymizationOptions.anonymizationString;
}
const location = {
locationPosition: options.locationTracker.currentPosition,
locationType: metricsUtil.targetTypeForMetricsOptions(options),
name: name,
};
if ((0, optional_1.isSome)(options.recoMetricsData)) {
Object.assign(location, options.recoMetricsData);
}
return location;
}
static buildContentLocation(options, title) {
const base = MetricsLocationTracker.buildBasicLocation(options, title);
// Use the location tracker if there is no id override.
if ((0, optional_1.isNothing)(options.id)) {
base.idType = "sequential" /* MetricsIDType.sequential */;
base.id = options.locationTracker.currentPosition.toString();
}
else {
// If there is a id specified, use that.
base.idType = metricsUtil.idTypeForMetricsOptions(options);
let id = options.id;
if ((0, optional_1.isSome)(options.anonymizationOptions)) {
id = options.anonymizationOptions.anonymizationString;
}
base.id = id;
}
if ((0, optional_1.isSome)(options.fcKind)) {
base.fcKind = options.fcKind;
}
if ((0, optional_1.isSome)(options.displayStyle)) {
base.displayStyle = options.displayStyle;
}
return base;
}
}
exports.MetricsLocationTracker = MetricsLocationTracker;
/**
* A type describing a metrics location item in location tracking stack.
*/
class MetricsLocationStackItem {
/**
* Create new metrics location stack item with all required attributes.
* @param location - The metrics location associated with this item.
* @param position - The position of the item.
*/
constructor(location, position = 0) {
this.location = location;
this.position = position;
}
}
//# sourceMappingURL=location.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=models.js.map

View File

@@ -0,0 +1,23 @@
"use strict";
/**
* Number related helper functions for metrics.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduceSignificantDigits = void 0;
/**
* Reduce significant figures of `value` by `significantDigits`.
* @param value - Value to reduce precision of.
* @param significantDigits - Number of significant digits to reduce precision by.
*
* Examples:
* value = 123.5, significantDigits = 0, result = 120 (no significant digit reduced)
* value = 123.5, significantDigits = 1, result = 120 (1 significant digit reduced)
* value = 123.5, significantDigits = 2, result = 100 (2 significant digit reduced)
*/
function reduceSignificantDigits(value, significantDigits) {
const roundFactor = Math.pow(10.0, significantDigits);
const roundingFunction = value > 0.0 ? Math.floor : Math.ceil;
return roundingFunction(value / roundFactor) * roundFactor;
}
exports.reduceSignificantDigits = reduceSignificantDigits;
//# sourceMappingURL=numerics.js.map

76
node_modules/@jet/environment/metrics/helpers/util.js generated vendored Normal file
View File

@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchTermFromRefURL = exports.extractSiriRefAppFromRefURL = exports.idTypeForMetricsOptions = exports.targetTypeForMetricsOptions = void 0;
const optional_1 = require("../../types/optional");
const urls = require("../../util/urls");
/**
* Returns click target type for given base metrics options.
* @param options - Base metrics options to derive click target type for.
*/
function targetTypeForMetricsOptions(options) {
let type = options.targetType;
if ((0, optional_1.isNothing)(type)) {
type = "lockup" /* MetricsClickTargetType.lockup */;
}
return type;
}
exports.targetTypeForMetricsOptions = targetTypeForMetricsOptions;
/**
* Returns metrics ID type for given content metrics options.
* @param options - Content metrics options to derive metrics ID type for.
*/
function idTypeForMetricsOptions(options) {
let type = options.idType;
if ((0, optional_1.isNothing)(type)) {
type = "its_id" /* MetricsIDType.itsID */;
}
return type;
}
exports.idTypeForMetricsOptions = idTypeForMetricsOptions;
/**
* Extract and return Siri reference app from URL string.
* @param refUrlString - URL string.
* @returns An optional Siri reference app string.
*/
function extractSiriRefAppFromRefURL(urlString) {
const refUrl = new urls.URL(urlString);
if ((0, optional_1.isNothing)(refUrl.query)) {
return null;
}
let extractedRefApp = null;
for (const key of Object.keys(refUrl.query)) {
if (key === "referrer") {
if (refUrl.query[key] === "siri") {
extractedRefApp = "com.apple.siri";
}
break;
}
}
return extractedRefApp;
}
exports.extractSiriRefAppFromRefURL = extractSiriRefAppFromRefURL;
/**
* Extract and return search term from reference URL string.
* @param refUrlString - Reference URL string.
* @returns An optional search term string.
*/
function searchTermFromRefURL(refUrlString) {
const refUrl = new urls.URL(refUrlString);
const queryItems = refUrl.query;
if ((0, optional_1.isNothing)(queryItems)) {
return null;
}
const searchTerm = queryItems["term"];
const path = refUrl.pathname;
if ((0, optional_1.isNothing)(searchTerm) || (0, optional_1.isNothing)(path)) {
return null;
}
if (!path.endsWith("/search")) {
return null;
}
// the url object has already url-decoded this query parameter
const plainTerm = searchTerm;
return plainTerm;
}
exports.searchTermFromRefURL = searchTermFromRefURL;
//# sourceMappingURL=util.js.map

23
node_modules/@jet/environment/metrics/index.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
"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("./builder"), exports);
__exportStar(require("./cookies"), exports);
__exportStar(require("./event-linter"), exports);
__exportStar(require("./fetch-timing-metrics-builder"), exports);
__exportStar(require("./helpers"), exports);
__exportStar(require("./parse-and-build-model"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseAndBuildModel = exports.requestAndBuildModel = void 0;
const dependencies_1 = require("../dependencies");
const optional_1 = require("../types/optional");
const fetch_timing_metrics_builder_1 = require("./fetch-timing-metrics-builder");
/**
* Returns an object graph guaranteed to have a `FetchTimingMetricsBuilder` object.
*
* If a `FetchTimingMetricsBuilder` already exists, the same object graph is returned.
*
* If it doesn't exist, a new object graph is returned, which has a new `FetchTimingMetricsBuilder` added to it.
*/
function ensureFetchTimingMetricsBuilderExists(objectGraph, errorIfNotFound) {
const optionalBuilder = objectGraph.optional(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType);
if ((0, optional_1.isSome)(optionalBuilder)) {
return objectGraph;
}
else {
if (errorIfNotFound) {
throw new Error("Could not find FetchTimingMetricsBuilder in the object graph");
}
return objectGraph.adding(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, new fetch_timing_metrics_builder_1.FetchTimingMetricsBuilder());
}
}
/**
* Orchestrates the flow to make a network request and then build the view model,
* capturing timing points around the model building step, and then
* adding performance metrics data to the final result.
*
* **Important**
*
* When using this method, it is the responsibility of the `requester` to instrument the network times and parsing times
* using a `FetchTimingMetricsBuilder` which is in the object graph.
*
* A simplified implementation of a requester function might look like this:
```
import * as types from "@jet/environment/types/globals/types"
import { fetchTimingMetricsBuilderType } from "@jet/environment/metrics";
export async function requestFromAPI(request: FetchRequest, objectGraph: ObjectGraph): Promise<MyParsedModel> {
const net = inject(types.net, objectGraph);
const fetchResponse = await net.fetch(request);
const fetchTimingMetricsBuilder = inject(fetchTimingMetricsBuilderType, objectGraph);
return fetchTimingMetricsBuilder.measureParsing(fetchResponse, (response) => {
const parsedBody = JSON.parse(response.body);
return new MyParsedModel(parsedBody);
});
}
```
* This approach supports a common pattern in our adopters in which the code that coordinates the fetch of the network request
* is tightly coupled to the code which parses the response.
*
* For an alternative approach which includes orchestrating the parsing step, use `parseAndBuildModel()`.
*
* @param request - The request object to pass to the `requester` function.
* @param objectGraph - Object graph that can be used to pass data to the `requester` and `modelBuilder` steps.
* The object graph must contain a `FetchTimingMetricsBuilder` that the `requester` will use to collect network times and parsing times.
* @param requester - A function which can make a network request, and return a `ResponseType` which can be used by the `modelBuilder`.
* @param modelBuilder - A step that takes the output of the `requester` step, and builds the view model.
* This parameter supports both synchronous and asynchronous functions.
* @returns The view model.
*/
async function requestAndBuildModel(request, objectGraph, requester, modelBuilder) {
const modifiedObjectGraph = ensureFetchTimingMetricsBuilderExists(objectGraph, true);
const response = await requester(request, modifiedObjectGraph);
return await constructAndDecorateModel(response, modifiedObjectGraph, modelBuilder);
}
exports.requestAndBuildModel = requestAndBuildModel;
/**
* Orchestrates the flow to parse a `FetchResponse` and then build the view model,
* adding performance metrics data to the final result.
*
* Timing points are captured around the parsing and model building steps,
* and this is added to the metrics which were returned from the `FetchResponse`.
*
* When using this method, it is the responsibility of the caller
* to perform the network fetch in order to have a `FetchResponse` object.
* The parsing logic which transforms the `FetchResponse` object into an intermediate model object
* will need to be decoupled so that it can be implemented in the `parser` function.
*
* @param response - The response from a `Network.fetch()` call.
* @param objectGraph - Object graph that can be used to pass data to the `parser` and `renderer` steps.
* @param parser - A step that parses a `FetchResponse` to an intermediate model object.
* @param modelBuilder - A step that takes the output of the `parser` step, and builds the view model.
* This parameter supports both synchronous and asynchronous functions.
* @returns The view model.
*/
async function parseAndBuildModel(response, objectGraph, parser, modelBuilder) {
const modifiedObjectGraph = ensureFetchTimingMetricsBuilderExists(objectGraph, false);
const fetchTimingMetricsBuilder = (0, dependencies_1.inject)(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, modifiedObjectGraph);
// Add metrics from FetchResponse, and run the parser, capturing timing points.
const parsedObject = fetchTimingMetricsBuilder.measureParsing(response, () => {
return parser(response, modifiedObjectGraph);
});
if ((0, optional_1.isNothing)(parsedObject)) {
throw new Error("parser function returned null or undefined");
}
return await constructAndDecorateModel(parsedObject, modifiedObjectGraph, modelBuilder);
}
exports.parseAndBuildModel = parseAndBuildModel;
async function constructAndDecorateModel(parsedObject, objectGraph, modelBuilder) {
const fetchTimingMetricsBuilder = (0, dependencies_1.inject)(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, objectGraph);
// Run the model builder, capturing timing points.
const model = await fetchTimingMetricsBuilder.measureModelConstructionAsync(async () => {
const maybePromise = modelBuilder(parsedObject, objectGraph); // The actual model, or a Promise of the model.
return await Promise.resolve(maybePromise); // If it was promise, it will await until the promise is resolved.
});
if ((0, optional_1.isNothing)(model)) {
throw new Error("model builder function returned null or undefined");
}
// Decorate the final output with the metrics data.
fetchTimingMetricsBuilder.decorate(model);
return model;
}
//# sourceMappingURL=parse-and-build-model.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=alert-action.js.map

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeCompoundAction = exports.isCompoundAction = void 0;
/**
* Custom type guard to determine if an action is a CompoundAction.
*/
function isCompoundAction(action) {
return (action === null || action === void 0 ? void 0 : action.$kind) === "compoundAction";
}
exports.isCompoundAction = isCompoundAction;
/**
* Helper that returns a CompoundAction, given an ActionMetrics and ActionModel[] of subactions.
*/
function makeCompoundAction(actionMetrics, subactions) {
return {
$kind: "compoundAction",
subactions,
actionMetrics,
};
}
exports.makeCompoundAction = makeCompoundAction;
//# sourceMappingURL=compound-action.js.map

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeEmptyAction = exports.isEmptyAction = void 0;
/**
* Custom type guard to determine if an action is an EmptyAction.
*/
function isEmptyAction(action) {
return (action === null || action === void 0 ? void 0 : action.$kind) === "emptyAction";
}
exports.isEmptyAction = isEmptyAction;
/**
* Helper that returns an EmptyAction, given an ActionMetrics.
*/
function makeEmptyAction(actionMetrics) {
return {
$kind: "emptyAction",
actionMetrics,
};
}
exports.makeEmptyAction = makeEmptyAction;
//# sourceMappingURL=empty-action.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=external-url-action.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=flow-action.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=flow-back-action.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=http-action.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=http-template-action.js.map

26
node_modules/@jet/environment/models/actions/index.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
"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("./alert-action"), exports);
__exportStar(require("./compound-action"), exports);
__exportStar(require("./empty-action"), exports);
__exportStar(require("./external-url-action"), exports);
__exportStar(require("./flow-action"), exports);
__exportStar(require("./flow-back-action"), exports);
__exportStar(require("./http-action"), exports);
__exportStar(require("./http-template-action"), exports);
__exportStar(require("./toast-action"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=toast-action.js.map

39
node_modules/@jet/environment/models/artwork.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeArtworkURLTemplate = void 0;
const validation = require("../json/validation");
const optional_1 = require("../types/optional");
const urls_1 = require("../util/urls");
/**
* Regex to parse artwork URL template string.
*/
const URL_TEMPLATE_PARSER = new RegExp("^({w}|[0-9]+(?:.[0-9]*)?)x({h}|[0-9]+(?:.[0-9]*)?)({c}|[a-z]{2}).({f}|[a-z]+)$");
/**
* Create an instance of artwork URL template from string.
* @param fromString - String to create artwork URL template from.
* @returns A new artwork URL template or `null` if string
* does not represent a valid artwork URL template.
*/
function makeArtworkURLTemplate(fromString) {
// A valid URL that ends with '{w}x{h}{c}.{f}'
// with any of placeholders possibly resolved to an actual value.
const url = new urls_1.URL(fromString);
if (url.pathname === undefined) {
validation.context("makeArtworkURLTemplate", () => {
validation.unexpectedType("ignoredValue", "A valid URL string", fromString);
});
return null;
}
// Expecting 5 matches: whole string + width, height, crop code and format.
const lastPathComponent = fromString.substring(fromString.lastIndexOf("/") + 1);
const matches = URL_TEMPLATE_PARSER.exec(lastPathComponent);
if ((0, optional_1.isNothing)(matches) || matches.length !== 5) {
validation.context("makeArtworkURLTemplate", () => {
validation.unexpectedType("ignoredValue", "A valid artwork URL template ending with {w}x{h}{c}.{f} format", lastPathComponent);
});
return null;
}
return fromString;
}
exports.makeArtworkURLTemplate = makeArtworkURLTemplate;
//# sourceMappingURL=artwork.js.map

3
node_modules/@jet/environment/models/button.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=button.js.map

196
node_modules/@jet/environment/models/color.js generated vendored Normal file
View File

@@ -0,0 +1,196 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.areEqual = exports.luminanceFrom = exports.dynamicWith = exports.named = exports.rgbWith = exports.htmlWith = exports.Color = void 0;
const optional_1 = require("../types/optional");
// endregion
// region Constructors
// eslint-disable-next-line no-redeclare, @typescript-eslint/no-redeclare
exports.Color = {
/**
* Create new `HTMLColor` from hexadecimal string representation.
*
* @param hexString - Hexadecimal string representation.
*/
fromHex(string) {
if ((0, optional_1.isNothing)(string)) {
return null;
}
return {
$kind: "html",
value: string,
};
},
/**
* Create new `RBGColor` with RGB components and opacity value.
*
* @param red - Red color value.
* @param green - Green color value.
* @param blue - Blue color value.
* @param alpha - Opacity value.
*/
fromRGB(red, green, blue, alpha = 1.0) {
const newColor = {
$kind: "rgb",
red: red,
green: green,
blue: blue,
alpha: alpha,
};
return newColor;
},
/**
* Create new named color using the color name.
*
* @param name - The name of the color.
*/
named(name) {
const newColor = {
$kind: "named",
name: name,
};
return newColor;
},
/**
* Create new dynamic color with light and dark color variants.
*
* @param lightColor - The light color variant.
* @param lightHighContrastColor - The light hight-contrast color variant.
* @param darkColor - The dark color variant.
* @param darkHighContrastColor - The dark hight-contrast color variant.
*/
dynamicWith(lightColor, lightHighContrastColor, darkColor, darkHighContrastColor) {
const newColor = {
$kind: "dynamic",
lightColor: lightColor,
lightHighContrastColor: lightHighContrastColor,
darkColor: darkColor,
darkHighContrastColor: darkHighContrastColor,
};
return newColor;
},
// endregion
// region Properties
/**
* Get the luminance of the color.
*
* @param rgbColor - The RGB color to get luminance for.
*/
luminanceFrom(rgbColor) {
// Note: This is lifted from UIColor_Private
// Using RGB color components, calculates and returns (0.2126 * r) + (0.7152 * g) + (0.0722 * b).
return rgbColor.red * 0.2126 + rgbColor.green * 0.7152 + rgbColor.blue * 0.0722;
},
// endregion
// region Identity
/**
* Compare two colors for equality.
*
* @param color1 - Left hand side color to compare.
* @param color2 - Right hand side color to compare.
* @returns A Boolean indicating whether the colors are equal.
*/
areEqual(color1, color2) {
if ((0, optional_1.isNothing)(color1)) {
return (0, optional_1.isNothing)(color2);
}
else if ((0, optional_1.isNothing)(color2)) {
return (0, optional_1.isNothing)(color1);
}
const kind1 = color1.$kind;
const kind2 = color2.$kind;
if (kind1 === "named" && kind2 === "named") {
const namedColor1 = color1;
const namedColor2 = color2;
return namedColor1.name === namedColor2.name;
}
else if (kind1 === "rgb" && kind2 === "rgb") {
const rgbColor1 = color1;
const rgbColor2 = color2;
return (rgbColor1.red === rgbColor2.red &&
rgbColor1.green === rgbColor2.green &&
rgbColor1.blue === rgbColor2.blue &&
rgbColor1.alpha === rgbColor2.alpha);
}
else if (kind1 === "dynamic" && kind2 === "dynamic") {
const dynamicColor1 = color1;
const dynamicColor2 = color2;
return (exports.Color.areEqual(dynamicColor1.lightColor, dynamicColor2.lightColor) &&
exports.Color.areEqual(dynamicColor1.lightHighContrastColor, dynamicColor2.lightHighContrastColor) &&
exports.Color.areEqual(dynamicColor1.darkColor, dynamicColor2.darkColor) &&
exports.Color.areEqual(dynamicColor1.darkHighContrastColor, dynamicColor2.darkHighContrastColor));
}
else {
return false;
}
},
};
/**
* Create new `HTMLColor` from hexadecimal string representation.
*
* @param hexString - Hexadecimal string representation.
*
* @deprecated This symbol has been moved to `Color.fromHex` and will be removed
* in the future.
*/
const htmlWith = exports.Color.fromHex;
exports.htmlWith = htmlWith;
/**
* Create new `RBGColor` with RGB components and opacity value.
*
* @param red - Red color value.
* @param green - Green color value.
* @param blue - Blue color value.
* @param alpha - Opacity value.
*
* @deprecated This symbol has been moved to `Color.fromRGB` and will be removed
* in the future.
*/
const rgbWith = exports.Color.fromRGB;
exports.rgbWith = rgbWith;
/**
* Create new named color using the color name.
*
* @param name - The name of the color.
*
* @deprecated This symbol has been moved to `Color.named` and will be removed
* in the future.
*/
const named = exports.Color.named;
exports.named = named;
/**
* Create new dynamic color with light and dark color variants.
*
* @param lightColor - The light color variant.
* @param lightHighContrastColor - The light hight-contrast color variant.
* @param darkColor - The dark color variant.
* @param darkHighContrastColor - The dark hight-contrast color variant.
*
* @deprecated This symbol has been moved to `Color.dynamicWith` and will be removed
* in the future.
*/
const dynamicWith = exports.Color.dynamicWith;
exports.dynamicWith = dynamicWith;
/**
* Get the luminance of the color.
*
* @param rgbColor - The RGB color to get luminance for.
*
* @deprecated This symbol has been moved to `Color.luminanceFrom` and will be removed
* in the future.
*/
const luminanceFrom = exports.Color.luminanceFrom;
exports.luminanceFrom = luminanceFrom;
/**
* Compare two colors for equality.
*
* @param color1 - Left hand side color to compare.
* @param color2 - Right hand side color to compare.
* @returns A Boolean indicating whether the colors are equal.
*
* @deprecated This symbol has been moved to `Color.areEqual` and will be removed
* in the future.
*/
const areEqual = exports.Color.areEqual;
exports.areEqual = areEqual;
// endregion
//# sourceMappingURL=color.js.map

25
node_modules/@jet/environment/models/index.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
"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("./actions"), exports);
__exportStar(require("./artwork"), exports);
__exportStar(require("./button"), exports);
__exportStar(require("./color"), exports);
__exportStar(require("./menu"), exports);
__exportStar(require("./paragraph"), exports);
__exportStar(require("./programmed-text"), exports);
__exportStar(require("./video"), exports);
//# sourceMappingURL=index.js.map

8
node_modules/@jet/environment/models/menu.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.menuSeparatorID = void 0;
/**
* A standard identifier for including a separator in a menu.
*/
exports.menuSeparatorID = "com.apple.JetEngine.separator";
//# sourceMappingURL=menu.js.map

4
node_modules/@jet/environment/models/paragraph.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// endregion
//# sourceMappingURL=paragraph.js.map

View File

@@ -0,0 +1,5 @@
"use strict";
// region ProgrammedText
Object.defineProperty(exports, "__esModule", { value: true });
// endregion
//# sourceMappingURL=programmed-text.js.map

3
node_modules/@jet/environment/models/video.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=video.js.map

20
node_modules/@jet/environment/routing/index.js generated vendored Normal file
View 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("./router"), exports);
__exportStar(require("./route-provider"), exports);
__exportStar(require("./router-factory"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerRoutesProvider = exports.isRouteProvider = void 0;
const optional_1 = require("../types/optional");
/**
* Checks if an object conforms to `RouteProvider`.
* @remarks This function does not perform any checking for the generic types.
* @param provider - The object that may be a route provider.
*/
function isRouteProvider(provider) {
if (typeof provider !== "object") {
return false;
}
return (0, optional_1.isSome)(provider === null || provider === void 0 ? void 0 : provider["routes"]);
}
exports.isRouteProvider = isRouteProvider;
/**
* Registers all routes provided by a `RouteProvider` to a router.
* @param router - The router to register routes on.
* @param provider - The route provider to get the routes from.
* @param objectGraph - An object graph for dependency injection.
*/
function registerRoutesProvider(router, provider, objectGraph) {
provider.routes(objectGraph).forEach((definition) => {
router.associate(definition.rules, definition.handler);
});
}
exports.registerRoutesProvider = registerRoutesProvider;
//# sourceMappingURL=route-provider.js.map

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeRouterUsingRegisteredControllers = void 0;
const route_provider_1 = require("./route-provider");
const router_1 = require("./router");
/**
* Creates a new router using the routes from any controller registered on the provided
* dispatcher that conforms to `RouteProvider`.
* @param dispatcher - The dispatcher to get the controllers from.
* @param objectGraph - An object graph for dependency injection.
*/
function makeRouterUsingRegisteredControllers(dispatcher, objectGraph) {
const router = new router_1.Router();
for (const controller of dispatcher.registeredControllers) {
if ((0, route_provider_1.isRouteProvider)(controller)) {
(0, route_provider_1.registerRoutesProvider)(router, controller, objectGraph);
}
}
return router;
}
exports.makeRouterUsingRegisteredControllers = makeRouterUsingRegisteredControllers;
//# sourceMappingURL=router-factory.js.map

39
node_modules/@jet/environment/routing/router.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Router = void 0;
const optional_1 = require("../types/optional");
const routing_components_1 = require("./routing-components");
/**
* Converts a URL into an intent. This intent can then be dispatched using a dispatcher
* (see `IntentDispatcher`).
*
* Routes can be registered using either the `associate` function or using route providers
* (see `RouteProvider`).
*/
class Router {
constructor() {
this.router = new routing_components_1.UrlRouter();
}
/**
* Registers a new implementation that will be invoked when any of the provided
* URL rules are matched.
* @param urlRules - The rules that will be registered.
* @param implementation - The implementation to invoke if any of the rules are matched.
*/
associate(urlRules, implementation) {
this.router.associate(urlRules, implementation);
}
/**
* Uses the registered routing rules to produce an intent for the provided URL.
* @param url - The URL to route;
*/
intentFor(url) {
const routerResult = this.router.routedObjectForUrl(url);
if ((0, optional_1.isSome)(routerResult.object) && (0, optional_1.isSome)(routerResult.parameters)) {
return routerResult.object(routerResult.normalizedUrl, routerResult.parameters, routerResult);
}
return null;
}
}
exports.Router = Router;
//# sourceMappingURL=router.js.map

View File

@@ -0,0 +1,295 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UrlRouter = exports.UrlRule = void 0;
const optional_1 = require("../types/optional");
const urls = require("../util/urls");
// endregion
// region private URLRule helpers.
/**
* Checks whether or not a given pathComponents component contains a parameter.
* @param pathComponent - The pathComponents component to check.
* @returns true if the pathComponents component is surrounded by curly braces; false otherwise.
*/
function isPathComponentParameter(pathComponent) {
return pathComponent.startsWith("{") && pathComponent.endsWith("}");
}
/**
* Extracts the parameter contained in a pathComponents component.
* @param pathComponent - A pathComponents component surrounded by curly braces.
* @returns The parameter contained in the component.
*/
function getPathComponentParameter(pathComponent) {
return pathComponent.replace("{", "").replace("}", "");
}
/**
* Creates a mapping from key to pathComponents component index
* for efficiently extracting parameters from a pathComponents.
* @param rulePath - The pathComponents to create a mapping for.
* @returns A map of keys to pathComponents component indexes.
*/
function makePathParameterMapping(rulePath) {
const mapping = {};
rulePath.forEach((ruleComponent, index) => {
if (isPathComponentParameter(ruleComponent)) {
mapping[ruleComponent] = index;
}
});
return mapping;
}
/**
* Creates `UrlRouteQuery` objects from substring of url.
* @param parameters - strings of form `<key>[?]=<value>`.
* @returns Array of `UrlRouteQuery` objects.
*/
function parseQuery(parameters) {
const parsedQuery = [];
if ((0, optional_1.isNothing)(parameters)) {
return parsedQuery;
}
for (const param of parameters) {
const parts = param.split("=");
let key = parts[0];
const optional = key.includes("?");
key = key.replace("?", "");
let value = null;
if (parts.length > 1) {
value = decodeURIComponent(parts[1]);
}
parsedQuery.push({
key,
value,
optional,
});
}
return parsedQuery;
}
/**
* The `UrlRule` class extracts the pattern format from `UrlRuleDefinition`s, and encapsulates
* the information needed to match against a candidate URL and extract parameters from it.
*
* The terminology here is:
* - rule: A specific url pattern.
* - route: A group of rules that together form a single route, i.e. UrlRule[].
*/
class UrlRule {
/**
* Construct the route with all required properties.
* @param rule - The rule to match.
*/
constructor(rule) {
this.identifier = rule.identifier;
this.protocol = rule.protocol;
this.hostName = rule.hostName;
if ((0, optional_1.isSome)(rule.path)) {
this.pathComponents = rule.path.split("/").filter((component) => component.length > 0);
this.pathParameterMap = makePathParameterMapping(this.pathComponents);
}
else {
this.pathComponents = undefined;
this.pathParameterMap = undefined;
}
this.pathExtension = rule.pathExtension;
this.query = parseQuery(rule.query);
this.hash = rule.hash;
this.regex = rule.regex;
if ((0, optional_1.isSome)(rule.exclusions)) {
this.exclusions = rule.exclusions.map(function (ex) {
return new UrlRule(ex);
});
}
else {
this.exclusions = undefined;
}
}
/**
* Checks whether or not the route matches a given URL.
* @param url - The URL to check against.
* @returns true if the route matches `urls`; false otherwise.
*
* @deprecated prefer `match` to have access to regex match groups
*/
matches(url) {
return (0, optional_1.isSome)(this.match(url));
}
/**
* Extract information from a matching url.
* @param matchingUrl - The url to extract parameters from.
* @returns `Parameters` extracted from `matchingUrl`
* @remarks This function is only valid when `this.matches(matchingUrl) === true`.
*/
extractParameters(matchingUrl) {
var _a;
const parameters = {};
if ((0, optional_1.isSome)(this.pathComponents) && (0, optional_1.isSome)(this.pathParameterMap)) {
const urlPathComponents = matchingUrl.pathComponents();
for (const internalKey of Object.keys(this.pathParameterMap)) {
const externalKey = getPathComponentParameter(internalKey);
const index = this.pathParameterMap[internalKey];
parameters[externalKey] = decodeURIComponent(urlPathComponents[index]);
}
}
if ((0, optional_1.isSome)(this.query)) {
for (const param of this.query) {
const queryParam = (_a = matchingUrl.query) === null || _a === void 0 ? void 0 : _a[param.key];
if ((0, optional_1.isSome)(queryParam)) {
parameters[param.key] = queryParam;
}
}
}
return parameters;
}
/**
* Checks whether or not the route matches a given URL.
* @param url - The URL to check against.
* @returns an optional `UrlRuleMatchResult` if the route matches `url`.
*/
match(url) {
var _a, _b;
let matchGroups = null;
if ((0, optional_1.isSome)(this.regex)) {
if (this.regex.length === 0) {
// If the rule specifies regex but does not supply patterns, we need to return false. Otherwise, we will
// risk matching against everything. This is because an empty regex with no other rule parameters will
// cause us to fallthrough to the end and match against all URLs.
return null;
}
let didMatchRegex = false;
for (const regexPattern of this.regex) {
const execResult = regexPattern.exec(url.toString());
if (execResult !== null) {
// If we match against any of regex patterns, then we should proceed.
// If no matches are found, then this rule is not matched.
didMatchRegex = true;
matchGroups = (_a = execResult.groups) !== null && _a !== void 0 ? _a : null;
break;
}
}
if (!didMatchRegex) {
return null;
}
}
if ((0, optional_1.isSome)(this.protocol) && url.protocol !== this.protocol) {
return null;
}
if ((0, optional_1.isSome)(this.hostName) && url.host !== this.hostName) {
return null;
}
if ((0, optional_1.isSome)(this.pathComponents)) {
const rulePathComponents = this.pathComponents;
const urlPathComponents = url.pathComponents();
if (rulePathComponents.length !== urlPathComponents.length) {
return null;
}
// We're iterating two arrays here, an old style for-loop is appropriate
const length = rulePathComponents.length;
for (let i = 0; i < length; i += 1) {
const ruleComponent = rulePathComponents[i];
if (isPathComponentParameter(ruleComponent)) {
// component parameters always match
continue;
}
const urlComponent = urlPathComponents[i];
if (ruleComponent !== urlComponent) {
return null;
}
}
}
if ((0, optional_1.isSome)(this.pathExtension)) {
if (url.pathExtension() !== this.pathExtension) {
return null;
}
}
if ((0, optional_1.isSome)(this.query)) {
for (const param of this.query) {
const value = (_b = url.query) === null || _b === void 0 ? void 0 : _b[param.key];
if ((0, optional_1.isNothing)(value) && !param.optional) {
return null;
}
if ((0, optional_1.isSome)(param.value) && param.value !== value) {
return null;
}
}
}
if ((0, optional_1.isSome)(this.hash) && url.hash !== this.hash) {
return null;
}
if ((0, optional_1.isSome)(this.exclusions)) {
for (const exclusionRule of this.exclusions) {
if ((0, optional_1.isSome)(exclusionRule.exclusions)) {
throw Error("Matching exclusion rules with further exclusion rules may introduce significant code-complexity and/or reduce the ease with which developers are able to reason about your desired goals. Are there any simpler options?");
}
if ((0, optional_1.isSome)(exclusionRule.match(url))) {
return null;
}
}
}
const parameters = this.extractParameters(url);
return {
parameters,
matchGroups,
};
}
}
exports.UrlRule = UrlRule;
/**
* `UrlRouter` manages a set of url rule templates to allow `urls` to serve as keys for different associated objects (like Builders).
*
* @remarks This is replaces old `UrlRouter` as a synchronous way match route URLs to handlers. In contrast to the previous implementation,
* it maps entire objects (containing related async handlers and properties) to urls.
*/
class UrlRouter {
/**
* Constructs an empty URL router object.
*/
constructor() {
this.routeMappings = [];
}
/**
* Register a new route defined by a set of definitions and object on the router.
* @param routeDefinitions - The definitions of rules to register.
* @param object - The object for the rule.
*/
associate(routeDefinitions, object) {
const route = [];
for (const definition of routeDefinitions) {
route.push(new UrlRule(definition));
}
this.routeMappings.push({ route: route, object: object });
}
/**
* Resolve given url to associated object, if any exist. Rules will be evaluated
* in the order they are added using the `associate` function. Evaluation will stop
* after any rule matches.
* @param urlOrString - URL or string representation of url to resolve objects for.
* @returns `UrlRouterResult` containing url, extracted parameters, and associated object, or `null` if no match was found.
*/
routedObjectForUrl(urlOrString) {
var _a;
const url = typeof urlOrString === "string" ? new urls.URL(urlOrString) : urlOrString;
for (const mapping of this.routeMappings) {
for (const rule of mapping.route) {
const matchResult = rule.match(url);
if ((0, optional_1.isSome)(matchResult)) {
return {
normalizedUrl: url,
parameters: matchResult.parameters,
object: mapping.object,
matchedRuleIdentifier: (_a = rule.identifier) !== null && _a !== void 0 ? _a : null,
regexMatchGroups: matchResult.matchGroups,
};
}
}
}
// No match. Still return a result with normalized url.
return {
normalizedUrl: url,
parameters: null,
object: null,
matchedRuleIdentifier: null,
regexMatchGroups: null,
};
}
}
exports.UrlRouter = UrlRouter;
// endregion
//# sourceMappingURL=routing-components.js.map

47
node_modules/@jet/environment/runtime/bootstrap.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.exportBootstrap = void 0;
const jet_proxy_1 = require("../dependencies/jet-proxy");
function exportBootstrap(bootstrap) {
if (typeof $exportBootstrap !== "undefined") {
/* Wraps the given bootstrap function to perform custom bootstrap behavior such
as supporting lazy dependencies. */
const customBootstrap = (service) => {
proxyLazyDependencies(service);
return bootstrap(service);
};
$exportBootstrap(customBootstrap);
}
}
exports.exportBootstrap = exportBootstrap;
// We put has_lazy_support on the global object so native can check that the Jet runtime has lazy support.
globalThis["has_lazy_support"] = true;
// Installs proxies for lazy dependencies so we can create objects only as needed.
function proxyLazyDependencies(service) {
const lazyDependencyNames = service.$lazyDependencyNames;
const lazyDependencyNamesSet = new Set(lazyDependencyNames !== null && lazyDependencyNames !== void 0 ? lazyDependencyNames : []);
const lazyGlobalNames = globalThis.$lazyGlobalNames;
const lazyGlobalNamesSet = new Set(lazyGlobalNames !== null && lazyGlobalNames !== void 0 ? lazyGlobalNames : []);
/* We take the union of lazy globals and lazy dependencies. For each lazy dependency name,
we will make one proxy. We must avoid creating more than one proxy for a given name.
For instance, if the name is present in the lazy dependencies and lazy globals, we do
not want to create two proxies. Doing so would cause multiple object instances to be created
natively for use in JS (one instance in the dependency object,
another instance in the global object), leading to potential bugs. */
const uniqueLazyNames = new Set([...lazyDependencyNamesSet, ...lazyGlobalNamesSet]);
const proxyMap = new Map();
const lazyProvider = globalThis.$lazyProvider;
for (const lazyName of uniqueLazyNames) {
// Create one proxy per name present in either lazy globals or lazy dependencies.
proxyMap.set(lazyName, jet_proxy_1.LazyProxyFactory.makeProxy(lazyName, lazyProvider));
}
// For each lazy dependency name, put the proxy on the dependency (service) object under the given name.
for (const lazyDependencyName of lazyDependencyNamesSet) {
service[lazyDependencyName] = proxyMap.get(lazyDependencyName);
}
// For each lazy global name, put the proxy on the global object under the given name.
for (const lazyGlobalName of lazyGlobalNamesSet) {
globalThis[lazyGlobalName] = proxyMap.get(lazyGlobalName);
}
}
//# sourceMappingURL=bootstrap.js.map

19
node_modules/@jet/environment/runtime/index.js generated vendored Normal file
View 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("./bootstrap"), exports);
__exportStar(require("./runtime"), exports);
//# sourceMappingURL=index.js.map

35
node_modules/@jet/environment/runtime/runtime.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LegacyRuntime = exports.Runtime = void 0;
const isJetEnvironment = typeof exportService === "function";
function nativeExportService(name, service) {
exportService(name, service);
}
class Runtime {
constructor(dispatcher, objectGraph) {
this.dispatcher = dispatcher;
this.objectGraph = objectGraph;
}
async dispatch(intent) {
return await this.dispatcher.dispatch(intent, this.objectGraph);
}
}
exports.Runtime = Runtime;
class LegacyRuntime extends Runtime {
constructor(dispatcher, objectGraph, services) {
super(dispatcher, objectGraph);
this.services = services;
}
serviceWithName(name) {
return this.services[name];
}
exportingService(name, service) {
if (isJetEnvironment) {
nativeExportService(name, service);
}
this.services[name] = service;
return this;
}
}
exports.LegacyRuntime = LegacyRuntime;
//# sourceMappingURL=runtime.js.map

3
node_modules/@jet/environment/types/globals/bag.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=bag.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=bundle.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=cookie-provider.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=cryptography.js.map

3
node_modules/@jet/environment/types/globals/host.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=host.js.map

55
node_modules/@jet/environment/types/globals/index.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
"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 });
/* `preprocessor` and `testContent` are normally replaced by inline literals while bundling an app's JS.
*
* If these values have not been set we want to provide defaults however
* attempting to access them can trigger a ReferenceError as the
* variables are undefined (distinct from a defined variable being set to
* `undefined`).
*
* `typeof` checks can safely test undefined variables, note that these checks will become:
* `typeof { DEBUG_BUILD: true, ... }` when webpack's DefinePlugin is used in @jet/build's webpack task.
* When these variables have not been replaced we need to use `globalThis` to set them on the global scope
* in order to avoid ReferenceErrors attempting to access them.
*/
if (typeof preprocessor === "undefined") {
globalThis.preprocessor = {
PRODUCTION_BUILD: false,
CARRY_BUILD: false,
DEBUG_BUILD: false,
INTERNAL_BUILD: false,
};
}
if (typeof testContent === "undefined") {
globalThis.testContent = {
INCLUDE_TEST_CONTENT: false,
};
}
__exportStar(require("./bag"), exports);
__exportStar(require("./bundle"), exports);
__exportStar(require("./cookie-provider"), exports);
__exportStar(require("./cryptography"), exports);
__exportStar(require("./host"), exports);
__exportStar(require("./jscookie"), exports);
__exportStar(require("./net"), exports);
__exportStar(require("./platform"), exports);
__exportStar(require("./plist"), exports);
__exportStar(require("./preprocessor"), exports);
__exportStar(require("./random"), exports);
__exportStar(require("./service"), exports);
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=jscookie.js.map

19
node_modules/@jet/environment/types/globals/net.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProxiedNetwork = void 0;
/**
* `Network` object designed to wrap the bridged native network object,
* which automatically includes page intent instrumentation data in the fetch request.
*/
class ProxiedNetwork {
constructor(original, pageIntentInstrumentation) {
this.original = original;
this.pageIntentInstrumentation = pageIntentInstrumentation;
}
async fetch(request) {
request["$pageIntentInstrumentation"] = this.pageIntentInstrumentation;
return await this.original.fetch(request);
}
}
exports.ProxiedNetwork = ProxiedNetwork;
//# sourceMappingURL=net.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=platform.js.map

3
node_modules/@jet/environment/types/globals/plist.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=plist.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=preprocessor.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=random.js.map

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=service.js.map

16
node_modules/@jet/environment/types/globals/types.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.services = exports.random = exports.plist = exports.platform = exports.net = exports.localizer = exports.host = exports.cryptography = exports.cookieProvider = exports.bundle = exports.bag = void 0;
const metatype_1 = require("../../util/metatype");
exports.bag = (0, metatype_1.makeMetatype)("jet-engine:bag");
exports.bundle = (0, metatype_1.makeMetatype)("jet-engine:bundle");
exports.cookieProvider = (0, metatype_1.makeMetatype)("jet-engine:cookieProvider");
exports.cryptography = (0, metatype_1.makeMetatype)("jet-engine:cryptography");
exports.host = (0, metatype_1.makeMetatype)("jet-engine:host");
exports.localizer = (0, metatype_1.makeMetatype)("jet-engine:localizer");
exports.net = (0, metatype_1.makeMetatype)("jet-engine:net");
exports.platform = (0, metatype_1.makeMetatype)("jet-engine:platform");
exports.plist = (0, metatype_1.makeMetatype)("jet-engine:plist");
exports.random = (0, metatype_1.makeMetatype)("jet-engine:random");
exports.services = (0, metatype_1.makeMetatype)("jet-engine:services");
//# sourceMappingURL=types.js.map

22
node_modules/@jet/environment/types/index.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
"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("./globals"), exports);
__exportStar(require("./javascriptcore"), exports);
__exportStar(require("./metrics"), exports);
__exportStar(require("./models"), exports);
__exportStar(require("./optional"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,14 @@
"use strict";
/*
* Describes standard functionality available in JSContexts
*
* Types are defined here to allow us to match the behavior available in JSContext in the target OS
* which may not exactly match the definitions in standard TypeScript lib files, particularly on a
* pre-release OS.
*
* The living standard for the Console API is available at https://console.spec.whatwg.org
* The WebKit team has documented their interfaces at https://webkit.org/web-inspector/console-object-api/
* The equivalent interface in Node is https://nodejs.org/api/console.html
*/
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=console.js.map

View File

@@ -0,0 +1,18 @@
"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("./console"), exports);
//# sourceMappingURL=index.js.map

57
node_modules/@jet/environment/types/metrics.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.notInstrumented = exports.PageInvocationPoint = exports.EMPTY_LINTED_METRICS_EVENT = void 0;
/**
* An empty linted metrics event.
*
* The empty events should be skipped from recording
* by metrics event recorders.
*/
exports.EMPTY_LINTED_METRICS_EVENT = {
fields: {},
issues: [],
};
var PageInvocationPoint;
(function (PageInvocationPoint) {
PageInvocationPoint["pageEnter"] = "pageEnter";
PageInvocationPoint["pageExit"] = "pageExit";
PageInvocationPoint["appExit"] = "appExit";
PageInvocationPoint["appEnter"] = "appEnter";
PageInvocationPoint["backButton"] = "backButton";
})(PageInvocationPoint = exports.PageInvocationPoint || (exports.PageInvocationPoint = {}));
/**
* Returns an empty metrics instance of the specified metrics type.
* @param metricsType - Type of the metrics data to return.
*
* @deprecated Do not use, all metrics events should be instrumented.
*/
function notInstrumented(metricsType) {
switch (metricsType) {
case 0 /* NotInstrumentedMetricsType.ActionMetrics */:
return {
data: [],
custom: {},
};
case 1 /* NotInstrumentedMetricsType.FetchTimingMetrics */:
return {};
case 2 /* NotInstrumentedMetricsType.PageMetrics */:
return {
instructions: [],
custom: {},
};
case 3 /* NotInstrumentedMetricsType.ImpressionMetrics */:
return {
id: {
id: "",
impressionIndex: -1,
},
fields: {},
custom: {},
};
default:
return {};
}
}
exports.notInstrumented = notInstrumented;
// endregion
//# sourceMappingURL=metrics.js.map

3
node_modules/@jet/environment/types/models.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=models.js.map

71
node_modules/@jet/environment/types/optional.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flatMapOptional = exports.mapOptional = exports.unsafeUnwrapOptional = exports.unwrapOptional = exports.isSome = exports.isNothing = exports.unsafeUninitialized = void 0;
/**
* Bypass the protection provided by the `Optional` type
* and pretend to produce a value of `Some<T>` while
* actually returning `Nothing`.
*/
function unsafeUninitialized() {
return undefined;
}
exports.unsafeUninitialized = unsafeUninitialized;
/**
* Test whether an optional does not contain a value.
*
* @param value - An optional value to test.
*/
function isNothing(value) {
return value === undefined || value === null;
}
exports.isNothing = isNothing;
/**
* Test whether an optional contains a value.
* @param value - An optional value to test.
*/
function isSome(value) {
return value !== undefined && value !== null;
}
exports.isSome = isSome;
/**
* Unwrap the value contained in a given optional,
* throwing an error if there is no value.
*
* @param value - A value to unwrap.
*/
function unwrapOptional(value) {
if (isNothing(value)) {
throw new ReferenceError();
}
return value;
}
exports.unwrapOptional = unwrapOptional;
/**
* Unwrap the value contained in a given optional
* without checking if the value exists.
*
* @param value - A value to unwrap.
*/
function unsafeUnwrapOptional(value) {
return value;
}
exports.unsafeUnwrapOptional = unsafeUnwrapOptional;
function mapOptional(value, body) {
if (isSome(value)) {
return body(value);
}
else {
return value;
}
}
exports.mapOptional = mapOptional;
function flatMapOptional(value, body) {
if (isSome(value)) {
return body(value);
}
else {
return value;
}
}
exports.flatMapOptional = flatMapOptional;
//# sourceMappingURL=optional.js.map

18
node_modules/@jet/environment/util/clone.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shallowCloneOf = void 0;
/**
* Create a copy of a given object without copying any of its members.
*
* Use this function to efficiently copy an object for your
* implementation of the `Clone` interface.
*
* @param object - An object to create a shallow copy of.
* @returns A new shallow copy of `object`.
*/
function shallowCloneOf(object) {
const copy = Object.create(Object.getPrototypeOf(object));
return Object.assign(copy, object);
}
exports.shallowCloneOf = shallowCloneOf;
//# sourceMappingURL=clone.js.map

22
node_modules/@jet/environment/util/expiring-value.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExpiringValue = void 0;
/**
* A class that wraps some value that expires in some future time.
*/
class ExpiringValue {
constructor(value, maxAge) {
this._value = value;
this._maxAge = maxAge;
}
/// Whether or not value is valid (not expired).
isValid() {
return Date.now() < this._maxAge;
}
/** Access the expiring value, returning null if it is expired. */
get value() {
return this.isValid() ? this._value : null;
}
}
exports.ExpiringValue = ExpiringValue;
//# sourceMappingURL=expiring-value.js.map

24
node_modules/@jet/environment/util/index.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"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("./clone"), exports);
__exportStar(require("./expiring-value"), exports);
__exportStar(require("./metatype"), exports);
__exportStar(require("./promise"), exports);
__exportStar(require("./rewindable-value"), exports);
__exportStar(require("./set"), exports);
__exportStar(require("./urls"), exports);
//# sourceMappingURL=index.js.map

10
node_modules/@jet/environment/util/metatype.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeMetatype = void 0;
function makeMetatype(name) {
return {
name: name,
};
}
exports.makeMetatype = makeMetatype;
//# sourceMappingURL=metatype.js.map

9
node_modules/@jet/environment/util/promise.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPromise = void 0;
/** Whether the given object is a promise. */
function isPromise(obj) {
return obj !== null && typeof obj === "object" && typeof obj.then === "function";
}
exports.isPromise = isPromise;
//# sourceMappingURL=promise.js.map

58
node_modules/@jet/environment/util/rewindable-value.js generated vendored Normal file
View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RewindableValue = void 0;
const clone_1 = require("./clone");
/* eslint-disable no-underscore-dangle */
/**
* A lightweight wrapper around a primitive value which allows its state
* to saved and later restored.
*/
class RewindableValue {
/**
* Create a rewindable value.
*
* @param initialValue - The initial value for the new instance.
*/
constructor(initialValue) {
this._values = [initialValue];
}
/**
* Returns the current value of this instance.
*/
get() {
return this._values[this._values.length - 1];
}
/**
* Replace the current value of this instance.
*
* @param newValue - The value to assign this instance.
*/
set(newValue) {
this._values[this._values.length - 1] = newValue;
}
/**
* Save the current state of this value.
*
* Calls to this method should be balanced by calls to `restore`.
*/
save() {
this._values.push(this._values[this._values.length - 1]);
}
/**
* Restore a previously saved value.
*/
restore() {
if (this._values.length === 1) {
throw new RangeError("Calls to restore must balance previous calls to save");
}
this._values.pop();
}
// section Cloneable
clone() {
const copy = (0, clone_1.shallowCloneOf)(this);
copy._values = this._values.slice();
return copy;
}
}
exports.RewindableValue = RewindableValue;
//# sourceMappingURL=rewindable-value.js.map

92
node_modules/@jet/environment/util/set.js generated vendored Normal file
View File

@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.difference = exports.symmetricDifference = exports.intersection = exports.union = exports.isSuperset = void 0;
/**
* Test if a Set contains all elements of another Set.
*
* @param set -
* @param subset -
*
* @returns True if set contains all elements of subset, otherwise false.
*/
function isSuperset(set, subset) {
for (const elem of subset) {
if (!set.has(elem)) {
return false;
}
}
return true;
}
exports.isSuperset = isSuperset;
/**
* Construct the union of two Sets.
*
* @param setA -
* @param setB -
*
* @returns A new Set containing all elements from setA and setB.
*/
function union(setA, setB) {
const result = new Set(setA);
for (const elem of setB) {
result.add(elem);
}
return result;
}
exports.union = union;
/**
* Construct the intersection of two Sets.
*
* @param setA -
* @param setB -
*
* @returns A new Set containing only those elements which appear in both setA and setB.
*/
function intersection(setA, setB) {
const result = new Set();
for (const elem of setB) {
if (setA.has(elem)) {
result.add(elem);
}
}
return result;
}
exports.intersection = intersection;
/**
* Construct the symmetric difference (XOR) of two Sets.
*
* @param setA -
* @param setB -
*
* @returns A new Set containing only those elements which appear in setA or in setB but not in both setA and setB.
*/
function symmetricDifference(setA, setB) {
const result = new Set(setA);
for (const elem of setB) {
if (result.has(elem)) {
result.delete(elem);
}
else {
result.add(elem);
}
}
return result;
}
exports.symmetricDifference = symmetricDifference;
/**
* Construct the difference of two Sets.
*
* @param setA -
* @param setB -
*
* @returns A new Set containing the elements of setA which do not appear in setB.
*/
function difference(setA, setB) {
const result = new Set(setA);
for (const elem of setB) {
result.delete(elem);
}
return result;
}
exports.difference = difference;
//# sourceMappingURL=set.js.map

430
node_modules/@jet/environment/util/urls.js generated vendored Normal file
View File

@@ -0,0 +1,430 @@
"use strict";
// MARK: - Parsing Regular Expressions
Object.defineProperty(exports, "__esModule", { value: true });
exports.URL = exports.QueryHandling = void 0;
const optional_1 = require("../types/optional");
const protocolRegex = /^([a-z][a-z0-9.+-]*:)(\/\/)?([\S\s]*)/i;
const queryParamRegex = /([^=?&]+)=?([^&]*)/g;
const componentOrder = ["hash", "query", "pathname", "host"];
/**
* Defines how query parameters should be parsed and encoded.
*/
var QueryHandling;
(function (QueryHandling) {
/**
* Handle according to `application/x-www-form-urlencoded` rules (HTML forms).
*
* This is the **default decoding mode** for backward compatibility.
*
* **Example:**
* ```typescript
* // Input: "?search=hello+world&category=news+articles"
* // Parsed: { search: "hello world", category: "news articles" }
* // Output: "?search=hello+world&category=news+articles"
* ```
*
* @see {@link https://url.spec.whatwg.org/#concept-urlencoded-parser WHATWG URL Standard}
*/
QueryHandling["FORM_ENCODED"] = "form-encoded";
/**
* Handle according to RFC 3986 URI specification rules.
*
* This is the **default encoding mode** for backward compatibility.
*
* **Example:**
* ```typescript
* // Input: "?search=hello+world&math=2+2%3D4"
* // Parsed: { search: "hello+world", math: "2+2=4" }
* // Output: "?search=hello+world&math=2+2%3D4"
* ```
*
* @see {@link https://tools.ietf.org/html/rfc3986#section-3.4 RFC 3986 Section 3.4}
*/
QueryHandling["RFC3986"] = "rfc3986";
})(QueryHandling = exports.QueryHandling || (exports.QueryHandling = {}));
class URL {
constructor(url, options) {
var _a;
this.query = {};
this.queryHandling = options === null || options === void 0 ? void 0 : options.queryHandling;
if ((0, optional_1.isNothing)(url)) {
return;
}
// Split the protocol from the rest of the urls
let remainder = url;
const match = protocolRegex.exec(url);
if ((0, optional_1.isSome)(match)) {
// Pull out the protocol
let protocol = match[1];
if (protocol !== null && protocol !== undefined) {
protocol = protocol.split(":")[0];
}
this.protocol = protocol !== null && protocol !== void 0 ? protocol : undefined;
// Save the remainder
remainder = (_a = match[3]) !== null && _a !== void 0 ? _a : undefined;
}
// Then match each component in a specific order
let parse = { remainder: remainder, result: undefined };
for (const component of componentOrder) {
if (parse === undefined || parse.remainder === undefined) {
break;
}
switch (component) {
case "hash": {
parse = splitUrlComponent(parse.remainder, "#", "suffix");
this.hash = parse === null || parse === void 0 ? void 0 : parse.result;
break;
}
case "query": {
parse = splitUrlComponent(parse.remainder, "?", "suffix");
if ((parse === null || parse === void 0 ? void 0 : parse.result) !== undefined) {
this.query = URL.queryFromString(parse.result, this.queryHandling);
}
break;
}
case "pathname": {
parse = splitUrlComponent(parse.remainder, "/", "suffix");
if ((parse === null || parse === void 0 ? void 0 : parse.result) !== undefined) {
// Replace the initial /, since paths require it
this.pathname = "/" + parse.result;
}
break;
}
case "host": {
const authorityParse = splitUrlComponent(parse.remainder, "@", "prefix");
const userInfo = authorityParse === null || authorityParse === void 0 ? void 0 : authorityParse.result;
const hostPort = authorityParse === null || authorityParse === void 0 ? void 0 : authorityParse.remainder;
if (userInfo !== undefined) {
const userInfoSplit = userInfo.split(":");
this.username = decodeURIComponent(userInfoSplit[0]);
this.password = decodeURIComponent(userInfoSplit[1]);
}
if (hostPort !== undefined) {
const hostPortSplit = hostPort.split(":");
this.host = hostPortSplit[0];
this.port = hostPortSplit[1];
}
break;
}
default: {
throw new Error("Unhandled case!");
}
}
}
}
get(component) {
switch (component) {
// Exhaustive match to make sure TS property minifiers and other
// transformer plugins do not break this code.
case "protocol":
return this.protocol;
case "username":
return this.username;
case "password":
return this.password;
case "port":
return this.port;
case "pathname":
return this.pathname;
case "query":
return this.query;
case "hash":
return this.hash;
default:
// The fallback for component which is not a property of URL object.
return this[component];
}
}
set(component, value) {
if (value === undefined) {
return this;
}
if (component === "query") {
if (typeof value === "string") {
value = URL.queryFromString(value, this.queryHandling);
}
}
switch (component) {
// Exhaustive match to make sure TS property minifiers and other
// transformer plugins do not break this code.
case "protocol":
this.protocol = value;
break;
case "username":
this.username = value;
break;
case "password":
this.password = value;
break;
case "port":
this.port = value;
break;
case "pathname":
this.pathname = value;
break;
case "query":
this.query = value;
break;
case "hash":
this.hash = value;
break;
default:
// The fallback for component which is not a property of URL object.
this[component] = value;
break;
}
return this;
}
append(component, value) {
let existingValue = this.get(component);
let newValue;
if (component === "query") {
if (existingValue === undefined) {
existingValue = {};
}
if (typeof value === "string") {
value = URL.queryFromString(value, this.queryHandling);
}
if (typeof existingValue === "string") {
newValue = { existingValue, ...value };
}
else {
newValue = { ...existingValue, ...value };
}
}
else {
if (existingValue === undefined) {
existingValue = "";
}
let existingValueString = existingValue;
if (existingValueString === undefined) {
existingValueString = "";
}
let newValueString = existingValueString;
if (component === "pathname") {
const pathLength = existingValueString.length;
if (pathLength === 0 || existingValueString[pathLength - 1] !== "/") {
newValueString += "/";
}
}
// The component is not "query" so we treat value as string.
// eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-plus-operands
newValueString += value;
newValue = newValueString;
}
return this.set(component, newValue);
}
param(key, value) {
if (key === null) {
return this;
}
if (this.query === undefined) {
this.query = {};
}
if (value === undefined) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.query[key];
}
else {
this.query[key] = value;
}
return this;
}
removeParam(key) {
if (key === undefined || this.query === undefined) {
return this;
}
if (key in this.query) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.query[key];
}
return this;
}
path(value) {
return this.append("pathname", value);
}
pathExtension() {
var _a, _b;
// Extract path extension if one exists
if (this.pathname === undefined) {
return undefined;
}
const lastFilenameComponents = (_b = (_a = this.pathname
.split("/")
.filter((item) => item.length > 0) // Remove any double or trailing slashes
.pop()) === null || _a === void 0 ? void 0 : _a.split(".")) !== null && _b !== void 0 ? _b : [];
if (lastFilenameComponents.filter(function (part) {
return part !== "";
}).length < 2 // Remove any empty parts (e.g. .ssh_config -> ["ssh_config"])
) {
return undefined;
}
return lastFilenameComponents.pop();
}
/**
* Returns the path components of the URL
* @returns An array of non-empty path components from `urls`.
*/
pathComponents() {
if (this.pathname === undefined) {
return [];
}
return this.pathname.split("/").filter((component) => component.length > 0);
}
/**
* Same as toString
*
* @returns A string representation of the URL
*/
build() {
return this.toString();
}
/**
* Converts the URL to a string
*
* @returns A string representation of the URL
*/
toString() {
let url = "";
if (this.protocol !== undefined) {
url += this.protocol + "://";
}
if (this.username !== undefined) {
url += encodeURIComponent(this.username);
if (this.password !== undefined) {
url += ":" + encodeURIComponent(this.password);
}
url += "@";
}
if (this.host !== undefined) {
url += this.host;
if (this.port !== undefined) {
url += ":" + this.port;
}
}
if (this.pathname !== undefined) {
url += this.pathname;
}
if (this.query !== undefined && Object.keys(this.query).length !== 0) {
url += "?" + URL.toQueryString(this.query, this.queryHandling);
}
if (this.hash !== undefined) {
url += "#" + this.hash;
}
return url;
}
// ----------------
// Static API
// ----------------
/**
* Converts a string into a query dictionary
* @param query - The string to parse
* @returns The query dictionary containing the key-value pairs in the query string
*/
static queryFromString(query, queryHandling = QueryHandling.FORM_ENCODED) {
const result = {};
let parseResult = queryParamRegex.exec(query);
while (parseResult !== null && parseResult.length >= 3) {
let key = parseResult[1];
let value = parseResult[2];
// We support the legacy query format for "application/x-www-form-urlencoded" which can represent spaces as "+" symbols.
// https://url.spec.whatwg.org/#concept-urlencoded-parser
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#decoding_query_parameters_from_a_url
//
// For RFC3986 mode, plus signs remain as literal plus signs
if (queryHandling === QueryHandling.FORM_ENCODED) {
key = key.replace(/\+/g, " ");
value = value.replace(/\+/g, " ");
}
const decodedKey = decodeURIComponent(key);
const decodedValue = decodeURIComponent(value);
result[decodedKey] = decodedValue;
parseResult = queryParamRegex.exec(query);
}
return result;
}
/**
* Converts a query dictionary into a query string
*
* @param query - The query dictionary
* @returns The string representation of the query dictionary
*/
static toQueryString(query, queryHandling = QueryHandling.RFC3986) {
let queryString = "";
let first = true;
for (const key of Object.keys(query)) {
if (!first) {
queryString += "&";
}
first = false;
queryString += URL.encodeQueryComponent(key, queryHandling);
const value = query[key];
if (value !== null && value.length > 0) {
queryString += "=" + URL.encodeQueryComponent(value, queryHandling);
}
}
return queryString;
}
/**
* Encode a query parameter key or value according to the specified mode.
* @param component - The key or value to encode
* @param queryHandling - The encoding mode
* @returns The encoded component
*/
static encodeQueryComponent(component, queryHandling) {
if (queryHandling === QueryHandling.FORM_ENCODED) {
// For form-encoded: encode with encodeURIComponent, then convert %20 back to +
return encodeURIComponent(component).replace(/%20/g, "+");
}
else {
// For RFC 3986: standard percent-encoding (spaces become %20)
return encodeURIComponent(component);
}
}
static from(url) {
return new URL(url);
}
/**
* Convenience method to instantiate a URL from numerous (optional) components
* @param protocol - The protocol type
* @param host - The host name
* @param path - The path
* @param query - The query
* @param hash - The hash
* @param options - Configuration options for URL construction
* @returns The new URL object representing the URL
*/
static fromComponents(protocol, host, path, query, hash, options) {
const url = new URL(undefined, options);
url.protocol = protocol;
url.host = host;
url.pathname = path;
url.query = query !== null && query !== void 0 ? query : {};
url.hash = hash;
return url;
}
}
exports.URL = URL;
// MARK: - Helpers
function splitUrlComponent(input, marker, style) {
const index = input.indexOf(marker);
let result;
let remainder = input;
if (index !== -1) {
const prefix = input.slice(0, index);
const suffix = input.slice(index + marker.length, input.length);
if (style === "prefix") {
result = prefix;
remainder = suffix;
}
else {
result = suffix;
remainder = prefix;
}
}
return {
result: result,
remainder: remainder,
};
}
//# sourceMappingURL=urls.js.map