@datafog/node 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
Binary file
Binary file
Binary file
package/index.d.ts ADDED
@@ -0,0 +1,284 @@
1
+ /** Canonical built-in values are uppercase, but custom detectors may add values. */
2
+ export type EntityType = string;
3
+
4
+ export type TransformationStrategy =
5
+ | "redact"
6
+ | "mask"
7
+ | "remove"
8
+ | "pseudonymize"
9
+ | "tokenize";
10
+
11
+ export interface MaskRevealConfig {
12
+ readonly direction: "first" | "last";
13
+ readonly count: number;
14
+ }
15
+
16
+ export type TransformationStrategyConfig =
17
+ | { readonly strategy: "redact" }
18
+ | { readonly strategy: "remove" }
19
+ | {
20
+ readonly strategy: "pseudonymize";
21
+ readonly key_ref: string;
22
+ readonly key_version?: string;
23
+ }
24
+ | {
25
+ readonly strategy: "tokenize";
26
+ readonly token_ref: string;
27
+ }
28
+ | {
29
+ readonly strategy: "mask";
30
+ readonly character?: string;
31
+ readonly reveal?: MaskRevealConfig;
32
+ };
33
+
34
+ export interface RegexAllowRule {
35
+ readonly pattern: string;
36
+ readonly case_sensitive?: boolean;
37
+ }
38
+
39
+ export interface AllowConfig {
40
+ readonly exact?: Readonly<Record<EntityType, readonly string[]>>;
41
+ readonly regex?: Readonly<Record<EntityType, readonly RegexAllowRule[]>>;
42
+ }
43
+
44
+ export interface TransformationConfig {
45
+ readonly default: TransformationStrategyConfig;
46
+ readonly entities?: readonly EntityType[];
47
+ readonly overrides?: Readonly<Record<EntityType, TransformationStrategyConfig>>;
48
+ readonly allow?: AllowConfig;
49
+ }
50
+
51
+ export interface ScanConfig {
52
+ readonly locale?: string;
53
+ }
54
+
55
+ export interface ScanAndTransformConfig {
56
+ readonly scan?: ScanConfig;
57
+ readonly transform: TransformationConfig;
58
+ }
59
+
60
+ export type DataFogErrorCode =
61
+ | "invalid_configuration"
62
+ | "invalid_finding"
63
+ | "key_provider_required"
64
+ | "key_not_found"
65
+ | "key_access_denied"
66
+ | "key_provider_unavailable"
67
+ | "invalid_key_material"
68
+ | "key_provider_error"
69
+ | "token_provider_required"
70
+ | "invalid_token"
71
+ | "unsupported_token_version"
72
+ | "token_not_found"
73
+ | "token_expired"
74
+ | "token_access_denied"
75
+ | "invalid_token_material"
76
+ | "token_provider_unavailable"
77
+ | "token_provider_error"
78
+ | "unsupported_strategy"
79
+ | "internal_error";
80
+
81
+ export declare class DataFogError extends Error {
82
+ readonly code: DataFogErrorCode;
83
+ readonly reason?: string;
84
+ readonly path?: string;
85
+ readonly findingIndex?: number;
86
+ }
87
+
88
+ export interface KeyProviderRequest {
89
+ readonly keyRef: string;
90
+ readonly keyVersion?: string;
91
+ }
92
+
93
+ export interface KeyProviderResponse {
94
+ readonly key: Uint8Array;
95
+ readonly resolvedVersion: string;
96
+ }
97
+
98
+ export interface KeyProvider {
99
+ resolveKey(request: KeyProviderRequest): Promise<KeyProviderResponse>;
100
+ }
101
+
102
+ export interface PrivacyContext {
103
+ readonly scope: string;
104
+ }
105
+
106
+ export interface TokenizeProviderItem {
107
+ readonly id: string;
108
+ readonly exactValue: string;
109
+ readonly tokenRef: string;
110
+ }
111
+
112
+ export interface TokenizeProviderResult {
113
+ readonly id: string;
114
+ readonly payload: Uint8Array;
115
+ readonly resolvedVersion: string;
116
+ }
117
+
118
+ export interface RestoreProviderItem {
119
+ readonly id: string;
120
+ readonly tokenRef: string;
121
+ readonly resolvedVersion: string;
122
+ readonly payload: Uint8Array;
123
+ }
124
+
125
+ export interface RestoreProviderResult {
126
+ readonly id: string;
127
+ readonly value: string;
128
+ }
129
+
130
+ export interface TokenProvider {
131
+ tokenizeBatch(scope: string, items: TokenizeProviderItem[]): Promise<TokenizeProviderResult[]>;
132
+ restoreBatch(scope: string, items: RestoreProviderItem[]): Promise<RestoreProviderResult[]>;
133
+ }
134
+
135
+ export interface PrivacyManagerProviders {
136
+ readonly keyProvider?: KeyProvider;
137
+ readonly tokenProvider?: TokenProvider;
138
+ }
139
+
140
+ export declare class PrivacyManager {
141
+ constructor(provider: KeyProvider | PrivacyManagerProviders, tokenProvider?: TokenProvider);
142
+ transform(
143
+ text: string,
144
+ findings: FindingInput[],
145
+ config: TransformationConfig,
146
+ context?: PrivacyContext,
147
+ ): Promise<TransformResult>;
148
+ scanAndTransform(
149
+ text: string,
150
+ config: ScanAndTransformConfig,
151
+ context?: PrivacyContext,
152
+ ): Promise<TransformResult>;
153
+ restore(text: string, context: PrivacyContext): Promise<RestoreResult>;
154
+ }
155
+ export interface Finding {
156
+ readonly entityType: EntityType
157
+ readonly matchedText: string
158
+ readonly byteRange: TextRange
159
+ readonly codepointRange: TextRange
160
+ readonly utf16Range: TextRange
161
+ readonly confidence?: number
162
+ readonly detectorName: string
163
+ readonly detectorVersion?: string
164
+ }
165
+
166
+ export interface FindingInput {
167
+ entityType: EntityType
168
+ matchedText: string
169
+ byteRange: TextRange
170
+ codepointRange: TextRange
171
+ confidence?: number
172
+ detectorName: string
173
+ detectorVersion?: string
174
+ }
175
+
176
+ export interface KeySelector {
177
+ readonly index: number
178
+ readonly keyRef: string
179
+ readonly keyVersion?: string
180
+ readonly path: string
181
+ }
182
+
183
+ export interface PreparedScanAndTransform {
184
+ readonly findings: Array<Finding>
185
+ readonly selectors: Array<KeySelector>
186
+ }
187
+
188
+ export declare function prepareScanAndTransform(text: string, config: ScanAndTransformConfig): PreparedScanAndTransform
189
+
190
+ export declare function requiredKeySelectors(text: string, findings: FindingInput[], config: TransformationConfig): Array<KeySelector>
191
+
192
+ export declare function requiredRestoreItems(text: string, context: PrivacyContext): Array<RestoreItem>
193
+
194
+ export declare function requiredTokenizationItems(text: string, findings: FindingInput[], config: TransformationConfig, context?: PrivacyContext | undefined): Array<TokenizeItem>
195
+
196
+ export interface ResolvedKeyInput {
197
+ selectorIndex: number
198
+ key: Uint8Array
199
+ resolvedVersion: string
200
+ }
201
+
202
+ export interface Restoration {
203
+ readonly sourceByteRange: TextRange
204
+ readonly sourceCodepointRange: TextRange
205
+ readonly sourceUtf16Range: TextRange
206
+ readonly outputByteRange: TextRange
207
+ readonly outputCodepointRange: TextRange
208
+ readonly outputUtf16Range: TextRange
209
+ readonly tokenRef: string
210
+ readonly resolvedTokenVersion: string
211
+ }
212
+
213
+ export interface RestoredValueInput {
214
+ id: string
215
+ value: string
216
+ }
217
+
218
+ export interface RestoreItem {
219
+ readonly id: string
220
+ readonly tokenRef: string
221
+ readonly resolvedVersion: string
222
+ readonly payload: Uint8Array
223
+ }
224
+
225
+ export interface RestoreResult {
226
+ readonly text: string
227
+ readonly restorations: Array<Restoration>
228
+ }
229
+
230
+ export declare function restoreWithResults(text: string, context: PrivacyContext, results: Array<RestoredValueInput>): RestoreResult
231
+
232
+ /** Scan text for supported PII findings. */
233
+ export declare function scan(text: string, config?: ScanConfig | undefined): Array<Finding>
234
+
235
+ /** Scan text and transform the detected findings. */
236
+ export declare function scanAndTransform(text: string, config: ScanAndTransformConfig): TransformResult
237
+
238
+ export interface TextRange {
239
+ readonly start: number
240
+ readonly end: number
241
+ }
242
+
243
+ export interface TokenizeItem {
244
+ readonly id: string
245
+ readonly exactValue: string
246
+ readonly tokenRef: string
247
+ }
248
+
249
+ export interface TokenizeResultInput {
250
+ id: string
251
+ payload: Uint8Array
252
+ resolvedVersion: string
253
+ }
254
+
255
+ /** Transform explicit findings without scanning implicitly. */
256
+ export declare function transform(text: string, findings: FindingInput[], config: TransformationConfig): TransformResult
257
+
258
+ export interface Transformation {
259
+ readonly entityType: string
260
+ readonly sourceByteRange: TextRange
261
+ readonly sourceCodepointRange: TextRange
262
+ readonly sourceUtf16Range: TextRange
263
+ readonly confidence?: number
264
+ readonly detectorName: string
265
+ readonly detectorVersion?: string
266
+ readonly strategy: TransformationStrategy
267
+ readonly replacement: string
268
+ readonly outputByteRange: TextRange
269
+ readonly outputCodepointRange: TextRange
270
+ readonly outputUtf16Range: TextRange
271
+ readonly keyRef?: string
272
+ readonly resolvedKeyVersion?: string
273
+ readonly tokenRef?: string
274
+ readonly resolvedTokenVersion?: string
275
+ }
276
+
277
+ export interface TransformResult {
278
+ readonly text: string
279
+ readonly transformations: Array<Transformation>
280
+ }
281
+
282
+ export declare function transformWithProviderResults(text: string, findings: FindingInput[], config: TransformationConfig, context: PrivacyContext | undefined, resolvedKeys: Array<ResolvedKeyInput>, tokenResults: Array<TokenizeResultInput>): TransformResult
283
+
284
+ export declare function transformWithResolvedKeys(text: string, findings: FindingInput[], config: TransformationConfig, resolvedKeys: Array<ResolvedKeyInput>): TransformResult
package/index.js ADDED
@@ -0,0 +1,289 @@
1
+ import { Buffer } from "node:buffer";
2
+ import {
3
+ prepareScanAndTransform as nativePrepareScanAndTransform,
4
+ requiredKeySelectors as nativeRequiredKeySelectors,
5
+ requiredRestoreItems as nativeRequiredRestoreItems,
6
+ requiredTokenizationItems as nativeRequiredTokenizationItems,
7
+ restoreWithResults as nativeRestoreWithResults,
8
+ scan as nativeScan,
9
+ scanAndTransform as nativeScanAndTransform,
10
+ transform as nativeTransform,
11
+ transformWithProviderResults as nativeTransformWithProviderResults,
12
+ } from "./native.js";
13
+
14
+ export class DataFogError extends Error {
15
+ constructor({ code, reason, message, path, findingIndex }) {
16
+ super(message);
17
+ this.name = "DataFogError";
18
+ this.code = code;
19
+ this.reason = reason;
20
+ this.path = path;
21
+ this.findingIndex = findingIndex;
22
+ }
23
+ }
24
+
25
+ function normalizeError(error, fallbackCode) {
26
+ if (error instanceof DataFogError) return error;
27
+ try {
28
+ const details = JSON.parse(error?.message ?? "");
29
+ if (typeof details.code === "string" && typeof details.message === "string") {
30
+ return new DataFogError(details);
31
+ }
32
+ } catch {
33
+ // Native conversion errors use the operation-specific fallback below.
34
+ }
35
+ return new DataFogError({
36
+ code: fallbackCode,
37
+ reason: fallbackCode === "invalid_configuration" ? "invalid_type" : undefined,
38
+ message:
39
+ fallbackCode === "invalid_configuration"
40
+ ? "request configuration could not be decoded"
41
+ : "the native operation failed unexpectedly",
42
+ path: fallbackCode === "invalid_configuration" ? "" : undefined,
43
+ });
44
+ }
45
+
46
+ const providerErrorMessages = {
47
+ key_not_found: "key provider could not find the requested key",
48
+ key_access_denied: "key provider denied access to the requested key",
49
+ key_provider_unavailable: "key provider is temporarily unavailable",
50
+ key_provider_error: "key provider could not resolve the requested key",
51
+ token_not_found: "token was not found",
52
+ token_expired: "token has expired",
53
+ token_access_denied: "token access was denied",
54
+ token_provider_unavailable: "token provider is temporarily unavailable",
55
+ token_provider_error: "token provider could not complete the request",
56
+ };
57
+
58
+ function normalizeProviderError(error, path, fallback = "key_provider_error") {
59
+ const candidateCode = error?.code;
60
+ const expectedPrefix = fallback.startsWith("token_") ? "token_" : "key_";
61
+ const code =
62
+ typeof candidateCode === "string" &&
63
+ candidateCode.startsWith(expectedPrefix) &&
64
+ candidateCode in providerErrorMessages
65
+ ? candidateCode
66
+ : fallback;
67
+ return new DataFogError({
68
+ code,
69
+ message: providerErrorMessages[code],
70
+ path,
71
+ });
72
+ }
73
+
74
+ function withPathPrefix(error, prefix) {
75
+ const normalized = normalizeError(error, "internal_error");
76
+ return new DataFogError({
77
+ code: normalized.code,
78
+ reason: normalized.reason,
79
+ message: normalized.message,
80
+ path: normalized.path ? `${prefix}${normalized.path}` : normalized.path,
81
+ findingIndex: normalized.findingIndex,
82
+ });
83
+ }
84
+
85
+ function resolvedKeyInput(selector, response) {
86
+ if (
87
+ !response ||
88
+ !(response.key instanceof Uint8Array) ||
89
+ typeof response.resolvedVersion !== "string"
90
+ ) {
91
+ return {
92
+ selectorIndex: selector.index,
93
+ key: Buffer.alloc(0),
94
+ resolvedVersion: "",
95
+ };
96
+ }
97
+ return {
98
+ selectorIndex: selector.index,
99
+ key: Buffer.from(response.key),
100
+ resolvedVersion: response.resolvedVersion,
101
+ };
102
+ }
103
+
104
+ export class PrivacyManager {
105
+ #keyProvider;
106
+ #tokenProvider;
107
+
108
+ constructor(provider, tokenProvider) {
109
+ const options = provider && ("keyProvider" in provider || "tokenProvider" in provider)
110
+ ? provider
111
+ : { keyProvider: provider, tokenProvider };
112
+ if (options.keyProvider && typeof options.keyProvider.resolveKey !== "function") {
113
+ throw new TypeError("key provider must define resolveKey(request)");
114
+ }
115
+ if (options.tokenProvider &&
116
+ (typeof options.tokenProvider.tokenizeBatch !== "function" ||
117
+ typeof options.tokenProvider.restoreBatch !== "function")) {
118
+ throw new TypeError("token provider must define tokenizeBatch(scope, items) and restoreBatch(scope, items)");
119
+ }
120
+ this.#keyProvider = options.keyProvider;
121
+ this.#tokenProvider = options.tokenProvider;
122
+ }
123
+
124
+ async #resolve(selectors, pathPrefix = "") {
125
+ const resolved = [];
126
+ if (selectors.length > 0 && !this.#keyProvider) {
127
+ throw new DataFogError({
128
+ code: "key_provider_required",
129
+ message: "pseudonymization requires a runtime key provider",
130
+ path: `${pathPrefix}${selectors[0].path}`,
131
+ });
132
+ }
133
+ for (const selector of selectors) {
134
+ let response;
135
+ try {
136
+ response = await this.#keyProvider.resolveKey({
137
+ keyRef: selector.keyRef,
138
+ keyVersion: selector.keyVersion,
139
+ });
140
+ } catch (error) {
141
+ throw normalizeProviderError(error, `${pathPrefix}${selector.path}`);
142
+ }
143
+ resolved.push(resolvedKeyInput(selector, response));
144
+ }
145
+ return resolved;
146
+ }
147
+
148
+ async #tokenize(items, context) {
149
+ if (items.length === 0) return [];
150
+ if (!this.#tokenProvider) {
151
+ throw new DataFogError({
152
+ code: "token_provider_required",
153
+ message: "tokenization requires a runtime token provider and request scope",
154
+ });
155
+ }
156
+ let results;
157
+ try {
158
+ results = await this.#tokenProvider.tokenizeBatch(context.scope, items);
159
+ } catch (error) {
160
+ throw normalizeProviderError(error, undefined, "token_provider_error");
161
+ }
162
+ if (!Array.isArray(results)) return [];
163
+ return results.map((result) => ({
164
+ id: result?.id ?? "",
165
+ payload: result?.payload instanceof Uint8Array ? Buffer.from(result.payload) : Buffer.alloc(0),
166
+ resolvedVersion: typeof result?.resolvedVersion === "string" ? result.resolvedVersion : "",
167
+ }));
168
+ }
169
+
170
+ async transform(text, findings, config, context) {
171
+ if (typeof text !== "string") {
172
+ throw new TypeError("transform text must be a string");
173
+ }
174
+ if (!Array.isArray(findings)) {
175
+ throw new TypeError("transform findings must be an array");
176
+ }
177
+ let resolved = [];
178
+ try {
179
+ const selectors = nativeRequiredKeySelectors(text, findings, config);
180
+ resolved = await this.#resolve(selectors);
181
+ const items = nativeRequiredTokenizationItems(text, findings, config, context);
182
+ const tokens = await this.#tokenize(items, context);
183
+ return nativeTransformWithProviderResults(text, findings, config, context, resolved, tokens);
184
+ } catch (error) {
185
+ if (error instanceof DataFogError) throw error;
186
+ throw normalizeError(error, "invalid_configuration");
187
+ } finally {
188
+ resolved.forEach(({ key }) => key.fill(0));
189
+ }
190
+ }
191
+
192
+ async scanAndTransform(text, config, context) {
193
+ if (typeof text !== "string") {
194
+ throw new TypeError("scanAndTransform text must be a string");
195
+ }
196
+ let prepared;
197
+ try {
198
+ prepared = nativePrepareScanAndTransform(text, config);
199
+ } catch (error) {
200
+ throw normalizeError(error, "invalid_configuration");
201
+ }
202
+ const resolved = await this.#resolve(prepared.selectors, "/transform");
203
+ try {
204
+ const items = nativeRequiredTokenizationItems(text, prepared.findings, config.transform, context);
205
+ const tokens = await this.#tokenize(items, context);
206
+ return nativeTransformWithProviderResults(
207
+ text,
208
+ prepared.findings,
209
+ config.transform,
210
+ context,
211
+ resolved,
212
+ tokens,
213
+ );
214
+ } catch (error) {
215
+ throw withPathPrefix(error, "/transform");
216
+ } finally {
217
+ resolved.forEach(({ key }) => key.fill(0));
218
+ }
219
+ }
220
+
221
+
222
+ async restore(text, context) {
223
+ if (typeof text !== "string") {
224
+ throw new TypeError("restore text must be a string");
225
+ }
226
+ let items;
227
+ try {
228
+ items = nativeRequiredRestoreItems(text, context);
229
+ } catch (error) {
230
+ throw normalizeError(error, "invalid_configuration");
231
+ }
232
+ if (items.length === 0) return nativeRestoreWithResults(text, context, []);
233
+ if (!this.#tokenProvider) {
234
+ throw new DataFogError({
235
+ code: "token_provider_required",
236
+ message: "restoration requires a runtime token provider",
237
+ });
238
+ }
239
+ let results;
240
+ try {
241
+ results = await this.#tokenProvider.restoreBatch(context.scope, items);
242
+ } catch (error) {
243
+ throw normalizeProviderError(error, undefined, "token_provider_error");
244
+ }
245
+ return nativeRestoreWithResults(text, context, Array.isArray(results) ? results : []);
246
+ }
247
+ }
248
+
249
+ export function scan(text, config) {
250
+ if (typeof text !== "string") {
251
+ throw new TypeError("scan text must be a string");
252
+ }
253
+
254
+ try {
255
+ return nativeScan(text, config);
256
+ } catch (error) {
257
+ throw normalizeError(
258
+ error,
259
+ config === undefined ? "internal_error" : "invalid_configuration",
260
+ );
261
+ }
262
+ }
263
+
264
+ export function transform(text, findings, config) {
265
+ if (typeof text !== "string") {
266
+ throw new TypeError("transform text must be a string");
267
+ }
268
+ if (!Array.isArray(findings)) {
269
+ throw new TypeError("transform findings must be an array");
270
+ }
271
+
272
+ try {
273
+ return nativeTransform(text, findings, config);
274
+ } catch (error) {
275
+ throw normalizeError(error, "invalid_configuration");
276
+ }
277
+ }
278
+
279
+ export function scanAndTransform(text, config) {
280
+ if (typeof text !== "string") {
281
+ throw new TypeError("scanAndTransform text must be a string");
282
+ }
283
+
284
+ try {
285
+ return nativeScanAndTransform(text, config);
286
+ } catch (error) {
287
+ throw normalizeError(error, "invalid_configuration");
288
+ }
289
+ }
package/native.js ADDED
@@ -0,0 +1,716 @@
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ // @ts-nocheck
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ import { createRequire } from 'module'
7
+ const require = createRequire(import.meta.url)
8
+ const __dirname = new URL('.', import.meta.url).pathname
9
+
10
+ const { readFileSync } = require('fs')
11
+ let nativeBinding = null
12
+ const loadErrors = []
13
+
14
+ const isMusl = () => {
15
+ let musl = false
16
+ if (process.platform === 'linux') {
17
+ musl = isMuslFromFilesystem()
18
+ if (musl === null) {
19
+ musl = isMuslFromReport()
20
+ }
21
+ if (musl === null) {
22
+ musl = isMuslFromChildProcess()
23
+ }
24
+ }
25
+ return musl
26
+ }
27
+
28
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
29
+
30
+ const isMuslFromFilesystem = () => {
31
+ try {
32
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
33
+ } catch {
34
+ return null
35
+ }
36
+ }
37
+
38
+ const isMuslFromReport = () => {
39
+ let report = null
40
+ if (process.report && typeof process.report.getReport === 'function') {
41
+ process.report.excludeNetwork = true
42
+ report = process.report.getReport()
43
+ }
44
+ if (!report) {
45
+ return null
46
+ }
47
+ if (report.header && report.header.glibcVersionRuntime) {
48
+ return false
49
+ }
50
+ if (Array.isArray(report.sharedObjects)) {
51
+ if (report.sharedObjects.some(isFileMusl)) {
52
+ return true
53
+ }
54
+ }
55
+ return false
56
+ }
57
+
58
+ const isMuslFromChildProcess = () => {
59
+ try {
60
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
61
+ } catch (e) {
62
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
63
+ return false
64
+ }
65
+ }
66
+
67
+ function requireNative() {
68
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
69
+ try {
70
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
71
+ } catch (err) {
72
+ loadErrors.push(err)
73
+ }
74
+ } else if (process.platform === 'android') {
75
+ if (process.arch === 'arm64') {
76
+ try {
77
+ return require('./datafog.android-arm64.node')
78
+ } catch (e) {
79
+ loadErrors.push(e)
80
+ }
81
+ try {
82
+ const binding = require('@datafog/node-android-arm64')
83
+ const bindingPackageVersion = require('@datafog/node-android-arm64/package.json').version
84
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
85
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
86
+ }
87
+ return binding
88
+ } catch (e) {
89
+ loadErrors.push(e)
90
+ }
91
+ } else if (process.arch === 'arm') {
92
+ try {
93
+ return require('./datafog.android-arm-eabi.node')
94
+ } catch (e) {
95
+ loadErrors.push(e)
96
+ }
97
+ try {
98
+ const binding = require('@datafog/node-android-arm-eabi')
99
+ const bindingPackageVersion = require('@datafog/node-android-arm-eabi/package.json').version
100
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
101
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
102
+ }
103
+ return binding
104
+ } catch (e) {
105
+ loadErrors.push(e)
106
+ }
107
+ } else {
108
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
109
+ }
110
+ } else if (process.platform === 'win32') {
111
+ if (process.arch === 'x64') {
112
+ if ((process.config && process.config.variables && process.config.variables.shlib_suffix === 'dll.a') || (process.config && process.config.variables && process.config.variables.node_target_type === 'shared_library')) {
113
+ try {
114
+ return require('./datafog.win32-x64-gnu.node')
115
+ } catch (e) {
116
+ loadErrors.push(e)
117
+ }
118
+ try {
119
+ const binding = require('@datafog/node-win32-x64-gnu')
120
+ const bindingPackageVersion = require('@datafog/node-win32-x64-gnu/package.json').version
121
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
122
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
123
+ }
124
+ return binding
125
+ } catch (e) {
126
+ loadErrors.push(e)
127
+ }
128
+ } else {
129
+ try {
130
+ return require('./datafog.win32-x64-msvc.node')
131
+ } catch (e) {
132
+ loadErrors.push(e)
133
+ }
134
+ try {
135
+ const binding = require('@datafog/node-win32-x64-msvc')
136
+ const bindingPackageVersion = require('@datafog/node-win32-x64-msvc/package.json').version
137
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
138
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
139
+ }
140
+ return binding
141
+ } catch (e) {
142
+ loadErrors.push(e)
143
+ }
144
+ }
145
+ } else if (process.arch === 'ia32') {
146
+ try {
147
+ return require('./datafog.win32-ia32-msvc.node')
148
+ } catch (e) {
149
+ loadErrors.push(e)
150
+ }
151
+ try {
152
+ const binding = require('@datafog/node-win32-ia32-msvc')
153
+ const bindingPackageVersion = require('@datafog/node-win32-ia32-msvc/package.json').version
154
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
155
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
156
+ }
157
+ return binding
158
+ } catch (e) {
159
+ loadErrors.push(e)
160
+ }
161
+ } else if (process.arch === 'arm64') {
162
+ try {
163
+ return require('./datafog.win32-arm64-msvc.node')
164
+ } catch (e) {
165
+ loadErrors.push(e)
166
+ }
167
+ try {
168
+ const binding = require('@datafog/node-win32-arm64-msvc')
169
+ const bindingPackageVersion = require('@datafog/node-win32-arm64-msvc/package.json').version
170
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
171
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
172
+ }
173
+ return binding
174
+ } catch (e) {
175
+ loadErrors.push(e)
176
+ }
177
+ } else {
178
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
179
+ }
180
+ } else if (process.platform === 'darwin') {
181
+ try {
182
+ return require('./datafog.darwin-universal.node')
183
+ } catch (e) {
184
+ loadErrors.push(e)
185
+ }
186
+ try {
187
+ const binding = require('@datafog/node-darwin-universal')
188
+ const bindingPackageVersion = require('@datafog/node-darwin-universal/package.json').version
189
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
190
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
191
+ }
192
+ return binding
193
+ } catch (e) {
194
+ loadErrors.push(e)
195
+ }
196
+ if (process.arch === 'x64') {
197
+ try {
198
+ return require('./datafog.darwin-x64.node')
199
+ } catch (e) {
200
+ loadErrors.push(e)
201
+ }
202
+ try {
203
+ const binding = require('@datafog/node-darwin-x64')
204
+ const bindingPackageVersion = require('@datafog/node-darwin-x64/package.json').version
205
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
206
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
207
+ }
208
+ return binding
209
+ } catch (e) {
210
+ loadErrors.push(e)
211
+ }
212
+ } else if (process.arch === 'arm64') {
213
+ try {
214
+ return require('./datafog.darwin-arm64.node')
215
+ } catch (e) {
216
+ loadErrors.push(e)
217
+ }
218
+ try {
219
+ const binding = require('@datafog/node-darwin-arm64')
220
+ const bindingPackageVersion = require('@datafog/node-darwin-arm64/package.json').version
221
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
222
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
223
+ }
224
+ return binding
225
+ } catch (e) {
226
+ loadErrors.push(e)
227
+ }
228
+ } else {
229
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
230
+ }
231
+ } else if (process.platform === 'freebsd') {
232
+ if (process.arch === 'x64') {
233
+ try {
234
+ return require('./datafog.freebsd-x64.node')
235
+ } catch (e) {
236
+ loadErrors.push(e)
237
+ }
238
+ try {
239
+ const binding = require('@datafog/node-freebsd-x64')
240
+ const bindingPackageVersion = require('@datafog/node-freebsd-x64/package.json').version
241
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
242
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
243
+ }
244
+ return binding
245
+ } catch (e) {
246
+ loadErrors.push(e)
247
+ }
248
+ } else if (process.arch === 'arm64') {
249
+ try {
250
+ return require('./datafog.freebsd-arm64.node')
251
+ } catch (e) {
252
+ loadErrors.push(e)
253
+ }
254
+ try {
255
+ const binding = require('@datafog/node-freebsd-arm64')
256
+ const bindingPackageVersion = require('@datafog/node-freebsd-arm64/package.json').version
257
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
258
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
259
+ }
260
+ return binding
261
+ } catch (e) {
262
+ loadErrors.push(e)
263
+ }
264
+ } else {
265
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
266
+ }
267
+ } else if (process.platform === 'linux') {
268
+ if (process.arch === 'x64') {
269
+ if (isMusl()) {
270
+ try {
271
+ return require('./datafog.linux-x64-musl.node')
272
+ } catch (e) {
273
+ loadErrors.push(e)
274
+ }
275
+ try {
276
+ const binding = require('@datafog/node-linux-x64-musl')
277
+ const bindingPackageVersion = require('@datafog/node-linux-x64-musl/package.json').version
278
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
279
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
280
+ }
281
+ return binding
282
+ } catch (e) {
283
+ loadErrors.push(e)
284
+ }
285
+ } else {
286
+ try {
287
+ return require('./datafog.linux-x64-gnu.node')
288
+ } catch (e) {
289
+ loadErrors.push(e)
290
+ }
291
+ try {
292
+ const binding = require('@datafog/node-linux-x64-gnu')
293
+ const bindingPackageVersion = require('@datafog/node-linux-x64-gnu/package.json').version
294
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
295
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
296
+ }
297
+ return binding
298
+ } catch (e) {
299
+ loadErrors.push(e)
300
+ }
301
+ }
302
+ } else if (process.arch === 'arm64') {
303
+ if (isMusl()) {
304
+ try {
305
+ return require('./datafog.linux-arm64-musl.node')
306
+ } catch (e) {
307
+ loadErrors.push(e)
308
+ }
309
+ try {
310
+ const binding = require('@datafog/node-linux-arm64-musl')
311
+ const bindingPackageVersion = require('@datafog/node-linux-arm64-musl/package.json').version
312
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
313
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
314
+ }
315
+ return binding
316
+ } catch (e) {
317
+ loadErrors.push(e)
318
+ }
319
+ } else {
320
+ try {
321
+ return require('./datafog.linux-arm64-gnu.node')
322
+ } catch (e) {
323
+ loadErrors.push(e)
324
+ }
325
+ try {
326
+ const binding = require('@datafog/node-linux-arm64-gnu')
327
+ const bindingPackageVersion = require('@datafog/node-linux-arm64-gnu/package.json').version
328
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
329
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
330
+ }
331
+ return binding
332
+ } catch (e) {
333
+ loadErrors.push(e)
334
+ }
335
+ }
336
+ } else if (process.arch === 'arm') {
337
+ if (isMusl()) {
338
+ try {
339
+ return require('./datafog.linux-arm-musleabihf.node')
340
+ } catch (e) {
341
+ loadErrors.push(e)
342
+ }
343
+ try {
344
+ const binding = require('@datafog/node-linux-arm-musleabihf')
345
+ const bindingPackageVersion = require('@datafog/node-linux-arm-musleabihf/package.json').version
346
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
347
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
348
+ }
349
+ return binding
350
+ } catch (e) {
351
+ loadErrors.push(e)
352
+ }
353
+ } else {
354
+ try {
355
+ return require('./datafog.linux-arm-gnueabihf.node')
356
+ } catch (e) {
357
+ loadErrors.push(e)
358
+ }
359
+ try {
360
+ const binding = require('@datafog/node-linux-arm-gnueabihf')
361
+ const bindingPackageVersion = require('@datafog/node-linux-arm-gnueabihf/package.json').version
362
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
363
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
364
+ }
365
+ return binding
366
+ } catch (e) {
367
+ loadErrors.push(e)
368
+ }
369
+ }
370
+ } else if (process.arch === 'loong64') {
371
+ if (isMusl()) {
372
+ try {
373
+ return require('./datafog.linux-loong64-musl.node')
374
+ } catch (e) {
375
+ loadErrors.push(e)
376
+ }
377
+ try {
378
+ const binding = require('@datafog/node-linux-loong64-musl')
379
+ const bindingPackageVersion = require('@datafog/node-linux-loong64-musl/package.json').version
380
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
381
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
382
+ }
383
+ return binding
384
+ } catch (e) {
385
+ loadErrors.push(e)
386
+ }
387
+ } else {
388
+ try {
389
+ return require('./datafog.linux-loong64-gnu.node')
390
+ } catch (e) {
391
+ loadErrors.push(e)
392
+ }
393
+ try {
394
+ const binding = require('@datafog/node-linux-loong64-gnu')
395
+ const bindingPackageVersion = require('@datafog/node-linux-loong64-gnu/package.json').version
396
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
397
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
398
+ }
399
+ return binding
400
+ } catch (e) {
401
+ loadErrors.push(e)
402
+ }
403
+ }
404
+ } else if (process.arch === 'riscv64') {
405
+ if (isMusl()) {
406
+ try {
407
+ return require('./datafog.linux-riscv64-musl.node')
408
+ } catch (e) {
409
+ loadErrors.push(e)
410
+ }
411
+ try {
412
+ const binding = require('@datafog/node-linux-riscv64-musl')
413
+ const bindingPackageVersion = require('@datafog/node-linux-riscv64-musl/package.json').version
414
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
415
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
416
+ }
417
+ return binding
418
+ } catch (e) {
419
+ loadErrors.push(e)
420
+ }
421
+ } else {
422
+ try {
423
+ return require('./datafog.linux-riscv64-gnu.node')
424
+ } catch (e) {
425
+ loadErrors.push(e)
426
+ }
427
+ try {
428
+ const binding = require('@datafog/node-linux-riscv64-gnu')
429
+ const bindingPackageVersion = require('@datafog/node-linux-riscv64-gnu/package.json').version
430
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
431
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
432
+ }
433
+ return binding
434
+ } catch (e) {
435
+ loadErrors.push(e)
436
+ }
437
+ }
438
+ } else if (process.arch === 'ppc64') {
439
+ try {
440
+ return require('./datafog.linux-ppc64-gnu.node')
441
+ } catch (e) {
442
+ loadErrors.push(e)
443
+ }
444
+ try {
445
+ const binding = require('@datafog/node-linux-ppc64-gnu')
446
+ const bindingPackageVersion = require('@datafog/node-linux-ppc64-gnu/package.json').version
447
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
448
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
449
+ }
450
+ return binding
451
+ } catch (e) {
452
+ loadErrors.push(e)
453
+ }
454
+ } else if (process.arch === 's390x') {
455
+ try {
456
+ return require('./datafog.linux-s390x-gnu.node')
457
+ } catch (e) {
458
+ loadErrors.push(e)
459
+ }
460
+ try {
461
+ const binding = require('@datafog/node-linux-s390x-gnu')
462
+ const bindingPackageVersion = require('@datafog/node-linux-s390x-gnu/package.json').version
463
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
464
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
465
+ }
466
+ return binding
467
+ } catch (e) {
468
+ loadErrors.push(e)
469
+ }
470
+ } else {
471
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
472
+ }
473
+ } else if (process.platform === 'openharmony') {
474
+ if (process.arch === 'arm64') {
475
+ try {
476
+ return require('./datafog.openharmony-arm64.node')
477
+ } catch (e) {
478
+ loadErrors.push(e)
479
+ }
480
+ try {
481
+ const binding = require('@datafog/node-openharmony-arm64')
482
+ const bindingPackageVersion = require('@datafog/node-openharmony-arm64/package.json').version
483
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
484
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
485
+ }
486
+ return binding
487
+ } catch (e) {
488
+ loadErrors.push(e)
489
+ }
490
+ } else if (process.arch === 'x64') {
491
+ try {
492
+ return require('./datafog.openharmony-x64.node')
493
+ } catch (e) {
494
+ loadErrors.push(e)
495
+ }
496
+ try {
497
+ const binding = require('@datafog/node-openharmony-x64')
498
+ const bindingPackageVersion = require('@datafog/node-openharmony-x64/package.json').version
499
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
500
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
501
+ }
502
+ return binding
503
+ } catch (e) {
504
+ loadErrors.push(e)
505
+ }
506
+ } else if (process.arch === 'arm') {
507
+ try {
508
+ return require('./datafog.openharmony-arm.node')
509
+ } catch (e) {
510
+ loadErrors.push(e)
511
+ }
512
+ try {
513
+ const binding = require('@datafog/node-openharmony-arm')
514
+ const bindingPackageVersion = require('@datafog/node-openharmony-arm/package.json').version
515
+ if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
516
+ throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
517
+ }
518
+ return binding
519
+ } catch (e) {
520
+ loadErrors.push(e)
521
+ }
522
+ } else {
523
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
524
+ }
525
+ } else {
526
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
527
+ }
528
+ }
529
+
530
+ function createLoadErrorChain(errors) {
531
+ return errors.reduce((previous, current) => {
532
+ let message
533
+ try {
534
+ message =
535
+ current && typeof current.message === 'string'
536
+ ? current.message
537
+ : String(current)
538
+ } catch {
539
+ message = 'Unknown error'
540
+ }
541
+ const error = new Error(message)
542
+ error.cause = previous
543
+ return error
544
+ }, null)
545
+ }
546
+
547
+ // NAPI_RS_FORCE_WASI is a tri-state flag:
548
+ // unset / any other value → native binding preferred, WASI is only a fallback
549
+ // 'true' → prefer WASI, but retain native as a lazy fallback
550
+ // 'error' → require WASI without initializing a native fallback
551
+ // Treating any non-empty string as truthy (the historical behavior) meant
552
+ // NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
553
+ // the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
554
+ //
555
+ // NAPI_RS_WASI_FLAVOR selects one exact generated flavor and implies strict
556
+ // WASI loading. It never crosses into another flavor or falls back to native.
557
+ const __napiWasiFlavors = ["wasm32-wasi"]
558
+ const __napiWasiFlavor = process.env.NAPI_RS_WASI_FLAVOR
559
+ const __napiWasiFlavorRequested =
560
+ typeof __napiWasiFlavor === 'string' && __napiWasiFlavor.length > 0
561
+ if (
562
+ __napiWasiFlavorRequested &&
563
+ __napiWasiFlavors.indexOf(__napiWasiFlavor) === -1
564
+ ) {
565
+ throw new Error(
566
+ 'Unsupported WASI flavor "' +
567
+ __napiWasiFlavor +
568
+ '". Available flavors: ' +
569
+ __napiWasiFlavors.join(', '),
570
+ )
571
+ }
572
+ const forceWasiError = process.env.NAPI_RS_FORCE_WASI === 'error'
573
+ const forceWasi =
574
+ process.env.NAPI_RS_FORCE_WASI === 'true' ||
575
+ forceWasiError ||
576
+ __napiWasiFlavorRequested
577
+
578
+ if (!forceWasi) {
579
+ nativeBinding = requireNative()
580
+ }
581
+
582
+ if (!nativeBinding || forceWasi) {
583
+ let wasiBinding = null
584
+ let wasiBindingLoaded = false
585
+ const wasiBindingErrors = []
586
+ const __napiWasiResolveCandidate = (specifier, isPackage, localArtifacts) => {
587
+ try {
588
+ require.resolve(specifier)
589
+ } catch (resolveError) {
590
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
591
+ throw resolveError
592
+ }
593
+ if (isPackage) {
594
+ try {
595
+ require.resolve(specifier + '/package.json')
596
+ } catch (packageError) {
597
+ if (packageError && packageError.code === 'MODULE_NOT_FOUND') {
598
+ return resolveError
599
+ }
600
+ // An exports restriction proves the package exists even when its
601
+ // package.json is not public. Preserve the root resolution failure.
602
+ throw resolveError
603
+ }
604
+ // The package exists but its main/export target is broken.
605
+ throw resolveError
606
+ }
607
+ return resolveError
608
+ }
609
+ if (localArtifacts) {
610
+ let artifactError = null
611
+ for (let i = 0; i < localArtifacts.length; i++) {
612
+ try {
613
+ require.resolve(localArtifacts[i])
614
+ return null
615
+ } catch (resolveError) {
616
+ if (!resolveError || resolveError.code !== 'MODULE_NOT_FOUND') {
617
+ throw resolveError
618
+ }
619
+ artifactError = resolveError
620
+ }
621
+ }
622
+ return artifactError
623
+ }
624
+ return null
625
+ }
626
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === "wasm32-wasi")) {
627
+ let candidateError = null
628
+ let candidateFailed = false
629
+ try {
630
+ candidateError = __napiWasiResolveCandidate('./datafog.wasi.cjs', false, ["./datafog.wasm32-wasi.debug.wasm","./datafog.wasm32-wasi.wasm"])
631
+ candidateFailed = candidateError !== null
632
+ if (!candidateFailed) {
633
+ wasiBinding = require('./datafog.wasi.cjs')
634
+ nativeBinding = wasiBinding
635
+ wasiBindingLoaded = true
636
+ }
637
+ } catch (err) {
638
+ candidateError = err
639
+ candidateFailed = true
640
+ }
641
+ if (candidateFailed) {
642
+ wasiBindingErrors.push(candidateError)
643
+ loadErrors.push(candidateError)
644
+ }
645
+ }
646
+ if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === "wasm32-wasi")) {
647
+ let candidateError = null
648
+ let candidateFailed = false
649
+ try {
650
+ candidateError = __napiWasiResolveCandidate('@datafog/node-wasm32-wasi', true, undefined)
651
+ candidateFailed = candidateError !== null
652
+ if (!candidateFailed) {
653
+ if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
654
+ const bindingPackageVersion = require('@datafog/node-wasm32-wasi/package.json').version
655
+ if (bindingPackageVersion !== '0.2.0') {
656
+ throw new Error(`WASI binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
657
+ }
658
+ }
659
+ wasiBinding = require('@datafog/node-wasm32-wasi')
660
+ nativeBinding = wasiBinding
661
+ wasiBindingLoaded = true
662
+ }
663
+ } catch (err) {
664
+ candidateError = err
665
+ candidateFailed = true
666
+ }
667
+ if (candidateFailed) {
668
+ wasiBindingErrors.push(candidateError)
669
+ loadErrors.push(candidateError)
670
+ }
671
+ }
672
+ if (
673
+ !wasiBindingLoaded &&
674
+ forceWasi &&
675
+ !forceWasiError &&
676
+ !__napiWasiFlavorRequested
677
+ ) {
678
+ nativeBinding = requireNative()
679
+ }
680
+ if ((forceWasiError || __napiWasiFlavorRequested) && !wasiBindingLoaded) {
681
+ const error = new Error(
682
+ __napiWasiFlavorRequested
683
+ ? 'WASI binding for flavor "' + __napiWasiFlavor + '" not found'
684
+ : 'WASI binding not found and NAPI_RS_FORCE_WASI is set to error',
685
+ )
686
+ error.cause = createLoadErrorChain(wasiBindingErrors)
687
+ throw error
688
+ }
689
+ }
690
+
691
+ if (!nativeBinding) {
692
+ if (loadErrors.length > 0) {
693
+ const error = new Error(
694
+ `Cannot find native binding. ` +
695
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
696
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
697
+ )
698
+ // assign instead of the `new Error(message, { cause })` options form,
699
+ // which Node < 16.9 silently ignores
700
+ error.cause = createLoadErrorChain(loadErrors)
701
+ throw error
702
+ }
703
+ throw new Error(`Failed to load native binding`)
704
+ }
705
+
706
+ const { prepareScanAndTransform, requiredKeySelectors, requiredRestoreItems, requiredTokenizationItems, restoreWithResults, scan, scanAndTransform, transform, transformWithProviderResults, transformWithResolvedKeys } = nativeBinding
707
+ export { prepareScanAndTransform }
708
+ export { requiredKeySelectors }
709
+ export { requiredRestoreItems }
710
+ export { requiredTokenizationItems }
711
+ export { restoreWithResults }
712
+ export { scan }
713
+ export { scanAndTransform }
714
+ export { transform }
715
+ export { transformWithProviderResults }
716
+ export { transformWithResolvedKeys }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@datafog/node",
3
+ "version": "0.2.0",
4
+ "description": "Fast structured PII detection for Node.js, powered by Rust",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/DataFog/datafog-core.git"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "type": "module",
14
+ "files": [
15
+ "index.js",
16
+ "native.js",
17
+ "index.d.ts",
18
+ "*.node"
19
+ ],
20
+ "exports": {
21
+ ".": {
22
+ "types": "./index.d.ts",
23
+ "import": "./index.js"
24
+ }
25
+ },
26
+ "types": "./index.d.ts",
27
+ "engines": {
28
+ "node": "24.x"
29
+ },
30
+ "napi": {
31
+ "binaryName": "datafog",
32
+ "targets": [
33
+ "aarch64-apple-darwin",
34
+ "x86_64-apple-darwin",
35
+ "x86_64-unknown-linux-gnu",
36
+ "aarch64-unknown-linux-gnu",
37
+ "x86_64-pc-windows-msvc"
38
+ ],
39
+ "dtsHeaderFile": "dts-header.d.ts"
40
+ },
41
+ "scripts": {
42
+ "build": "napi build --manifest-path Cargo.toml --release --platform --esm --js native.js --dts index.d.ts",
43
+ "test:package": "node ../../scripts/test-node-package.mjs",
44
+ "prepublishOnly": "napi prepublish -t npm --no-gh-release"
45
+ },
46
+ "devDependencies": {
47
+ "@napi-rs/cli": "3.8.6",
48
+ "typescript": "7.0.2"
49
+ },
50
+ "optionalDependencies": {
51
+ "@datafog/node-darwin-arm64": "0.2.0",
52
+ "@datafog/node-darwin-x64": "0.2.0",
53
+ "@datafog/node-linux-x64-gnu": "0.2.0",
54
+ "@datafog/node-linux-arm64-gnu": "0.2.0",
55
+ "@datafog/node-win32-x64-msvc": "0.2.0"
56
+ }
57
+ }