@walkeros/server-transformer-fingerprint 1.0.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.
@@ -0,0 +1,56 @@
1
+ import { Mapping, Transformer } from '@walkeros/core';
2
+
3
+ /**
4
+ * Fingerprint transformer settings.
5
+ */
6
+ interface FingerprintSettings {
7
+ /**
8
+ * Fields to include in hash (order matters!).
9
+ * Each field is resolved via getMappingValue with source object { event, ingest }.
10
+ *
11
+ * String fields use dot notation:
12
+ * - 'ingest.ip' -> context.ingest.ip
13
+ * - 'ingest.userAgent' -> context.ingest.userAgent
14
+ * - 'event.data.userId' -> event.data.userId
15
+ *
16
+ * Function fields via mapping config:
17
+ * - { fn: () => new Date().getDate() } -> day of month
18
+ * - { key: 'ingest.ip', fn: anonymizeIP } -> transform value
19
+ */
20
+ fields: Mapping.Value[];
21
+ /**
22
+ * Dot-notation path where hash is stored on the event.
23
+ * @default 'user.hash'
24
+ */
25
+ output?: string;
26
+ /**
27
+ * Truncate hash to this length.
28
+ * @default undefined (full 64-char SHA-256 hash)
29
+ */
30
+ length?: number;
31
+ }
32
+
33
+ /**
34
+ * Fingerprint transformer - hash configurable fields for session continuity.
35
+ *
36
+ * Resolves fields from { event, ingest } source object using getMappingValue,
37
+ * concatenates values in order, hashes with SHA-256, and stores at output path.
38
+ *
39
+ * @example
40
+ * transformerFingerprint({
41
+ * config: {
42
+ * settings: {
43
+ * fields: [
44
+ * 'ingest.ip',
45
+ * 'ingest.userAgent',
46
+ * { fn: () => new Date().getDate() },
47
+ * ],
48
+ * output: 'user.hash',
49
+ * length: 16,
50
+ * },
51
+ * },
52
+ * })
53
+ */
54
+ declare const transformerFingerprint: Transformer.Init<Transformer.Types<FingerprintSettings>>;
55
+
56
+ export { type FingerprintSettings, transformerFingerprint };
@@ -0,0 +1,56 @@
1
+ import { Mapping, Transformer } from '@walkeros/core';
2
+
3
+ /**
4
+ * Fingerprint transformer settings.
5
+ */
6
+ interface FingerprintSettings {
7
+ /**
8
+ * Fields to include in hash (order matters!).
9
+ * Each field is resolved via getMappingValue with source object { event, ingest }.
10
+ *
11
+ * String fields use dot notation:
12
+ * - 'ingest.ip' -> context.ingest.ip
13
+ * - 'ingest.userAgent' -> context.ingest.userAgent
14
+ * - 'event.data.userId' -> event.data.userId
15
+ *
16
+ * Function fields via mapping config:
17
+ * - { fn: () => new Date().getDate() } -> day of month
18
+ * - { key: 'ingest.ip', fn: anonymizeIP } -> transform value
19
+ */
20
+ fields: Mapping.Value[];
21
+ /**
22
+ * Dot-notation path where hash is stored on the event.
23
+ * @default 'user.hash'
24
+ */
25
+ output?: string;
26
+ /**
27
+ * Truncate hash to this length.
28
+ * @default undefined (full 64-char SHA-256 hash)
29
+ */
30
+ length?: number;
31
+ }
32
+
33
+ /**
34
+ * Fingerprint transformer - hash configurable fields for session continuity.
35
+ *
36
+ * Resolves fields from { event, ingest } source object using getMappingValue,
37
+ * concatenates values in order, hashes with SHA-256, and stores at output path.
38
+ *
39
+ * @example
40
+ * transformerFingerprint({
41
+ * config: {
42
+ * settings: {
43
+ * fields: [
44
+ * 'ingest.ip',
45
+ * 'ingest.userAgent',
46
+ * { fn: () => new Date().getDate() },
47
+ * ],
48
+ * output: 'user.hash',
49
+ * length: 16,
50
+ * },
51
+ * },
52
+ * })
53
+ */
54
+ declare const transformerFingerprint: Transformer.Init<Transformer.Types<FingerprintSettings>>;
55
+
56
+ export { type FingerprintSettings, transformerFingerprint };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,r=Object.defineProperty,t=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})})(a,{transformerFingerprint:()=>l}),module.exports=(e=a,((e,a,s,i)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let l of o(a))n.call(e,l)||l===s||r(e,l,{get:()=>a[l],enumerable:!(i=t(a,l))||i.enumerable});return e})(r({},"__esModule",{value:!0}),e));var s=require("@walkeros/core"),i=require("@walkeros/server-core"),l=e=>{const{config:r}=e,t=r.settings||{},o=t.fields||[],n=t.output||"user.hash",a=t.length;return{type:"fingerprint",config:r,async push(e,r){const{ingest:t,collector:l}=r,c={event:e,ingest:t},p=""+(await Promise.all(o.map(e=>(0,s.getMappingValue)(c,e,{collector:l})))).map(e=>String(null!=e?e:"")).join(""),u=await(0,i.getHashServer)(p,a);return(0,s.setByPath)(e,n,u)}}};//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/transformer.ts"],"sourcesContent":["export { transformerFingerprint } from './transformer';\nexport type { FingerprintSettings } from './types';\n","import type { Mapping, Transformer } from '@walkeros/core';\nimport { getMappingValue, setByPath } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { FingerprintSettings } from './types';\n\n/**\n * Fingerprint transformer - hash configurable fields for session continuity.\n *\n * Resolves fields from { event, ingest } source object using getMappingValue,\n * concatenates values in order, hashes with SHA-256, and stores at output path.\n *\n * @example\n * transformerFingerprint({\n * config: {\n * settings: {\n * fields: [\n * 'ingest.ip',\n * 'ingest.userAgent',\n * { fn: () => new Date().getDate() },\n * ],\n * output: 'user.hash',\n * length: 16,\n * },\n * },\n * })\n */\nexport const transformerFingerprint: Transformer.Init<\n Transformer.Types<FingerprintSettings>\n> = (context) => {\n const { config } = context;\n const settings = (config.settings || {}) as Partial<FingerprintSettings>;\n const fields: Mapping.Value[] = settings.fields || [];\n const output: string = settings.output || 'user.hash';\n const length: number | undefined = settings.length;\n\n return {\n type: 'fingerprint',\n config: config as Transformer.Config<\n Transformer.Types<FingerprintSettings>\n >,\n\n async push(event, context) {\n const { ingest, collector } = context;\n\n // Build source object for field resolution\n const source = { event, ingest };\n\n // Resolve each field via mapping (maintains order)\n const values = await Promise.all(\n fields.map((field: Mapping.Value) =>\n getMappingValue(source, field, { collector }),\n ),\n );\n\n // Safe string concatenation: '' prefix + String() cast for each value\n // '' prefix ensures we always have a string even if fields is empty\n // String(v ?? '') handles undefined/null gracefully\n const input = '' + values.map((v: unknown) => String(v ?? '')).join('');\n\n // Hash and store at output path\n const hash = await getHashServer(input, length);\n return setByPath(event, output, hash);\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAA2C;AAC3C,yBAA8B;AAwBvB,IAAM,yBAET,CAAC,YAAY;AACf,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAY,OAAO,YAAY,CAAC;AACtC,QAAM,SAA0B,SAAS,UAAU,CAAC;AACpD,QAAM,SAAiB,SAAS,UAAU;AAC1C,QAAM,SAA6B,SAAS;AAE5C,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IAIA,MAAM,KAAK,OAAOA,UAAS;AACzB,YAAM,EAAE,QAAQ,UAAU,IAAIA;AAG9B,YAAM,SAAS,EAAE,OAAO,OAAO;AAG/B,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,OAAO;AAAA,UAAI,CAAC,cACV,6BAAgB,QAAQ,OAAO,EAAE,UAAU,CAAC;AAAA,QAC9C;AAAA,MACF;AAKA,YAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAe,OAAO,gBAAK,EAAE,CAAC,EAAE,KAAK,EAAE;AAGtE,YAAM,OAAO,UAAM,kCAAc,OAAO,MAAM;AAC9C,iBAAO,uBAAU,OAAO,QAAQ,IAAI;AAAA,IACtC;AAAA,EACF;AACF;","names":["context"]}
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{getMappingValue as r,setByPath as e}from"@walkeros/core";import{getHashServer as t}from"@walkeros/server-core";var o=o=>{const{config:n}=o,i=n.settings||{},s=i.fields||[],a=i.output||"user.hash",l=i.length;return{type:"fingerprint",config:n,async push(o,n){const{ingest:i,collector:c}=n,p={event:o,ingest:i},g=""+(await Promise.all(s.map(e=>r(p,e,{collector:c})))).map(r=>String(null!=r?r:"")).join(""),m=await t(g,l);return e(o,a,m)}}};export{o as transformerFingerprint};//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transformer.ts"],"sourcesContent":["import type { Mapping, Transformer } from '@walkeros/core';\nimport { getMappingValue, setByPath } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { FingerprintSettings } from './types';\n\n/**\n * Fingerprint transformer - hash configurable fields for session continuity.\n *\n * Resolves fields from { event, ingest } source object using getMappingValue,\n * concatenates values in order, hashes with SHA-256, and stores at output path.\n *\n * @example\n * transformerFingerprint({\n * config: {\n * settings: {\n * fields: [\n * 'ingest.ip',\n * 'ingest.userAgent',\n * { fn: () => new Date().getDate() },\n * ],\n * output: 'user.hash',\n * length: 16,\n * },\n * },\n * })\n */\nexport const transformerFingerprint: Transformer.Init<\n Transformer.Types<FingerprintSettings>\n> = (context) => {\n const { config } = context;\n const settings = (config.settings || {}) as Partial<FingerprintSettings>;\n const fields: Mapping.Value[] = settings.fields || [];\n const output: string = settings.output || 'user.hash';\n const length: number | undefined = settings.length;\n\n return {\n type: 'fingerprint',\n config: config as Transformer.Config<\n Transformer.Types<FingerprintSettings>\n >,\n\n async push(event, context) {\n const { ingest, collector } = context;\n\n // Build source object for field resolution\n const source = { event, ingest };\n\n // Resolve each field via mapping (maintains order)\n const values = await Promise.all(\n fields.map((field: Mapping.Value) =>\n getMappingValue(source, field, { collector }),\n ),\n );\n\n // Safe string concatenation: '' prefix + String() cast for each value\n // '' prefix ensures we always have a string even if fields is empty\n // String(v ?? '') handles undefined/null gracefully\n const input = '' + values.map((v: unknown) => String(v ?? '')).join('');\n\n // Hash and store at output path\n const hash = await getHashServer(input, length);\n return setByPath(event, output, hash);\n },\n };\n};\n"],"mappings":";AACA,SAAS,iBAAiB,iBAAiB;AAC3C,SAAS,qBAAqB;AAwBvB,IAAM,yBAET,CAAC,YAAY;AACf,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAY,OAAO,YAAY,CAAC;AACtC,QAAM,SAA0B,SAAS,UAAU,CAAC;AACpD,QAAM,SAAiB,SAAS,UAAU;AAC1C,QAAM,SAA6B,SAAS;AAE5C,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IAIA,MAAM,KAAK,OAAOA,UAAS;AACzB,YAAM,EAAE,QAAQ,UAAU,IAAIA;AAG9B,YAAM,SAAS,EAAE,OAAO,OAAO;AAG/B,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,OAAO;AAAA,UAAI,CAAC,UACV,gBAAgB,QAAQ,OAAO,EAAE,UAAU,CAAC;AAAA,QAC9C;AAAA,MACF;AAKA,YAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAe,OAAO,gBAAK,EAAE,CAAC,EAAE,KAAK,EAAE;AAGtE,YAAM,OAAO,MAAM,cAAc,OAAO,MAAM;AAC9C,aAAO,UAAU,OAAO,QAAQ,IAAI;AAAA,IACtC;AAAA,EACF;AACF;","names":["context"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@walkeros/server-transformer-fingerprint",
3
+ "description": "Fingerprint transformer for walkerOS server - hash configurable fields for session continuity",
4
+ "version": "1.0.0",
5
+ "license": "MIT",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist/**"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup --silent",
21
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
22
+ "dev": "jest --watchAll --colors",
23
+ "lint": "tsc --noEmit && eslint \"**/*.ts*\"",
24
+ "test": "jest",
25
+ "update": "npx npm-check-updates -u && npm update"
26
+ },
27
+ "peerDependencies": {
28
+ "@walkeros/core": "^0.7.0",
29
+ "@walkeros/server-core": "^0.6.1"
30
+ },
31
+ "devDependencies": {
32
+ "@walkeros/core": "0.7.0",
33
+ "@walkeros/server-core": "0.6.1"
34
+ },
35
+ "repository": {
36
+ "url": "git+https://github.com/elbwalker/walkerOS.git",
37
+ "directory": "packages/server/transformers/fingerprint"
38
+ },
39
+ "author": "elbwalker <hello@elbwalker.com>",
40
+ "homepage": "https://github.com/elbwalker/walkerOS#readme",
41
+ "bugs": {
42
+ "url": "https://github.com/elbwalker/walkerOS/issues"
43
+ },
44
+ "keywords": [
45
+ "walker",
46
+ "walkerOS",
47
+ "transformer",
48
+ "fingerprint",
49
+ "hash",
50
+ "server"
51
+ ],
52
+ "funding": [
53
+ {
54
+ "type": "GitHub Sponsors",
55
+ "url": "https://github.com/sponsors/elbwalker"
56
+ }
57
+ ]
58
+ }