{"_id":"@37signals/basecamp","_rev":"24-9552905196ab7468755e7606ea529071","name":"@37signals/basecamp","dist-tags":{"latest":"0.18.0"},"versions":{"0.2.0":{"name":"@37signals/basecamp","version":"0.2.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.2.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"50dee7657f466d05d294c1e8ee33cb15184404e7","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.2.0.tgz","fileCount":356,"integrity":"sha512-8wLOgCJmSoIPSlA+d3TXbyhy0ywfrjbA/UEX7Q+rzphGPVbypOO8Sy2QFn/KqJrjELS9xZg5VGXaNSHYnFkN0A==","signatures":[{"sig":"MEQCIBB4GbYd/IF3rZy08ndsACgboCqfgUMfmjVtAHU9IdRCAiBmBMqY5j7lUsA+lBOJMnrtAWSzElMk2mKS3DGvXAfUxg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3454665},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc && npm run postbuild","generate":"tsx scripts/strip-account-id.ts ../spec/build/smithy/openapi/openapi/Basecamp.openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"bitsweat","email":"jeremydaer@gmail.com"},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.6.1","description":"TypeScript SDK for the Basecamp 3 API","directories":{},"_nodeVersion":"24.11.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.0","openapi-typescript":"^7.13.0"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.2.0_1772239134694_0.8041823829751447","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@37signals/basecamp","version":"0.2.1","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.2.1","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"022f56c2ed3aadd5fbf242954f061f4b5fc04140","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.2.1.tgz","fileCount":356,"integrity":"sha512-JQf9dG9mgMMAplMrTbLyDD7sPvPlFIgcFh+VUvnVaxFT1MB/oEl2q9HCV1/sNVvTZOU0IfMPi7nfhj9ZWET/ag==","signatures":[{"sig":"MEYCIQD5ysU/nw7/snqIgl5VuJ/OaKTfKtYGRG7juW362kHANQIhAKRQIIc7QsdxeWCM4mc5ppuqjWZhDhK0niaqN4hWmOjG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3459112},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"74bbff65f1300732f8caa9017a408e34aec59819","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../spec/build/smithy/openapi/openapi/Basecamp.openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.2.1_1772294008591_0.043110575989893096","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@37signals/basecamp","version":"0.2.2","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.2.2","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"c2a2fa238f3f0306baaf504b26e4f427399ce120","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.2.2.tgz","fileCount":356,"integrity":"sha512-nVrJGeRe3B0fSpmJmUd+g0nOqSse18uEsg/Xiez9usLFwtBm7DbGrcqzxDCO+PbwmZS7JWYRqhTNTYUEF+sIWw==","signatures":[{"sig":"MEUCIQDBtB2jhWt9sraASg9VomSEJPw7Eo6iy8Zjm1ymIU0ouAIgYnXP6kkj+r5FMboKqzBHPKhdWC8SGdgTbsPVzScY6bQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3462770},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"4fe6c0d8dd717a4a81f190170aa5122cf8fe7e61","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../spec/build/smithy/openapi/openapi/Basecamp.openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.2.2_1772595150580_0.3035565392979076","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@37signals/basecamp","version":"0.2.3","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.2.3","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"86dc432149ecd6308bc3714510b0e64703281761","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.2.3.tgz","fileCount":356,"integrity":"sha512-XqNKgw/KHnlcfgCFtcaK2g6begGWdhkcTjmCoGAXltztugx14uFUO7wMvWjcTVRi3wAzLkXEBPjg8IrpC5I1Zw==","signatures":[{"sig":"MEUCIQCjw5RjhjEHG8Q21xKpmIlNXFhd+BwW9E9rcBBy2YTmyQIgB0piR9Yx8vbgmAzRu/AIvcvxen8oRAUU+f2EkUI7uRQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3503645},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"a785ca01b33bd798434a325e09a8c9e4727289f9","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../spec/build/smithy/openapi/openapi/Basecamp.openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.2.3_1773089989927_0.1876812964529626","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@37signals/basecamp","version":"0.3.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.3.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"8f2b4c7e946b78a5219e48573151f51b2cc71bc4","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.3.0.tgz","fileCount":356,"integrity":"sha512-lDOJLubW3LONCE13w+9zsXQKuipiXb4c5XHp6ZSHJaHkXvlFwt+Ef3OOW9BYnxJh1QMyH2HzgTIB1qKtiDhWKg==","signatures":[{"sig":"MEUCIQCjISJFm1aqt0M6ViE1MGfPDZaG7s6YFaKiCeTlk/6fygIgW79wkqq3PjACfwhYI2Dof2JacLfJleXcSpmAPEnckYk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3502883},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"4b2db790a3669ca22fa07074dc7571f32d8060e5","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../spec/build/smithy/openapi/openapi/Basecamp.openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.3.0_1773095930261_0.2870860206967285","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@37signals/basecamp","version":"0.4.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.4.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"2253398ac481293d6ca7b8f73dd0731ccf2d4f99","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.4.0.tgz","fileCount":356,"integrity":"sha512-0Nqvk7y0FDllXoNrzDZzeECYiVjPLQ/xUmCnYhqaWWNO7X3xplWi6l+DtcUK3AdUtyIyd8uJvi4l83EUxpKCAw==","signatures":[{"sig":"MEQCICIDHbtGrVjz/XEgVFDdv3bfrEEX9OSYbK9U6m5YCV2EAiBnJq2+2hNTQ/wSP6C3YiMCJAeZ9/HemugwS2CCcF5vDg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3563905},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"92026d65a1561dcc220b9bd4e9e8460e08a92045","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.4.0_1773214327816_0.361505886256291","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@37signals/basecamp","version":"0.5.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.5.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"e069593b0f9e419d3f1f84a8ce0c4039d9e02cb7","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.5.0.tgz","fileCount":356,"integrity":"sha512-p0UZrhMd0g7eyxbfseYU5r5Y8+ix8gOFpOu05VzayzLqqTDTPkZhqSAD3xYKdmNb2A0QL+bM2pyFZ9hn3OGCow==","signatures":[{"sig":"MEYCIQDgl+2HrSx6jvfm/uKgkwKfrmc5cvfYfkF/hQiHvgyyuAIhAN6HAlSruEHYyB1V0QbZMVZfFf+K4ItJYS4CT7C6dEHW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3567643},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"3e110b2d289fa309a850588ff124652c0a7e6694","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.1","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.1","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.5.0_1773330993644_0.018763206245137942","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@37signals/basecamp","version":"0.6.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.6.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"7e188df99332c7da6869ee8a10e21bb8b2753793","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.6.0.tgz","fileCount":366,"integrity":"sha512-WyT65qX0HLmNo8Uim7JdXKRYKDqD2BJpwJkBruddeX8jDDnAcfKu+CDHjcc9asNOLozTYq5eXhslIJ6OIMhgeg==","signatures":[{"sig":"MEQCIAzufezCzqrj+C8I5RiIh1NDPBsygdSXqvkX6HwG6UinAiABE2kvFTJxUvzKVujvg5DiJLvlb0V5K/Pm53yK785BhA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3614378},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"7e55f2e3da9de49a3f92d2b721695605ab39480e","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.11.1","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.6.0_1773638619568_0.36583268804928903","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@37signals/basecamp","version":"0.7.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.7.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"e0ee6f03b4cc372dcef41665f45b9106da67e473","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.7.0.tgz","fileCount":396,"integrity":"sha512-4FWcvJOj/cKvhLwjjozYTnaF88Ct01cRaHuIcUVFXJnKNVTwQOnS+5m+KiFIE1ti65cSKb5LVL7Ft4/vXxWIew==","signatures":[{"sig":"MEUCIQDxBhrKDg3W+3YfYA3eAJOCiQUjf96WWy/SzlS/FctKFwIgE4mJXk3tpLmHYfeWNnl6oxtNzDcvPQ4cfDhA4MGloVI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4078511},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"c9cab1f0d44563be7aaf2cd531d560527c8dd10d","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.12.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.1","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.7.0_1774381689659_0.745359256936786","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@37signals/basecamp","version":"0.7.1","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.7.1","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"e7c3c2b5f6cd56ee28c66701ef974e81fb3c4d00","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.7.1.tgz","fileCount":396,"integrity":"sha512-ar6zGeMi4MVCnyJLMOJZ7rpQc5G5iqFflJkFD3Sd/lpRyo3OmIcGIz8d5aDSrast8O0EvZ4CuyeQUFfU2MLmEg==","signatures":[{"sig":"MEYCIQDxXKYHdOg2pCXmmxLNnDFTNnMkmwkdgYOqJgXRjQJN3wIhAPAmMmCcPc5ECwggUGLlj39jMrB7k9fEnbGDrvBrObne","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4084314},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"55ea29ab3388994921f83400f5cfbd9cf9182ff7","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.12.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.1","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.7.1_1774422096215_0.10017954678265073","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@37signals/basecamp","version":"0.7.2","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.7.2","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"a3d5accb69f6ed4cf8febec3697f09988cc0d4b7","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.7.2.tgz","fileCount":396,"integrity":"sha512-Nko1Yl+3A6zSp5qs6+oSNVvPbKq3i+/U50gI+W9E9tqx6UgRZG4DM76uQvlQ2KM22p2lLmsaAPy99dWr1D7AMQ==","signatures":[{"sig":"MEQCIHaY/XJPBMaJZG9FRTt8qsKEExIs+sEpInPvCTkSngCUAiBntbRIDQCtKux7kwurZpcZbEEAjxCi7n4tBG6FsstLew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.7.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4084464},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"0613b681ec217b1a9118fedd37a70fffbb3601bd","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.12.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.1","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.7.2_1774500674724_0.5917774222274594","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"@37signals/basecamp","version":"0.7.3","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.7.3","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"f9e5e5c1e8d08b7d078d79d45b2679b1397d2bcc","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.7.3.tgz","fileCount":396,"integrity":"sha512-UNJpDIbOTR5imXbxtaFe0Uic8ekwZUtkSRYCeJAu87UDRPYcBehjAy99vk1O3s0v2eQgqdWiEB1TavDqv9tBVw==","signatures":[{"sig":"MEQCIEmBrZDgSQYYr1Bo1cEa1lO+e2Uia0m643LGdktR0UZYAiB36va3tmxA8jDK2KqQI5oxsDW34YSA2upoqtzQmqLQKw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.7.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4084464},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"7f6992a806b1a4aad609486921c0873df3ff091b","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.json && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"minimatch":">=10.2.1"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.12.1","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"22.22.1","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^25.3.2","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.7.3_1774904178374_0.20744906687589548","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@37signals/basecamp","version":"0.8.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.8.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"89d7f858a302e12718a4e2f9b7530f6b7b12c3c6","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.8.0.tgz","fileCount":408,"integrity":"sha512-0mwPGXZDOyUC+ZLiDCZiHTyZD+kZnWOtxmdSWh79qXH6rddmmre2HGP6Dmt57WApyZNQoyYVFy9QR2wZuGCr0g==","signatures":[{"sig":"MEYCIQDaBpPlDDVhicAb4YYDnqAhV6l3hv2xo9kzAsCxcymFsAIhANl3mNqKIR0+unNdkYcY5Thc7vOgCPXxZnBvPKmptfzX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4324916},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"f55a6b51a9befa43f331d2badb904da5ae08920a","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.3","minimatch":">=10.2.1","brace-expansion":">=5.0.7"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.8.0_1784735136817_0.5109238578734301","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@37signals/basecamp","version":"0.9.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.9.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"4b07ae181fc98d259332145ea7c9b81450000a03","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.9.0.tgz","fileCount":414,"integrity":"sha512-+Bhr4lvNHzHJ7OK3BKPuNNgtKPURTz1zTNdH4flRO1p/A+LzIEq4jlw5CL94Hr2RmmNFsik0SYRTRzPEanfpaA==","signatures":[{"sig":"MEQCIFOdtLHfXqtYTloyoBAKbIc+3rNFPfXUc8RuiDQ/n4HxAiBw5v+Bz4OXFDPxdeZKImqCEkCCU4CriJWML393yhNUig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4470783},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"2d8992df49c297bac7c67495fc029cf760e168ce","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.3","minimatch":">=10.2.1","brace-expansion":">=5.0.7"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.9.0_1785108461072_0.12382809649544657","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@37signals/basecamp","version":"0.10.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.10.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"fedb779334cd369791e49b69da4d3ce82a07215a","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.10.0.tgz","fileCount":424,"integrity":"sha512-b2VDyEXG4R5Sd6WgRjFG5BBd17yQCPR7kyGV2PqKQjMALXlPWEK6Zr+uLehcZoo/dWh87nLL7RI/Ao30fXCJ0w==","signatures":[{"sig":"MEUCIQCWmvQ1eHKHu6Dsj3eqzG0TdwEoCVp8cY/ihPWtsmWy/AIgMrbyAgLbEaQTCc2Kq7or6NhVbMoMHSChVo8zZ/LRL9Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4907743},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"d1978c4ec8ca4d384b638e8227f585fd6066f264","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.3","minimatch":">=10.2.1","brace-expansion":">=5.0.7"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.10.0_1785306528273_0.8065906320986529","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@37signals/basecamp","version":"0.11.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.11.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"4b9fcde48fd9e106e708e0bd134063758ec9dcc4","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.11.0.tgz","fileCount":440,"integrity":"sha512-L7xc5FrrrOk3RXU2UN6ds9hYLntgwv9PxgdQagD6DbLMGxrpcnlcyT0PBFuUecz3Rn9kzu2SixUIPKWgMvqxoA==","signatures":[{"sig":"MEUCIEXC1zoBk5QwCtq31NbgLHI+595ApyhK6yeOGgB6F5MJAiEA2PoYwPzxkcEbdFuVfvUvaA0/K7dZScgirt1s6jd7q80=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5002183},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"b7124ca6a62a0da5b246e1ba82991d3d9b5b5a87","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.3","minimatch":">=10.2.1","brace-expansion":">=5.0.7"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.11.0_1785488564649_0.9714896785543787","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@37signals/basecamp","version":"0.12.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.12.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"22516726781146302438af4369f7afb4ea681f67","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.12.0.tgz","fileCount":464,"integrity":"sha512-O2+d1d/dCj31aPJinzVv/Dzzvjn+JTJOWGsKxPesjmR/54mmL+MW3MLuaHhakeUPCBfVUdJ1D0pshcWKE55O/w==","signatures":[{"sig":"MEUCIQCGKMzmB9fwPeKyBIAdvO/K+eY25A12z86kQpjo8nmGTQIgSF4CGVjUbGV0XKFkBY96oIhqjavYUvHnpjWXiwRi7SI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5325922},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"gitHead":"7e2925d25078107b3ecbcd59a0bde758d586e10f","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.3","minimatch":">=10.2.1","brace-expansion":">=5.0.7"},"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.12.0_1785545976804_0.9335018874918388","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@37signals/basecamp","version":"0.13.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.13.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"0c49e01b976326f200551f98c6b3c4ef7b91b5a4","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.13.0.tgz","fileCount":503,"integrity":"sha512-leP6JWfIzBbLsYlnvZArf6X1xCV9PbX9lEWzp9V3RDpBSlqo6xMRI1DSW7/iQSTzUh6/M0lfffrldC6Z9NfCew==","signatures":[{"sig":"MEUCIDbAZF1SknJSItC8VQmydDKXIqMH8cPFd7KCo5gPopQdAiEAsTrjvkYbGq3BQqU+fT5rz3mhGVBTt5/XKYkpEwSJqbE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5997399},"main":"dist/index.js","type":"module","_from":"file:37signals-basecamp-0.13.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.13.0.tgz","overrides":{"js-yaml":"^4.3.0","fast-uri":">=3.1.5 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-leP6JWfIzBbLsYlnvZArf6X1xCV9PbX9lEWzp9V3RDpBSlqo6xMRI1DSW7/iQSTzUh6/M0lfffrldC6Z9NfCew==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.17.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.19.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.13.0_1786086270392_0.582037907795562","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"@37signals/basecamp","version":"0.14.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.14.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"7cec8f4e1d3b6c96046cb7956fd76276979e4f65","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.14.0.tgz","fileCount":507,"integrity":"sha512-cjW7c2ZAiRdaO9FX9CGk5sdIBAO1hyo8ZCLCgLY71rTMDhn/Fo/R6ijJ4kLOQQhASKJLc3ysZ4QpptvyN960Xg==","signatures":[{"sig":"MEYCIQDxVHNlvBk3S0KkI7rhWduRCHHvc9NVWZwcyFFM7gGlRgIhAIsXWKH5t9nJXpT7PDzVyHD2S4P/FnD5Y1BHy51bDbyb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.14.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6062326},"main":"dist/index.js","type":"module","_from":"file:37signals-basecamp-0.14.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.14.0.tgz","overrides":{"js-yaml":">=4.3.1 <5","fast-uri":">=3.1.5 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-cjW7c2ZAiRdaO9FX9CGk5sdIBAO1hyo8ZCLCgLY71rTMDhn/Fo/R6ijJ4kLOQQhASKJLc3ysZ4QpptvyN960Xg==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.16.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.14.0_1786493414098_0.28124984248946183","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"@37signals/basecamp","version":"0.15.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.15.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"c79b4aae1f31dc398d77ede8763b7a166ff725fc","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.15.0.tgz","fileCount":507,"integrity":"sha512-D1qAQwFlLhTq4sC8QLsBil85b0OUSr7s/20zDeiUqCGtQnQtcFLr1NiMyA7mpsZeCMaaU/zyxyQwy/DtToTaDw==","signatures":[{"sig":"MEYCIQDL7D4bGoLxVvHoGKxmQWqmgLx8rLDGEmOx1JEGJYTY8wIhAPNZQ2Gl7tq+t2jwU+kf3S8olprxzAU5kQIUoBQGepbH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.15.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6131682},"main":"dist/index.js","type":"module","_from":"file:37signals-basecamp-0.15.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit && tsc -p tsconfig.test.json --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build","test:lint-rules":"node lint-rules/test-no-timer-scheduled-abort.mjs","lint:test-timers":"oxlint -c lint-rules/oxlintrc.json tests"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.15.0.tgz","overrides":{"js-yaml":">=4.3.1 <5","fast-uri":">=3.1.5 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-D1qAQwFlLhTq4sC8QLsBil85b0OUSr7s/20zDeiUqCGtQnQtcFLr1NiMyA7mpsZeCMaaU/zyxyQwy/DtToTaDw==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.17.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.19.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.15.0_1787392748244_0.5705843261575332","host":"s3://npm-registry-packages-npm-production"}},"0.16.0":{"name":"@37signals/basecamp","version":"0.16.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.16.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"0a966b477b436b26847d812669932c245ef187f8","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.16.0.tgz","fileCount":513,"integrity":"sha512-KKPekFmV1de0Bp6vxCwNoIQef5Ctg0RdoFWlTZ6G41/KYUlbZD508uofm92EBk+eSrJvA1luYoSuxuDdSf5KrA==","signatures":[{"sig":"MEUCIQCGZ+7qGYJVeP38rwdmmIskxY0SfbZmUyZkeKpUCR/BlAIganQQrGr30KDginzHKze0hVABY2qrl2bIW7RrWFaDJqk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIHL2bVsDSmIH4ZJPlc5PS9PhJYBs8Hy9/2b4/tlNWHTwAiEAhUl7p4P3NUnRw4+sHkV8zMFOdHZAOxcOHJwPsK+3u84=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.16.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6310159},"main":"dist/index.js","type":"module","_from":"file:37signals-basecamp-0.16.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit && tsc -p tsconfig.test.json --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build","test:lint-rules":"node lint-rules/test-no-timer-scheduled-abort.mjs","lint:test-timers":"oxlint -c lint-rules/oxlintrc.json tests"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.16.0.tgz","overrides":{"js-yaml":">=4.3.1 <5","fast-uri":">=3.1.7 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-KKPekFmV1de0Bp6vxCwNoIQef5Ctg0RdoFWlTZ6G41/KYUlbZD508uofm92EBk+eSrJvA1luYoSuxuDdSf5KrA==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.17.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.19.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.16.0_1788459918831_0.368603265257222","host":"s3://npm-registry-packages-npm-production"}},"0.17.0":{"name":"@37signals/basecamp","version":"0.17.0","keywords":["basecamp","api","sdk","typescript"],"author":{"name":"Basecamp"},"license":"MIT","_id":"@37signals/basecamp@0.17.0","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"homepage":"https://github.com/basecamp/basecamp-sdk#readme","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"429eb8da1f2373a36c4f86984742712cca988dc5","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.17.0.tgz","fileCount":513,"integrity":"sha512-CZ4C703+fBANhIw5i6P+QlkgVbbe+zmlEEVSTd/zOs/zGaHq5lifLWa6qG6TwoetSFFdTqwIVPhMhdVfxBhbog==","signatures":[{"sig":"MEYCIQDdXevCUt4N4xlj48EZ16yTDd/l43jIHTJxprffaiRZIgIhAJdSUNdKTfmduBGkYk8ykcCwr9vxa/3lYZY2mZtBTDjG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICgXncUoYaxwrIpKZaq0SF2GyMzTuPQiqowLuOcrxrlMAiB9BHLygkcYPs6exAQfR213zu5G/83ngUxdoKyZtooeMg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.17.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6389990},"main":"dist/index.js","type":"module","_from":"file:37signals-basecamp-0.17.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit && tsc -p tsconfig.test.json --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build","test:lint-rules":"node lint-rules/test-no-timer-scheduled-abort.mjs","lint:test-timers":"oxlint -c lint-rules/oxlintrc.json tests"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.17.0.tgz","overrides":{"js-yaml":">=4.3.2 <5","fast-uri":">=3.1.7 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-CZ4C703+fBANhIw5i6P+QlkgVbbe+zmlEEVSTd/zOs/zGaHq5lifLWa6qG6TwoetSFFdTqwIVPhMhdVfxBhbog==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.19.0","description":"TypeScript SDK for the Basecamp API","directories":{},"_nodeVersion":"24.20.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/basecamp_0.17.0_1788991588806_0.30207060682604925","host":"s3://npm-registry-packages-npm-production"}},"0.18.0":{"_id":"@37signals/basecamp@0.18.0","bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"dist":{"shasum":"3111c4454966530251d285e1b49938a7d337ae25","tarball":"https://registry.npmjs.org/@37signals/basecamp/-/basecamp-0.18.0.tgz","fileCount":513,"integrity":"sha512-whlc7I5x+tznIhlx56KhbiLGe7g8wbosPJYUyLEMyqlKGqe25hh42IeZTd0K7A/4tRMFblvNXj27VH/QnFWHMA==","signatures":[{"sig":"MEUCIQCRFmOWt5vdKdgg9H5DpM1WAWPH38IUheCNPw/fD1jVNwIga28ligd3BvVmdZzmrnZd0pB8+U4SQWBFaIcu+EQZYNI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAN0Pf2pyBKMFVRkzj8VKsznC0E/SJEZpjFAq2jyyLCYAiEAxjsLxFrFhxgVgoiC2o0HNssd4lNSAQCRP190zE+hiu4="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@37signals%2fbasecamp@0.18.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6391708},"main":"dist/index.js","name":"@37signals/basecamp","type":"module","_from":"file:37signals-basecamp-0.18.0.tgz","types":"dist/index.d.ts","author":{"name":"Basecamp"},"engines":{"node":">=22.12.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth/index.d.ts","import":"./dist/oauth/index.js"}},"license":"MIT","scripts":{"lint":"oxlint src --ignore-pattern 'src/generated/**'","test":"vitest run","build":"tsc","generate":"tsx scripts/strip-account-id.ts ../openapi.json src/generated/openapi-stripped.json && openapi-typescript src/generated/openapi-stripped.json -o src/generated/schema.d.ts && tsx scripts/patch-flexible-ids.ts && tsx scripts/extract-metadata.ts src/generated/openapi-stripped.json > src/generated/metadata.ts && tsx scripts/generate-path-mapping.ts","prebuild":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true});\"","postbuild":"node -e \"fs=require('fs');fs.cpSync('src/generated','dist/generated',{recursive:true});fs.writeFileSync('dist/.build-complete','');\"","typecheck":"tsc --noEmit && tsc -p tsconfig.test.json --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build","test:lint-rules":"node lint-rules/test-no-timer-scheduled-abort.mjs","lint:test-timers":"oxlint -c lint-rules/oxlintrc.json tests"},"version":"0.18.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a22ff866-6c37-421b-857f-95354ab082ce"}},"homepage":"https://github.com/basecamp/basecamp-sdk#readme","keywords":["basecamp","api","sdk","typescript"],"_resolved":"/home/runner/work/basecamp-sdk/basecamp-sdk/typescript/37signals-basecamp-0.18.0.tgz","overrides":{"js-yaml":">=4.3.2 <5","fast-uri":">=3.1.7 <4","minimatch":">=10.2.1","brace-expansion":">=5.0.9"},"_integrity":"sha512-whlc7I5x+tznIhlx56KhbiLGe7g8wbosPJYUyLEMyqlKGqe25hh42IeZTd0K7A/4tRMFblvNXj27VH/QnFWHMA==","repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"_npmVersion":"11.19.0","description":"TypeScript SDK for the Basecamp API","directories":{},"maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"_nodeVersion":"24.20.0","dependencies":{"openapi-fetch":"^0.17.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"msw":"^2.12.10","tsx":"^4.19.0","oxlint":"^1.50.0","vitest":"^4.0.18","typescript":"^5.7.0","@types/node":"^26.1.0","openapi-typescript":"^7.13.0","@vitest/coverage-v8":"^4.0.18"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/basecamp_0.18.0_1789018496217_0.013245633187724648"}}},"time":{"created":"2026-02-28T00:38:54.597Z","modified":"2026-09-10T05:34:56.621Z","0.2.0":"2026-02-28T00:38:54.880Z","0.2.1":"2026-02-28T15:53:28.818Z","0.2.2":"2026-03-04T03:32:30.756Z","0.2.3":"2026-03-09T20:59:50.087Z","0.3.0":"2026-03-09T22:38:50.504Z","0.4.0":"2026-03-11T07:32:08.028Z","0.5.0":"2026-03-12T15:56:33.866Z","0.6.0":"2026-03-16T05:23:39.804Z","0.7.0":"2026-03-24T19:48:09.817Z","0.7.1":"2026-03-25T07:01:36.399Z","0.7.2":"2026-03-26T04:51:14.933Z","0.7.3":"2026-03-30T20:56:18.585Z","0.8.0":"2026-07-22T15:45:36.980Z","0.9.0":"2026-07-26T23:27:41.220Z","0.10.0":"2026-07-29T06:28:48.439Z","0.11.0":"2026-07-31T09:02:44.815Z","0.12.0":"2026-08-01T00:59:36.941Z","0.13.0":"2026-08-07T07:04:30.563Z","0.14.0":"2026-08-12T00:10:14.269Z","0.15.0":"2026-08-22T09:59:08.397Z","0.16.0":"2026-09-03T18:25:18.960Z","0.17.0":"2026-09-09T22:06:28.926Z","0.18.0":"2026-09-10T05:34:56.316Z"},"bugs":{"url":"https://github.com/basecamp/basecamp-sdk/issues"},"author":{"name":"Basecamp"},"license":"MIT","homepage":"https://github.com/basecamp/basecamp-sdk#readme","keywords":["basecamp","api","sdk","typescript"],"repository":{"url":"git+https://github.com/basecamp/basecamp-sdk.git","type":"git","directory":"typescript"},"description":"TypeScript SDK for the Basecamp API","maintainers":[{"name":"bitsweat","email":"jeremydaer@gmail.com"},{"name":"dhh","email":"david@hey.com"},{"name":"packagethief","email":"jeff@hey.com"},{"name":"flavorjones","email":"mike.dalessio@gmail.com"},{"name":"samuelpecher","email":"samp@hey.com"},{"name":"rosapolis","email":"rosa@hey.com"},{"name":"jorgemanrubia","email":"jorge@hey.com"}],"readme":"# Basecamp TypeScript SDK\n\n[![npm version](https://img.shields.io/npm/v/@37signals/basecamp.svg)](https://www.npmjs.com/package/@37signals/basecamp)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)\n[![Test](https://github.com/basecamp/basecamp-sdk/actions/workflows/test.yml/badge.svg)](https://github.com/basecamp/basecamp-sdk/actions/workflows/test.yml)\n\nOfficial TypeScript SDK for the [Basecamp API](https://github.com/basecamp/bc3-api).\n\n**Upgrading to v0.14.0?** Read [MIGRATING.md](../MIGRATING.md) before you bump the version. The compiler catches the `uploads.listVersions` retype and any exhaustive handling of the widened `ErrorCode` union; what it will not catch is a non-exhaustive branch on `\"api_error\"`, which storage, project and webhook limit failures no longer reach — they now report `\"limit_exceeded\"`. Coming from v0.12.0 or earlier, read v0.13.0's section too.\n\n## Features\n\n- Full type safety with TypeScript generics\n- 30+ services covering the complete Basecamp API\n- OAuth 2.0 with PKCE support\n- ETag-based HTTP caching (opt-in)\n- Automatic retry with exponential backoff\n- Pagination helpers for large result sets\n- Observability hooks for logging, metrics, and tracing\n- OpenTelemetry integration\n\n## Installation\n\n```bash\nnpm install @37signals/basecamp\n```\n\nRequires Node.js 22.12+ and TypeScript 5.0+.\n\n## Getting a token\n\nEvery Basecamp API request carries an OAuth 2.0 access token. There is no API key and no personal access token, so even a throwaway script starts here:\n\n1. Choose the grant that matches how your code runs:\n\n| Your integration | Grant | Who refreshes the token |\n|---|---|---|\n| already holds a token you obtained elsewhere | **static token** — [`Token Providers`](#token-providers) | you do |\n| can receive a browser redirect (web app, or a local callback server) | **authorization code + PKCE** — [`Manual Authorization Flow`](#manual-authorization-flow), or [`Interactive Login`](#interactive-login-cli--desktop) for a CLI | your `accessToken` function, which the SDK re-invokes per request |\n| has no browser, but a person can approve on another device (CLI, headless server, TV) | **device flow** — [`Device flow`](#device-flow-rfc-8628) | your `accessToken` function, which the SDK re-invokes per request |\n\nThe one-line rule: **a redirect URI you control → authorization code; no browser but someone to approve → device flow; a token already in hand → static token.** An unattended daemon or CI job fits none of the three on its own — the device flow needs a person to enter the user code at the verification URI — so provision a token out of band and hand it to the process as a static or refresh token.\n\n2. Get the client credentials that grant needs:\n\n- **Authorization code + PKCE** — register your own integration at **<https://launchpad.37signals.com/integrations>**. You get a client ID, a client secret, and whatever redirect URI you nominated.\n- **Device flow** — nothing to register. It runs as the pre-registered public `basecamp-cli` client, which sends no secret, against the device endpoint that discovery returns. Launchpad advertises no device endpoint, so a client you register there is not the one this flow uses.\n- **Static token** — nothing to register; you already hold the token.\n\nA bare `accessToken` string is never refreshed — once it expires every call fails with `401` until you supply a new one. Use it to get a first successful call, then pass an async token provider or an `AuthStrategy` before you ship.\n\n## Finding your account ID\n\nEvery API path is scoped to an account — `https://3.basecampapi.com/{accountId}/…` — so `createBasecampClient` needs that number before your first call. One token can reach several accounts, so ask the token which. `getInfo()` addresses Launchpad by default, which is right for a Launchpad-issued token; a **device-flow** token is issued by the discovered BC5 server, so pass that issuer as the `endpoint` option:\n\n```ts\nimport { createBasecampClient } from \"@37signals/basecamp\";\n\nconst token = process.env.BASECAMP_TOKEN!;\n\n// createBasecampClient always requires an accountId, but authorization.getInfo()\n// talks to Launchpad rather than the account-scoped API, so a placeholder is fine\n// for the bootstrap call.\nconst bootstrap = createBasecampClient({ accountId: \"0\", accessToken: token });\n\n// \"bc3\" is Basecamp; the unfiltered response also carries \"hey\" and other products.\n// endpoint defaults to Launchpad, which is right for a Launchpad-issued token.\n// For a device-flow token, pass the discovered issuer:\n//   { filterProduct: \"bc3\", endpoint: `${issuer}/authorization.json` }\nconst info = await bootstrap.authorization.getInfo({ filterProduct: \"bc3\" });\nfor (const account of info.accounts) {\n  console.log(`${account.id}: ${account.name}`);\n}\n\n// Rebuild with the real account ID — that is the client you keep.\nconst client = createBasecampClient({\n  accountId: String(info.accounts[0].id),\n  accessToken: token,\n});\n```\n\n`info.expiresAt` is a `Date` telling you how long the token has left, which is the quickest way to confirm a static token has not lapsed.\n\n## Quick Start\n\n```ts\nimport { createBasecampClient } from \"@37signals/basecamp\";\n\nconst client = createBasecampClient({\n  accountId: process.env.BASECAMP_ACCOUNT_ID!,\n  accessToken: process.env.BASECAMP_TOKEN!,\n});\n\n// List all projects\nconst projects = await client.projects.list();\nfor (const project of projects) {\n  console.log(`${project.id}: ${project.name}`);\n}\n```\n\n## Configuration\n\n### Client Options\n\n```ts\nimport { createBasecampClient } from \"@37signals/basecamp\";\n\nconst client = createBasecampClient({\n  // Required\n  accountId: \"12345\",\n  accessToken: \"your-token\", // or async token provider\n\n  // Optional\n  baseUrl: \"https://3.basecampapi.com/12345\", // default\n  userAgent: \"my-app/1.0\",\n  enableCache: true, // ETag caching (default: false)\n  enableRetry: true, // Auto retry 429 and 503 (default: true)\n  hooks: myHooks, // Observability hooks\n});\n```\n\n### Token Providers\n\nFor simple use cases, pass a static token string:\n\n```ts\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"your-access-token\",\n});\n```\n\nFor token refresh scenarios, pass an async function:\n\n```ts\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: async () => {\n    // Fetch or refresh your token\n    const token = await myTokenStore.getValidToken();\n    return token.accessToken;\n  },\n});\n```\n\n## OAuth 2.0\n\nThe SDK includes utilities for implementing OAuth 2.0 with automatic PKCE negotiation.\nPKCE parameters are included only when the server's discovery metadata advertises\n`code_challenge_methods_supported: [\"S256\"]` (per [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414)\nand [RFC 7636](https://www.rfc-editor.org/rfc/rfc7636)).\n\n### Interactive Login (CLI / Desktop)\n\n`performInteractiveLogin` handles the full flow — discovery, PKCE negotiation, local\ncallback server, browser launch, code exchange, and token storage:\n\n```ts\nimport { performInteractiveLogin } from \"@37signals/basecamp\";\nimport open from \"open\";\n\nconst token = await performInteractiveLogin({\n  clientId: CLIENT_ID,\n  clientSecret: CLIENT_SECRET,\n  store: myTokenStore,\n  openBrowser: (url) => open(url),\n  onStatus: (msg) => console.log(msg),\n});\n```\n\n### Manual Authorization Flow\n\nFor web apps or custom flows, use the lower-level helpers directly:\n\n```ts\nimport {\n  discoverLaunchpad,\n  buildAuthorizationUrl,\n  generatePKCE,\n  generateState,\n  exchangeCode,\n  refreshToken,\n  isTokenExpired,\n} from \"@37signals/basecamp\";\n\n// 1. Discover OAuth endpoints\nconst config = await discoverLaunchpad();\n\n// 2. Generate PKCE (only if the server supports S256) and state\nconst supportsPKCE = config.codeChallengeMethodsSupported?.includes(\"S256\") ?? false;\nconst pkce = supportsPKCE ? await generatePKCE() : undefined;\nconst state = generateState();\n\n// Store pkce?.verifier and state in session for later\n\n// 3. Build authorization URL\nconst authUrl = buildAuthorizationUrl({\n  authorizationEndpoint: config.authorizationEndpoint,\n  clientId: CLIENT_ID,\n  redirectUri: REDIRECT_URI,\n  state,\n  pkce,\n});\n// Redirect user to authUrl.toString()\n\n// 4. Exchange code for tokens (in callback handler)\nconst token = await exchangeCode({\n  tokenEndpoint: config.tokenEndpoint,\n  code: callbackParams.code,\n  redirectUri: REDIRECT_URI,\n  clientId: CLIENT_ID,\n  clientSecret: CLIENT_SECRET,\n  codeVerifier: pkce?.verifier,\n  useLegacyFormat: true, // Required for Basecamp Launchpad\n});\n\n// 5. Refresh when expired\nif (isTokenExpired(token)) {\n  const newToken = await refreshToken({\n    tokenEndpoint: config.tokenEndpoint,\n    refreshToken: token.refreshToken!,\n    useLegacyFormat: true,\n  });\n}\n```\n\n### Resource-first discovery (BC5)\n\nBC5 serves its Authorization Server metadata only at its canonical issuer (the\nweb host), so discovery starts from the **resource** (RFC 9728) and composes with\nAS discovery (RFC 8414):\n\n```ts\nimport { discoverFromResource, DiscoverySelectionError } from \"@37signals/basecamp\";\n\nconst result = await discoverFromResource(\"https://3.basecampapi.com\");\nif (result.kind === \"selected\") {\n  // result.config is bound + validated for result.issuer\n} else {\n  // result.reason is \"resource_discovery_failed\" | \"no_as_advertised\"\n  // → fall back to Launchpad (discoverLaunchpad())\n}\n```\n\n`performInteractiveLogin` supports this via `resourceBaseUrl` (mutually exclusive\nwith the legacy `baseUrl`; supplying both is a `usage` error):\n\n```ts\nawait performInteractiveLogin({\n  clientId: \"basecamp-cli\",\n  store: myTokenStore,\n  resourceBaseUrl: \"https://3.basecampapi.com\",\n  expectedIssuer, // optional: authoritative, non-heuristic selection\n  openBrowser: (url) => open(url),\n});\n```\n\n**Selection.** With `expectedIssuer` (production canonical:\n`https://app.basecamp.com`), the advertised member equal by code-point is\nselected (else a hard `expected_issuer_unavailable`). Without it, the SDK uses a\ndocumented Basecamp-profile heuristic: exactly one non-Launchpad issuer → selected;\n≥2 → hard `ambiguous_issuers` (never guesses); zero → Launchpad.\n\nPass bare origins — no trailing slash. Binding is code-point exact, and the\nfailure mode depends on which parameter carries the slash: a trailing-slash\n`expectedIssuer` fails the advertised-member lookup and throws a **hard**\n`expected_issuer_unavailable`, while a trailing-slash *resource* origin breaks\nthe hop-1 resource binding and silently soft-falls back to Launchpad.\n\n**Fallback is allowed only before a first-party issuer is committed.** Once valid\nresource metadata advertises it and it is selected, every later failure is fatal —\nthe SDK **never** silently falls back to Launchpad:\n\n| Failure | Result |\n|---|---|\n| Hop-1 fetch/parse fails, or `resource` mismatch | soft `resource_discovery_failed` → Launchpad |\n| Valid metadata omits the first-party issuer | soft `no_as_advertised` → Launchpad |\n| ≥2 non-Launchpad issuers (no `expectedIssuer`) | throws `ambiguous_issuers` |\n| `expectedIssuer` not advertised | throws `expected_issuer_unavailable` |\n| Committed issuer origin invalid | throws `invalid_issuer_origin` |\n| Committed AS metadata fetch fails | throws `as_fetch_failed` |\n| Committed issuer binding mismatch | throws `issuer_mismatch` |\n\nHard cases throw `DiscoverySelectionError` (with a `.reason`); soft cases return a\n`{ kind: \"fallback\", reason }`.\n\n> **Breaking-ish:** `OAuthConfig.authorizationEndpoint` is now **optional** —\n> device-only servers omit it. Authorization-code consumers must assert it before\n> use (`performInteractiveLogin` does this and errors if it is missing). Both\n> discovery hops are SSRF-hardened (HTTPS-only origins, suppressed redirects,\n> bounded body reads).\n\n### Device flow (RFC 8628)\n\nFor CLIs and headless/remote environments, use the device authorization grant\nwith the public `basecamp-cli` client (no secret). `performDeviceLogin` takes an\nalready-selected config, guards the device capability, shows the user code via a\ndisplay hook, and polls for the token:\n\nThe device authorization endpoint lives on the **first-party** authorization\nserver, not Launchpad — so select a first-party issuer with `discoverFromResource`\nand hand its config to `performDeviceLogin`. (Launchpad advertises no device\nendpoint, so `performDeviceLogin`'s capability guard rejects it with\n`DeviceFlowError(\"unavailable\")`.)\n\n```ts\nimport {\n  createBasecampClient,\n  discoverFromResource,\n  performDeviceLogin,\n  refreshToken,\n  isTokenExpired,\n  DeviceFlowError,\n} from \"@37signals/basecamp\";\n\n// 1. Select an AS config. Discovery can select a config WITHOUT the device\n//    endpoint or device_code grant — performDeviceLogin then rejects it with\n//    DeviceFlowError(\"unavailable\").\nconst result = await discoverFromResource(\"https://3.basecampapi.com\");\nif (result.kind !== \"selected\") {\n  // \"resource_discovery_failed\" | \"no_as_advertised\" → Launchpad has no device\n  // flow; use the interactive (authorization-code) login instead.\n  throw new Error(`Device flow unavailable: ${result.reason}`);\n}\n\n// 2. Run the device grant against the selected config.\nconst abortController = new AbortController();\ntry {\n  const token = await performDeviceLogin({\n    config: result.config,\n    clientId: \"basecamp-cli\",\n    // scope pinned explicitly — \"read\" is also the server default, but an\n    // explicit scope never depends on registry defaults staying put.\n    scope: \"read\",\n    display: ({ userCode, verificationUri }) => {\n      console.log(`Visit ${verificationUri} and enter code: ${userCode}`);\n    },\n    signal: abortController.signal, // optional: cancel the poll\n  });\n  // Use the token — hand it to a client or persist it via your token store.\n  // Never print the token value itself.\n  const client = createBasecampClient({\n    accountId: process.env.BASECAMP_ACCOUNT_ID!,\n    accessToken: token.accessToken,\n  });\n  // A long-lived CLI should PERSIST the whole token and mint a fresh one once it\n  // expires — a client built from a static accessToken stops working when the\n  // device access token expires. A device-token response MAY omit refresh_token,\n  // so GUARD it: refresh only when one was issued, otherwise re-run the device\n  // login to reauthenticate. Refresh hits the SAME first-party token endpoint\n  // with the standard grant (device tokens never use Launchpad's legacy\n  // `type=refresh` format):\n  if (isTokenExpired(token)) {\n    if (token.refreshToken) {\n      const fresh = await refreshToken({\n        tokenEndpoint: result.config.tokenEndpoint,\n        clientId: \"basecamp-cli\", // public client — no secret\n        refreshToken: token.refreshToken,\n        // ECHO the token's RFC 8707 resource indicator: BC5 device logins as\n        // basecamp-cli mint MULTI-ACCOUNT refresh tokens, and refreshing one\n        // without `resource` is rejected (400 invalid_request).\n        resource: token.resource,\n      });\n      // A refresh response MAY omit refresh_token (the server keeps the current\n      // one) and MAY omit resource (the binding is unchanged). Persist the fresh\n      // access token but FALL BACK to the prior values so the next refresh still\n      // works:\n      const nextRefresh = fresh.refreshToken ?? token.refreshToken;\n      const nextResource = fresh.resource ?? token.resource;\n      // ...persist { ...fresh, refreshToken: nextRefresh, resource: nextResource }\n      // and rebuild the client. (TokenManager does all of this automatically.)\n    } else {\n      // No refresh token was issued: refreshing is impossible, so the user must\n      // authorize again. Re-run the device login to get a new token — pass the\n      // SAME abort signal so Ctrl-C cancels this second poll too, and don't keep\n      // using the expired one.\n      const reauthed = await performDeviceLogin({\n        config: result.config,\n        clientId: \"basecamp-cli\",\n        display: ({ userCode, verificationUri }) => {\n          console.log(`Visit ${verificationUri} and enter code: ${userCode}`);\n        },\n        signal: abortController.signal,\n      });\n      // ...persist `reauthed` and rebuild the client from reauthed.accessToken.\n    }\n  }\n} catch (err) {\n  if (err instanceof DeviceFlowError) {\n    // err.reason: \"access_denied\" | \"expired\" | \"transport\" | \"unavailable\" | \"cancelled\"\n    // err.code (parent category) is derived from the reason:\n    //   access_denied/expired → auth_required, transport → network,\n    //   unavailable → validation, cancelled → usage\n  } else {\n    // performDeviceLogin can also reject with BasecampError (e.g. a malformed\n    // or non-2xx server response) — don't swallow those.\n    throw err;\n  }\n}\n```\n\nThe poll loop honors `interval`, sustains `slow_down` (+5s), backs off\nexponentially on connection timeouts, and enforces a monotonic expiry deadline.\n`requestDeviceAuthorization` and `pollDeviceToken` are exported for lower-level\nuse; the polling clock is injectable for testing.\n\n## Services\n\nThe SDK provides typed services for the complete Basecamp API:\n\n### Projects & Organization\n\n| Service | Methods |\n|---------|---------|\n| `projects` | list, get, create, update, trash, archive, unarchive |\n| `templates` | list, get, createProject |\n| `tools` | list, get, update |\n| `people` | list, get, me, listPingable |\n\n### To-dos\n\n| Service | Methods |\n|---------|---------|\n| `todos` | list, get, create, update, complete, uncomplete, reposition |\n| `todolists` | list, get, create, update, trash, reposition |\n| `todosets` | get |\n| `todolistGroups` | list, get, create, reposition |\n\n### Messages & Communication\n\n| Service | Methods |\n|---------|---------|\n| `messages` | list, get, create, update, pin, unpin |\n| `messageBoards` | get |\n| `messageTypes` | list, get, create, update, delete |\n| `comments` | list, get, create, update |\n| `campfires` | list, get, listLines, getLine, createLine, updateLine, deleteLine |\n\n### Card Tables (Kanban)\n\n| Service | Methods |\n|---------|---------|\n| `cardTables` | get, listColumns |\n| `cards` | list, get, create, update, move |\n| `cardColumns` | get, create, update, move |\n| `cardSteps` | list, get, create, update, complete, uncomplete |\n| `wormholes` | create, update, delete |\n\n### Scheduling\n\n| Service | Methods |\n|---------|---------|\n| `schedules` | get, listEntries, getEntry, createEntry, updateEntry, trashEntry |\n| `lineup` | create, update, delete |\n| `checkins` | get, listQuestions, getQuestion, listAnswers, getAnswer |\n\n### Files & Documents\n\n| Service | Methods |\n|---------|---------|\n| `vaults` | list, get, create, update |\n| `documents` | list, get, create, update, trash |\n| `uploads` | list, get, create, update, trash |\n| `attachments` | createUploadUrl, create |\n\n### Integrations & Events\n\n| Service | Methods |\n|---------|---------|\n| `webhooks` | list, get, create, update, delete |\n| `subscriptions` | get, subscribe, unsubscribe, update |\n| `events` | list, listForRecording |\n| `recordings` | archive, unarchive, trash |\n\n### Search & Reports\n\n| Service | Methods |\n|---------|---------|\n| `search` | search |\n| `reports` | progress, upcoming, assigned, overdue, personProgress |\n| `timesheets` | forRecording, forProject, report |\n| `timeline` | get |\n\n### Client Portal\n\n| Service | Methods |\n|---------|---------|\n| `clientApprovals` | list, get |\n| `clientCorrespondences` | list, get |\n| `clientReplies` | list, get |\n| `clientVisibility` | get, update |\n\n### Email\n\n| Service | Methods |\n|---------|---------|\n| `forwards` | list, get, listReplies, getReply |\n\n## Downloading Files\n\nFetch an upload's file content in one call. The SDK fetches the upload\nmetadata, then follows the authenticated-hop + 302 flow against the signed\nstorage URL.\n\n```ts\nconst result = await client.uploads.download(1069479400);\n// result.body is a ReadableStream<Uint8Array>\nconst bytes = new Uint8Array(await new Response(result.body).arrayBuffer());\n// result.contentType, result.contentLength, result.filename are also available\n```\n\nFor any authenticated download URL (e.g. a `download_url` you already have\nin hand), use `client.downloadURL`:\n\n```ts\nconst result = await client.downloadURL(url);\n```\n\n## Pagination\n\nService `list()` methods auto-paginate: they follow the API's `Link: rel=\"next\"` headers and return every item across all pages (up to a 10,000-page safety cap).\n\nThe result is a `ListResult<T>` — an `Array<T>` subclass that works with `for...of`, `.map()`, `.filter()`, spread, `.length`, indexing, and `Array.isArray()` — plus a `.meta` property with pagination metadata:\n\n```ts\nconst projects = await client.projects.list();\n\nconsole.log(`${projects.length} of ${projects.meta.totalCount} projects`);\nif (projects.meta.truncated) console.warn(\"more results were available\");\nprojects.forEach(p => console.log(p.name));\n```\n\n`meta.totalCount` is parsed from the `X-Total-Count` response header (0 when the header is absent). `meta.truncated` is `true` when items beyond those returned were available — more items than `maxItems` arrived, or the last-fetched page still advertised a next page (including when the page safety cap stopped pagination early); when it is `false`, the result is complete.\n\nTo bound the work, pass `maxItems` — every list options type extends `PaginationOptions`. When `maxItems` is omitted or `0`, all pages are fetched:\n\n```ts\nconst firstFifty = await client.projects.list({ maxItems: 50 });\n```\n\n### The `page` option\n\nA positive `page` selects exactly that page: one request, that page's items,\nno link-following.\n\n```ts\nconst pageThree = await client.projects.list({ page: 3 });\nconsole.log(pageThree.meta.truncated); // true when a further page existed\n```\n\nOmit `page` (or pass `0`) to auto-paginate the whole collection. `maxItems`\nstill trims a pinned page.\n\nAll six SDKs share these semantics — one request, that page only, no\nlink-following. See SPEC section 8.\n\nFor endpoints not covered by a service, drive pagination yourself over a raw `client.GET` response with `fetchAllPages` (collects all pages into one array) or `paginateAll` (async generator that yields one page at a time):\n\n```ts\nimport { fetchAllPages, paginateAll } from \"@37signals/basecamp\";\n\nconst initial = await client.GET(\"/projects.json\");\n\n// Option 1: fetchAllPages - returns all results as an array\nconst all = await fetchAllPages(initial.response, (r) => r.json() as Promise<any[]>);\n\n// Option 2: paginateAll - async generator for streaming large result sets\nfor await (const page of paginateAll(initial.response, (r) => r.json() as Promise<any[]>)) {\n  for (const project of page) {\n    console.log(project.name);\n  }\n}\n```\n\n## Low-Level API Access\n\nFor endpoints not covered by services or advanced use cases, use the raw typed client:\n\n```ts\n// Direct API calls with full type inference\nconst { data, error, response } = await client.GET(\"/projects.json\");\n\nif (error) {\n  console.error(\"Failed:\", error);\n} else {\n  console.log(data.map((p) => p.name));\n}\n\n// With path parameters\nconst { data: project } = await client.GET(\"/projects/{projectId}\", {\n  params: { path: { projectId: 12345 } },\n});\n\n// POST with body\nconst { data: newProject } = await client.POST(\"/projects.json\", {\n  body: { name: \"My Project\", description: \"A new project\" },\n});\n```\n\n## Error Handling\n\nThe SDK provides structured errors with codes, hints, and exit codes for CLI applications:\n\n```ts\nimport { BasecampError, isBasecampError, isErrorCode } from \"@37signals/basecamp\";\n\ntry {\n  await client.todos.get(todoId);\n} catch (err) {\n  if (isBasecampError(err)) {\n    console.error(`Error [${err.code}]: ${err.message}`);\n\n    if (err.hint) {\n      console.error(`Hint: ${err.hint}`);\n    }\n\n    if (err.retryable && err.retryAfter) {\n      console.log(`Retry after ${err.retryAfter} seconds`);\n    }\n\n    // Use exit codes for CLI applications\n    process.exit(err.exitCode);\n  }\n  throw err;\n}\n```\n\n### Error Codes\n\n| Code | HTTP Status | Exit Code | Description |\n|------|-------------|-----------|-------------|\n| `auth_required` | 401 | 3 | Authentication required |\n| `forbidden` | 403 | 4 | Access denied |\n| `not_found` | 404 | 2 | Resource not found |\n| `rate_limit` | 429 | 5 | Rate limit exceeded (retryable) |\n| `network` | - | 6 | Network error (retryable) |\n| `api_error` | 500, 502, 503, 504, other 5xx | 7 | Server error |\n| `ambiguous` | - | 8 | Multiple matches found |\n| `validation` | 400, 422 | 9 | Invalid request data |\n| `limit_exceeded` | 507 | 10 | Account limit reached (file storage, projects, webhooks) — never retryable |\n| `usage` | - | 1 | Configuration or argument error |\n\n### Validation Errors\n\nBasecamp rejects invalid writes with a body keyed by field. The SDK folds those\nmessages into `message` and keeps the raw map in `fieldErrors`, so you can drive\na form without re-parsing the message:\n\n```typescript\ntry {\n  await client.calendars.updateCalendar(calendarId, { calendar: { color: \"chartreuse\" } });\n} catch (error) {\n  if (isErrorCode(error, \"validation\")) {\n    // \"color: is not a valid color\"\n    console.error(error.message);\n\n    for (const [field, messages] of Object.entries(error.fieldErrors ?? {})) {\n      console.error(`  ${field}: ${messages.join(\", \")}`);\n    }\n  }\n}\n```\n\n`fieldErrors` is `undefined` for every other error shape, and its messages are\nthe raw ones — `message` is capped at 500 characters, the map is not. It is a\nnull-prototype object, so a field literally named `__proto__` is an ordinary\nkey.\n\n## Retry Behavior\n\nThe SDK automatically retries requests on transient failures:\n\n- **Retryable errors**: 429 (rate limit) and 503 (service unavailable)\n- **Backoff**: Exponential with jitter\n- **Rate limits**: Respects `Retry-After` header\n- **Max retries**: 3 attempts by default\n\nDisable retry for specific use cases:\n\n```ts\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  enableRetry: false,\n});\n```\n\n## Caching\n\nThe SDK can do ETag-based HTTP caching to reduce API calls and respect Basecamp's rate limits, but it is **off by default** — `enableCache` defaults to `false`, and a client built without it sends no `If-None-Match` and stores no responses. Opt in:\n\n```ts\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  enableCache: true,\n});\n\n// First request fetches from the API and stores the ETag\nconst projects = await client.projects.list();\n\n// Second request revalidates with If-None-Match; a 304 is served from the store\nconst projects2 = await client.projects.list();\n```\n\nThe store is in-memory and per-client — it lives and dies with the client instance — holds at most 1,000 entries, and is keyed by URL plus a hash of the `Authorization` header, so a refreshed or swapped token never reads another token's entries.\n\n## Observability\n\n### Console Logging\n\nFor debugging or verbose CLI modes:\n\n```ts\nimport { createBasecampClient, consoleHooks } from \"@37signals/basecamp\";\n\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  hooks: consoleHooks({\n    logOperations: true,\n    logRequests: true, // More verbose\n    logRetries: true,\n    minDurationMs: 100, // Only log slow requests\n  }),\n});\n```\n\nOutput:\n```\n[Basecamp] Projects.List\n[Basecamp] -> GET https://3.basecampapi.com/12345/projects.json\n[Basecamp] <- GET https://3.basecampapi.com/12345/projects.json 200 (145ms)\n[Basecamp] Projects.List completed (147ms)\n```\n\n### Custom Hooks\n\nImplement the `BasecampHooks` interface for custom observability:\n\n```ts\nimport type { BasecampHooks } from \"@37signals/basecamp\";\n\nconst metricsHooks: BasecampHooks = {\n  onOperationStart(info) {\n    metrics.startTimer(`${info.service}.${info.operation}`);\n  },\n\n  onOperationEnd(info, result) {\n    metrics.recordDuration(`${info.service}.${info.operation}`, result.durationMs);\n    if (result.error) {\n      metrics.incrementError(`${info.service}.${info.operation}`);\n    }\n  },\n\n  onRetry(info, attempt, error, delayMs) {\n    logger.warn(`Retrying ${info.method} ${info.url} (attempt ${attempt})`);\n  },\n};\n\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  hooks: metricsHooks,\n});\n```\n\n### OpenTelemetry Integration\n\nFor distributed tracing and metrics:\n\n```ts\nimport { createBasecampClient, otelHooks } from \"@37signals/basecamp\";\nimport { trace, metrics } from \"@opentelemetry/api\";\n\nconst tracer = trace.getTracer(\"my-app\");\nconst meter = metrics.getMeter(\"my-app\");\n\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  hooks: otelHooks({\n    tracer,\n    meter,\n    recordRequestSpans: true, // Include HTTP-level spans\n  }),\n});\n```\n\nCreates spans and metrics:\n- `basecamp.operation.duration` - Histogram of operation durations\n- `basecamp.operations.total` - Counter of operations\n- `basecamp.errors.total` - Counter of errors\n- `basecamp.retries.total` - Counter of retry attempts\n\n### Combining Multiple Hooks\n\n```ts\nimport { chainHooks, consoleHooks, otelHooks } from \"@37signals/basecamp\";\n\nconst client = createBasecampClient({\n  accountId: \"12345\",\n  accessToken: \"token\",\n  hooks: chainHooks(\n    consoleHooks(),\n    otelHooks({ tracer, meter }),\n    myCustomHooks,\n  ),\n});\n```\n\n## Examples\n\n### Working with Todos\n\n```ts\n// List todos in a todolist\nconst todos = await client.todos.list(todolistId);\n\n// Create a todo with assignees\nconst todo = await client.todos.create(todolistId, {\n  content: \"Review pull request\",\n  description: \"<p>Check the new auth flow</p>\",\n  dueOn: \"2026-02-01\",\n  assigneeIds: [12345, 67890],\n});\n\n// Complete a todo\nawait client.todos.complete(todo.id);\n\n// Reposition a todo to the top\nawait client.todos.reposition(todo.id, { position: 1 });\n```\n\n### Working with Messages\n\n```ts\n// Get a message board\nconst board = await client.messageBoards.get(boardId);\n\n// List messages\nconst messages = await client.messages.list(board.id);\n\n// Create a message\nconst msg = await client.messages.create(board.id, {\n  subject: \"Weekly Update\",\n  content: \"<p>Here's what we accomplished...</p>\",\n});\n\n// Pin a message\nawait client.messages.pin(msg.id);\n```\n\n### Working with Campfire\n\n```ts\n// List campfires\nconst campfires = await client.campfires.list();\n\n// Send a message\nawait client.campfires.createLine(campfireId, {\n  content: \"Hello, team!\",\n});\n\n// List recent messages\nconst lines = await client.campfires.listLines(campfireId);\n```\n\n### Working with Webhooks\n\n```ts\nconst bucketId = 12345; // project/bucket ID\n\n// Create a webhook\nconst webhook = await client.webhooks.create(bucketId, {\n  payloadUrl: \"https://example.com/webhook\",\n  types: [\"Todo\", \"Comment\"],\n});\n\n// List webhooks\nconst webhooks = await client.webhooks.list(bucketId);\n\n// Delete a webhook\nawait client.webhooks.delete(webhook.id);\n```\n\n## TypeScript Types\n\nAll types are exported for use in your code:\n\n```ts\nimport type {\n  Project,\n  Todo,\n  Message,\n  Person,\n  CreateTodoRequest,\n  BasecampError,\n  ErrorCode,\n} from \"@37signals/basecamp\";\n\nfunction processTodo(todo: Todo): void {\n  console.log(todo.content);\n}\n\nfunction createTodo(data: CreateTodoRequest): Promise<Todo> {\n  return client.todos.create(todolistId, data);\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Generate types from OpenAPI spec\nnpm run generate\n\n# Build\nnpm run build\n\n# Run tests\nnpm test\n\n# Type check (src via tsconfig.json, then tests and scripts via tsconfig.test.json)\nnpm run typecheck\n\n# Lint\nnpm run lint\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}