Socket
Socket
Sign inDemoInstall

@expo/fingerprint

Package Overview
Dependencies
Maintainers
0
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expo/fingerprint - npm Package Compare versions

Comparing version 0.9.0 to 0.9.1-canary-20240625-2333e70

build/hash/ReactImportsPatcher.d.ts

1

build/Config.js

@@ -38,2 +38,3 @@ "use strict";

'sourceSkips',
'enableReactImportsPatcher',
'debug',

@@ -40,0 +41,0 @@ ];

9

build/Fingerprint.d.ts

@@ -1,2 +0,2 @@

import type { Fingerprint, FingerprintSource, Options } from './Fingerprint.types';
import type { Fingerprint, FingerprintDiffItem, Options } from './Fingerprint.types';
/**

@@ -13,6 +13,7 @@ * Create a fingerprint from project

*/
export declare function diffFingerprintChangesAsync(fingerprint: Fingerprint, projectRoot: string, options?: Options): Promise<FingerprintSource[]>;
export declare function diffFingerprintChangesAsync(fingerprint: Fingerprint, projectRoot: string, options?: Options): Promise<FingerprintDiffItem[]>;
/**
* Differentiate two fingerprints
* Differentiate two fingerprints with operation type.
* The implementation is assumed that the sources are sorted.
*/
export declare function diffFingerprints(fingerprint1: Fingerprint, fingerprint2: Fingerprint): FingerprintSource[];
export declare function diffFingerprints(fingerprint1: Fingerprint, fingerprint2: Fingerprint): FingerprintDiffItem[];

@@ -40,10 +40,40 @@ "use strict";

/**
* Differentiate two fingerprints
* Differentiate two fingerprints with operation type.
* The implementation is assumed that the sources are sorted.
*/
function diffFingerprints(fingerprint1, fingerprint2) {
return fingerprint2.sources.filter((newItem) => {
return !fingerprint1.sources.find((item) => item.type === newItem.type && item.hash === newItem.hash);
});
let index1 = 0;
let index2 = 0;
const diff = [];
while (index1 < fingerprint1.sources.length && index2 < fingerprint2.sources.length) {
const source1 = fingerprint1.sources[index1];
const source2 = fingerprint2.sources[index2];
const compareResult = (0, Sort_1.compareSource)(source1, source2);
if (compareResult === 0) {
if (source1.hash !== source2.hash) {
diff.push({ op: 'changed', source: source2 });
}
++index1;
++index2;
}
else if (compareResult < 0) {
diff.push({ op: 'removed', source: source1 });
++index1;
}
else {
diff.push({ op: 'added', source: source2 });
++index2;
}
}
while (index1 < fingerprint1.sources.length) {
diff.push({ op: 'removed', source: fingerprint1.sources[index1] });
++index1;
}
while (index2 < fingerprint2.sources.length) {
diff.push({ op: 'added', source: fingerprint2.sources[index2] });
++index2;
}
return diff;
}
exports.diffFingerprints = diffFingerprints;
//# sourceMappingURL=Fingerprint.js.map

@@ -25,2 +25,15 @@ /// <reference types="node" />

}
export interface FingerprintDiffItem {
/**
* The operation type of the diff item.
*/
op: 'added' | 'removed' | 'changed';
/**
* The source of the diff item.
* - When type is 'added', the source is the new source.
* - When type is 'removed', the source is the old source.
* - When type is 'changed', the source is the new source.
*/
source: FingerprintSource;
}
export type Platform = 'android' | 'ios';

@@ -62,6 +75,13 @@ export interface Options {

* Skips some sources from fingerprint.
* @default SourceSkips.None
* @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
*/
enableReactImportsPatcher?: boolean;
/**
* Whether running the functions should mute all console output. This is useful when fingerprinting is being done as

@@ -79,3 +99,3 @@ * part of a CLI that outputs a fingerprint and outputting anything else pollutes the results.

*/
export type Config = Pick<Options, 'concurrentIoLimit' | 'hashAlgorithm' | 'extraSources' | 'sourceSkips' | 'debug'>;
export type Config = Pick<Options, 'concurrentIoLimit' | 'hashAlgorithm' | 'extraSources' | 'sourceSkips' | 'enableReactImportsPatcher' | 'debug'>;
export interface NormalizedOptions extends Options {

@@ -87,2 +107,3 @@ platforms: NonNullable<Options['platforms']>;

sourceSkips: NonNullable<Options['sourceSkips']>;
enableReactImportsPatcher: NonNullable<Options['enableReactImportsPatcher']>;
}

@@ -89,0 +110,0 @@ export interface HashSourceFile {

@@ -12,2 +12,4 @@ "use strict";

const path_1 = __importDefault(require("path"));
const stream_1 = require("stream");
const ReactImportsPatcher_1 = require("./ReactImportsPatcher");
const Path_1 = require("../utils/Path");

@@ -94,3 +96,15 @@ const Predicates_1 = require("../utils/Predicates");

const hasher = (0, crypto_1.createHash)(options.hashAlgorithm);
const stream = (0, fs_1.createReadStream)(path_1.default.join(projectRoot, filePath));
let stream = (0, fs_1.createReadStream)(path_1.default.join(projectRoot, filePath), {
highWaterMark: 1024,
});
if (options.enableReactImportsPatcher &&
options.platforms.includes('ios') &&
(filePath.endsWith('.h') || filePath.endsWith('.m') || filePath.endsWith('.mm'))) {
const transform = new ReactImportsPatcher_1.ReactImportsPatchTransform();
stream = (0, stream_1.pipeline)(stream, transform, (err) => {
if (err) {
reject(err);
}
});
}
stream.on('close', () => {

@@ -97,0 +111,0 @@ if (!resolved) {

export * from './Fingerprint';
export * from './Fingerprint.types';
export * from './sourcer/SourceSkips';
export { DEFAULT_IGNORE_PATHS, DEFAULT_SOURCE_SKIPS } from './Options';

@@ -17,5 +17,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_SOURCE_SKIPS = exports.DEFAULT_IGNORE_PATHS = void 0;
__exportStar(require("./Fingerprint"), exports);
__exportStar(require("./Fingerprint.types"), exports);
__exportStar(require("./sourcer/SourceSkips"), exports);
var Options_1 = require("./Options");
Object.defineProperty(exports, "DEFAULT_IGNORE_PATHS", { enumerable: true, get: function () { return Options_1.DEFAULT_IGNORE_PATHS; } });
Object.defineProperty(exports, "DEFAULT_SOURCE_SKIPS", { enumerable: true, get: function () { return Options_1.DEFAULT_SOURCE_SKIPS; } });
//# sourceMappingURL=index.js.map
import type { NormalizedOptions, Options } from './Fingerprint.types';
import { SourceSkips } from './sourcer/SourceSkips';
export declare const FINGERPRINT_IGNORE_FILENAME = ".fingerprintignore";
export declare const DEFAULT_IGNORE_PATHS: string[];
export declare const DEFAULT_SOURCE_SKIPS = SourceSkips.PackageJsonAndroidAndIosScriptsIfNotContainRun;
export declare function normalizeOptionsAsync(projectRoot: string, options?: Options): Promise<NormalizedOptions>;

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeOptionsAsync = exports.DEFAULT_IGNORE_PATHS = exports.FINGERPRINT_IGNORE_FILENAME = void 0;
exports.normalizeOptionsAsync = exports.DEFAULT_SOURCE_SKIPS = exports.DEFAULT_IGNORE_PATHS = exports.FINGERPRINT_IGNORE_FILENAME = void 0;
const promises_1 = __importDefault(require("fs/promises"));

@@ -75,2 +75,3 @@ const os_1 = __importDefault(require("os"));

];
exports.DEFAULT_SOURCE_SKIPS = SourceSkips_1.SourceSkips.PackageJsonAndroidAndIosScriptsIfNotContainRun;
async function normalizeOptionsAsync(projectRoot, options) {

@@ -83,4 +84,4 @@ const config = await (0, Config_1.loadConfigAsync)(projectRoot, options?.silent ?? false);

hashAlgorithm: 'sha1',
ignorePaths: await collectIgnorePathsAsync(projectRoot, options),
sourceSkips: SourceSkips_1.SourceSkips.None,
sourceSkips: exports.DEFAULT_SOURCE_SKIPS,
enableReactImportsPatcher: true,
// Options from config

@@ -90,2 +91,4 @@ ...config,

...options,
// These options are computed by both default and explicit options, so we put them last.
ignorePaths: await collectIgnorePathsAsync(projectRoot, options),
};

@@ -92,0 +95,0 @@ }

import type { HashSource } from './Fingerprint.types';
export declare function sortSources<T extends HashSource>(sources: T[]): T[];
/**
* Comparator between two sources.
* This is useful for sorting sources in a consistent order.
* @returns:
* == 0 if a and b are equal,
* < 0 if a is less than b,
* > 0 if a is greater than b.
*/
export declare function compareSource(a: HashSource, b: HashSource): number;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sortSources = void 0;
exports.compareSource = exports.sortSources = void 0;
function sortSources(sources) {
const typeOrder = {
file: 0,
dir: 1,
contents: 2,
};
return sources.sort((a, b) => {
const typeResult = typeOrder[a.type] - typeOrder[b.type];
if (typeResult === 0) {
if (a.type === 'file' && b.type === 'file') {
return a.filePath.localeCompare(b.filePath);
}
else if (a.type === 'dir' && b.type === 'dir') {
return a.filePath.localeCompare(b.filePath);
}
else if (a.type === 'contents' && b.type === 'contents') {
return a.id.localeCompare(b.id);
}
return sources.sort(compareSource);
}
exports.sortSources = sortSources;
const typeOrder = {
file: 0,
dir: 1,
contents: 2,
};
/**
* Comparator between two sources.
* This is useful for sorting sources in a consistent order.
* @returns:
* == 0 if a and b are equal,
* < 0 if a is less than b,
* > 0 if a is greater than b.
*/
function compareSource(a, b) {
const typeResult = typeOrder[a.type] - typeOrder[b.type];
if (typeResult === 0) {
if (a.type === 'file' && b.type === 'file') {
return a.filePath.localeCompare(b.filePath);
}
return typeResult;
});
else if (a.type === 'dir' && b.type === 'dir') {
return a.filePath.localeCompare(b.filePath);
}
else if (a.type === 'contents' && b.type === 'contents') {
return a.id.localeCompare(b.id);
}
}
return typeResult;
}
exports.sortSources = sortSources;
exports.compareSource = compareSource;
//# sourceMappingURL=Sort.js.map

@@ -12,2 +12,3 @@ "use strict";

const resolve_from_1 = __importDefault(require("resolve-from"));
const SourceSkips_1 = require("./SourceSkips");
const Utils_1 = require("./Utils");

@@ -53,3 +54,3 @@ const debug = require('debug')('expo:fingerprint:sourcer:Bare');

id,
contents: JSON.stringify(packageJson.scripts),
contents: normalizePackageJsonScriptSources(packageJson.scripts, options),
reasons: [id],

@@ -114,2 +115,14 @@ });

}
function normalizePackageJsonScriptSources(scripts, options) {
if (options.sourceSkips & SourceSkips_1.SourceSkips.PackageJsonAndroidAndIosScriptsIfNotContainRun) {
// Replicate the behavior of `expo prebuild`
if (!scripts.android?.includes('run')) {
delete scripts.android;
}
if (!scripts.ios?.includes('run')) {
delete scripts.ios;
}
}
return JSON.stringify(scripts);
}
//# sourceMappingURL=Bare.js.map

@@ -26,5 +26,6 @@ "use strict";

let loadedModules = [];
const ignoredFile = await createTempIgnoredFileAsync(options);
const tmpDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'expo-fingerprint-'));
const ignoredFile = await createTempIgnoredFileAsync(tmpDir, options);
try {
const { stdout } = await (0, spawn_async_1.default)('node', [(0, ExpoConfigLoader_1.getExpoConfigLoaderPath)(), path_1.default.resolve(projectRoot), ignoredFile], { cwd: __dirname });
const { stdout } = await (0, spawn_async_1.default)('node', [(0, ExpoConfigLoader_1.getExpoConfigLoaderPath)(), path_1.default.resolve(projectRoot), ignoredFile], { cwd: projectRoot });
const stdoutJson = JSON.parse(stdout);

@@ -47,2 +48,8 @@ config = stdoutJson.config;

}
finally {
try {
await promises_1.default.rm(tmpDir, { recursive: true });
}
catch { }
}
// external files in config

@@ -153,5 +160,4 @@ const isAndroid = options.platforms.includes('android');

*/
async function createTempIgnoredFileAsync(options) {
await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'expo-fingerprint-'));
const ignoredFile = path_1.default.join(os_1.default.tmpdir(), '.fingerprintignore');
async function createTempIgnoredFileAsync(tmpDir, options) {
const ignoredFile = path_1.default.join(tmpDir, '.fingerprintignore');
await promises_1.default.writeFile(ignoredFile, options.ignorePaths.join('\n'));

@@ -158,0 +164,0 @@ return ignoredFile;

@@ -67,6 +67,2 @@ "use strict";

catch { }
try {
await promises_1.default.rm(ignoredFile);
}
catch { }
return ignorePaths;

@@ -73,0 +69,0 @@ }

@@ -13,3 +13,4 @@ /**

ExpoConfigEASProject = 64,
ExpoConfigAssets = 128
ExpoConfigAssets = 128,
PackageJsonAndroidAndIosScriptsIfNotContainRun = 256
}

@@ -27,3 +27,7 @@ "use strict";

SourceSkips[SourceSkips["ExpoConfigAssets"] = 128] = "ExpoConfigAssets";
// package.json scripts if android and ios items do not contain "run".
// Because prebuild will change the scripts in package.json,
// this is useful to generate a consistent fingerprint before and after prebuild.
SourceSkips[SourceSkips["PackageJsonAndroidAndIosScriptsIfNotContainRun"] = 256] = "PackageJsonAndroidAndIosScriptsIfNotContainRun";
})(SourceSkips || (exports.SourceSkips = SourceSkips = {}));
//# sourceMappingURL=SourceSkips.js.map
{
"name": "@expo/fingerprint",
"version": "0.9.0",
"version": "0.9.1-canary-20240625-2333e70",
"description": "A library to generate a fingerprint from a React Native project",

@@ -55,8 +55,8 @@ "main": "build/index.js",

"@types/find-up": "^4.0.0",
"expo-module-scripts": "^3.3.0",
"glob": "^7.1.7",
"expo-module-scripts": "3.6.0-canary-20240625-2333e70",
"glob": "^10.4.2",
"require-from-string": "^2.0.2",
"temp-dir": "^2.0.0"
},
"gitHead": "b5404611ac2ff4512eccad0c3fa507e7f365ddce"
"gitHead": "2333e70a4bd3ac91895402dac77ae8ae0ed25995"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc