UNPKG

jscrewit

Version:

Converts plain JavaScript into JSFuck code, which consists of only six different characters: ! ( ) + [ ]

320 lines (298 loc) 11.2 kB
import type { ElementaryFeatureName, FeatureAll, PredefinedFeatureName } from './feature-all'; export interface CustomFeature extends Feature { readonly elementary: false; } export interface ElementaryFeature extends PredefinedFeature { readonly elementary: true; readonly name: ElementaryFeatureName; } /** * Objects of this type indicate which of the capabilities that JScrewIt can use to minimize the * length of its output are available in a particular JavaScript engine. * * JScrewIt comes with a set of predefined feature objects exposed as property values of * `JScrewIt.Feature` or {@link FeatureConstructor.ALL | `JScrewIt.Feature.ALL`}, where the property * name is the feature's name or alias. * * Besides these predefined features, it is possible to construct custom features from the union or * intersection of other features. * * Among the predefined features, there are some special ones called *elementary* features. * Elementary features either cannot be expressed as a union of any number of other features, or * they are different from such a union in that they exclude some other feature not excluded by * their elementary components. * All other features, called *composite* features, can be constructed as a union of zero or more * elementary features. * Two of the predefined composite features are particularly important: {@link * FeatureConstructor.DEFAULT | `DEFAULT`} is the empty feature, indicating that no elementary * feature is available at all; {@link FeatureConstructor.AUTO | `AUTO`} is the union of all * elementary features available in the current environment. * * Not all features can be available at the same time: some features are necessarily incompatible, * meaning that they mutually exclude each other, and thus their union cannot be constructed. */ export interface Feature { /** * An array of all elementary feature names included in this feature object, without aliases and * implied features. */ readonly canonicalNames: ElementaryFeatureName[]; /** A boolean value indicating whether this is an elementary feature object. */ readonly elementary: boolean; /** * An array of all elementary feature names included in this feature object, without aliases. */ readonly elementaryNames: ElementaryFeatureName[]; /** * The primary name of this feature object, useful for identification purpose. * * All predefined features have a name; custom features may be optionally assigned a name, too. * If a name is assigned, it will be used when the feature is converted into a string. */ name?: string; /** * Determines whether this feature object includes all of the specified features. * * @returns * * `true` if this feature object includes all of the specified features; otherwise, `false`. * If no arguments are specified, the return value is `true`. */ includes(...features: FeatureElementOrCompatibleArray[]): boolean; /** * Creates a new feature object from this feature by removing elementary features that are not * available inside a particular environment. * * This method is useful to selectively exclude features that are not available in environments * that require strict mode code, or inside web workers. * * @param environment * * The environment to which this feature should be restricted. * Two environments are currently supported. * * <dl> * * <dt><code>"forced-strict-mode"</code></dt> * <dd> * Removes features that are not available in environments that require strict mode code. * </dd> * * <dt><code>"web-worker"</code></dt> * <dd>Removes features that are not available inside web workers.</dd> * * </dl> * * @param engineFeatureObjs * * An array of predefined feature objects, each corresponding to a particular engine in which * the restriction should be enacted. * If this parameter is omitted, the restriction is enacted in all engines. */ restrict ( environment: 'forced-strict-mode' | 'web-worker', engineFeatureObjs?: readonly PredefinedFeature[], ): CustomFeature; } export const Feature: FeatureConstructor; export interface FeatureConstructor extends FeatureAll { /** * Creates a new feature object from the union of the specified features. * * The constructor can be used with or without the `new` operator, e.g. * `new JScrewIt.Feature(feature1, feature2)` or `JScrewIt.Feature(feature1, feature2)`. * If no arguments are specified, the new feature object will be equivalent to * {@link FeatureConstructor.DEFAULT | `DEFAULT`}. * * @example * * The following statements are equivalent, and will all construct a new feature object * including both {@link FeatureConstructor.ANY_DOCUMENT | `ANY_DOCUMENT`} and {@link * FeatureConstructor.ANY_WINDOW | `ANY_WINDOW`}. * * ```js * new JScrewIt.Feature("ANY_DOCUMENT", "ANY_WINDOW"); * ``` * * ```js * new JScrewIt.Feature(JScrewIt.Feature.ANY_DOCUMENT, JScrewIt.Feature.ANY_WINDOW); * ``` * * ```js * new JScrewIt.Feature([JScrewIt.Feature.ANY_DOCUMENT, JScrewIt.Feature.ANY_WINDOW]); * ``` * * @throws * * An error is thrown if any of the specified features are not mutually compatible. */ (...features: FeatureElementOrCompatibleArray[]): CustomFeature; /** * An immutable mapping of all predefined feature objects accessed by name or alias. * * @example * * This will produce an array with the names and aliases of all predefined features. * * ```js * Object.keys(JScrewIt.Feature.ALL) * ``` * * This will determine if a particular feature object is predefined or not. * * ```js * featureObj === JScrewIt.Feature.ALL[featureObj.name] * ``` */ readonly ALL: FeatureAll; /** An immutable array of all elementary feature objects ordered by name. */ readonly ELEMENTARY: readonly ElementaryFeature[]; /** * Creates a new feature object from the union of the specified features. * * The constructor can be used with or without the `new` operator, e.g. * `new JScrewIt.Feature(feature1, feature2)` or `JScrewIt.Feature(feature1, feature2)`. * If no arguments are specified, the new feature object will be equivalent to * {@link FeatureConstructor.DEFAULT | `DEFAULT`}. * * @example * * The following statements are equivalent, and will all construct a new feature object * including both {@link FeatureConstructor.ANY_DOCUMENT | `ANY_DOCUMENT`} and {@link * FeatureConstructor.ANY_WINDOW | `ANY_WINDOW`}. * * ```js * JScrewIt.Feature("ANY_DOCUMENT", "ANY_WINDOW"); * ``` * * ```js * JScrewIt.Feature(JScrewIt.Feature.ANY_DOCUMENT, JScrewIt.Feature.ANY_WINDOW); * ``` * * ```js * JScrewIt.Feature([JScrewIt.Feature.ANY_DOCUMENT, JScrewIt.Feature.ANY_WINDOW]); * ``` * * @throws * * An error is thrown if any of the specified features are not mutually compatible. */ new (...features: FeatureElementOrCompatibleArray[]): CustomFeature; /** * Determines whether the specified features are mutually compatible. * * @returns * * `true` if the specified features are mutually compatible; otherwise, `false`. * If less than two features are specified, the return value is `true`. * * @example * * ```js * // false: only one of "V8_SRC" or "IE_SRC" may be available. * JScrewIt.Feature.areCompatible("V8_SRC", "IE_SRC") * ``` * * ```js * // true * JScrewIt.Feature.areCompatible(JScrewIt.Feature.DEFAULT, JScrewIt.Feature.FILL) * ``` */ areCompatible(...features: FeatureElement[]): boolean; /** * Determines whether all of the specified features are equivalent. * * Different features are considered equivalent if they include the same set of elementary * features, regardless of any other difference. * * @returns * * `true` if all of the specified features are equivalent; otherwise, `false`. * If less than two arguments are specified, the return value is `true`. * * @example * * ```js * // false * JScrewIt.Feature.areEqual(JScrewIt.Feature.CHROME, JScrewIt.Feature.FF) * ``` * * ```js * // true * JScrewIt.Feature.areEqual("DEFAULT", []) * ``` */ areEqual(...features: FeatureElementOrCompatibleArray[]): boolean; /** * Creates a new feature object equivalent to the intersection of the specified features. * * @returns * * A feature object, or `null` if no arguments are specified. * * @example * * This will create a new feature object equivalent to {@link FeatureConstructor.NAME | `NAME`}. * * ```js * const newFeature = JScrewIt.Feature.commonOf(["ATOB", "NAME"], ["NAME", "SELF"]); * ``` * * This will create a new feature object equivalent to {@link FeatureConstructor.ANY_WINDOW | * `ANY_WINDOW`}. * This is because both {@link FeatureConstructor.DOMWINDOW | `DOMWINDOW`} and {@link * FeatureConstructor.WINDOW | `WINDOW`} imply {@link FeatureConstructor.ANY_WINDOW | * `ANY_WINDOW`}. * * ```js * const newFeature = JScrewIt.Feature.commonOf("DOMWINDOW", "WINDOW"); * ``` */ commonOf(...features: FeatureElementOrCompatibleArray[]): CustomFeature | null; /** * Returns a short description of a predefined feature in plain English. * * @param name * * A name or alias of a predefined feature. * * @remarks * * Different names or aliases of the same feature may have different descriptions. * * @throws * * An error is thrown if the specified argument is not a name or alias of a predefined feature. */ descriptionFor(name: keyof FeatureAll): string; } /** * A feature object or a name or alias of a predefined feature. * * @remarks * * Methods that accept parameters of this type throw an error if the specified value is neither a * feature object nor a name or alias of a predefined feature. */ export type FeatureElement = Feature | keyof FeatureAll; /** * A feature object, a name or alias of a predefined feature, or an array of such values that * defines a union of mutually compatible features. * * @remarks * * Methods that accept parameters of this type throw an error if the specified value is neither a * feature object nor a name or alias of a predefined feature, or if it is an array of values that * does not define a union of mutually compatible features. */ export type FeatureElementOrCompatibleArray = FeatureElement | readonly FeatureElement[]; export interface PredefinedFeature extends Feature { readonly name: PredefinedFeatureName; }