{"_id":"@aikotools/datafilter","_rev":"14-0310f8e454cb1557d5eb6b2192bb86e0","name":"@aikotools/datafilter","dist-tags":{"latest":"1.2.2"},"versions":{"1.0.0":{"name":"@aikotools/datafilter","version":"1.0.0","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.0","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"037c7b3a9e6ae3d0e1b7df3a61980e489c3f05ed","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.0.tgz","fileCount":22,"integrity":"sha512-3NbWoQftU6j+Je+FTSYtoQBTIR/HOx4FeOVKqYGGeuI1YfTeqCoRA/MSbQYXuzGCITJUxCXpKS5AfmwTZWgfLg==","signatures":[{"sig":"MEUCIQCazZtTFp37oogEozz6b6PZ5uaKDUkbN+Pwr0iTFrZthAIgeqDkaJrhhHhWXnFllWhDzG5EIEXkbCooi87GfY/0+po=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54723},"main":"dist/aikotools-datafilter.js","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.js","gitHead":"2206e0861298d71f357194c0b2b035730a26186c","scripts":{"dev":"vite","lint":"eslint \"src/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"src/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"10.9.4","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.0.0","eslint":"^8.57.0","vitest":"^1.0.0","prettier":"^3.0.0","typescript":"^5.4.0","@types/node":"^20.0.0","@types/luxon":"^3.7.1","vite-plugin-dts":"^3.0.0","@vitest/coverage-v8":"^1.6.0","@typescript-eslint/parser":"^7.0.0","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.0_1760355940011_0.2695449938095065","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aikotools/datafilter","version":"1.0.1","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.1","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"f485c9950a431d3d05750d4fdc4c2043a970c831","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.1.tgz","fileCount":22,"integrity":"sha512-A5npMpRuI/zivLH24ETD4GPy/fXnVk7eiOFbcMYAoOnfCFNV5leWtJO8/loe1xOXlsa5njixIheQnxBi7yBoCQ==","signatures":[{"sig":"MEUCIGAFtusK5LbEWYtl/3RKX+yBDQPj+24duVNYb5MRaaZWAiEA49f1PvP5/ggH9H975fqYba4mvjVEbAqpuFFjK8QO0FE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54655},"main":"dist/aikotools-datafilter.js","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.js","gitHead":"6dd8d49f51f0074b68f354d5a8226dd1056d4741","scripts":{"dev":"vite","lint":"eslint \"src/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"src/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.1_1761141904830_0.5688334819907981","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@aikotools/datafilter","version":"1.0.2","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.2","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"e0898ffc45c9ccb15e74f43cbd003e27d18bccfb","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.2.tgz","fileCount":23,"integrity":"sha512-ZwvPIRcarf5BeyELI98I0A53O2zSNFvspUgUsPX5ONyDIkguROi9mnKzDEPvqRaolSv7E2L8Bvs97VThBlE9mA==","signatures":[{"sig":"MEQCIF61YQnwZhixAOkLDzm+wLfhQ1OtU/Av7w9M08/sRh/YAiA4szGPk3ABZ4PYuk26k7N0m5/Vyx3F9E8ebHubP7RK/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63867},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"ad34034cf447d08f8889e8d93e07f809d6bdb0fb","scripts":{"dev":"vite","lint":"eslint \"src/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"src/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.2_1761207487904_0.21187049609159714","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@aikotools/datafilter","version":"1.0.3","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.3","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"6972f77353147e3153a2e6bc224b3909cb2243ca","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.3.tgz","fileCount":23,"integrity":"sha512-pd8zdm73brYpBLO4vRLfeA7RHxnqtgaO8I6HRn8aspO7kzPYSXwaO7DAcYN/wab3iR9PIY9/9+L3W4qJUb+Ajw==","signatures":[{"sig":"MEUCIGBZjCkldUbvvJIJCgaJWpvkTOf2DylK64Y+QTlCJhmdAiEAmXc9BAcKZnrpgI2SRqSGdcA2KztA6WSA5du0BQSfDko=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70909},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"5abd850555208093c89280521faa5d12b27d4f54","scripts":{"dev":"vite","lint":"eslint \"src/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"src/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.3_1761297221831_0.75862659495377","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@aikotools/datafilter","version":"1.0.4","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.4","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"210230d3065f7eea408c3d234dd827794be4561c","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.4.tgz","fileCount":23,"integrity":"sha512-YALo5GKXh8IxcJfNubukG5rhy0K49ccbGZpTcF4jqmURUfCFzSTrH61NTX3DLJPOaZqvE04ZgBi49aSJyPHOsA==","signatures":[{"sig":"MEUCIEOqxQQXKyPDvP+lfCr4r0OH6On/Fznl2iAvEmfkyvVgAiEA4AbKtAT2lGapdsOv3Dqy+H2UwMJbSV21TA2YYv49uSU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70925},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"e1b4ad826ff0aab3af89d06855f4280981af9ccb","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.4_1761307635180_0.03456730350171311","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@aikotools/datafilter","version":"1.0.5","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.0.5","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"656f659ae880d39eca5d6444718a15c606756d6c","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.0.5.tgz","fileCount":23,"integrity":"sha512-etZ9EJ6AXArtkwy8SVnllXfwEKXu5Sfi09jol7GnLDQwUr6e06mjQPLLShLmWbyJ5NPF4Dbec54+nWn4b3MFOQ==","signatures":[{"sig":"MEQCIEuEQSndBQIBSxogLGsK/WFuRWAekIEdX9dv+V9ppA24AiB+7f6TSbSprNZvFFStAii45ft1Urr79w/D8Rqhqr/OTA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70925},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"843667f1232881ed8aa1fc3def171265e0407209","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.0.5_1761308682515_0.0007201168286024018","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@aikotools/datafilter","version":"1.1.0","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.1.0","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"44827ef6614f60eb8639b60fb369dd482d35d432","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.1.0.tgz","fileCount":25,"integrity":"sha512-VddeAciBFVDZtOLXdm2jtKR7kv8uZKhjbC/Ob+C3G3jB/bnPPbQJqH8hdXm0yuHl5L2F5K4g9u3B8didoUb9ew==","signatures":[{"sig":"MEUCIQD+Zpr8X+sajvEtoJn5Oui44/X6iW/P63jIc0C1jc+bbwIgDI2vBrlXSEC/BxZJYEg9C5Qzs5KsZkEsw2KZ6z8+7n8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":238368},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"5b47363d90455cb36c53feea5d707b644c03508e","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.10.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.1.0_1761561384403_0.04799179985743263","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@aikotools/datafilter","version":"1.1.1","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.1.1","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"5e0165d7ecdde007beeb303efae3cdc169640fe6","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.1.1.tgz","fileCount":25,"integrity":"sha512-hIPM/1yUZsz1cJDcU3OOjvX5eFVpRAVZ4Z6ZlMbSgDk5Gpbyq5k8MpNSbL8WBS8L4R5wV1a7i9xRVNfc01VWQQ==","signatures":[{"sig":"MEYCIQDGZS/zRdq9HTZRNcuO3B+HsMzT2wtBGnepps+mRsc+XAIhAODgsXOtNPpOlf+qmvJFTcSOpvF9WKVZ/2T0/f7XlKHf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":238369},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"3468f17419b7952ef723545c1cccb0890461ea88","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.11.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.1.1_1761734922301_0.1611593721746487","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@aikotools/datafilter","version":"1.1.2","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.1.2","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"5301604149a5823475006184019870f5371ebcc5","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.1.2.tgz","fileCount":25,"integrity":"sha512-39+SVKvUrM3qYFhDzAtb3os9jt/R3+HzFeRMcrWnoNAhFO66tW7Y+ncEWZ6CNE8KyoXfeRk0kHkoQecewCwXNg==","signatures":[{"sig":"MEYCIQDm1OMebYQSnVo52PPC/PfMa+V/V6RbfpdDf1nu74pUJwIhALTE1SEkjT9oY9d2JXzVTc8Sy2U92hPzGxl8GKOPqNdQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":240143},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"ad1d600e01ee0ac3dca652816e192766e98b6584","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.11.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.1.2_1761816811636_0.6388292080236972","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"@aikotools/datafilter","version":"1.1.3","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.1.3","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"22b26fabe7a84b516c7c66c7a93df0e14f000bf0","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.1.3.tgz","fileCount":25,"integrity":"sha512-TM9VSaiM3bW1ll85M/CDkcUGXou1NTC8vI4FZmErtyWRaiKIams9j9I7zOfe98MCPYIsEB+z1Kr+G74rqaCWLA==","signatures":[{"sig":"MEYCIQDZtFYWnapl6+FHW8TAI5XsIc71661KSKljWIXxhm754wIhALDwXvDiFVEh8Vf0jqjvf/L+Z1S5emeNZpN4F7TqwEtF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":247006},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"bab5d886f743fb5815f08003656815c5557a7725","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.11.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.1.3_1761911625310_0.26432094989295907","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"@aikotools/datafilter","version":"1.1.4","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.1.4","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"dist":{"shasum":"4e781696e6b89920262933c35641b7a24b98a3a8","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.1.4.tgz","fileCount":25,"integrity":"sha512-a0KJQtyzYjvrpn0BU71vNaHFvCOGMhciMOIwtPR3Zms20VCuB8zh+XQxIpnVrGctDvo/LjHw8DfVnA6YnhMHmw==","signatures":[{"sig":"MEYCIQDf9WEt6DdRt8pAWZgGNj2fCJ3B9DOD1A69C0oDA1do+gIhAJhYYJHJ42f3Q9imIJRPTaUeYGbMGo3R2m8qt/vnRT2+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":249278},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"7c5e594d3d364cf271d738e060f28653e88afdab","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"darlenya","email":"torstenlink@gmx.de"},"_npmVersion":"11.6.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.11.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.11","eslint":"^9.38.0","vitest":"^3.2.4","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.1","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^3.2.4","@typescript-eslint/parser":"^8.46.2","@typescript-eslint/eslint-plugin":"^8.46.2"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.1.4_1762169957228_0.035945929257082065","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@aikotools/datafilter","version":"1.2.0","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.2.0","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"homepage":"https://github.com/aikotools/datafilter#readme","bugs":{"url":"https://github.com/aikotools/datafilter/issues"},"dist":{"shasum":"7776a1ea32abc74cf93dbef8056d40d0c84afe32","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.2.0.tgz","fileCount":25,"integrity":"sha512-U8pQ4Jp0e5BpZMKdXDxG4wrM9a6gXiMD7a62CtJeRbvxlrPDjuDSCHdzhshBwnoeuQdAex3wsRrUA/x6enlh6w==","signatures":[{"sig":"MEUCIQCgRTfhFTQOChUGuPAr57GC01mLSfpukZy6n4s+Viu+sQIgSoi9SJyljcTORJjO1tn9awSoAC4N9RV18Xy7+gaAGIQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aikotools%2fdatafilter@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":256331},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"5f6130b52bb4979c7bf15a87216e65a7364975ce","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f26a94fd-f8f7-4c34-a3a5-a30020924ce2"}},"repository":{"url":"git+https://github.com/aikotools/datafilter.git","type":"git"},"_npmVersion":"11.9.0","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.13.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","eslint":"^9.38.0","vitest":"^4.0.18","prettier":"^3.8.1","typescript":"^5.9.3","@types/node":"^25.2.2","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^4.0.18","@typescript-eslint/parser":"^8.55.0","@typescript-eslint/eslint-plugin":"^8.55.0"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.2.0_1770664471718_0.4181812347686449","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@aikotools/datafilter","version":"1.2.1","keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","_id":"@aikotools/datafilter@1.2.1","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"homepage":"https://github.com/aikotools/datafilter#readme","bugs":{"url":"https://github.com/aikotools/datafilter/issues"},"dist":{"shasum":"3d4ce1002a9fc154233fd01bcda43af222afd15b","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.2.1.tgz","fileCount":25,"integrity":"sha512-dByt9zD4pKyEV1fzPhIuZseCAe0fQnfZEnTkx+WCUmOR1Rf2ecMfy4H9PiZhCGJ5XCD041riCjT7phQLIAXWGQ==","signatures":[{"sig":"MEYCIQCJTzv8Agv4evw+ouf7q9R+xOka8jHtFGmwyLe3fluo0gIhAO40wDKSNRNCqDkmf/VlcO9Jbyu2udNYQCgz0LTzw3H7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aikotools%2fdatafilter@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":256331},"main":"dist/aikotools-datafilter.cjs","type":"module","types":"dist/src/index.d.ts","module":"dist/aikotools-datafilter.mjs","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"gitHead":"ac1d650ab1c4186c4c04b27e45a976880b1e1b21","scripts":{"dev":"vite","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","test":"npm run build && vitest run --coverage","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","depcheck":"depcheck","test:run":"vitest run","docs:build":"bash scripts/build-readme.sh","test:watch":"vitest"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f26a94fd-f8f7-4c34-a3a5-a30020924ce2"}},"repository":{"url":"git+https://github.com/aikotools/datafilter.git","type":"git"},"_npmVersion":"11.10.0","description":"Advanced data filtering engine for JSON file matching in E2E testing","directories":{},"_nodeVersion":"24.13.0","dependencies":{"luxon":"^3.7.2","depcheck":"^1.4.7"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","eslint":"^10.0.0","vitest":"^4.0.18","prettier":"^3.8.1","typescript":"^5.9.3","@types/node":"^25.2.3","@types/luxon":"^3.7.1","vite-plugin-dts":"^4.5.4","@vitest/coverage-v8":"^4.0.18","@typescript-eslint/parser":"^8.56.0","@typescript-eslint/eslint-plugin":"^8.56.0"},"_npmOperationalInternal":{"tmp":"tmp/datafilter_1.2.1_1771330049115_0.2547445475005994","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@aikotools/datafilter","version":"1.2.2","description":"Advanced data filtering engine for JSON file matching in E2E testing","type":"module","main":"dist/aikotools-datafilter.cjs","module":"dist/aikotools-datafilter.mjs","types":"dist/src/index.d.ts","exports":{".":{"import":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.mjs"},"require":{"types":"./dist/src/index.d.ts","default":"./dist/aikotools-datafilter.cjs"}}},"repository":{"type":"git","url":"git+https://github.com/aikotools/datafilter.git"},"publishConfig":{"access":"public","provenance":true},"scripts":{"dev":"vite","format":"prettier --write \"{src,tests}/**/*.{js,ts,json}\"","lint":"eslint \"{src,tests}/**/*.{js,ts}\"","depcheck":"depcheck","build":"npm run format && npm run lint && npm run depcheck && tsc && vite build","test":"npm run build && vitest run --coverage","test:run":"vitest run","test:watch":"vitest","docs:build":"bash scripts/build-readme.sh"},"keywords":["filter","json","e2e","testing","matcher","data"],"author":"","license":"MIT","dependencies":{"luxon":"^3.7.2"},"devDependencies":{"@types/luxon":"^3.7.1","@types/node":"^25.2.3","@typescript-eslint/eslint-plugin":"^8.56.0","@typescript-eslint/parser":"^8.56.0","@vitest/coverage-v8":"^4.0.18","depcheck":"^1.4.7","eslint":"^10.0.0","prettier":"^3.8.1","typescript":"^5.9.3","vite":"^7.3.1","vite-plugin-dts":"^4.5.4","vitest":"^4.0.18"},"gitHead":"709c6d80718e7a3ab370b211fafb7f69ec28ba03","_id":"@aikotools/datafilter@1.2.2","bugs":{"url":"https://github.com/aikotools/datafilter/issues"},"homepage":"https://github.com/aikotools/datafilter#readme","_nodeVersion":"24.13.0","_npmVersion":"11.10.0","dist":{"integrity":"sha512-oKXncSOeyCtwy19G2Cv2luH3JFSbkGOe8cOqfIwwejASuDcd/0LbDGP/+E5blHNcXw1J4o0td3kCgcc5/7X04A==","shasum":"e8582ae09b4fae9a4de4b0e96758246aa47922ed","tarball":"https://registry.npmjs.org/@aikotools/datafilter/-/datafilter-1.2.2.tgz","fileCount":25,"unpackedSize":256331,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aikotools%2fdatafilter@1.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCVC85BZCTEhTp5TPJ3xzd1eL1XG0wHfI3Ws6VSG0aYHQIgchhsAIqkI9xrPC4kVM9NdR+uE2U/md38RwRO25boGJE="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f26a94fd-f8f7-4c34-a3a5-a30020924ce2"}},"directories":{},"maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/datafilter_1.2.2_1771330613912_0.5291340781044276"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-13T11:45:39.885Z","modified":"2026-02-17T12:16:54.365Z","1.0.0":"2025-10-13T11:45:40.187Z","1.0.1":"2025-10-22T14:05:05.027Z","1.0.2":"2025-10-23T08:18:08.160Z","1.0.3":"2025-10-24T09:13:42.026Z","1.0.4":"2025-10-24T12:07:15.370Z","1.0.5":"2025-10-24T12:24:42.679Z","1.1.0":"2025-10-27T10:36:24.595Z","1.1.1":"2025-10-29T10:48:42.496Z","1.1.2":"2025-10-30T09:33:31.824Z","1.1.3":"2025-10-31T11:53:45.510Z","1.1.4":"2025-11-03T11:39:17.435Z","1.2.0":"2026-02-09T19:14:31.892Z","1.2.1":"2026-02-17T12:07:29.265Z","1.2.2":"2026-02-17T12:16:54.050Z"},"bugs":{"url":"https://github.com/aikotools/datafilter/issues"},"license":"MIT","homepage":"https://github.com/aikotools/datafilter#readme","keywords":["filter","json","e2e","testing","matcher","data"],"repository":{"type":"git","url":"git+https://github.com/aikotools/datafilter.git"},"description":"Advanced data filtering engine for JSON file matching in E2E testing","maintainers":[{"name":"darlenya","email":"torstenlink@gmx.de"}],"readme":"# @aikotools/datafilter\n\nAdvanced data filtering engine for JSON file matching in E2E testing.\n\n[![npm version](https://badge.fury.io/js/@aikotools%2Fdatafilter.svg)](https://www.npmjs.com/package/@aikotools/datafilter)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n## Overview\n\n`@aikotools/datafilter` provides sophisticated file filtering and matching capabilities specifically designed for E2E testing scenarios where you need to map actual result files to expected files.\n\n### Key Features\n\n- **Flexible Matching**: Match files using various filter criteria (value, exists, array checks, time ranges)\n- **Order Handling**: Support for both strict and flexible ordering of expected files\n- **🆕 Optional Mode**: Automatically treat unmatched files as optional without explicit rules\n- **🆕 Wildcard Optionals**: Match arbitrary number of optional files without explicit specification\n- **Greedy vs. Non-Greedy**: Control whether wildcards match once or multiple times\n- **PreFilter Support**: Global file filtering before rule matching\n- **Group Filtering**: Organize files into groups with shared filter criteria\n- **Deep Object Access**: Path-based navigation through nested JSON structures\n- **Sort Integration**: Custom sort functions for file ordering before matching\n\n## Installation\n\n```bash\nnpm install @aikotools/datafilter\n```\n\n## Quick Start\n\n```typescript\nimport { filterFiles } from '@aikotools/datafilter';\n\nconst result = filterFiles({\n  files: [\n    { fileName: 'event1.json', data: { type: 'event1', value: 42 } },\n    { fileName: 'optional1.json', data: { type: 'optional' } },\n    { fileName: 'optional2.json', data: { type: 'optional' } },\n    { fileName: 'event2.json', data: { type: 'event2', value: 100 } },\n  ],\n  rules: [\n    // Match specific file\n    { match: [{ path: ['type'], check: { value: 'event1' } }], expected: 'event1' },\n\n    // 🆕 NEW: Match arbitrary optionals with wildcard\n    {\n      matchAny: [{ path: ['type'], check: { value: 'optional' } }],\n      optional: true,\n      greedy: true, // Match all optionals\n    },\n\n    // Match another specific file\n    { match: [{ path: ['type'], check: { value: 'event2' } }], expected: 'event2' },\n  ],\n});\n\nconsole.log(result.mapped.length); // 2 (event1, event2)\nconsole.log(result.wildcardMatched.length); // 2 (both optionals)\nconsole.log(result.unmapped.length); // 0\n```\n\n## Core Concepts\n\n### Filter Criteria\n\nAll filter criteria use path-based access and various check types:\n\n```typescript\n{\n  path: ['data', 'user', 'name'],  // Navigate through object\n  check: { value: 'John' }         // Check type\n}\n```\n\n### Match Rules\n\n#### Single Match Rule\n\nMaps exactly one file to an expected identifier:\n\n```typescript\n{\n  match: [\n    { path: ['type'], check: { value: 'event1' } },\n    { path: ['status'], check: { value: 'active' } }\n  ],\n  expected: 'event1',\n  optional: false  // Default: false\n}\n```\n\n**🆕 Sequential Matching Behavior (NEW):**\n\nEach single match rule can be used **exactly once**. When you have multiple files that could match the same rule, only the first matching file will be assigned to that rule. Subsequent matching files will move to the next available rule.\n\n```typescript\n// Example: 3 identical files, 3 identical rules\nconst result = filterFiles({\n  files: [\n    { fileName: 'event1.json', data: { type: 'event' } },\n    { fileName: 'event2.json', data: { type: 'event' } },\n    { fileName: 'event3.json', data: { type: 'event' } },\n  ],\n  rules: [\n    { match: [{ path: ['type'], check: { value: 'event' } }], expected: 'expected1' },\n    { match: [{ path: ['type'], check: { value: 'event' } }], expected: 'expected2' },\n    { match: [{ path: ['type'], check: { value: 'event' } }], expected: 'expected3' },\n  ]\n});\n\n// Result:\n// - event1.json → expected1\n// - event2.json → expected2\n// - event3.json → expected3\n```\n\n**Note:** Wildcard rules (`matchAny`) are not affected - they can still match multiple files when `greedy: true`.\n\n#### 🆕 Wildcard Match Rule (NEW)\n\nMatches arbitrary number of files without explicit specification:\n\n```typescript\n{\n  matchAny: [\n    { path: ['category'], check: { value: 'optional' } }\n  ],\n  optional: true,   // Always true for wildcards\n  greedy: true      // Match all (true) or just one (false)\n}\n```\n\n#### Flexible Ordering\n\nUse arrays of rules when order is not deterministic:\n\n```typescript\n[\n  { match: [{ path: ['type'], check: { value: 'event3' } }], expected: 'event3' },\n  { match: [{ path: ['type'], check: { value: 'event4' } }], expected: 'event4' }\n]\n// Either event3 or event4 can come first\n```\n\n## Filter Check Types\n\n### 1. Value Check\n\nDeep equality comparison:\n\n```typescript\n{ path: ['user', 'name'], check: { value: 'John' } }\n{ path: ['user', 'address'], check: { value: { city: 'Berlin', zip: '10115' } } }\n```\n\n### 2. Exists Check\n\nCheck if a path exists:\n\n```typescript\n{ path: ['optional', 'field'], check: { exists: true } }\n{ path: ['deprecated'], check: { exists: false } }\n```\n\n### 3. Array Element Check\n\nCheck if array contains (or doesn't contain) an element:\n\n```typescript\n{ path: ['tags'], check: { itemExists: true, item: 'typescript' } }\n{ path: ['status'], check: { itemExists: false, item: 'banned' } }\n```\n\n### 4. Array Size Check\n\nValidate array length:\n\n```typescript\n{ path: ['items'], check: { type: 'equal', size: 3 } }\n{ path: ['errors'], check: { type: 'lessThan', size: 5 } }\n{ path: ['records'], check: { type: 'greaterThan', size: 10 } }\n```\n\n### 5. Time Range Check\n\nValidate timestamps (ISO strings or numeric):\n\n```typescript\n// ISO timestamp\n{\n  path: ['timestamp'],\n  check: {\n    min: '2023-11-08T15:00:00+01:00',\n    max: '2023-11-08T16:00:00+01:00'\n  }\n}\n\n// Numeric timestamp (milliseconds)\n{\n  path: ['timestamp'],\n  check: {\n    min: '1699452000000',\n    max: '1699455600000'\n  }\n}\n```\n\n## Advanced Features\n\n### 🆕 Optional Mode - Automatic Optional File Handling (NEW)\n\nOptional mode allows you to focus on matching critical files while automatically treating unmatched files as optional. This eliminates the need to create explicit wildcard rules for every gap between expected files.\n\n**Use Case:** Event streams, log files, or test executions where you want to validate specific checkpoints but allow arbitrary intermediate files.\n\n\n#### Three Matching Modes\n\n```typescript\n// Mode 1: 'strict' (default) - Current behavior\n// Every file must match a rule, non-matching files → unmapped (error)\nconst result = filterFiles({\n  files,\n  rules,\n  mode: 'strict' // or omit for default\n});\n\n// Mode 2: 'optional' - Permissive mode\n// Files between matches are automatically treated as optional\n// Non-matched files → optionalFiles (not an error)\nconst result = filterFiles({\n  files: [\n    { fileName: 'critical_A.json', data: { type: 'critical' } },\n    { fileName: 'info_1.json', data: { type: 'info' } },      // ← automatically optional\n    { fileName: 'debug_1.json', data: { type: 'debug' } },    // ← automatically optional\n    { fileName: 'critical_B.json', data: { type: 'critical' } },\n  ],\n  rules: [\n    { match: [{ path: ['type'], check: { value: 'critical' } }], expected: 'A' },\n    { match: [{ path: ['type'], check: { value: 'critical' } }], expected: 'B' },\n  ],\n  mode: 'optional' // Enable permissive mode\n});\n\n// Result:\n// - mapped: critical_A.json, critical_B.json\n// - optionalFiles: info_1.json, debug_1.json (with position and context)\n// - unmapped: [] (always empty in optional mode)\n\n// Mode 3: 'strict-optional' - Balanced approach\n// Similar to optional mode but respects optional flags on rules\nconst result = filterFiles({\n  files,\n  rules,\n  mode: 'strict-optional'\n});\n```\n\n#### Optional File Information\n\nWhen files are treated as optional, they include detailed context:\n\n```typescript\nresult.optionalFiles = [\n  {\n    fileName: 'info_1.json',\n    position: 1,\n    between: {\n      afterRule: 'A',      // After which matched rule\n      beforeRule: 'B'      // Before which matched rule\n    },\n    failedMatches: [...]   // Why this file didn't match any rule\n  },\n  // ...\n]\n```\n\n#### Benefits\n\n✅ **Simplicity**: No need for explicit wildcard matchers at every position\n✅ **Flexibility**: Handle variable numbers of files between rules\n✅ **Transparency**: Track which files were optional and why\n✅ **Debugging**: `failedMatches` helps understand filter behavior\n✅ **Clarity**: `unmapped` empty when optional mode active - clear intent\n\n### PreFilter - Global File Exclusion\n\nPreFilter allows you to exclude files globally **before** any rule matching occurs. Files not matching the preFilter criteria are collected in the `preFiltered` property of the result, separate from `unmapped` files.\n\n**Use Case:** Filter out irrelevant files (e.g., debug files, temporary files) before processing, while keeping track of what was excluded.\n\n```typescript\nconst result = filterFiles({\n  files: [\n    { fileName: 'event1.json', data: { type: 'event', status: 'active', value: 42 } },\n    { fileName: 'event2.json', data: { type: 'event', status: 'active', value: 100 } },\n    { fileName: 'debug.json', data: { type: 'debug', status: 'inactive', value: 0 } },\n    { fileName: 'temp.json', data: { type: 'temp', status: 'inactive', value: -1 } },\n  ],\n  preFilter: [\n    // Only process files with status 'active'\n    { path: ['status'], check: { value: 'active' } }\n  ],\n  rules: [\n    { match: [{ path: ['type'], check: { value: 'event' } }], expected: 'event1' },\n    { match: [{ path: ['type'], check: { value: 'event' } }], expected: 'event2' },\n  ],\n});\n\n// Result:\n// - mapped: event1.json, event2.json\n// - preFiltered: debug.json, temp.json (with failed check details)\n// - unmapped: []\n```\n\n### Group Filtering - Organize by Categories\n\nGroup filtering allows you to organize files into categories with shared filter criteria, then apply category-specific rules.\n\n**Use Case:** Different file types (e.g., orders, invoices, reports) need different validation rules.\n\n```typescript\nimport { filterFilesWithGroups } from '@aikotools/datafilter';\n\nconst result = filterFilesWithGroups({\n  files: [\n    { fileName: 'order1.json', data: { category: 'order', orderId: 'A123', amount: 100 } },\n    { fileName: 'order2.json', data: { category: 'order', orderId: 'A124', amount: 200 } },\n    { fileName: 'invoice1.json', data: { category: 'invoice', invoiceId: 'INV-001', total: 100 } },\n    { fileName: 'invoice2.json', data: { category: 'invoice', invoiceId: 'INV-002', total: 200 } },\n    { fileName: 'report.json', data: { category: 'report', month: 'January' } },\n  ],\n  groups: [\n    {\n      // Group 1: Orders\n      groupFilter: [\n        { path: ['category'], check: { value: 'order' } }\n      ],\n      rules: [\n        { match: [{ path: ['orderId'], check: { value: 'A123' } }], expected: 'order_A123' },\n        { match: [{ path: ['orderId'], check: { value: 'A124' } }], expected: 'order_A124' },\n      ]\n    },\n    {\n      // Group 2: Invoices\n      groupFilter: [\n        { path: ['category'], check: { value: 'invoice' } }\n      ],\n      rules: [\n        { match: [{ path: ['invoiceId'], check: { value: 'INV-001' } }], expected: 'invoice_001' },\n        { match: [{ path: ['invoiceId'], check: { value: 'INV-002' } }], expected: 'invoice_002' },\n      ]\n    },\n    {\n      // Group 3: Reports (with wildcard)\n      groupFilter: [\n        { path: ['category'], check: { value: 'report' } }\n      ],\n      rules: [\n        { matchAny: [{ path: ['category'], check: { value: 'report' } }], optional: true, greedy: true }\n      ]\n    }\n  ],\n  preFilter: [\n    // Optional: Only process files with specific structure\n    { path: ['category'], check: { exists: true } }\n  ]\n});\n\n// Result:\n// - mapped: order_A123, order_A124, invoice_001, invoice_002\n// - wildcardMatched: report.json\n// - unmapped: []\n```\n\n### Combining PreFilter, Groups, and Wildcards\n\n```typescript\nconst result = filterFilesWithGroups({\n  files: allFiles,\n\n  // Step 1: Global exclusion\n  preFilter: [\n    { path: ['status'], check: { value: 'active' } },\n    { path: ['deleted'], check: { exists: false } }\n  ],\n\n  // Step 2: Group by type and apply rules\n  groups: [\n    {\n      groupFilter: [{ path: ['type'], check: { value: 'critical' } }],\n      rules: [\n        { match: [{ path: ['priority'], check: { value: 1 } }], expected: 'critical_1' },\n        { match: [{ path: ['priority'], check: { value: 2 } }], expected: 'critical_2' },\n      ]\n    },\n    {\n      groupFilter: [{ path: ['type'], check: { value: 'normal' } }],\n      rules: [\n        { matchAny: [{ path: ['type'], check: { value: 'normal' } }], optional: true, greedy: true }\n      ]\n    }\n  ],\n\n  sortFn: (a, b) => a.data.timestamp - b.data.timestamp\n});\n```\n\n## Complete Example\n\n### Scenario from Requirements\n\n```\nevent1\n    - event1.1 (optional)\nevent2\n    - event3, event4 (flexible order)\nevent5\n```\n\n### Without Wildcard (Old Way)\n\nEvery optional file must be explicitly specified:\n\n```typescript\nconst result = filterFiles({\n  files: actualFiles,\n  rules: [\n    { match: [{ path: ['type'], check: { value: 'event1' } }], expected: 'event1' },\n    { match: [{ path: ['type'], check: { value: 'event1.1' } }], expected: 'event1.1', optional: true },\n    { match: [{ path: ['type'], check: { value: 'event2' } }], expected: 'event2' },\n    [\n      { match: [{ path: ['type'], check: { value: 'event3' } }], expected: 'event3' },\n      { match: [{ path: ['type'], check: { value: 'event4' } }], expected: 'event4' }\n    ],\n    { match: [{ path: ['type'], check: { value: 'event5' } }], expected: 'event5' },\n  ],\n});\n```\n\n### With Wildcard (New Way) 🆕\n\nArbitrary number of optional files without explicit specification:\n\n```typescript\nconst result = filterFiles({\n  files: actualFiles,\n  rules: [\n    { match: [{ path: ['type'], check: { value: 'event1' } }], expected: 'event1' },\n\n    // 🆕 NEW: Match ANY number of optional files\n    {\n      matchAny: [{ path: ['category'], check: { value: 'optional' } }],\n      optional: true,\n      greedy: true\n    },\n\n    { match: [{ path: ['type'], check: { value: 'event2' } }], expected: 'event2' },\n    [\n      { match: [{ path: ['type'], check: { value: 'event3' } }], expected: 'event3' },\n      { match: [{ path: ['type'], check: { value: 'event4' } }], expected: 'event4' }\n    ],\n    { match: [{ path: ['type'], check: { value: 'event5' } }], expected: 'event5' },\n  ],\n  sortFn: (a, b) => a.data.timestamp - b.data.timestamp\n});\n\nconsole.log(result.mapped); // event1, event2, event3, event4, event5\nconsole.log(result.wildcardMatched); // All files matching optional criteria\nconsole.log(result.unmapped); // Files that didn't match any rule\n```\n\n## API Reference\n\n### filterFiles(request: FilterRequest): FilterResult\n\nMain filtering function.\n\n**FilterRequest:**\n- `files: JsonFile[]` - Files to filter\n- `rules: (MatchRule | MatchRule[])[]` - Matching rules\n- `sortFn?: (a, b) => number` - Optional sort function\n- `preFilter?: FilterCriterion[]` - Optional pre-filter criteria (files not matching are collected in `preFiltered`)\n- `mode?: 'strict' | 'strict-optional' | 'optional'` - 🆕 Matching mode (default: 'strict')\n  - `'strict'`: All files must match a rule (unmapped = errors)\n  - `'optional'`: Unmatched files → optionalFiles (unmapped always empty)\n  - `'strict-optional'`: Similar to optional but respects optional flags\n- `context?: { startTimeScript?, startTimeTest?, pathTime? }` - Optional context\n\n**FilterResult:**\n- `mapped: MappedFile[]` - Successfully mapped files\n- `wildcardMatched: WildcardMappedFile[]` - Files matched by wildcards\n- `optionalFiles: OptionalFile[]` - 🆕 Files treated as optional (with position and context)\n- `unmapped: UnmappedFile[]` - Files that passed preFilter but couldn't be matched to any rule (empty when mode is 'optional' or 'strict-optional')\n- `preFiltered: PreFilteredFile[]` - Files excluded by preFilter criteria (with failed check details)\n- `stats: { totalFiles, mappedFiles, wildcardMatchedFiles, optionalFiles, unmappedFiles, preFilteredFiles, ... }`\n\n### filterFilesWithGroups(request: FilterGroupRequest): FilterResult\n\nFiltering with grouped rules for categorized file processing.\n\n**FilterGroupRequest:**\n- `files: JsonFile[]` - Files to filter\n- `groups: FilterGroup[]` - Filter groups with common criteria and rules\n- `sortFn?: (a, b) => number` - Optional sort function\n- `preFilter?: FilterCriterion[]` - Optional pre-filter criteria (applied before group filtering)\n- `mode?: 'strict' | 'strict-optional' | 'optional'` - 🆕 Matching mode (default: 'strict')\n- `context?: { startTimeScript?, startTimeTest?, pathTime? }` - Optional context\n\n**FilterGroup:**\n- `groupFilter: FilterCriterion[]` - Criteria to identify files belonging to this group\n- `rules: (MatchRule | MatchRule[])[]` - Rules to apply to files in this group\n\n**FilterResult:** Same as `filterFiles()`\n\n### Matcher Class\n\nFor advanced usage with multiple filter operations:\n\n```typescript\nimport { Matcher } from '@aikotools/datafilter';\n\nconst matcher = new Matcher({ startTimeScript, startTimeTest });\n\n// With preFilter and mode\nconst result = matcher.filterFiles(files, rules, sortFn, preFilter, mode);\n\n// With groups and mode\nconst groupResult = matcher.filterFilesWithGroups(files, groups, sortFn, preFilter, mode);\n```\n\n### FilterEngine Class\n\nFor custom filter criterion evaluation:\n\n```typescript\nimport { FilterEngine } from '@aikotools/datafilter';\n\nconst engine = new FilterEngine();\nconst checkResult = engine.evaluateCriterion(data, criterion);\n```\n\n### Utility Functions\n\n```typescript\nimport { getValueFromPath, pathExists, getValueOr } from '@aikotools/datafilter';\n\n// Get value from path\nconst result = getValueFromPath(obj, ['data', 'user', 'name']);\n// result: { value: 'John', found: true, validPath: ['data', 'user', 'name'] }\n\n// Check if path exists\nconst exists = pathExists(obj, ['data', 'user']);\n// exists: true\n\n// Get value with default fallback\nconst value = getValueOr(obj, ['data', 'missing'], 'default');\n// value: 'default'\n```\n\n## Migration from e2e-tool-util-result-mapper\n\n### Key Differences\n\n1. **Wildcard Support**: New wildcard rules eliminate need to specify every optional file\n2. **Simpler API**: Focused on filtering, not entire pipeline (dedupe, sort, etc.)\n3. **Type Safety**: Full TypeScript support with comprehensive types\n4. **Modern Structure**: ESM modules, Vite build, Vitest testing\n\n### Migration Example\n\n**Old (result-mapper):**\n```typescript\n// Every optional must be explicitly specified\n{\n  \"mappingCriteria\": [\n    { \"expected\": \"event1.json\", \"optional\": false, \"filter\": {...} },\n    { \"expected\": \"optional1.json\", \"optional\": true, \"filter\": {...} },\n    { \"expected\": \"optional2.json\", \"optional\": true, \"filter\": {...} },\n    { \"expected\": \"optional3.json\", \"optional\": true, \"filter\": {...} },\n    { \"expected\": \"event2.json\", \"optional\": false, \"filter\": {...} }\n  ]\n}\n```\n\n**New (datafilter):**\n```typescript\n// Wildcard matches all optionals\n{\n  rules: [\n    { match: [...], expected: 'event1' },\n    { matchAny: [...], optional: true, greedy: true }, // 🆕 All optionals\n    { match: [...], expected: 'event2' }\n  ]\n}\n```\n\n## Test Results\n\n✅ **204/204 tests passing** (97.93% coverage for Matcher module)\n- ✅ Basic filtering with single matches\n- ✅ Flexible ordering (array of rules)\n- ✅ Optional rules\n- ✅ 🆕 Optional mode (automatic optional file handling)\n- ✅ 🆕 Strict-optional mode\n- ✅ 🆕 Wildcard matches (greedy & non-greedy)\n- ✅ 🆕 Sequential rule matching (each rule matches once)\n- ✅ All filter check types (value, exists, array, time)\n- ✅ PreFilter support\n- ✅ Group filtering\n- ✅ Complex real-world scenarios\n- ✅ Sort function integration\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Test\nnpm test\n\n# Lint\nnpm run lint\n\n# Format\nnpm run format\n```\n\n## Architecture\n\n```\nFilterEngine\n├── Evaluates individual filter criteria\n├── Supports: value, exists, array checks, time ranges\n└── Deep equality comparison\n\nMatcher\n├── Orchestrates file-to-rule matching\n├── Handles: single rules, arrays, wildcards\n├── Tracks: matched files, exhausted rules\n└── Produces detailed results\n\nUtilities\n└── Path-based object access (getValueFromPath, pathExists)\n```\n\n## License\n\nMIT - See [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nThis is part of the @aikotools ecosystem. For issues and contributions, please see the repository.\n\n---\n\n**Built for E2E Testing** 🚀\n","readmeFilename":"README.md"}