@stackone/redaction 1.13.0 → 1.13.1

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.
@@ -2,6 +2,8 @@ import { t as __name } from "./chunk-BhWHdk3m.mjs";
2
2
  import { ILogger } from "@stackone/logger";
3
3
 
4
4
  //#region src/shared/index.d.ts
5
+ declare const KEYS_TO_REDACT: string[];
6
+ declare const PATHS_TO_REDACT: string[];
5
7
  declare const REDACT_CENSOR = "**redacted**";
6
8
  declare enum CensorType {
7
9
  FULL = "FULL",
@@ -17,4 +19,4 @@ declare const safeClone: <T>(value: T) => T;
17
19
  declare const redactObject: <T>(obj: T, censorType?: CensorType) => T;
18
20
  declare const I_AM_EDGE = true;
19
21
  //#endregion
20
- export { CensorType, I_AM_EDGE, REDACT_CENSOR, redactFields, redactObject, redactPath, redactUrl, safeClone, splitPath };
22
+ export { CensorType, I_AM_EDGE, KEYS_TO_REDACT, PATHS_TO_REDACT, REDACT_CENSOR, redactFields, redactObject, redactPath, redactUrl, safeClone, splitPath };
@@ -1 +1 @@
1
- import"./chunk-BhWHdk3m.mjs";import{isMissing as e}from"@stackone/utils";const t=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`],n=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...t],r=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>t.map(t=>`${e}[${JSON.stringify(t)}]`))],i=`**redacted**`;let a=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>i,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?i:`${i}${e.slice(-5)}`:i,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),o=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||o.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},s={FULL:censorFn,PARTIAL:partialCensorFn},c=getKeysToRedact(n),l=[...getPathsToRedact(r),...Array.from(c).map(asValidPath)],redactUrl=(t,n=`FULL`,r)=>{if(!e(t))try{let e=new URL(t),r=[...e.searchParams].reduce((e,[t,r])=>(e.set(t,c.has(t)?s[n](r):r),e),new URLSearchParams);return`${e.origin}${e.pathname}${r.toString()?`?`+r:``}${e.hash}`}catch(e){return r?.warning({message:`Invalid URL provided, unable to redact`,context:{value:t,error:e},category:`redactUrl`}),typeof t==`string`?t:t?.toString()}},redactPath=(t,n=`FULL`,r)=>{if(!e(t))try{let[e,r]=t.split(`?`);return r?`${e}?${[...new URLSearchParams(r)].reduce((e,[t,r])=>(e.set(t,c.has(t)?s[n](r):r),e),new URLSearchParams)}`:t}catch(e){return r?.warning({message:`Invalid path provided, unable to redact`,context:{value:t,error:e},category:`redactPath`}),t}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return`**circular**`;if(r>64)return`**max-depth**`;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return`**unreadable**`}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>c.has(e)?[e,s[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet);let u;const getRedactors=()=>(e(u)&&(u={FULL:edgeRedact({paths:l,serialize:!1,censor:s.FULL}),PARTIAL:edgeRedact({paths:l,serialize:!1,censor:s.PARTIAL})}),u),splitPath=e=>e.replace(/\[["']?([^[\]"']*)["']?\]/g,`.$1`).split(`.`).filter(Boolean),fallbackCensor=()=>`***`,edgeRedact=e=>{let t=(e.paths??[]).map(splitPath),n=typeof e.censor==`function`?e.censor:fallbackCensor,r=!!e.serialize,redact=e=>{if(typeof e!=`object`||!e)return r?String(e):e;for(let r of t){let t=e;for(let e=0;e<r.length-1&&t&&typeof t==`object`;e++)t=t[r[e]];let i=r[r.length-1];t&&Object.prototype.hasOwnProperty.call(t,i)&&(t[i]=n(t[i]))}return r?JSON.stringify(e):e};return redact.restore=()=>{},redact},safeClone=e=>{let t=globalThis.structuredClone;return typeof t==`function`?t(e):JSON.parse(JSON.stringify(e))},redactObject=(e,t=`FULL`)=>{if(typeof e!=`object`||!e)return e;let n=safeClone(e);return getRedactors()[t](n)},d=!0;export{a as CensorType,d as I_AM_EDGE,i as REDACT_CENSOR,redactFields,redactObject,redactPath,redactUrl,safeClone,splitPath};
1
+ import"./chunk-BhWHdk3m.mjs";import{isMissing as e}from"@stackone/utils";const t=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`,`klaviyo-api-key`,`x-sn-apikey`],n=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...t],r=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>t.map(t=>`${e}[${JSON.stringify(t)}]`))],i=`**redacted**`;let a=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>i,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?i:`${i}${e.slice(-5)}`:i,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),o=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||o.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},s={FULL:censorFn,PARTIAL:partialCensorFn},c=getKeysToRedact(n),l=new Set(Array.from(c,e=>e.toLowerCase())),matchesRedactedKey=e=>{let t=e.toLowerCase();return l.has(t)?!0:t.includes(`[`)?t.split(/[\[\]]/).some(e=>e&&l.has(e)):!1},u=[...getPathsToRedact(r),...Array.from(c).map(asValidPath)],redactUrl=(t,n=`FULL`,r)=>{if(!e(t))try{let e=new URL(t),r=[...e.searchParams].reduce((e,[t,r])=>(e.set(t,matchesRedactedKey(t)?s[n](r):r),e),new URLSearchParams);return`${e.origin}${e.pathname}${r.toString()?`?`+r:``}${e.hash}`}catch(e){return r?.warning({message:`Invalid URL provided, unable to redact`,context:{value:t,error:e},category:`redactUrl`}),typeof t==`string`?t:t?.toString()}},redactPath=(t,n=`FULL`,r)=>{if(!e(t))try{let[e,r]=t.split(`?`);return r?`${e}?${[...new URLSearchParams(r)].reduce((e,[t,r])=>(e.set(t,matchesRedactedKey(t)?s[n](r):r),e),new URLSearchParams)}`:t}catch(e){return r?.warning({message:`Invalid path provided, unable to redact`,context:{value:t,error:e},category:`redactPath`}),t}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return`**circular**`;if(r>64)return`**max-depth**`;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return`**unreadable**`}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>matchesRedactedKey(e)?[e,s[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet);let d;const getRedactors=()=>(e(d)&&(d={FULL:edgeRedact({paths:u,serialize:!1,censor:s.FULL}),PARTIAL:edgeRedact({paths:u,serialize:!1,censor:s.PARTIAL})}),d),splitPath=e=>e.replace(/\[["']?([^[\]"']*)["']?\]/g,`.$1`).split(`.`).filter(Boolean),fallbackCensor=()=>`***`,edgeRedact=e=>{let t=(e.paths??[]).map(splitPath),n=typeof e.censor==`function`?e.censor:fallbackCensor,r=!!e.serialize,redact=e=>{if(typeof e!=`object`||!e)return r?String(e):e;for(let r of t){let t=e;for(let e=0;e<r.length-1&&t&&typeof t==`object`;e++)t=t[r[e]];let i=r[r.length-1];t&&Object.prototype.hasOwnProperty.call(t,i)&&(t[i]=n(t[i]))}return r?JSON.stringify(e):e};return redact.restore=()=>{},redact},safeClone=e=>{let t=globalThis.structuredClone;return typeof t==`function`?t(e):JSON.parse(JSON.stringify(e))},redactObject=(e,t=`FULL`)=>{if(typeof e!=`object`||!e)return e;let n=safeClone(e);return getRedactors()[t](n)},f=!0;export{a as CensorType,f as I_AM_EDGE,n as KEYS_TO_REDACT,r as PATHS_TO_REDACT,i as REDACT_CENSOR,redactFields,redactObject,redactPath,redactUrl,safeClone,splitPath};
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./config-BPwtMZw7.cjs");let t=require("@stackone/utils"),n=require("fast-redact");n=e.p(n);const r=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`],i=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...r],a=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>r.map(t=>`${e}[${JSON.stringify(t)}]`))],o=`**redacted**`,s=`**circular**`,c=`**max-depth**`,l=`**unreadable**`;let u=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>o,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?o:`${o}${e.slice(-5)}`:o,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),d=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||d.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},f={FULL:censorFn,PARTIAL:partialCensorFn},p=getKeysToRedact(i),m=[...getPathsToRedact(a),...Array.from(p).map(asValidPath)],redactUrl=(e,n=`FULL`,r)=>{if(!(0,t.isMissing)(e))try{let t=new URL(e),r=[...t.searchParams].reduce((e,[t,r])=>(e.set(t,p.has(t)?f[n](r):r),e),new URLSearchParams);return`${t.origin}${t.pathname}${r.toString()?`?`+r:``}${t.hash}`}catch(t){return r?.warning({message:`Invalid URL provided, unable to redact`,context:{value:e,error:t},category:`redactUrl`}),typeof e==`string`?e:e?.toString()}},redactPath=(e,n=`FULL`,r)=>{if(!(0,t.isMissing)(e))try{let[t,r]=e.split(`?`);return r?`${t}?${[...new URLSearchParams(r)].reduce((e,[t,r])=>(e.set(t,p.has(t)?f[n](r):r),e),new URLSearchParams)}`:e}catch(t){return r?.warning({message:`Invalid path provided, unable to redact`,context:{value:e,error:t},category:`redactPath`}),e}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return s;if(r>64)return c;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return l}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>p.has(e)?[e,f[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet),defineOwn=(e,t,n)=>{Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})},walk=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(n.has(e))return s;if(t>64)return c;if(Array.isArray(e)){n.add(e);let a=Array(e.length);return e.forEach((e,o)=>{typeof e==`string`?(a[o]=e,r.push(e),i.push(e=>{a[o]=e})):a[o]=walk(e,t+1,n,r,i)}),n.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return l}if(!a)return e;n.add(e);let o={};for(let[a,s]of Object.entries(e))typeof s==`string`?(defineOwn(o,a,s),r.push(s),i.push(e=>{defineOwn(o,a,e)})):defineOwn(o,a,walk(s,t+1,n,r,i));return n.delete(e),o};async function scrubObjectAsync(e,t){if(typeof e==`string`)return(await t.scrubAsync(e)).scrubbed;let n=[],r=[],i=walk(e,0,new WeakSet,n,r);return n.length>0&&(await t.scrubManyAsync(n)).forEach((e,t)=>r[t](e.scrubbed)),i}function shannonEntropy(e){if(!e)return 0;let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=e.length,r=0;for(let e of t.values()){let t=e/n;r-=t*Math.log2(t)}return r}function entropyScrub(t,n=`[REDACTED]`,r=e.t){let i=e.a(t,r.skipPatterns),a=[],o=r.candidatePattern.flags.includes(`g`)?r.candidatePattern.flags:`${r.candidatePattern.flags}g`,s=new RegExp(r.candidatePattern.source,o),c;for(;(c=s.exec(t))!==null;){let t=c[0];t.length<r.minLength||e.o(c.index,c.index+t.length,i)||shannonEntropy(t)>=r.threshold&&a.push({start:c.index,end:c.index+t.length,original:t,replacement:n,source:`entropy`})}for(let o of r.piiPatterns??[]){let r=new RegExp(o.source,o.flags.includes(`g`)?o.flags:`${o.flags}g`),s;for(;(s=r.exec(t))!==null;){let t=s.index,r=t+s[0].length;e.o(t,r,i)||a.push({start:t,end:r,original:s[0],replacement:n,source:`entropy`})}}let l=e.s(a);return{scrubbed:e.i(t,l),redactions:l}}var PiiRedaction=class{constructor(t){this.tier2=null,this.tier2LoadPromise=null,this.config=e.r(t),this.enableTier2=t?.enableTier2??!1,this.logger=t?.logger}async warmupTier2(){this.enableTier2&&(await this.loadTier2(),this.tier2&&await this.tier2.warmup())}isTier2Ready(){return this.tier2?.isReady()??!1}scrub(e){let t=performance.now(),{scrubbed:n,redactions:r}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return{scrubbed:n,redactions:r,tier:`entropy`,modelAvailable:!1,latencyMs:performance.now()-t}}async scrubAsync(t){let n=performance.now();if(!this.enableTier2)return this.scrub(t);let r=!1,i=[];try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);let e=await this.tier2.detectSecrets(t);for(let t of e)i.push({start:t.start,end:t.end,original:t.text,replacement:this.config.redactionToken,source:`model`,label:t.label});r=!0}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 model detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}let{redactions:a}=entropyScrub(t,this.config.redactionToken,this.config.entropy);i.push(...a);let o=e.s(i);return{scrubbed:e.i(t,o),redactions:o,tier:r?`model+entropy`:`entropy`,modelAvailable:r,latencyMs:performance.now()-n}}async scrubManyAsync(t){if(!this.enableTier2)return t.map(e=>this.scrub(e));let n=null;try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);n=await this.tier2.detectSecretsBatch(t)}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 batch detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}return t.map((t,r)=>{let i=performance.now(),a=[];for(let e of n?.[r]??[])a.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});let{redactions:o}=entropyScrub(t,this.config.redactionToken,this.config.entropy);a.push(...o);let s=e.s(a);return{scrubbed:e.i(t,s),redactions:s,tier:n?`model+entropy`:`entropy`,modelAvailable:n!==null,latencyMs:performance.now()-i}})}async dispose(){let e=this.tier2;this.tier2=null,this.tier2LoadPromise=null,await e?.dispose()}detect(e){let{redactions:t}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return t}getConfig(){return structuredClone(this.config)}async loadTier2(){if(!this.tier2){if(this.tier2LoadPromise)return this.tier2LoadPromise;this.tier2LoadPromise=(async()=>{let{Tier2Classifier:e}=await Promise.resolve().then(()=>require("./tier2-classifier-CK7UcktD.cjs"));this.tier2=new e({onnxModelPath:this.config.model.modelPath})})();try{await this.tier2LoadPromise}catch(e){throw this.tier2LoadPromise=null,Error(`Failed to load Tier 2 classifier: ${e instanceof Error?e.message:String(e)}. Ensure onnxruntime-node and @huggingface/transformers are installed. The model ships bundled with @stackone/redaction — try reinstalling the package, or configure modelPath.`)}}}};function createPiiRedaction(e){return new PiiRedaction(e)}let h;const getRedactors=()=>((0,t.isMissing)(h)&&(h={FULL:(0,n.default)({paths:m,serialize:!1,censor:f.FULL}),PARTIAL:(0,n.default)({paths:m,serialize:!1,censor:f.PARTIAL})}),h),redactObject=(e,n=`FULL`)=>(0,t.isMissing)(e)||typeof e!=`object`||!e?e:getRedactors()[n]((0,t.deepCopy)(e));exports.CensorType=u,exports.I_AM_EDGE=!1,exports.MODEL_FILES=e.c,exports.PiiRedaction=PiiRedaction,exports.REDACT_CENSOR=o,exports.createPiiRedaction=createPiiRedaction,exports.entropyScrub=entropyScrub,exports.getDefaultModelCacheDir=e.u,exports.isModelPresent=e.d,exports.redactFields=redactFields,exports.redactObject=redactObject,exports.redactPath=redactPath,exports.redactUrl=redactUrl,exports.scrubObjectAsync=scrubObjectAsync,exports.shannonEntropy=shannonEntropy;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./config-BPwtMZw7.cjs");let t=require("@stackone/utils"),n=require("fast-redact");n=e.p(n);const r=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`,`klaviyo-api-key`,`x-sn-apikey`],i=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...r],a=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>r.map(t=>`${e}[${JSON.stringify(t)}]`))],o=`**redacted**`,s=`**circular**`,c=`**max-depth**`,l=`**unreadable**`;let u=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>o,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?o:`${o}${e.slice(-5)}`:o,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),d=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||d.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},f={FULL:censorFn,PARTIAL:partialCensorFn},p=getKeysToRedact(i),m=new Set(Array.from(p,e=>e.toLowerCase())),matchesRedactedKey=e=>{let t=e.toLowerCase();return m.has(t)?!0:t.includes(`[`)?t.split(/[\[\]]/).some(e=>e&&m.has(e)):!1},h=[...getPathsToRedact(a),...Array.from(p).map(asValidPath)],redactUrl=(e,n=`FULL`,r)=>{if(!(0,t.isMissing)(e))try{let t=new URL(e),r=[...t.searchParams].reduce((e,[t,r])=>(e.set(t,matchesRedactedKey(t)?f[n](r):r),e),new URLSearchParams);return`${t.origin}${t.pathname}${r.toString()?`?`+r:``}${t.hash}`}catch(t){return r?.warning({message:`Invalid URL provided, unable to redact`,context:{value:e,error:t},category:`redactUrl`}),typeof e==`string`?e:e?.toString()}},redactPath=(e,n=`FULL`,r)=>{if(!(0,t.isMissing)(e))try{let[t,r]=e.split(`?`);return r?`${t}?${[...new URLSearchParams(r)].reduce((e,[t,r])=>(e.set(t,matchesRedactedKey(t)?f[n](r):r),e),new URLSearchParams)}`:e}catch(t){return r?.warning({message:`Invalid path provided, unable to redact`,context:{value:e,error:t},category:`redactPath`}),e}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return s;if(r>64)return c;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return l}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>matchesRedactedKey(e)?[e,f[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet),defineOwn=(e,t,n)=>{Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})},walk=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(n.has(e))return s;if(t>64)return c;if(Array.isArray(e)){n.add(e);let a=Array(e.length);return e.forEach((e,o)=>{typeof e==`string`?(a[o]=e,r.push(e),i.push(e=>{a[o]=e})):a[o]=walk(e,t+1,n,r,i)}),n.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return l}if(!a)return e;n.add(e);let o={};for(let[a,s]of Object.entries(e))typeof s==`string`?(defineOwn(o,a,s),r.push(s),i.push(e=>{defineOwn(o,a,e)})):defineOwn(o,a,walk(s,t+1,n,r,i));return n.delete(e),o};async function scrubObjectAsync(e,t){if(typeof e==`string`)return(await t.scrubAsync(e)).scrubbed;let n=[],r=[],i=walk(e,0,new WeakSet,n,r);return n.length>0&&(await t.scrubManyAsync(n)).forEach((e,t)=>r[t](e.scrubbed)),i}function shannonEntropy(e){if(!e)return 0;let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=e.length,r=0;for(let e of t.values()){let t=e/n;r-=t*Math.log2(t)}return r}function entropyScrub(t,n=`[REDACTED]`,r=e.t){let i=e.a(t,r.skipPatterns),a=[],o=r.candidatePattern.flags.includes(`g`)?r.candidatePattern.flags:`${r.candidatePattern.flags}g`,s=new RegExp(r.candidatePattern.source,o),c;for(;(c=s.exec(t))!==null;){let t=c[0];t.length<r.minLength||e.o(c.index,c.index+t.length,i)||shannonEntropy(t)>=r.threshold&&a.push({start:c.index,end:c.index+t.length,original:t,replacement:n,source:`entropy`})}for(let o of r.piiPatterns??[]){let r=new RegExp(o.source,o.flags.includes(`g`)?o.flags:`${o.flags}g`),s;for(;(s=r.exec(t))!==null;){let t=s.index,r=t+s[0].length;e.o(t,r,i)||a.push({start:t,end:r,original:s[0],replacement:n,source:`entropy`})}}let l=e.s(a);return{scrubbed:e.i(t,l),redactions:l}}var PiiRedaction=class{constructor(t){this.tier2=null,this.tier2LoadPromise=null,this.config=e.r(t),this.enableTier2=t?.enableTier2??!1,this.logger=t?.logger}async warmupTier2(){this.enableTier2&&(await this.loadTier2(),this.tier2&&await this.tier2.warmup())}isTier2Ready(){return this.tier2?.isReady()??!1}scrub(e){let t=performance.now(),{scrubbed:n,redactions:r}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return{scrubbed:n,redactions:r,tier:`entropy`,modelAvailable:!1,latencyMs:performance.now()-t}}async scrubAsync(t){let n=performance.now();if(!this.enableTier2)return this.scrub(t);let r=!1,i=[];try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);let e=await this.tier2.detectSecrets(t);for(let t of e)i.push({start:t.start,end:t.end,original:t.text,replacement:this.config.redactionToken,source:`model`,label:t.label});r=!0}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 model detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}let{redactions:a}=entropyScrub(t,this.config.redactionToken,this.config.entropy);i.push(...a);let o=e.s(i);return{scrubbed:e.i(t,o),redactions:o,tier:r?`model+entropy`:`entropy`,modelAvailable:r,latencyMs:performance.now()-n}}async scrubManyAsync(t){if(!this.enableTier2)return t.map(e=>this.scrub(e));let n=null;try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);n=await this.tier2.detectSecretsBatch(t)}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 batch detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}return t.map((t,r)=>{let i=performance.now(),a=[];for(let e of n?.[r]??[])a.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});let{redactions:o}=entropyScrub(t,this.config.redactionToken,this.config.entropy);a.push(...o);let s=e.s(a);return{scrubbed:e.i(t,s),redactions:s,tier:n?`model+entropy`:`entropy`,modelAvailable:n!==null,latencyMs:performance.now()-i}})}async dispose(){let e=this.tier2;this.tier2=null,this.tier2LoadPromise=null,await e?.dispose()}detect(e){let{redactions:t}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return t}getConfig(){return structuredClone(this.config)}async loadTier2(){if(!this.tier2){if(this.tier2LoadPromise)return this.tier2LoadPromise;this.tier2LoadPromise=(async()=>{let{Tier2Classifier:e}=await Promise.resolve().then(()=>require("./tier2-classifier-CK7UcktD.cjs"));this.tier2=new e({onnxModelPath:this.config.model.modelPath})})();try{await this.tier2LoadPromise}catch(e){throw this.tier2LoadPromise=null,Error(`Failed to load Tier 2 classifier: ${e instanceof Error?e.message:String(e)}. Ensure onnxruntime-node and @huggingface/transformers are installed. The model ships bundled with @stackone/redaction — try reinstalling the package, or configure modelPath.`)}}}};function createPiiRedaction(e){return new PiiRedaction(e)}let g;const getRedactors=()=>((0,t.isMissing)(g)&&(g={FULL:(0,n.default)({paths:h,serialize:!1,censor:f.FULL}),PARTIAL:(0,n.default)({paths:h,serialize:!1,censor:f.PARTIAL})}),g),redactObject=(e,n=`FULL`)=>(0,t.isMissing)(e)||typeof e!=`object`||!e?e:getRedactors()[n]((0,t.deepCopy)(e));exports.CensorType=u,exports.I_AM_EDGE=!1,exports.KEYS_TO_REDACT=i,exports.MODEL_FILES=e.c,exports.PATHS_TO_REDACT=a,exports.PiiRedaction=PiiRedaction,exports.REDACT_CENSOR=o,exports.createPiiRedaction=createPiiRedaction,exports.entropyScrub=entropyScrub,exports.getDefaultModelCacheDir=e.u,exports.isModelPresent=e.d,exports.redactFields=redactFields,exports.redactObject=redactObject,exports.redactPath=redactPath,exports.redactUrl=redactUrl,exports.scrubObjectAsync=scrubObjectAsync,exports.shannonEntropy=shannonEntropy;
@@ -3,6 +3,8 @@ import { ILogger } from "@stackone/logger";
3
3
  //#region \0rolldown/runtime.js
4
4
  //#endregion
5
5
  //#region src/shared/index.d.ts
6
+ declare const KEYS_TO_REDACT: string[];
7
+ declare const PATHS_TO_REDACT: string[];
6
8
  declare const REDACT_CENSOR = "**redacted**";
7
9
  declare enum CensorType {
8
10
  FULL = "FULL",
@@ -97,4 +99,4 @@ declare function entropyScrub(text: string, redactionToken?: string, config?: En
97
99
  declare const redactObject: <T>(obj: T, censorType?: CensorType) => T;
98
100
  declare const I_AM_EDGE = false;
99
101
  //#endregion
100
- export { CensorType, type EntropyConfig, type EntropyScrubResult, I_AM_EDGE, MODEL_FILES, type ModelConfig, type ModelDetection, PiiRedaction, type PiiRedactionConfig, type PiiRedactionOptions, REDACT_CENSOR, type RedactionResult, type RedactionSpan, createPiiRedaction, entropyScrub, getDefaultModelCacheDir, isModelPresent, redactFields, redactObject, redactPath, redactUrl, scrubObjectAsync, shannonEntropy };
102
+ export { CensorType, type EntropyConfig, type EntropyScrubResult, I_AM_EDGE, KEYS_TO_REDACT, MODEL_FILES, type ModelConfig, type ModelDetection, PATHS_TO_REDACT, PiiRedaction, type PiiRedactionConfig, type PiiRedactionOptions, REDACT_CENSOR, type RedactionResult, type RedactionSpan, createPiiRedaction, entropyScrub, getDefaultModelCacheDir, isModelPresent, redactFields, redactObject, redactPath, redactUrl, scrubObjectAsync, shannonEntropy };
@@ -2,6 +2,8 @@ import { t as __name } from "./chunk-BhWHdk3m.mjs";
2
2
  import { ILogger } from "@stackone/logger";
3
3
 
4
4
  //#region src/shared/index.d.ts
5
+ declare const KEYS_TO_REDACT: string[];
6
+ declare const PATHS_TO_REDACT: string[];
5
7
  declare const REDACT_CENSOR = "**redacted**";
6
8
  declare enum CensorType {
7
9
  FULL = "FULL",
@@ -96,4 +98,4 @@ declare function entropyScrub(text: string, redactionToken?: string, config?: En
96
98
  declare const redactObject: <T>(obj: T, censorType?: CensorType) => T;
97
99
  declare const I_AM_EDGE = false;
98
100
  //#endregion
99
- export { CensorType, type EntropyConfig, type EntropyScrubResult, I_AM_EDGE, MODEL_FILES, type ModelConfig, type ModelDetection, PiiRedaction, type PiiRedactionConfig, type PiiRedactionOptions, REDACT_CENSOR, type RedactionResult, type RedactionSpan, createPiiRedaction, entropyScrub, getDefaultModelCacheDir, isModelPresent, redactFields, redactObject, redactPath, redactUrl, scrubObjectAsync, shannonEntropy };
101
+ export { CensorType, type EntropyConfig, type EntropyScrubResult, I_AM_EDGE, KEYS_TO_REDACT, MODEL_FILES, type ModelConfig, type ModelDetection, PATHS_TO_REDACT, PiiRedaction, type PiiRedactionConfig, type PiiRedactionOptions, REDACT_CENSOR, type RedactionResult, type RedactionSpan, createPiiRedaction, entropyScrub, getDefaultModelCacheDir, isModelPresent, redactFields, redactObject, redactPath, redactUrl, scrubObjectAsync, shannonEntropy };
@@ -1 +1 @@
1
- import"./chunk-BhWHdk3m.mjs";import{a as e,c as t,d as n,i as r,o as i,r as a,s as o,t as s,u as c}from"./config-BgN6jr5v.mjs";import{deepCopy as l,isMissing as u}from"@stackone/utils";import d from"fast-redact";const f=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`],p=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...f],m=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>f.map(t=>`${e}[${JSON.stringify(t)}]`))],h=`**redacted**`,g=`**circular**`,_=`**max-depth**`,v=`**unreadable**`;let y=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>h,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?h:`${h}${e.slice(-5)}`:h,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),b=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||b.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},x={FULL:censorFn,PARTIAL:partialCensorFn},S=getKeysToRedact(p),C=[...getPathsToRedact(m),...Array.from(S).map(asValidPath)],redactUrl=(e,t=`FULL`,n)=>{if(!u(e))try{let n=new URL(e),r=[...n.searchParams].reduce((e,[n,r])=>(e.set(n,S.has(n)?x[t](r):r),e),new URLSearchParams);return`${n.origin}${n.pathname}${r.toString()?`?`+r:``}${n.hash}`}catch(t){return n?.warning({message:`Invalid URL provided, unable to redact`,context:{value:e,error:t},category:`redactUrl`}),typeof e==`string`?e:e?.toString()}},redactPath=(e,t=`FULL`,n)=>{if(!u(e))try{let[n,r]=e.split(`?`);return r?`${n}?${[...new URLSearchParams(r)].reduce((e,[n,r])=>(e.set(n,S.has(n)?x[t](r):r),e),new URLSearchParams)}`:e}catch(t){return n?.warning({message:`Invalid path provided, unable to redact`,context:{value:e,error:t},category:`redactPath`}),e}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return g;if(r>64)return _;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return v}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>S.has(e)?[e,x[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet),defineOwn=(e,t,n)=>{Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})},walk=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(n.has(e))return g;if(t>64)return _;if(Array.isArray(e)){n.add(e);let a=Array(e.length);return e.forEach((e,o)=>{typeof e==`string`?(a[o]=e,r.push(e),i.push(e=>{a[o]=e})):a[o]=walk(e,t+1,n,r,i)}),n.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return v}if(!a)return e;n.add(e);let o={};for(let[a,s]of Object.entries(e))typeof s==`string`?(defineOwn(o,a,s),r.push(s),i.push(e=>{defineOwn(o,a,e)})):defineOwn(o,a,walk(s,t+1,n,r,i));return n.delete(e),o};async function scrubObjectAsync(e,t){if(typeof e==`string`)return(await t.scrubAsync(e)).scrubbed;let n=[],r=[],i=walk(e,0,new WeakSet,n,r);return n.length>0&&(await t.scrubManyAsync(n)).forEach((e,t)=>r[t](e.scrubbed)),i}function shannonEntropy(e){if(!e)return 0;let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=e.length,r=0;for(let e of t.values()){let t=e/n;r-=t*Math.log2(t)}return r}function entropyScrub(t,n=`[REDACTED]`,a=s){let c=e(t,a.skipPatterns),l=[],u=a.candidatePattern.flags.includes(`g`)?a.candidatePattern.flags:`${a.candidatePattern.flags}g`,d=new RegExp(a.candidatePattern.source,u),f;for(;(f=d.exec(t))!==null;){let e=f[0];e.length<a.minLength||i(f.index,f.index+e.length,c)||shannonEntropy(e)>=a.threshold&&l.push({start:f.index,end:f.index+e.length,original:e,replacement:n,source:`entropy`})}for(let e of a.piiPatterns??[]){let r=new RegExp(e.source,e.flags.includes(`g`)?e.flags:`${e.flags}g`),a;for(;(a=r.exec(t))!==null;){let e=a.index,t=e+a[0].length;i(e,t,c)||l.push({start:e,end:t,original:a[0],replacement:n,source:`entropy`})}}let p=o(l);return{scrubbed:r(t,p),redactions:p}}var PiiRedaction=class{constructor(e){this.tier2=null,this.tier2LoadPromise=null,this.config=a(e),this.enableTier2=e?.enableTier2??!1,this.logger=e?.logger}async warmupTier2(){this.enableTier2&&(await this.loadTier2(),this.tier2&&await this.tier2.warmup())}isTier2Ready(){return this.tier2?.isReady()??!1}scrub(e){let t=performance.now(),{scrubbed:n,redactions:r}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return{scrubbed:n,redactions:r,tier:`entropy`,modelAvailable:!1,latencyMs:performance.now()-t}}async scrubAsync(e){let t=performance.now();if(!this.enableTier2)return this.scrub(e);let n=!1,i=[];try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);let t=await this.tier2.detectSecrets(e);for(let e of t)i.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});n=!0}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 model detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}let{redactions:a}=entropyScrub(e,this.config.redactionToken,this.config.entropy);i.push(...a);let s=o(i);return{scrubbed:r(e,s),redactions:s,tier:n?`model+entropy`:`entropy`,modelAvailable:n,latencyMs:performance.now()-t}}async scrubManyAsync(e){if(!this.enableTier2)return e.map(e=>this.scrub(e));let t=null;try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);t=await this.tier2.detectSecretsBatch(e)}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 batch detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}return e.map((e,n)=>{let i=performance.now(),a=[];for(let e of t?.[n]??[])a.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});let{redactions:s}=entropyScrub(e,this.config.redactionToken,this.config.entropy);a.push(...s);let c=o(a);return{scrubbed:r(e,c),redactions:c,tier:t?`model+entropy`:`entropy`,modelAvailable:t!==null,latencyMs:performance.now()-i}})}async dispose(){let e=this.tier2;this.tier2=null,this.tier2LoadPromise=null,await e?.dispose()}detect(e){let{redactions:t}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return t}getConfig(){return structuredClone(this.config)}async loadTier2(){if(!this.tier2){if(this.tier2LoadPromise)return this.tier2LoadPromise;this.tier2LoadPromise=(async()=>{let{Tier2Classifier:e}=await import(`./tier2-classifier-CY0XZ85t.mjs`);this.tier2=new e({onnxModelPath:this.config.model.modelPath})})();try{await this.tier2LoadPromise}catch(e){throw this.tier2LoadPromise=null,Error(`Failed to load Tier 2 classifier: ${e instanceof Error?e.message:String(e)}. Ensure onnxruntime-node and @huggingface/transformers are installed. The model ships bundled with @stackone/redaction — try reinstalling the package, or configure modelPath.`)}}}};function createPiiRedaction(e){return new PiiRedaction(e)}let w;const getRedactors=()=>(u(w)&&(w={FULL:d({paths:C,serialize:!1,censor:x.FULL}),PARTIAL:d({paths:C,serialize:!1,censor:x.PARTIAL})}),w),redactObject=(e,t=`FULL`)=>u(e)||typeof e!=`object`||!e?e:getRedactors()[t](l(e)),T=!1;export{y as CensorType,T as I_AM_EDGE,t as MODEL_FILES,PiiRedaction,h as REDACT_CENSOR,createPiiRedaction,entropyScrub,c as getDefaultModelCacheDir,n as isModelPresent,redactFields,redactObject,redactPath,redactUrl,scrubObjectAsync,shannonEntropy};
1
+ import"./chunk-BhWHdk3m.mjs";import{a as e,c as t,d as n,i as r,o as i,r as a,s as o,t as s,u as c}from"./config-BgN6jr5v.mjs";import{deepCopy as l,isMissing as u}from"@stackone/utils";import d from"fast-redact";const f=[`x-api-key`,`x-connect-token`,`x-signature`,`x-idp-session-token`,`us-customer-api-key`,`x-stackone-external-trigger-token`,`klaviyo-api-key`,`x-sn-apikey`],p=[`client_secret`,`access_token`,`refresh_token`,`api_key`,`password`,`job_board_token`,`private_key`,`certificate`,`service_user_token`,`key_id`,`secret_key`,`provhash`,`admin_key`,`session_key`,`id_token`,`authorization`,`bh_rest_token`,`external_trigger_token`,`tempauth`,`token`,`secret`,`secrets`,`credentials`,`setup_information`,`setup_fields`,`authentication_config_key`,`cookie`,`set-cookie`,`bearer`,`apikey`,...f],m=[`req.headers.authorization`,`req.headers.cookie`,`req.headers.cookies`,`req.headers["set-cookie"]`,`req.headers["set-cookies"]`,`req.headers.httpsAgent.options.cert`,`req.headers.httpsAgent.options.key`,`req.headers["x-stackone-external-trigger-token"]`,`error.config.headers.authorization`,`error.config.data`,`error.config.headers.cookie`,`error.config.headers.cookies`,`error.config.headers["set-cookie"]`,`error.config.headers["set-cookies"]`,`error.config.httpsAgent.options.cert`,`error.config.httpsAgent.options.key`,`err.config.headers.authorization`,`err.config.data`,`err.config.headers.cookie`,`err.config.headers.cookies`,`err.config.headers["set-cookie"]`,`err.config.headers["set-cookies"]`,`err.config.httpsAgent.options.cert`,`err.config.httpsAgent.options.key`,`res.headers.authorization`,`res.headers.cookie`,`res.headers.cookies`,`res.headers["set-cookie"]`,`res.headers["set-cookies"]`,`res.headers.httpsAgent.options.cert`,`res.headers.httpsAgent.options.key`,`context.credentials`,...[`req.headers`,`res.headers`,`error.config.headers`,`err.config.headers`].flatMap(e=>f.map(t=>`${e}[${JSON.stringify(t)}]`))],h=`**redacted**`,g=`**circular**`,_=`**max-depth**`,v=`**unreadable**`;let y=function(e){return e.FULL=`FULL`,e.PARTIAL=`PARTIAL`,e}({});const censorFn=e=>h,partialCensorFn=e=>typeof e==`string`?e.startsWith(`**redacted**`)?e:e.length<=10?h:`${h}${e.slice(-5)}`:h,capitalizeWord=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,capitalizeLastWordAfterLastDot=e=>{let t=e.split(`.`);if(t.length<2)return capitalizeWord(e);let n=capitalizeWord(t.pop()??``);return[...t,n].join(`.`)},capitalizeWordInsideLastBrackets=e=>{let t=e.lastIndexOf(`[`),n=e.indexOf(`]`,t);if(t===-1||n===-1)return;let r=e.slice(t,n+1).replace(/(["'])([^"']*)(["'])/g,(e,t,n)=>n?t+capitalizeWord(n)+t:t+t);return`${e.slice(0,t)}${r}${e.slice(n+1)}`},capitalizeKey=e=>capitalizeWordInsideLastBrackets(e)||capitalizeLastWordAfterLastDot(e),b=/^[A-Za-z_$][\w$]*$/,asValidPath=e=>e.includes(`.`)||e.includes(`[`)||b.test(e)?e:`[${JSON.stringify(e)}]`,getPathsToRedact=(e=[],t=!0)=>{if(!t)return[];let n=e.map(e=>asValidPath(e)),r=n.map(e=>capitalizeKey(e));return[...n,...r]},getKeysToRedact=(e=[],t=!0)=>{if(!t)return new Set;let n=new Set;return e.forEach(e=>{n.add(e);let t;t=e.includes(`_`)?e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase()):/^[A-Z]/.test(e)?e.charAt(0).toLowerCase()+e.slice(1):e;let r=t.charAt(0).toUpperCase()+t.slice(1),i=t.replace(/([A-Z])/g,`_$1`).toLowerCase();n.add(t),n.add(r),n.add(i)}),n},x={FULL:censorFn,PARTIAL:partialCensorFn},S=getKeysToRedact(p),C=new Set(Array.from(S,e=>e.toLowerCase())),matchesRedactedKey=e=>{let t=e.toLowerCase();return C.has(t)?!0:t.includes(`[`)?t.split(/[\[\]]/).some(e=>e&&C.has(e)):!1},w=[...getPathsToRedact(m),...Array.from(S).map(asValidPath)],redactUrl=(e,t=`FULL`,n)=>{if(!u(e))try{let n=new URL(e),r=[...n.searchParams].reduce((e,[n,r])=>(e.set(n,matchesRedactedKey(n)?x[t](r):r),e),new URLSearchParams);return`${n.origin}${n.pathname}${r.toString()?`?`+r:``}${n.hash}`}catch(t){return n?.warning({message:`Invalid URL provided, unable to redact`,context:{value:e,error:t},category:`redactUrl`}),typeof e==`string`?e:e?.toString()}},redactPath=(e,t=`FULL`,n)=>{if(!u(e))try{let[n,r]=e.split(`?`);return r?`${n}?${[...new URLSearchParams(r)].reduce((e,[n,r])=>(e.set(n,matchesRedactedKey(n)?x[t](r):r),e),new URLSearchParams)}`:e}catch(t){return n?.warning({message:`Invalid path provided, unable to redact`,context:{value:e,error:t},category:`redactPath`}),e}},redactNode=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(i.has(e))return g;if(r>64)return _;if(Array.isArray(e)){if(!n)return[...e];i.add(e);let a=e.map(e=>typeof e==`object`&&e?redactNode(e,t,n,r+1,i):e);return i.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return v}if(!a)return e;i.add(e);let o=Object.fromEntries(Object.entries(e).map(([e,a])=>matchesRedactedKey(e)?[e,x[t](a)]:n&&typeof a==`object`&&a?[e,redactNode(a,t,n,r+1,i)]:[e,a]));return i.delete(e),o},redactFields=(e,t=`FULL`,n=!1)=>redactNode(e,t,n,0,new WeakSet),defineOwn=(e,t,n)=>{Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})},walk=(e,t,n,r,i)=>{if(typeof e!=`object`||!e)return e;if(n.has(e))return g;if(t>64)return _;if(Array.isArray(e)){n.add(e);let a=Array(e.length);return e.forEach((e,o)=>{typeof e==`string`?(a[o]=e,r.push(e),i.push(e=>{a[o]=e})):a[o]=walk(e,t+1,n,r,i)}),n.delete(e),a}let a;try{let t=Object.getPrototypeOf(e);a=t===null||Object.getPrototypeOf(t)===null}catch{return v}if(!a)return e;n.add(e);let o={};for(let[a,s]of Object.entries(e))typeof s==`string`?(defineOwn(o,a,s),r.push(s),i.push(e=>{defineOwn(o,a,e)})):defineOwn(o,a,walk(s,t+1,n,r,i));return n.delete(e),o};async function scrubObjectAsync(e,t){if(typeof e==`string`)return(await t.scrubAsync(e)).scrubbed;let n=[],r=[],i=walk(e,0,new WeakSet,n,r);return n.length>0&&(await t.scrubManyAsync(n)).forEach((e,t)=>r[t](e.scrubbed)),i}function shannonEntropy(e){if(!e)return 0;let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=e.length,r=0;for(let e of t.values()){let t=e/n;r-=t*Math.log2(t)}return r}function entropyScrub(t,n=`[REDACTED]`,a=s){let c=e(t,a.skipPatterns),l=[],u=a.candidatePattern.flags.includes(`g`)?a.candidatePattern.flags:`${a.candidatePattern.flags}g`,d=new RegExp(a.candidatePattern.source,u),f;for(;(f=d.exec(t))!==null;){let e=f[0];e.length<a.minLength||i(f.index,f.index+e.length,c)||shannonEntropy(e)>=a.threshold&&l.push({start:f.index,end:f.index+e.length,original:e,replacement:n,source:`entropy`})}for(let e of a.piiPatterns??[]){let r=new RegExp(e.source,e.flags.includes(`g`)?e.flags:`${e.flags}g`),a;for(;(a=r.exec(t))!==null;){let e=a.index,t=e+a[0].length;i(e,t,c)||l.push({start:e,end:t,original:a[0],replacement:n,source:`entropy`})}}let p=o(l);return{scrubbed:r(t,p),redactions:p}}var PiiRedaction=class{constructor(e){this.tier2=null,this.tier2LoadPromise=null,this.config=a(e),this.enableTier2=e?.enableTier2??!1,this.logger=e?.logger}async warmupTier2(){this.enableTier2&&(await this.loadTier2(),this.tier2&&await this.tier2.warmup())}isTier2Ready(){return this.tier2?.isReady()??!1}scrub(e){let t=performance.now(),{scrubbed:n,redactions:r}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return{scrubbed:n,redactions:r,tier:`entropy`,modelAvailable:!1,latencyMs:performance.now()-t}}async scrubAsync(e){let t=performance.now();if(!this.enableTier2)return this.scrub(e);let n=!1,i=[];try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);let t=await this.tier2.detectSecrets(e);for(let e of t)i.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});n=!0}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 model detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}let{redactions:a}=entropyScrub(e,this.config.redactionToken,this.config.entropy);i.push(...a);let s=o(i);return{scrubbed:r(e,s),redactions:s,tier:n?`model+entropy`:`entropy`,modelAvailable:n,latencyMs:performance.now()-t}}async scrubManyAsync(e){if(!this.enableTier2)return e.map(e=>this.scrub(e));let t=null;try{if(await this.loadTier2(),!this.tier2)throw Error(`Tier 2 classifier not loaded`);t=await this.tier2.detectSecretsBatch(e)}catch(e){this.logger?.warning({category:`pii-redaction`,message:`Tier 2 batch detection failed, falling back to entropy only`,error:e instanceof Error?e:void 0,code:`TIER2_FALLBACK`})}return e.map((e,n)=>{let i=performance.now(),a=[];for(let e of t?.[n]??[])a.push({start:e.start,end:e.end,original:e.text,replacement:this.config.redactionToken,source:`model`,label:e.label});let{redactions:s}=entropyScrub(e,this.config.redactionToken,this.config.entropy);a.push(...s);let c=o(a);return{scrubbed:r(e,c),redactions:c,tier:t?`model+entropy`:`entropy`,modelAvailable:t!==null,latencyMs:performance.now()-i}})}async dispose(){let e=this.tier2;this.tier2=null,this.tier2LoadPromise=null,await e?.dispose()}detect(e){let{redactions:t}=entropyScrub(e,this.config.redactionToken,this.config.entropy);return t}getConfig(){return structuredClone(this.config)}async loadTier2(){if(!this.tier2){if(this.tier2LoadPromise)return this.tier2LoadPromise;this.tier2LoadPromise=(async()=>{let{Tier2Classifier:e}=await import(`./tier2-classifier-CY0XZ85t.mjs`);this.tier2=new e({onnxModelPath:this.config.model.modelPath})})();try{await this.tier2LoadPromise}catch(e){throw this.tier2LoadPromise=null,Error(`Failed to load Tier 2 classifier: ${e instanceof Error?e.message:String(e)}. Ensure onnxruntime-node and @huggingface/transformers are installed. The model ships bundled with @stackone/redaction — try reinstalling the package, or configure modelPath.`)}}}};function createPiiRedaction(e){return new PiiRedaction(e)}let T;const getRedactors=()=>(u(T)&&(T={FULL:d({paths:w,serialize:!1,censor:x.FULL}),PARTIAL:d({paths:w,serialize:!1,censor:x.PARTIAL})}),T),redactObject=(e,t=`FULL`)=>u(e)||typeof e!=`object`||!e?e:getRedactors()[t](l(e)),E=!1;export{y as CensorType,E as I_AM_EDGE,p as KEYS_TO_REDACT,t as MODEL_FILES,m as PATHS_TO_REDACT,PiiRedaction,h as REDACT_CENSOR,createPiiRedaction,entropyScrub,c as getDefaultModelCacheDir,n as isModelPresent,redactFields,redactObject,redactPath,redactUrl,scrubObjectAsync,shannonEntropy};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/redaction",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "",
5
5
  "main": "dist/node/index.cjs",
6
6
  "files": [