{"_id":"@4cloudguru/terraform-drift-contract","_rev":"10-f59b1c63708a396d8318ed69b32f12ca","name":"@4cloudguru/terraform-drift-contract","dist-tags":{"latest":"1.4.1"},"versions":{"0.0.0":{"name":"@4cloudguru/terraform-drift-contract","version":"0.0.0","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@0.0.0","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"23526464ae6cb0a987c054265a2183aedab1c8de","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-0.0.0.tgz","fileCount":8,"integrity":"sha512-w9IuqbYoRF2a+cuZ0Et2r6L/E69sGczAmaT03dALWCZigA7Zncm+wom3KHU7o8bcoWOdAg0MtmY+w+ESUc2zWQ==","signatures":[{"sig":"MEQCIHqbNpe9o/pN8tTwut5aGsWx23nuod57uF3FnYam9D7fAiB6kLg17MSZTh2nwIxvI+SHOyLVZNZhidb1pJhT0XSFUg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35501},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"a891cf3902db2ef944fe9c7f3280fd6133a3d7cc","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc -p tsconfig.json","prepack":"npm run build"},"_npmUser":{"name":"dragonthegn","email":"stbacon@gmail.com"},"repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.9.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.14.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^5.6.0","@types/node":"^24"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_0.0.0_1786582204452_0.769868996556424","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@4cloudguru/terraform-drift-contract","version":"1.1.0","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.1.0","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"2aadb739782230b5ec1b6d76799b449b4b155e37","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.1.0.tgz","fileCount":8,"integrity":"sha512-ZOx8xw7b1Ehn929Kvawj/3jbjFHW9Mt/7mIdRv1A1hRulUu2HQlxe32raFucNlVl0IH3zLCn0oTcJe6xF9TDbQ==","signatures":[{"sig":"MEUCIQCVfe7RnCAR0xuZZDsz03pkYSpwOQ5HtQE0Lb7KWenwWgIgGdKXKr+zFwZF3r1bbAOCQkOAJgJ+rk1DGcLaHT7gNZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":35501},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.1.0.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc -p tsconfig.json","prepack":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.1.0.tgz","_integrity":"sha512-ZOx8xw7b1Ehn929Kvawj/3jbjFHW9Mt/7mIdRv1A1hRulUu2HQlxe32raFucNlVl0IH3zLCn0oTcJe6xF9TDbQ==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.17.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^5.6.0","@types/node":"^24"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.1.0_1786583674592_0.6390322981658416","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@4cloudguru/terraform-drift-contract","version":"1.1.1","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.1.1","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"7fd8642f165f7de5f42d3a61da6abd0322704afe","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.1.1.tgz","fileCount":8,"integrity":"sha512-8A4YWU7lk6AlTEAXTF+J/6hmFRFH/biJk69EnlEiuDMYMwRwDBmSY6xvbyW7QaTd21Vc4uYaFGQzNeP90ybbTw==","signatures":[{"sig":"MEQCIGhT4cWDmK9EXDQri6xcLE9Mrc2lgoteEJAZZsTaBKiUAiBvO0BbyngNU5UlvY5bj5W+85JEkjsReMIc5G3EFkAZrA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":43432},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.1.1.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc -p tsconfig.json","prepack":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.1.1.tgz","_integrity":"sha512-8A4YWU7lk6AlTEAXTF+J/6hmFRFH/biJk69EnlEiuDMYMwRwDBmSY6xvbyW7QaTd21Vc4uYaFGQzNeP90ybbTw==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^5.6.0","@types/node":"^24"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.1.1_1786669665624_0.25563737042587564","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@4cloudguru/terraform-drift-contract","version":"1.2.0","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.2.0","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"24e49fc3f210073829f3541b2d6c4be8f651af4e","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.2.0.tgz","fileCount":8,"integrity":"sha512-6nMLtYZJdPh3p4ijUOZuoTH2syVzFI94FrkHu94TLe5sVZ/gAnEKsjcNTm1E2+60prABvt8nBfQfH3H6zpWTPg==","signatures":[{"sig":"MEUCIDqX/3vPErLGuJbtloMyRxTA7wSgj/uMBkZRsv5C34NCAiEAz//zt440yL44aqI8jyoS8cdMOOYudQlu7YcwwRlKiOo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63084},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.2.0.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.2.0.tgz","_integrity":"sha512-6nMLtYZJdPh3p4ijUOZuoTH2syVzFI94FrkHu94TLe5sVZ/gAnEKsjcNTm1E2+60prABvt8nBfQfH3H6zpWTPg==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^5.6.0","@types/node":"^24","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.2.0_1786693691225_0.1136237806709135","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@4cloudguru/terraform-drift-contract","version":"1.2.1","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.2.1","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"91e1cd476beac33c2ef9495b6bc48bcc18a30dba","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.2.1.tgz","fileCount":8,"integrity":"sha512-z8FdASVlZwz/BqtEd56U05FBOcOluIuHr2g9qhH/iAvro2ndC0T+aZSH3WmxM1jKkFQqUfzVwKe6FE6WNElALg==","signatures":[{"sig":"MEQCIGJPyBDL4ocxLWe9Yb4ifKb3/RoONX630HlIewLb8gu2AiAV5Y/322LSy4KPBQ2inHNOBnkmp3dH8TYiu/zOASBH4w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63084},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.2.1.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.2.1.tgz","_integrity":"sha512-z8FdASVlZwz/BqtEd56U05FBOcOluIuHr2g9qhH/iAvro2ndC0T+aZSH3WmxM1jKkFQqUfzVwKe6FE6WNElALg==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.17.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^7.0.2","@types/node":"^26","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.2.1_1787275851589_0.4590830204602827","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@4cloudguru/terraform-drift-contract","version":"1.2.2","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.2.2","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"e073847774cb1982890f484eb3cb927db77a0549","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.2.2.tgz","fileCount":8,"integrity":"sha512-sNvGUMarh90Bm7/aaTSdRByVTyg8GQ9zxRMQGl8yU45OwQ5cJSYQq8jEpe+uKU4yUtQB+8IZwMrUkBb0hmvjtQ==","signatures":[{"sig":"MEUCICf33XKV/F/X6OJGcPtWx6wYrOC4ldRemJbh+KS99+84AiEA7aG1jiDNHeUTAljU/P3i2fbjV7Ilc3jVvUjjQ8iZzag=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63150},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.2.2.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:advisory":"node scripts/test-dependabot-advisory.mjs","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.2.2.tgz","_integrity":"sha512-sNvGUMarh90Bm7/aaTSdRByVTyg8GQ9zxRMQGl8yU45OwQ5cJSYQq8jEpe+uKU4yUtQB+8IZwMrUkBb0hmvjtQ==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.17.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^7.0.2","@types/node":"^26","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.2.2_1787616622166_0.14456675152688248","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"@4cloudguru/terraform-drift-contract","version":"1.2.3","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.2.3","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"98d36e6c4c96d10eab92d0cfdc77a95a5042fbc0","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.2.3.tgz","fileCount":8,"integrity":"sha512-91cA6Ik/xRW4mjZdqFLYTiyjYHZzLosYGt8fnFlRIp6myfqyhv3bGTyukr/qJWe2u5omwNdKGJpnpro4gW2fKw==","signatures":[{"sig":"MEUCIBw0ApNvzWkqt6Ww/vsVsMHooIe7bZzwPDvnpzCeX2lcAiEAsGxPZjfoZBqSEiMymbLkZCuJZWve/1NWSnZN9KjCxN0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63150},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.2.3.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:advisory":"node scripts/test-dependabot-advisory.mjs","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.2.3.tgz","_integrity":"sha512-91cA6Ik/xRW4mjZdqFLYTiyjYHZzLosYGt8fnFlRIp6myfqyhv3bGTyukr/qJWe2u5omwNdKGJpnpro4gW2fKw==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.17.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^7.0.2","@types/node":"^26","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.2.3_1788063006678_0.023573762859806058","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@4cloudguru/terraform-drift-contract","version":"1.3.0","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.3.0","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"d5bbc59e9c98bb8c5667e84eb33d3630c43fbf6d","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.3.0.tgz","fileCount":8,"integrity":"sha512-fF40EuVmybifPEo9GiKY62FFdEf6/OPbTG8EyUVpXDy37xPcxcPiwKE9bpum2W9gmZEargYjs0pZG4Ednq1LWg==","signatures":[{"sig":"MEYCIQClYSCMNY8bBvSSwW2QYtulzBeOW+DYU1HAgdvx+dGwdQIhAIdOQJwazknu5tGLJsmRzJRZByyEO3mx69rTPvHJtLHS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63150},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.3.0.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:advisory":"node scripts/test-dependabot-advisory.mjs","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.3.0.tgz","_integrity":"sha512-fF40EuVmybifPEo9GiKY62FFdEf6/OPbTG8EyUVpXDy37xPcxcPiwKE9bpum2W9gmZEargYjs0pZG4Ednq1LWg==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.17.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^7.0.2","@types/node":"^26","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.3.0_1788192216341_0.11314236261627553","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@4cloudguru/terraform-drift-contract","version":"1.4.0","license":"Apache-2.0","_id":"@4cloudguru/terraform-drift-contract@1.4.0","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"dist":{"shasum":"d53fc1e1dab85da2a11f9870024625352b174195","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.4.0.tgz","fileCount":8,"integrity":"sha512-P1PWDuNRf94cFaqbtgdX2vq4tvG/IeNvzQ4gz0k2fWlJDJyJnfdr7qkFzxQx87Tb4DZfWocjV4ZxxhWG1rDEyw==","signatures":[{"sig":"MEYCIQCUGRIKGmH7LEihBAWdzEfYfnBYDvzfxeV8CWTeYG9zTAIhAItKkkPu/6IJGgG2cX+aVH/687CcWZjQmD9/AMNtqQzI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":67407},"main":"dist/index.js","_from":"file:4cloudguru-terraform-drift-contract-1.4.0.tgz","types":"dist/index.d.ts","private":false,"scripts":{"lint":"tsc --noEmit","test":"vitest run --coverage","build":"tsc -p tsconfig.json","prepack":"npm run build","test:advisory":"node scripts/test-dependabot-advisory.mjs","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.4.0.tgz","_integrity":"sha512-P1PWDuNRf94cFaqbtgdX2vq4tvG/IeNvzQ4gz0k2fWlJDJyJnfdr7qkFzxQx87Tb4DZfWocjV4ZxxhWG1rDEyw==","repository":{"url":"git+https://github.com/4cloudguru/terraform-drift-contract.git","type":"git"},"_npmVersion":"11.19.0","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.9","typescript":"^7.0.2","@types/node":"^26","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"tmp":"tmp/terraform-drift-contract_1.4.0_1788709752938_0.8562951741954175","host":"s3://npm-registry-packages-npm-production"}},"1.4.1":{"name":"@4cloudguru/terraform-drift-contract","version":"1.4.1","description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","license":"Apache-2.0","private":false,"publishConfig":{"registry":"https://registry.npmjs.org","access":"public","provenance":true},"repository":{"type":"git","url":"git+https://github.com/4cloudguru/terraform-drift-contract.git"},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","test":"vitest run --coverage","lint":"tsc --noEmit","test:advisory":"node scripts/test-dependabot-advisory.mjs","prepack":"npm run build","test:coverage":"vitest run --coverage"},"devDependencies":{"@types/node":"^26","@vitest/coverage-v8":"^4.1.10","typescript":"^7.0.2","vitest":"^4.1.9"},"_id":"@4cloudguru/terraform-drift-contract@1.4.1","bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","_integrity":"sha512-o6rEpcAYhnaCnYKxmuu5xD7OZuOfxBvJavosFf/JVgL07BfkPE//sBt38OXsl6iENLMenlKg+DQC/wSCf1ccjw==","_resolved":"/home/runner/work/terraform-drift-contract/terraform-drift-contract/4cloudguru-terraform-drift-contract-1.4.1.tgz","_from":"file:4cloudguru-terraform-drift-contract-1.4.1.tgz","_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-o6rEpcAYhnaCnYKxmuu5xD7OZuOfxBvJavosFf/JVgL07BfkPE//sBt38OXsl6iENLMenlKg+DQC/wSCf1ccjw==","shasum":"ae89687a39c3679f279ddfbf0846df18a6d8ac2e","tarball":"https://registry.npmjs.org/@4cloudguru/terraform-drift-contract/-/terraform-drift-contract-1.4.1.tgz","fileCount":8,"unpackedSize":67407,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@4cloudguru%2fterraform-drift-contract@1.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDx5Hmc0S4DIwhZWeKA4anXpWN4AhrZmLkufNrkX1vo6AiEAkwPUe85YuXOp5KZXgXKghhZp4P6GO0arruOdUJJk9lg="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:767b9c31-aac0-4a5e-8ccc-ad72008ca110"}},"directories":{},"maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/terraform-drift-contract_1.4.1_1788957973582_0.3224544729302754"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-13T00:50:04.244Z","modified":"2026-09-09T12:46:14.162Z","0.0.0":"2026-08-13T00:50:04.647Z","1.1.0":"2026-08-13T01:14:34.793Z","1.1.1":"2026-08-14T01:07:45.777Z","1.2.0":"2026-08-14T07:48:11.373Z","1.2.1":"2026-08-21T01:30:51.743Z","1.2.2":"2026-08-25T00:10:22.301Z","1.2.3":"2026-08-30T04:10:06.821Z","1.3.0":"2026-08-31T16:03:36.479Z","1.4.0":"2026-09-06T15:49:13.061Z","1.4.1":"2026-09-09T12:46:13.707Z"},"bugs":{"url":"https://github.com/4cloudguru/terraform-drift-contract/issues"},"license":"Apache-2.0","homepage":"https://github.com/4cloudguru/terraform-drift-contract#readme","repository":{"type":"git","url":"git+https://github.com/4cloudguru/terraform-drift-contract.git"},"description":"Shared parser for Terraform/OpenTofu plan JSON → TSM drift counts + summary. One source of truth for the GitHub Action, the Azure DevOps task, and the backend's driftingest semantics.","maintainers":[{"name":"dragonthegn","email":"stbacon@gmail.com"}],"readme":"# @4cloudguru/terraform-drift-contract\n\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n[![npm](https://img.shields.io/npm/v/@4cloudguru/terraform-drift-contract.svg)](https://www.npmjs.com/package/@4cloudguru/terraform-drift-contract)\n\nThe **single source of truth** for parsing a Terraform/OpenTofu plan JSON\n(`terraform show -json` / `tofu show -json`) into Terraform State Manager (TSM)\ndrift counts + a changed-resource summary.\n\nOne tiny package, consumed (and bundled) by every drift implementation so they\ncannot diverge:\n\n- [`terraform-drift-report`](https://github.com/sethbacon/terraform-drift-report) — the GitHub Action\n- the Azure DevOps `TerraformDriftReport` task (`azure-pipelines-terraform`, initiative 6)\n- mirrored by the backend's Go `internal/services/driftingest` and the jq in the\n  dispatched CI templates. This package — `src/summarize.ts` plus `__tests__/` —\n  is the authority those two are diffed against, and the diffing is done by the\n  shared [conformance corpus](conformance/), which all three implementations run\n  and compare byte-for-byte. See\n  [cross-implementation status](#cross-implementation-status).\n\n## Install\n\n```bash\nnpm install @4cloudguru/terraform-drift-contract\n```\n\n```jsonc\n// package.json of a consumer\n\"dependencies\": {\n  \"@4cloudguru/terraform-drift-contract\": \"^1.1.0\"\n}\n```\n\nPublished to the public npm registry with [provenance](https://docs.npmjs.com/generating-provenance-statements),\nso `npm audit signatures` verifies the tarball back to the workflow run that\nbuilt it. No registry auth is needed to install it.\n\n> **Consumer status.** Both consumers are on the scoped npm package at\n> `^1.1.0` — the GitHub Action (`terraform-drift-report`) and the Azure DevOps\n> `TerraformDriftReport` task — so the v1.1.0 redaction fixes reach both. They\n> previously pinned the pre-transfer git URL\n> `github:sethbacon/terraform-drift-contract#v1.0.0`, which is why an earlier\n> revision of this note said fixes did not reach them. `dist/` stays committed\n> so the git form keeps working for anything not yet migrated.\n>\n> **If you must use the git form, pin a commit SHA, not a tag.** A git tag is\n> mutable and the tags here are unsigned and unprotected, so\n> `github:4cloudguru/terraform-drift-contract#v1.1.0` can be repointed at\n> different code with no npm publish, no provenance and no signature to check\n> against — in a package two CI systems execute. `#<full-40-char-sha>` is\n> immutable. The npm package above is the supported channel and the only one\n> that carries provenance.\n\n## API\n\n```ts\nimport { summarize, moduleCallsPlan, type Plan, type Result } from '@4cloudguru/terraform-drift-contract'\n\n// `Plan` is a compile-time DESCRIPTION of the document, not a runtime check —\n// TypeScript interfaces are erased, so every field is `unknown` at run time no\n// matter what the annotation says. That is fine here, and deliberately so: the\n// plan is attacker-influenceable on a fork PR, and `summarize()` normalises\n// every field it reads at the loop head rather than trusting the declared type.\n// No separate validator is exported, because a second notion of \"valid\" would\n// be one more thing the four implementations have to agree on.\nconst plan: Plan = JSON.parse(fs.readFileSync('plan.json', 'utf8'))\nconst r: Result = summarize(plan)\n// r = { added, changed, destroyed, drift_added, drift_changed, drift_destroyed,\n//       drifted, summary: [{ address, actions }], drift_summary: [{ address, actions }],\n//       unparseable, unmasked, truncated, omitted_entries, omitted_attrs }\n\n// Bounds are defaulted, not mandatory. Both defaults are declared in the shared\n// conformance corpus and asserted by every implementation.\nsummarize(plan, { maxEntries: 500, maxAttrsPerEntry: 50 })\n```\n\n**Do not read `drifted: false` as \"verified clean\" on its own.** `unparseable`\nis what separates a clean plan from a document that was never a plan — a\ntruncated `terraform show -json`, the wrong file, a broken pipeline step. All of\nthose used to produce the identical `drifted: false`.\n\n**Where this output goes, and why that matters.** Consumers POST `summary` (and\n`attrs`) to a TSM callback endpoint over the network, write it to a JSON report\nfile on the runner, and echo part of it into the CI log. An unmasked `attrs`\nvalue — up to 300 code points of plaintext whenever the sensitivity mirrors are\nabsent, or whenever the secret sits below an unmarked top-level key — is\ntherefore transmitted, persisted and displayed, not merely held in memory. Read\nthe masking semantics below with that in mind.\n\n`fmt` and `isSens` are exported alongside `summarize`/`moduleCallsPlan` and are\npart of the public contract: `fmt(v)` is the 300-code-point formatter described\nbelow and `isSens(mirror, key)` is the masking predicate. They are exported so a\nporter can check a mirror implementation against them value-by-value, and the\npublish workflow asserts all four are present on the CJS entry point. The same\ntruncation and masking caveats apply to them as to `attrs`.\n\n### Semantics (the authority the other implementations mirror)\n\n- `added` / `changed` / `destroyed` = resources whose actions **contain**\n  create / update / delete (a replacement `[\"delete\",\"create\"]` counts as\n  **both** added and destroyed; counts are **not** mutually exclusive — use\n  `summary.length` for a distinct resource count);\n- `summary` = every change whose actions are **not exactly** `[\"no-op\"]` or\n  `[\"read\"]`, as `{address, actions, attrs?}`;\n- `attrs` (in-place updates/replaces only) = the top-level keys whose value\n  differs, each `{name, before, after}` with values run through `fmt()`\n  (300 code-point truncation, U+2026 marker) and masked to the literal\n  `\"(sensitive)\"` when **either** `before_sensitive` **or** `after_sensitive`\n  marks them (terraform `-json` does **not** pre-mask — masking happens here,\n  before `fmt()`, so a marked secret never reaches the formatter). The union\n  landed in v1.1.0 and is now matched by the other implementations — see\n  [cross-implementation status](#cross-implementation-status).\n  **Two preconditions, both real:** masking is applied *per top-level changed\n  key* and is driven *entirely* by `before_sensitive`/`after_sensitive`. A\n  secret nested under an unmarked top-level key is serialised whole, and a plan\n  that omits the sensitivity mirrors gets no masking at all for that resource.\n  Do not treat this as a redaction guarantee for plans of unknown or untrusted\n  provenance — see [SECURITY.md](SECURITY.md);\n- `drifted` = `(added + changed + destroyed) > 0` (a pure replace has\n  `changed == 0` but `drifted == true`; do not infer \"no drift\" from\n  `changed == 0`);\n- `unparseable` = the document had no `resource_changes` array, so it was not a\n  plan. Distinct from `drifted`, and the field a CI gate should fail loud on;\n- `unmasked` = at least one non-skipped in-place change carried **neither**\n  sensitivity mirror, so nothing was masked for it (see the masking preconditions\n  above). Deliberately shape-based and slightly over-broad: it is the definition\n  all three implementations can compute identically, and over-warning is the\n  right direction for a redaction signal. A present-but-`false` mirror is\n  metadata and does not set it;\n- `truncated` / `omitted_entries` / `omitted_attrs` = a bound was reached, and by\n  how much, so a consumer can tell \"no more drift\" from \"we stopped looking\".\n  **The counts are never capped** — capping them would turn a payload bound into\n  a missed detection — so `drifted` stays truthful when the summary does not;\n- `drift_added` / `drift_changed` / `drift_destroyed` / `drift_summary` = the\n  same rules as `added`/`changed`/`destroyed`/`summary` above (skip, count,\n  attrs, masking, bounds — the identical per-item logic, not a second\n  implementation), computed from the optional `resource_drift` array instead of\n  `resource_changes`. `resource_drift` is **infra drift** — hand-edits or other\n  out-of-band changes — as distinct from the unapplied config changes in\n  `resource_changes`. Zero / `[]` when `resource_drift` is absent or not an\n  array. Purely additive: never affects `drifted`, `summary`, or the three\n  original counts, and `unmasked`/`truncated`/`omitted_entries`/`omitted_attrs`\n  report only the `resource_changes` path — see [SECURITY.md](SECURITY.md).\n\n### Module provenance (`moduleCallsPlan`)\n\nOptional, orthogonal to the summary, and not part of the count/skip semantics\nabove: the `plan` field of the drift callback, carrying which modules a root\nmodule calls.\n\nThe plan's `configuration` block carries **no terraform sensitivity metadata**\nat all — `before_sensitive`/`after_sensitive` exist only inside\n`resource_changes` — so anything forwarded from it is unredacted by\nconstruction. `module_calls` entries carry `expressions` (the `constant_value`\nof every literal argument), the full recursive `module` subtree (its own\nresources' expressions and its variables' `default`s, sensitive ones included)\nand the raw `source` (which can embed a PAT). The subtree is therefore\n**projected, never forwarded verbatim**:\n\n- per call, only `source` and `version_constraint` — exactly the two fields the\n  backend's `driftingest.Configuration` reads, so nothing a consumer uses is\n  lost. `expressions`, `module` and every other member are dropped;\n- `source` has its credentials scrubbed: URL userinfo (`https://token@host/…`,\n  `https://user:pass@host/…`) becomes `(redacted)@`, and of the query\n  parameters only `ref` survives — every other value (`sshkey=`,\n  `X-Amz-Signature=`, `token=`) is redacted;\n- every emitted string is capped by `fmt()` at 300 code points, and at most\n  **100** module calls are emitted (sorted by name); an overflow sets\n  `configuration.root_module.module_calls_truncated: true`.\n\n### Cross-implementation status\n\nThe two redaction behaviours this package introduced ahead of the others are now\n**matched by both** — the Go `driftingest` and the jq in the backend's dispatched\nCI templates:\n\n| Behaviour | Status |\n| --- | --- |\n| An attribute marked sensitive on **one** side only (config-derived marks apply to the planned value only, so this is routine) → **both** sides `\"(sensitive)\"` | reconciled with Go in [backend#374](https://github.com/sethbacon/terraform-state-manager-backend/pull/374); the jq path has no `attrs` to mask |\n| `module_calls` provenance projected + credential-scrubbed + capped (above) | both jq templates project identically as of [backend#374](https://github.com/sethbacon/terraform-state-manager-backend/pull/374) |\n| Byte-level serialized form — code-point key order, U+2028/U+2029 escaped, `<`/`>`/`&` raw, `-0` | reconciled by the corpus ([#17](https://github.com/4cloudguru/terraform-drift-contract/issues/17), [#18](https://github.com/4cloudguru/terraform-drift-contract/issues/18)) |\n| jq skips `[\"read\"]`, and `drifted` comes from the counts | reconciled in the backend ([#20](https://github.com/4cloudguru/terraform-drift-contract/issues/20), [#21](https://github.com/4cloudguru/terraform-drift-contract/issues/21)) |\n\nNeither behaviour changes counting or skip semantics, and neither changes the\nsymmetric case (both mirrors marking the key, or neither): those stay\nbyte-identical. When **neither** mirror is present the change is emitted\nunmasked — that is the shape of a plan with no sensitivity metadata at all, and\nmasking it would mask every attribute of every such plan; this is asserted in\nthe class test so it cannot change silently.\n\nThe serialized byte form is reconciled too, as of the corpus: keys sort by code\npoint everywhere, U+2028/U+2029 are escaped, `<`/`>`/`&` stay raw (the Go mirror\nserialises with `SetEscapeHTML(false)`), and negative zero emits `-0`. The jq\n`SUMMARY` now skips `[\"read\"]` and takes `drifted` from the counts rather than\nfrom `terraform plan -detailed-exitcode`.\n\nWhat still differs is **stated in the corpus, per vector**: Go rejects a\nmalformed document at its unmarshal boundary where this package tolerates it\n(fail-closed, a 422 rather than a wrong answer), and Go marshals a nil action\nlist as `null` where this package emits `[]`. Neither is a redaction gap. See\n[SECURITY.md](SECURITY.md) for the detail and for the cross-implementation\nobligation.\n\n> **Note.** Earlier revisions of this README named a Python `drift_summary.py` as\n> the file these semantics must match. No such file exists anywhere in the suite.\n> The authority is this package: `src/summarize.ts` and its test vectors.\n\n## Contract\n\n`__tests__/` is this package's vector set, and this package is the authority.\n**If the semantics change here, update the mirrors in the same change** — every\nconsumer pulls from here.\n\n`__tests__/fixtures/` are this package's own unit fixtures. The **shared** set —\nthe one the mirrors run — is [`conformance/vectors.json`](conformance/), and it\nis the artifact a disagreement gets settled with. Each implementation pins the\nsame SHA-256 of that file and the same digest over its own rendered results, so\na divergence reddens both repositories without either CI job needing to run the\nother language. Differences that are real and deliberate are **stated per\nvector**; a difference with no entry there is a regression. See\n[`conformance/README.md`](conformance/README.md) for the procedure when the\nsemantics change.\n\n> An earlier revision of this section said the fixtures were \"vendored from the\n> backend's `driftingest` tests\", and the correction that replaced it said\n> nothing verified parity automatically. Both are superseded by the corpus\n> ([#22](https://github.com/4cloudguru/terraform-drift-contract/issues/22)).\n\n## Development\n\n```bash\nnpm install\nnpm test              # vitest contract tests + the conformance corpus\nnpm run test:coverage # the same run, gated on the thresholds in vitest.config.mts\nnpm run lint          # tsc --noEmit\nnpm run build         # tsc → dist/  (commit the result)\n```\n\nCI runs `test:coverage`, not `test`. Every gap this suite has had was an\nuntested branch — the fail-open masking path, the asymmetric key path, the\nprototype-chain read — so the thresholds sit just under the current numbers and\nonly ever move up.\n\n`dist/` is committed and CI fails if it is stale, so a source change that is not\nrebuilt in the same commit does not merge.\n\n## Releasing\n\nThere is no manual publish step and no long-lived registry token.\n\n1. **Land conventional commits on `main`.** PR titles are validated by the\n   `Conventional PR Title` check and PRs are squash-merged, so the PR title\n   becomes the commit subject that release-please reads.\n2. **release-please opens a release PR** (`.github/workflows/release-please.yml`)\n   computing the next version from the commit history — `fix:` → patch, `feat:`\n   → minor, `BREAKING CHANGE:` → major. It maintains `CHANGELOG.md`, the\n   `package.json` version and `.release-please-manifest.json`. Per the suite\n   convention, one merged commit announces **at most one** breaking change.\n3. **Merging the release PR** tags `vX.Y.Z` and publishes a GitHub Release.\n4. **The release publishes the package** (`.github/workflows/publish.yml`): an\n   unprivileged job builds, tests, audits and packs the tarball, then a separate\n   job — gated on the `release` environment's required reviewer and a `v*` tag\n   policy — publishes it.\n\nPublishing uses **npm trusted publishing**: the registry credential is minted\nfrom the workflow's OIDC token and matched against the trusted publisher\nconfigured on npmjs for this package. There is no `NPM_TOKEN` anywhere, and the\npublishing job holds no repository secrets. `publishConfig.provenance` plus\n`id-token: write` produce the provenance attestation, and the published tarball\nis additionally attested with its CycloneDX SBOM.\n\nThe CHANGELOG is load-bearing: this package's semantics are mirrored by a Go and\na jq implementation, and the release notes are how those learn that a divergence\nexists.\n\n## License\n\nApache-2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).\n","readmeFilename":"README.md"}