UNPKG

@expo/fingerprint

Version:

A library to generate a fingerprint from a React Native project

256 lines (255 loc) 7.94 kB
import type { Minimatch } from 'minimatch'; import type { SourceSkips } from './sourcer/SourceSkips'; export type FingerprintSource = HashSource & { /** * Hash value of the `source`. * If the source is excluded the value will be null. */ hash: string | null; /** * Debug info from the hashing process. Differs based on source type. Designed to be consumed by humans * as opposed to programmatically. */ debugInfo?: DebugInfo; }; export interface Fingerprint { /** * Sources and their hash values from which the project fingerprint was generated. */ sources: FingerprintSource[]; /** * The final hash value of the whole project fingerprint. */ hash: string; } export type FingerprintDiffItem = { /** * The operation type of the diff item. */ op: 'added'; /** * The added source. */ addedSource: FingerprintSource; } | { /** * The operation type of the diff item. */ op: 'removed'; /** * The removed source. */ removedSource: FingerprintSource; } | { /** * The operation type of the diff item. */ op: 'changed'; /** * The source before. */ beforeSource: FingerprintSource; /** * The source after. */ afterSource: FingerprintSource; }; export type Platform = 'android' | 'ios'; export type ProjectWorkflow = 'generic' | 'managed' | 'unknown'; export interface Options { /** * Limit native files to those for specified platforms. * @default ['android', 'ios'] */ platforms?: Platform[]; /** * I/O concurrency limit. * @default The number of CPU cores. */ concurrentIoLimit?: number; /** * The algorithm to use for `crypto.createHash()`. * @default 'sha1' */ hashAlgorithm?: string; /** * Exclude specified directories from hashing. The supported pattern is the same as `glob()`. * Default is `['android/build', 'android/app/build', 'android/app/.cxx', 'ios/Pods']`. * @deprecated Use `ignorePaths` instead. */ dirExcludes?: string[]; /** * Ignore files and directories from hashing. The supported pattern is the same as `glob()`. * * The pattern matching is slightly different from gitignore. Partial matching is unsupported. For example, `build` does not match `android/build`; instead, use `'**' + '/build'`. * @see [minimatch implementations](https://github.com/isaacs/minimatch#comparisons-to-other-fnmatchglob-implementations) for further reference. * * Fingerprint comes with implicit default ignorePaths defined in `Options.DEFAULT_IGNORE_PATHS`. * If you want to override the default ignorePaths, use `!` prefix in `ignorePaths`. */ ignorePaths?: string[]; /** * Additional sources for hashing. */ extraSources?: HashSource[]; /** * Skips some sources from fingerprint. Value is the result of bitwise-OR'ing desired values of SourceSkips. * @default DEFAULT_SOURCE_SKIPS */ sourceSkips?: SourceSkips; /** * Enable ReactImportsPatcher to transform imports from React of the form `#import "RCTBridge.h"` to `#import <React/RCTBridge.h>`. * This is useful when you want to have a stable fingerprint for Expo projects, * since expo-modules-autolinking will change the import style on iOS. * @default true for Expo SDK 51 and lower. */ enableReactImportsPatcher?: boolean; /** * Use the react-native core autolinking sources from `expo-modules-autolinking` rather than `@react-native-community/cli`. * @default true for Expo SDK 52 and higher. */ useRNCoreAutolinkingFromExpo?: boolean; /** * Whether running the functions should mute all console output. This is useful when fingerprinting is being done as * part of a CLI that outputs a fingerprint and outputting anything else pollutes the results. */ silent?: boolean; /** * Whether to include verbose debug info in source output. Useful for debugging. */ debug?: boolean; /** * A custom hook function to transform file content sources before hashing. */ fileHookTransform?: FileHookTransformFunction; } type SourceSkipsKeys = keyof typeof SourceSkips; /** * Supported options for use in fingerprint.config.js */ export type Config = Pick<Options, 'concurrentIoLimit' | 'hashAlgorithm' | 'ignorePaths' | 'extraSources' | 'enableReactImportsPatcher' | 'useRNCoreAutolinkingFromExpo' | 'debug' | 'fileHookTransform'> & { sourceSkips?: SourceSkips | SourceSkipsKeys[]; }; /** * Hook function to transform file content sources before hashing. */ export type FileHookTransformFunction = ( /** * Source from HashSourceFile or HashSourceContents. */ source: FileHookTransformSource, /** * The chunk of file content. * When the stream reaches the end, the chunk will be null. */ chunk: Buffer | string | null, /** * Indicates the end of the file. */ isEndOfFile: boolean, /** * The encoding of the chunk. */ encoding: BufferEncoding) => Buffer | string | null; /** * The `source` parameter for `FileHookTransformFunction`. */ export type FileHookTransformSource = { type: 'file'; filePath: string; } | { type: 'contents'; id: string; }; export interface HashSourceFile { type: 'file'; filePath: string; /** * Reasons of this source coming from. */ reasons: string[]; /** * Override key for hashing. * Without this key, the `filePath` is used as the hash key. */ overrideHashKey?: string; } export interface HashSourceDir { type: 'dir'; filePath: string; /** * Reasons of this source coming from. */ reasons: string[]; /** * Override key for hashing. * Without this key, the `filePath` is used as the hash key. */ overrideHashKey?: string; } export interface HashSourceContents { type: 'contents'; id: string; contents: string | Buffer; /** * Reasons of this source coming from. */ reasons: string[]; } export type HashSource = HashSourceFile | HashSourceDir | HashSourceContents; export interface DebugInfoFile { path: string; hash: string; /** Indicates whether the source is transformed by `fileHookTransform`. */ isTransformed?: boolean; } export interface DebugInfoDir { path: string; hash: string; children: (DebugInfoFile | DebugInfoDir | undefined)[]; } export interface DebugInfoContents { hash: string; /** Indicates whether the source is transformed by `fileHookTransform`. */ isTransformed?: boolean; } export type DebugInfo = DebugInfoFile | DebugInfoDir | DebugInfoContents; export interface HashResultFile { type: 'file'; id: string; hex: string; debugInfo?: DebugInfoFile; } export interface HashResultDir { type: 'dir'; id: string; hex: string; debugInfo?: DebugInfoDir; } export interface HashResultContents { type: 'contents'; id: string; hex: string; debugInfo?: DebugInfoContents; } export type HashResult = HashResultFile | HashResultDir | HashResultContents; /** * @hidden */ export type NormalizedOptions = Omit<Options, 'ignorePaths'> & { platforms: NonNullable<Options['platforms']>; concurrentIoLimit: NonNullable<Options['concurrentIoLimit']>; hashAlgorithm: NonNullable<Options['hashAlgorithm']>; sourceSkips: NonNullable<Options['sourceSkips']>; enableReactImportsPatcher: NonNullable<Options['enableReactImportsPatcher']>; ignorePathMatchObjects: Minimatch[]; /** * A ignore pattern list specific for dir matching. It is built by `ignorePathMatchObjects` in runtime. */ ignoreDirMatchObjects: Minimatch[]; /** * Indicate whether the project is using CNG for each platform. */ useCNGForPlatforms: Record<Platform, boolean>; }; export {};