Skip to content

Commit

Permalink
chore(pluginutils): Use readonly arrays, add TSDoc (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
NotWoods authored Jan 29, 2020
1 parent b3d0905 commit 07f325d
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 29 deletions.
2 changes: 1 addition & 1 deletion packages/pluginutils/src/createFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const createFilter: CreateFilter = function createFilter(include?, exclude?, opt
const includeMatchers = ensureArray(include).map(getMatcher);
const excludeMatchers = ensureArray(exclude).map(getMatcher);

return function result(id: string | any): boolean {
return function result(id: string | unknown): boolean {
if (typeof id !== 'string') return false;
if (/\0/.test(id)) return false;

Expand Down
18 changes: 9 additions & 9 deletions packages/pluginutils/src/dataToEsm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import makeLegalIdentifier from './makeLegalIdentifier';

export type Indent = string | null | undefined;

function stringify(obj: any): string {
function stringify(obj: unknown): string {
return (JSON.stringify(obj) || 'undefined').replace(
/[\u2028\u2029]/g,
(char) => `\\u${`000${char.charCodeAt(0).toString(16)}`.slice(-4)}`
);
}

function serializeArray<T>(arr: Array<T>, indent: Indent, baseIndent: string): string {
function serializeArray<T>(arr: T[], indent: Indent, baseIndent: string): string {
let output = '[';
const separator = indent ? `\n${baseIndent}${indent}` : '';
for (let i = 0; i < arr.length; i++) {
Expand All @@ -21,23 +21,23 @@ function serializeArray<T>(arr: Array<T>, indent: Indent, baseIndent: string): s
return `${output}${indent ? `\n${baseIndent}` : ''}]`;
}

function serializeObject<T>(obj: { [key: string]: T }, indent: Indent, baseIndent: string): string {
function serializeObject(obj: object, indent: Indent, baseIndent: string): string {
let output = '{';
const separator = indent ? `\n${baseIndent}${indent}` : '';
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const entries = Object.entries(obj);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
const stringKey = makeLegalIdentifier(key) === key ? key : stringify(key);
output += `${i > 0 ? ',' : ''}${separator}${stringKey}:${indent ? ' ' : ''}${serialize(
obj[key],
value,
indent,
baseIndent + indent
)}`;
}
return `${output}${indent ? `\n${baseIndent}` : ''}}`;
}

function serialize(obj: any, indent: Indent, baseIndent: string): string {
function serialize(obj: unknown, indent: Indent, baseIndent: string): string {
if (obj === Infinity) return 'Infinity';
if (obj === -Infinity) return '-Infinity';
if (obj === 0 && 1 / obj === -Infinity) return '-0';
Expand All @@ -46,7 +46,7 @@ function serialize(obj: any, indent: Indent, baseIndent: string): string {
if (obj !== obj) return 'NaN'; // eslint-disable-line no-self-compare
if (Array.isArray(obj)) return serializeArray(obj, indent, baseIndent);
if (obj === null) return 'null';
if (typeof obj === 'object') return serializeObject(obj, indent, baseIndent);
if (typeof obj === 'object') return serializeObject(obj!, indent, baseIndent);
return stringify(obj);
}

Expand Down
11 changes: 8 additions & 3 deletions packages/pluginutils/src/utils/ensureArray.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export default function ensureArray<T>(thing: Array<T> | T | undefined | null): Array<T> {
if (Array.isArray(thing)) return thing;
if (thing == undefined) return []; // eslint-disable-line no-undefined, eqeqeq
// Helper since Typescript can't detect readonly arrays with Array.isArray
function isArray(arg: unknown): arg is any[] | readonly any[] {
return Array.isArray(arg);
}

export default function ensureArray<T>(thing: readonly T[] | T | undefined | null): readonly T[] {
if (isArray(thing)) return thing;
if (thing == null) return [];
return [thing];
}
66 changes: 50 additions & 16 deletions packages/pluginutils/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,66 @@ export interface DataToEsmOptions {
preferConst?: boolean;
}

export type AddExtension = (filename: string, ext?: string) => string;
export const addExtension: AddExtension;
/**
* A valid `minimatch` pattern, or array of patterns.
*/
export type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;

export type AttachScopes = (
/**
* Adds an extension to a module ID if one does not exist.
*/
export function addExtension(filename: string, ext?: string): string;

/**
* Attaches `Scope` objects to the relevant nodes of an AST.
* Each `Scope` object has a `scope.contains(name)` method that returns `true`
* if a given name is defined in the current scope or a parent scope.
*/
export function attachScopes(
ast: BaseNode,
propertyName?: string
) => AttachedScope;
export const attachScopes: AttachScopes;

export type FilterPattern = Array<string | RegExp> | string | RegExp | null;
): AttachedScope;

export type CreateFilter = (
/**
* Constructs a filter function which can be used to determine whether or not
* certain modules should be operated upon.
* @param include If `include` is omitted or has zero length, filter will return `true` by default.
* @param exclude ID must not match any of the `exclude` patterns.
* @param options Optionally resolves the patterns against a directory other than `process.cwd()`.
* If a `string` is specified, then the value will be used as the base directory.
* Relative paths will be resolved against `process.cwd()` first.
* If `false`, then the patterns will not be resolved against any directory.
* This can be useful if you want to create a filter for virtual module names.
*/
export function createFilter(
include?: FilterPattern,
exclude?: FilterPattern,
options?: { resolve?: string | false | null }
) => (id: string | any) => boolean;
export const createFilter: CreateFilter;
): (id: string | unknown) => boolean;

/**
* Transforms objects into tree-shakable ES Module imports.
* @param data An object to transform into an ES module.
*/
export function dataToEsm(data: unknown, options?: DataToEsmOptions): string;

export type MakeLegalIdentifier = (str: string) => string;
export const makeLegalIdentifier: MakeLegalIdentifier;
/**
* Extracts the names of all assignment targets based upon specified patterns.
* @param param An `acorn` AST Node.
*/
export function extractAssignedNames(param: BaseNode): string[];

export type DataToEsm = (data: unknown, options?: DataToEsmOptions) => string;
export const dataToEsm: DataToEsm;
/**
* Constructs a bundle-safe identifier from a `string`.
*/
export function makeLegalIdentifier(str: string): string;

export type ExtractAssignedNames = (param: BaseNode) => string[];
export const extractAssignedNames: ExtractAssignedNames;
export type AddExtension = typeof addExtension;
export type AttachScopes = typeof attachScopes;
export type CreateFilter = typeof createFilter;
export type ExtractAssignedNames = typeof extractAssignedNames;
export type MakeLegalIdentifier = typeof makeLegalIdentifier;
export type DataToEsm = typeof dataToEsm;

declare const defaultExport: {
addExtension: AddExtension;
Expand Down

0 comments on commit 07f325d

Please sign in to comment.