{"_id":"@dlwiest/ts-tonal-client","_rev":"11-7e51564b74ebb56d8d7378fd0b99136f","name":"@dlwiest/ts-tonal-client","dist-tags":{"latest":"0.6.0"},"versions":{"0.0.1":{"name":"@dlwiest/ts-tonal-client","version":"0.0.1","keywords":[],"author":"","license":"ISC","_id":"@dlwiest/ts-tonal-client@0.0.1","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"5111a2c5e28d2e1cfeb63363cbfe42fb5d513be9","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.0.1.tgz","fileCount":8,"integrity":"sha512-8fhvuH+U02qoFTDo7nHrW8pMu6GBimfjpyn7296bNUuUJrDtVKI6/NemaeAPLT0YkkWbv0pc27R0+/BKJLXGtg==","signatures":[{"sig":"MEUCIBR9cGvFbRDbsSRdCdBFWqGfzCovkRBqwGDAwCTKKR63AiEAmRPR6WL/CCtYqO1kQ2OkZcnJLWNXIIY86CxXGT9nF9k=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":23283},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","gitHead":"5830b7e53fe2287ce902d977e87d97448b901010","scripts":{"build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"10.8.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.4.0","_hasShrinkwrap":false,"devDependencies":{"tslib":"^2.7.0","rollup":"^3.20.2","ts-node":"^10.9.2","typescript":"^5.5.4","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.0.1_1725249653274_0.12752309300548847","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"@dlwiest/ts-tonal-client","version":"0.1.0","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"ISC","_id":"@dlwiest/ts-tonal-client@0.1.0","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"4189cf79475b21d828279c42a79313df3d1d66b1","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.1.0.tgz","fileCount":51,"integrity":"sha512-ymqqGACxm80WXVc0ZBTmlxzy8xt9LiL/2Uj0lNiNLGo3LxLht48gkRmkhVojGSL7a28qki3wdyY3PWHVkCgS2Q==","signatures":[{"sig":"MEUCIQDAN0QxH3TFtsBQrgg7A+PSUq4RHz/CUoaUrtXjvpy0rAIgAx3sqwEpiSnN5LVNgwTJqK8e+sHf6DHhL2Zr98iBUYw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110382},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js"}},"gitHead":"63999782429d7472d5d447f2bd37147d9c866d1c","scripts":{"dev":"tsc --watch --noEmit","build":"rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","prepublishOnly":"npm run typecheck && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-node":"^10.9.2","typescript":"^5.5.4","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.1.0_1761786488537_0.25556768270266605","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dlwiest/ts-tonal-client","version":"0.1.1","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"ISC","_id":"@dlwiest/ts-tonal-client@0.1.1","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"d0d962b20496d355f74878fab03ebda4b5445cd7","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.1.1.tgz","fileCount":51,"integrity":"sha512-mPMUAe+b1za6DJyrkDXkQyeX8R+ww3TxU3hufaU1nyU181N4Y193+ym6EjjiYYqLks7kxbQ20cyNxaRlaZ9Glg==","signatures":[{"sig":"MEYCIQDeYNqAdIAonVbTTncTw+ysX5ZvLUmDGyO7PwUrD5mCpwIhAIajcO7VveC58jwo+UBgxySAD9wyf8+wh1qtYwUe6DE5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116236},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js"}},"gitHead":"ef628bbfa3e1f6315c147cc754872e8ce84e7aa4","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.1.1_1762147635920_0.4896963743806859","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@dlwiest/ts-tonal-client","version":"0.2.0","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"ISC","_id":"@dlwiest/ts-tonal-client@0.2.0","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"e2943760e8e1496c65218b13f2f8dc60ac027995","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.2.0.tgz","fileCount":50,"integrity":"sha512-oRctgMkRPFZIZ2w1VijsX6F7C29E6vzUHpac6Cjjo3nXQEJbiEY/QOJFp9XcigW0AGV+NhRET16RVTyTRO1z8g==","signatures":[{"sig":"MEUCIGvWMCtzNqxUO8ANbJs8o/dbSJ43MBsT+rkfyk1UFsVHAiEAouj55pNfyo/dlC6vSoEs5skCRdkPSvWsaAQBbzUCSoI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118300},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js"}},"gitHead":"af23f202166e2679ce0fe65420f5b2a77427f690","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.2.0_1763234851809_0.4345759361022352","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@dlwiest/ts-tonal-client","version":"0.2.1","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"ISC","_id":"@dlwiest/ts-tonal-client@0.2.1","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"c9cc571d7398737e20fcdf19ee415786645635ef","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.2.1.tgz","fileCount":51,"integrity":"sha512-TFXVPmxSa3/g5HpSVXS2NmO11cxy8ZrTDsZ5hWGVQXkj9GDk1Zvoatl4zi099/HInXeD9Qi2q5OjPdiP1P/+zg==","signatures":[{"sig":"MEUCIF21i+7MLgTjxelH71EHAa6E7y8u6QFhjQ7YEJuaXbBVAiEAtowpiumwEbxHy0wf+Y+6+x89Mh5o+A+S0zarhR1K0po=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118793},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js"}},"gitHead":"331cade5d7c759b3cadb44eade997c969e3a2b92","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.2.1_1763438802004_0.03898841305350853","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@dlwiest/ts-tonal-client","version":"0.3.0","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","_id":"@dlwiest/ts-tonal-client@0.3.0","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"3afd14726aab66c560671bfde74d5483aca53e14","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.3.0.tgz","fileCount":6,"integrity":"sha512-1lO1IYIpDl2TVUPP/qE+8ZtWU1fTgdsGzbvSNNgD2t/EOve659k/9MrvrxbHaBXEzMGeGD9tj6l5M4nuvBzOXQ==","signatures":[{"sig":"MEUCIBjbzQry0n4t55Cff+NvBGDFPq59R5O3cgSlcfmlo/tIAiEAo7r8zrvtuPqfkUf01TCkW5RsXuOxfxZAbjuV3wixEc8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95225},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"gitHead":"bdf47d4ddeb6592b3a385a56ab3beb76e4107058","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.3.0_1786807179628_0.9573219925373622","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@dlwiest/ts-tonal-client","version":"0.3.1","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","_id":"@dlwiest/ts-tonal-client@0.3.1","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"3ee882ec18f2fef77b7819a4c37f41947d13e556","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.3.1.tgz","fileCount":6,"integrity":"sha512-GmJut7kWduBhlPVp55HuwAIFXFgSRbgt7KcU9UR+ebnwva+YgR3tdiym7xVcSEH8s2ScP+Ac0CCiC4nm4kPmQQ==","signatures":[{"sig":"MEYCIQCCR9UzMKBjkTt/41YOGFhPwKcY20UBnZVzT6uDATiW4QIhAOwth7yJLZv3BdHC6xwgnQ20S+BHH4v/NTA6fEwy5TSj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95217},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"gitHead":"be15b432baf05ca14ec5657ae96efd48f17e4243","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.3.1_1787600241735_0.6521917839335216","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@dlwiest/ts-tonal-client","version":"0.4.0","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","_id":"@dlwiest/ts-tonal-client@0.4.0","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"03432b6f4a1282ef57f5ca93f6c16a6949f44062","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.4.0.tgz","fileCount":6,"integrity":"sha512-HDIBzgBq157j+EflI5KmRCvGfQsbRMKZB0JyX4lvo/NBMNrvDPMlwXIBL7Grgu/NuEloKipPRG1fVgnRN1d5+g==","signatures":[{"sig":"MEUCIQD7NfhVU2OrTQMMwfO1G6N5qAHqNqAnkhxUWGvHE5b1kAIgEHA6eQMD6RzgumBszi/e7iRFIbFcDdNGAjQ0/2tGUyE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102383},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"gitHead":"bd6c20c4c353bc7a5cee3750fafd2e460586d9df","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.4.0_1787710752879_0.6057593361959133","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@dlwiest/ts-tonal-client","version":"0.5.0","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","_id":"@dlwiest/ts-tonal-client@0.5.0","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"9ffc8ca4c80b46b553c2a469dbdce215c78232e0","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.5.0.tgz","fileCount":6,"integrity":"sha512-F4hOjA7m4Apim5g1OVBuC5J+QEt4qzT2JTQ2pghqpZUCUCXKK2iFV1uwakA1PJ78svskn3DJaJJJQD60A5YpdQ==","signatures":[{"sig":"MEUCIQD9iii1wSe0LpleCEapzU1ahh1EirFQB/BTGebO6FFNGAIgfuv/jKMSUKIXeJDSn6bqkZJPlQmGwFvIkE+qJEJGGZg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113716},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"gitHead":"cbe040433795c37f8bd943f05bba4518214c7c15","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:workout-activity":"tsx examples/get-workout-activity.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.5.0_1788315814579_0.676994660748292","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@dlwiest/ts-tonal-client","version":"0.5.1","keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","_id":"@dlwiest/ts-tonal-client@0.5.1","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"dist":{"shasum":"de0eda99f05b6b54211bd05ef0ca613646eefe66","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.5.1.tgz","fileCount":6,"integrity":"sha512-7/qjIIwRK7LDjxp/Y7AQQLKBZ8z1P8Gyw7FUEI11g6fZ96dmfkFIXzpRaDFIufjjrO3+fa6xXauwPQdVo25Svg==","signatures":[{"sig":"MEUCICekIjKkM1Mqvwnn3NTjxPQDvPGbHrcDyhPehBc17RmZAiEAi/KCT8WeiAHh7/T+pLTiOOYPzelBChSQWiSBmwRxjnE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115488},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"gitHead":"a32d95af0cee509a9c4fddcc0b7cbda3ff9a351b","scripts":{"dev":"tsc --watch --noEmit","test":"jest","build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","test:watch":"jest --watch","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:estimate":"tsx examples/estimate-workout.ts","example:movements":"tsx examples/get-movements.ts","example:workout:id":"tsx examples/get-workout-by-id.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:achievements":"tsx examples/get-achievements.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:create-workout":"tsx examples/create-workout.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:training-types":"tsx examples/get-training-types.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:workout-activity":"tsx examples/get-workout-activity.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts"},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"repository":{"url":"git+https://github.com/dlwiest/ts-tonal-client.git","type":"git"},"_npmVersion":"11.4.1","description":"TypeScript client for Tonal API","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","jest":"^30.2.0","tslib":"^2.7.0","dotenv":"^16.4.5","rollup":"^3.20.2","ts-jest":"^29.4.5","ts-node":"^10.9.2","typescript":"^5.5.4","@types/jest":"^30.0.0","@types/node":"^20.14.8","rollup-plugin-dts":"^5.3.1","@rollup/plugin-typescript":"^11.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ts-tonal-client_0.5.1_1788316187410_0.8326845588434151","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@dlwiest/ts-tonal-client","version":"0.6.0","description":"TypeScript client for Tonal API","main":"dist/index.cjs","module":"dist/index.esm.js","types":"dist/index.d.ts","type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs"}},"scripts":{"build":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && rollup -c --bundleConfigAsCjs","typecheck":"tsc --noEmit","dev":"tsc --watch --noEmit","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","prepublishOnly":"npm run typecheck && npm run test && npm run build","example:movements":"tsx examples/get-movements.ts","example:movements:save":"tsx examples/get-movements.ts --save","example:workout:id":"tsx examples/get-workout-by-id.ts","example:workout:name":"tsx examples/get-workout-by-name.ts","example:workout:share":"tsx examples/get-workout-by-share-url.ts","example:user":"tsx examples/get-user-info.ts","example:goals":"tsx examples/get-goals.ts","example:user-workouts":"tsx examples/get-user-workouts.ts","example:estimate":"tsx examples/estimate-workout.ts","example:create-workout":"tsx examples/create-workout.ts","example:edit-workout":"tsx examples/edit-workout.ts","example:delete-workout":"tsx examples/delete-workout.ts","example:daily-lifts":"tsx examples/get-daily-lifts.ts","example:training-effect-goals":"tsx examples/get-training-effect-goals.ts","example:training-types":"tsx examples/get-training-types.ts","example:goal-metrics":"tsx examples/get-goal-metrics.ts","example:user-settings":"tsx examples/get-user-settings.ts","example:daily-metrics":"tsx examples/get-daily-metrics.ts","example:current-streak":"tsx examples/get-current-streak.ts","example:activity-summaries":"tsx examples/get-activity-summaries.ts","example:user-statistics":"tsx examples/get-user-statistics.ts","example:achievement-stats":"tsx examples/get-achievement-stats.ts","example:achievements":"tsx examples/get-achievements.ts","example:home-calendar":"tsx examples/get-home-calendar.ts","example:muscle-readiness":"tsx examples/get-muscle-readiness.ts","example:program-by-id":"tsx examples/get-program-by-id.ts","example:target-scores":"tsx examples/get-target-scores.ts","example:metric-scores":"tsx examples/get-metric-scores.ts","example:workout-activity":"tsx examples/get-workout-activity.ts","example:health-export":"tsx examples/export-health-data.ts","example:complete-health-export":"tsx examples/export-complete-health-data.ts"},"repository":{"type":"git","url":"git+https://github.com/dlwiest/ts-tonal-client.git"},"keywords":["tonal","tonal-api","typescript","client"],"author":{"name":"dlwiest"},"license":"MIT","bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"homepage":"https://github.com/dlwiest/ts-tonal-client#readme","devDependencies":{"@rollup/plugin-typescript":"^11.1.0","@types/jest":"^30.0.0","@types/node":"^20.14.8","dotenv":"^16.4.5","jest":"^30.2.0","rollup":"^3.20.2","rollup-plugin-dts":"^5.3.1","ts-jest":"^29.4.5","ts-node":"^10.9.2","tslib":"^2.7.0","tsx":"^4.20.6","typescript":"^5.5.4"},"_id":"@dlwiest/ts-tonal-client@0.6.0","gitHead":"08c41bc936fd4a451a49da0faa2c498c337d7311","_nodeVersion":"22.16.0","_npmVersion":"11.4.1","dist":{"integrity":"sha512-lE3i3IQGq2mW7E00wJ7DzwPunyhb3JrKtCKjp6s8co0AzrRbRmytgQzc9GpckkobZ/rYvoqrT2EMBs0bV7ITSw==","shasum":"d2ca2a2d1c7bcb7eebfacb01deff4b0e4269d0b0","tarball":"https://registry.npmjs.org/@dlwiest/ts-tonal-client/-/ts-tonal-client-0.6.0.tgz","fileCount":6,"unpackedSize":167740,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFZT0192CNYeJiYQYH1F/5qT6fVt56lzOnE5cX1G84LaAiBgbOn9eMncI/iW2BSUzP/pvvAgODZd4490LYeJBhljSQ=="}]},"_npmUser":{"name":"dlwiest","email":"me@dlwiest.com"},"directories":{},"maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ts-tonal-client_0.6.0_1788357144193_0.2718484888463766"},"_hasShrinkwrap":false}},"time":{"created":"2024-09-02T04:00:53.190Z","modified":"2026-09-02T13:52:24.906Z","0.0.1":"2024-09-02T04:00:53.455Z","0.1.0":"2025-10-30T01:08:08.764Z","0.1.1":"2025-11-03T05:27:16.138Z","0.2.0":"2025-11-15T19:27:32.007Z","0.2.1":"2025-11-18T04:06:42.206Z","0.3.0":"2026-08-15T15:19:39.774Z","0.3.1":"2026-08-24T19:37:21.874Z","0.4.0":"2026-08-26T02:19:13.035Z","0.5.0":"2026-09-02T02:23:34.710Z","0.5.1":"2026-09-02T02:29:47.517Z","0.6.0":"2026-09-02T13:52:24.333Z"},"bugs":{"url":"https://github.com/dlwiest/ts-tonal-client/issues"},"author":{"name":"dlwiest"},"license":"MIT","homepage":"https://github.com/dlwiest/ts-tonal-client#readme","keywords":["tonal","tonal-api","typescript","client"],"repository":{"type":"git","url":"git+https://github.com/dlwiest/ts-tonal-client.git"},"description":"TypeScript client for Tonal API","maintainers":[{"name":"dlwiest","email":"me@dlwiest.com"}],"readme":"# TypeScript Tonal Client\n\n[![npm version](https://badge.fury.io/js/@dlwiest%2Fts-tonal-client.svg)](https://badge.fury.io/js/@dlwiest%2Fts-tonal-client)\n[![npm downloads](https://img.shields.io/npm/dm/@dlwiest/ts-tonal-client.svg)](https://www.npmjs.com/package/@dlwiest/ts-tonal-client)\n\nA TypeScript client for working with data from a Tonal account. It wraps\nauthentication, workout and movement APIs, completed performance data, recovery\nmetrics, programs, goals, and personal health-data exports in a typed interface.\n\n> [!IMPORTANT]\n> This is an unofficial community project. It is not affiliated with or\n> supported by Tonal, and the private APIs it uses may change without notice.\n\n## Product Overview\n\nThe client is meant for personal tools, data exports, and applications that need\nmore Tonal detail than a general fitness integration may provide. In particular,\nit can retrieve performed set data—movements, reps, weight, volume, training\nmodes, timing, and estimated one-rep max—and combine it with workout summaries,\nmuscle readiness, and lifetime totals.\n\nOne intended workflow is to create a privacy-conscious JSON snapshot and upload\nit to an AI assistant such as ChatGPT for personal health analysis. This is a\nfile-based bridge, not a live or automatic ChatGPT connection: generate a new\nexport whenever the assistant needs current Tonal data.\n\n## Product Features\n\n| Area | Current capabilities |\n| --- | --- |\n| Authentication | Sign in with Tonal account credentials and automatically manage access-token refresh |\n| Workout library | List, retrieve, create, update, delete, share, and estimate workouts; retrieve Daily Lifts |\n| Completed performance | Retrieve activity summaries, paginated workout history, and individual workout details including performed sets, reps, weights, volume, timing, training modes, and estimated one-rep max |\n| Movements and programs | Browse Tonal movements and muscle groups and retrieve detailed training programs |\n| Training and recovery | Retrieve daily metrics, streaks, muscle readiness, weekly targets, and actual metric scores |\n| History and achievements | Retrieve lifetime statistics, achievement progress, earned achievements, and home-calendar recommendations |\n| Health data export | Produce date-filtered JSON with aggregate totals, optional recovery and lifetime data, and optional set-level workout details |\n| Developer experience | TypeScript response types, request validation, retries, timeouts, movement caching, and runnable examples |\n\n## Current Limitations\n\n- Tonal does not publish or guarantee the private APIs used by this project.\n- Authentication currently requires Tonal account credentials; never commit a\n  populated `.env` file or include credentials in an export.\n- Health exports are point-in-time files. They do not continuously synchronize\n  Tonal with ChatGPT or another health service.\n- Detailed exports fetch paginated workout activity data, so large account\n  histories may require additional requests and take longer.\n- Tonal reports average resistance per cable. The export preserves that value\n  and derives effective average resistance from Tonal's total on-machine volume\n  divided by completed reps, correctly accounting for dual-cable movements such\n  as straight-bar lifts.\n\n## Installation\n\n### Option 1: Install from npm (Recommended)\n\n```bash\nnpm install @dlwiest/ts-tonal-client\n```\n\n### Option 2: Clone and build from source\n\n```bash\ngit clone https://github.com/dlwiest/ts-tonal-client.git\ncd ts-tonal-client\nnpm install\nnpm run build\n```\n\n## Quick Start\n\nBasic usage:\n\n```typescript\nimport TonalClient from '@dlwiest/ts-tonal-client'\n\nconst client = await TonalClient.create({\n  username: 'your_email@example.com',\n  password: 'your_password',\n})\n\n// Get your workouts\nconst workouts = await client.getUserWorkouts()\nconsole.log(`You have ${workouts.length} workouts`)\n```\n\n### Client setup\n\n`TonalClient.create()` accepts credentials and an optional cache directory:\n\n```typescript\nTonalClient.create(credentials: {\n  username: string,\n  password: string,\n  cacheDir?: string,\n}): Promise<TonalClient>\n```\n\nWithout `cacheDir`, cached movements and completed workout activities are stored in `$XDG_CACHE_HOME/ts-tonal-client` when `XDG_CACHE_HOME` is set. Otherwise, the cache lives at `~/.cache/ts-tonal-client`. The directory is created on the first successful cache write, not when the client is created.\n\nPass `cacheDir` to store both caches somewhere else:\n\n```typescript\nconst client = await TonalClient.create({\n  username: 'your_email@example.com',\n  password: 'your_password',\n  cacheDir: '/path/to/cache',\n})\n```\n\n### Cache invalidation\n\n`await client.invalidateMovementsCache()` clears the movements cache only. It does not clear cached workout activities.\n\n`client.invalidateUserInfo()` clears the in-memory user profile. Call it before the next `getUserInfo()` request to fetch fresh data.\n\n## Examples\n\nTo run the example scripts, first create a `.env` file:\n\n```bash\ncp .env.sample .env\n# Edit .env with your Tonal username (email) and password\n```\n\nThen try the examples:\n\n```bash\n# See all your workouts\nnpm run example:user-workouts\n\n# Search for workouts by name\nnpm run example:workout:name \"Upper Body\"\n\n# Get your user info\nnpm run example:user\n\n# Browse available movements\nnpm run example:movements\n\n# See fitness goals\nnpm run example:goals\n\n# Estimate workout duration\nnpm run example:estimate\n\n# Create a new workout\nnpm run example:create-workout\n\n# Edit an existing workout\nnpm run example:edit-workout\n\n# Delete a workout\nnpm run example:delete-workout\n\n# Get daily lifts\nnpm run example:daily-lifts\n\n# Get training effect goals\nnpm run example:training-effect-goals\n\n# Get training types\nnpm run example:training-types\n\n# Get user settings\nnpm run example:user-settings\n\n# Get daily metrics\nnpm run example:daily-metrics\n\n# Get current workout streak\nnpm run example:current-streak\n\n# Get workout activity history\nnpm run example:activity-summaries\n\n# Get lifetime user statistics\nnpm run example:user-statistics\n\n# Get achievement stats and milestones\nnpm run example:achievement-stats\n\n# Get earned achievement history\nnpm run example:achievements\n\n# Get home calendar and workout recommendations\nnpm run example:home-calendar\n\n# Get muscle readiness and recovery status\nnpm run example:muscle-readiness\n\n# Get detailed program information by ID\nnpm run example:program-by-id\n\n# Get weekly fitness targets and progress tracking\nnpm run example:target-scores\n\n# Get actual performance scores vs targets with comprehensive analytics\nnpm run example:metric-scores\n\n# Export workout summaries for personal health analysis\nnpm run example:health-export\n\n# Export complete Tonal history and all available health metrics\nnpm run example:complete-health-export\n```\n\n## Health Data Export\n\nCreate a JSON-ready export containing workout summaries, aggregate totals, current\nmuscle readiness, and lifetime statistics:\n\n```typescript\nimport { writeFile } from 'node:fs/promises'\n\nconst exportData = await client.getHealthExport({\n  startDate: '2026-01-01',\n  limit: 100,\n  includeSetDetails: true,\n})\n\nawait writeFile(\n  'tonal-health-export.json',\n  JSON.stringify(exportData, null, 2)\n)\n```\n\nRun `npm run example:health-export` to write a compact export of the 50 most\nrecent Tonal workouts to `tonal-health-export.json`. The example atomically\nreplaces the file with owner-only permissions and refuses symbolic-link\ndestinations.\n\nThe export intentionally excludes profile details, account identifiers, device\nidentifiers, application versions, and authentication data. It still contains\nprivate health and workout information, so store and share it carefully.\n\nAvailable options:\n\n- `startDate` and `endDate`: include activities within an ISO-8601 range;\n  date-only values use each workout's local calendar day\n- `limit`: include at most this many activities, newest first\n- `includeMuscleReadiness`: include current readiness data (default: `true`)\n- `includeLifetimeStatistics`: include lifetime aggregate data (default: `true`)\n- `includeExternalActivities`: include workouts imported into Tonal from another\n  service (default: `false`, preventing duplication with Apple Health data)\n- `includeSetDetails`: fetch performed sets, reps, weights, movement names, and\n  one-rep-max estimates from paginated workout activity data (default: `false`)\n\nSet details keep Tonal's reported per-cable values in\n`averageResistancePerCablePounds` and\n`estimatedOneRepMaxPerCablePounds`. Arithmetic derived from total volume and\ncompleted reps is separated under `derivedEstimates`, with\n`averageResistancePounds` and `oneRepMaxPounds` explicitly documented as\nestimates rather than measured values. `totalVolumePounds` uses Tonal's\n`totalOnMachineVolume`, which reconciles with the completed workout's total\nvolume.\n\nDetailed completed workouts are also available directly:\n\n```typescript\n// Get a page of completed activities with performed set data\nconst activities = await client.getWorkoutActivities(0, 100)\n\n// Get every activity, with duplicate-page and page-cap safety checks\nconst completeHistory = await client.getAllWorkoutActivities()\n\n// Get one completed activity by its activity ID\nconst activity = await client.getWorkoutActivityById('activity-uuid')\nconsole.log(activity.workoutSetActivity)\n\n// Get the summary returned for one activity\nconst summary = await client.getFormattedWorkoutSummary('activity-uuid')\n\n// Get summaries in bounded request batches\nconst summaries = await client.getFormattedWorkoutSummaries(\n  completeHistory.map(item => item.id),\n  5\n)\n```\n\n### Complete History Export\n\nRun `npm run example:complete-health-export` to retrieve every paginated Tonal\nworkout from the beginning of the account history. The resulting\n`tonal-complete-health-export.json` includes raw set-performance metrics,\nformatted workout and movement summaries, full daily metrics for the covered\nperiod, strength-score history, weekly targets and scores, current readiness,\nstreaks, lifetime statistics, achievements, and reference definitions.\n\nThe complete export is structured as JSON for analysis tools such as ChatGPT.\nIt includes a data dictionary explaining units and Tonal's per-cable resistance\nconvention. Account, device, application, subscription, and authentication\nidentifiers and user weight are removed recursively. The JSON is compacted to\nreduce upload size and text-token usage without dropping allowed data. The file\nstill contains highly private health information and is atomically replaced\nwith owner-only permissions.\n\nThe script also atomically recreates a private `tonal-chatgpt-export` directory\ncontaining `overview-and-metrics.json` and one `workouts-YYYY.json` file for\neach year in the history, so files from an older export cannot survive a rerun.\nUpload every file listed by `overview-and-metrics.json` together. The split\nbundle contains the same information but keeps each text file smaller and\neasier for ChatGPT to analyze completely.\n\n## API Reference\n\n### Workouts\n\n```typescript\n// Get your workouts (with pagination)\nconst workouts = await client.getUserWorkouts(0, 10)\nconsole.log(`You have ${workouts.length} workouts`)\n\n// Get daily lifts (auto-detects timezone)\nconst dailyLifts = await client.getDailyLifts()\nconsole.log(`You have ${dailyLifts.length} daily lifts`)\n\n// Get daily lifts with specific timezone\nconst dailyLiftsEST = await client.getDailyLifts('America/New_York')\n\n// Get specific workout details\nconst workout = await client.getWorkoutById('workout-uuid')\n\n// Search for workouts by name (case-insensitive partial match)\nconst workouts = await client.getUserWorkouts(0, 50)\nconst matches = workouts.filter(w =>\n  w.title.toLowerCase().includes('upper body')\n)\nconsole.log(`Found ${matches.length} matching workouts`)\n\n// Get shared workout\nconst sharedWorkout = await client.getWorkoutByShareUrl('https://share.tonal.com/workout/...')\n\n// Estimate workout duration\nconst sets = [/* workout sets */]\nconst estimate = await client.estimateWorkoutDuration(sets)\nconsole.log(`Estimated duration: ${estimate.duration} seconds`)\n\n// Create a new workout\nconst newWorkout = await client.createWorkout({\n  title: 'My Custom Workout',\n  sets: sets,\n  createdSource: 'WorkoutBuilder',\n  description: 'A great workout!'\n})\n\n// Edit an existing workout\nconst updatedWorkout = await client.updateWorkout({\n  id: 'workout-uuid',\n  title: 'My Updated Workout Title',\n  description: 'Updated description with changes',\n  coachId: '00000000-0000-0000-0000-000000000000',\n  sets: modifiedSets,\n  assetId: 'asset-uuid',\n  createdSource: 'WorkoutBuilder'\n})\n\n// Delete a workout\nawait client.deleteWorkout('workout-uuid')\n```\n\n### Performed workout activities\n\nA workout activity is one performed workout session, not a workout template. Get an activity ID from `getActivitySummaries()`, then fetch its detail from `/users/{userId}/workout-activities/{activityId}`:\n\n```typescript\nconst summaries = await client.getActivitySummaries()\nconst recent = [...summaries]\n  .filter(summary => summary.completed)\n  .sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp))[0]\n\nif (recent) {\n  const activity = await client.getWorkoutActivityById(recent.id)\n  console.log(`${activity.totalSets} sets, ${activity.totalReps} reps`)\n  console.log(`Completed: ${activity.completed === true}`)\n}\n```\n\nThe method signature is:\n\n```typescript\nasync getWorkoutActivityById(\n  activityId: string,\n  useCache: boolean = true\n): Promise<TonalWorkoutActivity>\n```\n\nCompleted activities are immutable, so results with `completed === true` are cached permanently with no TTL. In-progress activities are never cached. Cache keys include both the user and activity IDs, which prevents collisions between accounts. Cache reads and writes are best-effort: a cache failure never fails the API request or hides a successful response. Pass `false` for `useCache` to force a fresh request.\n\nActivity entries use the same `cacheDir` and default cache location described under [Client setup](#client-setup). Permanent entries never expire and nothing evicts them automatically, so the cache grows by one small file for each completed activity viewed. `invalidateMovementsCache()` does not clear these entries.\n\n#### Activity response types\n\n`TonalWorkoutActivity` contains the performed session's IDs, timestamps, duration and aggregate totals, completion state, device metadata, and its set activity records:\n\n```typescript\ninterface TonalWorkoutActivity {\n  id: string\n  userId: string\n  workoutId: string\n  workoutType?: string | null\n  beginTime: string\n  endTime?: string | null\n  totalDuration: number\n  activeDuration?: number | null\n  restDuration?: number | null\n  totalMovements?: number | null\n  totalSets: number\n  totalReps: number\n  totalVolume: number\n  totalConcentricWork?: number | null\n  percentCompleted?: number | null\n  completed?: boolean | null\n  workoutSetActivity: TonalWorkoutSetActivity[]\n  contentCard?: unknown\n  deviceId?: string | null\n  timezone?: string | null\n  appVersion?: string | null\n}\n```\n\nEach `TonalWorkoutSetActivity` identifies a movement and includes the performed or prescribed values available for that set:\n\n```typescript\ninterface TonalWorkoutSetActivity {\n  movementId: string\n  prescribedReps?: number | null\n  repetition?: number | null\n  repetitionTotal?: number | null\n  weightPercentage?: number | null\n  baseWeight?: number | null\n  eccentricWeight?: number | null\n  chainsWeight?: number | null\n  blockNumber?: number | null\n  blockStart?: boolean | null\n  sideNumber?: number | null\n  setId?: string | null\n  spotter?: boolean | null\n}\n```\n\n### User Information\n\n```typescript\n// Get your profile information\nconst userInfo = await client.getUserInfo()\nconsole.log(`Welcome ${userInfo.firstName}!`)\nconsole.log(`Level: ${userInfo.level}`)\nconsole.log(`Location: ${userInfo.location}`)\n\n// Get available fitness goals\nconst goals = await client.getGoals()\ngoals.forEach(goal => {\n  console.log(`${goal.name}: ${goal.description}`)\n})\n\n// Get training effect goals with relationships\nconst trainingGoals = await client.getTrainingEffectGoals()\nconsole.log(`${trainingGoals.goals.length} training goals available`)\ntrainingGoals.relations.forEach(relation => {\n  console.log(`Primary goal relationships found`)\n})\n\n// Get all training types\nconst trainingTypes = await client.getTrainingTypes()\nconsole.log(`${trainingTypes.length} training types available`)\ntrainingTypes.forEach(type => {\n  console.log(`${type.name}: ${type.description}`)\n})\n\n// Get goal metrics\nconst goalMetrics = await client.getGoalMetrics()\nconsole.log(`${goalMetrics.length} goal metrics available`)\ngoalMetrics.forEach(metric => {\n  console.log(`${metric.name}: ${metric.description}`)\n})\n\n// Get comprehensive user settings\nconst userSettings = await client.getUserSettings()\nconsole.log(`Audio settings: ${userSettings.overallVolume * 100}% volume`)\nconsole.log(`Preferred music service: ${userSettings.preferredMusicService}`)\nconsole.log(`Time zone: ${userSettings.timeZone}`)\nconsole.log(`Total settings tracked: ${Object.keys(userSettings).length}`)\n\n// Get daily fitness metrics (analyzes 60 days, shows recent 10 workouts)\nconst dailyMetrics = await client.getDailyMetrics(60)\nconst activeDays = dailyMetrics.filter(day => day.totalWorkouts > 0)\nconsole.log(`Workout frequency over 60 days: ${(activeDays.length / dailyMetrics.length * 100).toFixed(1)}%`)\nconsole.log(`Total volume (all workouts): ${activeDays.reduce((sum, day) => sum + day.totalVolume, 0).toLocaleString()} lbs`)\nconsole.log(`Average workout duration: ${Math.round(activeDays.reduce((sum, day) => sum + day.totalDuration, 0) / activeDays.length / 60)} minutes`)\n\n// Get current workout streak\nconst streak = await client.getCurrentStreak()\nconsole.log(`Current streak: ${streak.currentStreak} workouts`)\nconsole.log(`Personal best: ${streak.maxStreak} workouts`)\nconsole.log(`Progress to personal best: ${Math.round((streak.currentStreak / streak.maxStreak) * 100)}%`)\n\n// Get lifetime statistics and achievements\nconst stats = await client.getUserStatistics()\nconsole.log(`Total volume: ${stats.volume.total.toLocaleString()} lbs over ${stats.workouts.total} workouts`)\nconsole.log(`Average per workout: ${stats.volume.avgVolumePerWorkout.toLocaleString()} lbs`)\nconsole.log(`Total workout time: ${Math.round(stats.workouts.totalDuration / 3600)} hours`)\nconsole.log(`Movement diversity: ${stats.movements.total} unique movements performed`)\n\n// Get achievement progress and upcoming milestones\nconst achievementStats = await client.getAchievementStats()\nconsole.log(`Achievements earned: ${achievementStats.totalAchievements}`)\nconsole.log(`Upcoming milestones: ${achievementStats.nextMilestones.length}`)\nachievementStats.nextMilestones.forEach(milestone => {\n  console.log(`Next goal: ${milestone.name} (${milestone.value.toLocaleString()})`)\n})\n\n// Get complete earned achievement history\nconst earnedAchievements = await client.getAchievements()\nconsole.log(`Total achievements earned: ${earnedAchievements.length}`)\nconst recentAchievement = earnedAchievements[0]\nconsole.log(`Most recent: ${recentAchievement.name} (${new Date(recentAchievement.createdAt).toLocaleDateString()})`)\nconst categories = [...new Set(earnedAchievements.map(a => a.achievement.achievementCategory.name))]\nconsole.log(`Achievement categories: ${categories.join(', ')}`)\n\n// Get home calendar with workout history and recommendations\nconst homeCalendar = await client.getHomeCalendar()\nconst completedWorkouts = homeCalendar.dailySchedules.filter(day => \n  day.tiles.some(tile => tile.completed)\n).length\nconst recommendationCategories = [...new Set(\n  homeCalendar.dailySchedules.map(day => day.recommendationType).filter(Boolean)\n)]\nconsole.log(`Completed workout days: ${completedWorkouts}`)\nconsole.log(`Recommendation categories: ${recommendationCategories.join(', ')}`)\n\n// Get muscle readiness for all muscle groups\nconst readiness = await client.getMuscleReadiness()\nconsole.log(`Muscle Readiness Status:`)\nconsole.log(`  Chest: ${readiness.Chest}%`)\nconsole.log(`  Shoulders: ${readiness.Shoulders}%`)\nconsole.log(`  Back: ${readiness.Back}%`)\nconsole.log(`  Triceps: ${readiness.Triceps}%`)\nconsole.log(`  Biceps: ${readiness.Biceps}%`)\nconsole.log(`  Abs: ${readiness.Abs}%`)\nconsole.log(`  Obliques: ${readiness.Obliques}%`)\nconsole.log(`  Quads: ${readiness.Quads}%`)\nconsole.log(`  Glutes: ${readiness.Glutes}%`)\nconsole.log(`  Hamstrings: ${readiness.Hamstrings}%`)\nconsole.log(`  Calves: ${readiness.Calves}%`)\n\n// Calculate average readiness\nconst allMuscles = Object.values(readiness)\nconst averageReadiness = Math.round(allMuscles.reduce((sum, val) => sum + val, 0) / allMuscles.length)\nconsole.log(`Average readiness: ${averageReadiness}%`)\n\n// Find muscles that need recovery (< 60%)\nconst needsRecovery = Object.entries(readiness)\n  .filter(([_, percentage]) => percentage < 60)\n  .map(([muscle]) => muscle)\nif (needsRecovery.length > 0) {\n  console.log(`Muscles needing recovery: ${needsRecovery.join(', ')}`)\n}\n\n// Get detailed program information\nconst programId = 'f243be64-76f2-4073-8ce7-8adb37657e9f' // Example: House of Volume\nconst program = await client.getProgramById(programId)\nconsole.log(`Program: ${program.name}`)\nconsole.log(`Level: ${program.level}`)\nconsole.log(`Duration: ${program.weeks} weeks`)\nconsole.log(`Workouts per week: ${program.workoutsPerWeek}`)\nconsole.log(`Total workouts: ${program.workouts.length}`)\nconsole.log(`Description: ${program.description}`)\n\n// Analyze program structure\nconst targetAreas = program.workouts.map(w => w.targetArea)\nconst targetAreaCounts = targetAreas.reduce((acc, area) => {\n  acc[area] = (acc[area] || 0) + 1\n  return acc\n}, {} as Record<string, number>)\nconsole.log(`Target area distribution:`, targetAreaCounts)\n\n// Show weekly schedule\nconst days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\nconst schedule = program.cadence.map((isWorkout, i) => \n  isWorkout ? `${days[i]}: Workout` : `${days[i]}: Rest`\n)\nconsole.log(`Weekly schedule: ${schedule.join(', ')}`)\n\n// Get weekly fitness targets for all metrics\nconst targetScores = await client.getTargetScores()\nconsole.log('Weekly Fitness Targets:')\n\nObject.entries(targetScores).forEach(([metricId, weeklyTargets]) => {\n  // Get the most recent week target\n  const currentTarget = weeklyTargets.sort((a, b) => b.weekNumber - a.weekNumber)[0]\n  const year = Math.floor(currentTarget.weekNumber / 100)\n  const week = currentTarget.weekNumber % 100\n  \n  console.log(`Metric ${metricId}:`)\n  console.log(`  Target: ${currentTarget.target}`)\n  console.log(`  Range: ${currentTarget.lowRange} - ${currentTarget.highRange}`)\n  console.log(`  Week: ${week}/${year}`)\n})\n\n// Analyze target trends\nconst volumeTargets = targetScores['2a2f499e-ae13-45d1-b501-aa1d25ff6a4a'] // Volume metric\nif (volumeTargets && volumeTargets.length >= 2) {\n  const sorted = volumeTargets.sort((a, b) => a.weekNumber - b.weekNumber)\n  const firstTarget = sorted[0].target\n  const lastTarget = sorted[sorted.length - 1].target\n  const change = Math.round(((lastTarget - firstTarget) / firstTarget) * 100)\n  console.log(`Volume trend: ${change > 0 ? '+' : ''}${change}% over ${sorted.length} weeks`)\n}\n\n// Get actual performance scores vs targets with comprehensive analytics\nconst metricScores = await client.getMetricScores()\n// Optional: get scores starting from a specific week\n// const metricScores = await client.getMetricScores(202440) // Start from week 40 of 2024\n\nconsole.log('Performance vs Targets Analysis:')\n\nObject.entries(metricScores).forEach(([metricId, weeklyScores]) => {\n  // Get the most recent week score\n  const currentScore = weeklyScores.sort((a, b) => b.weekNumber - a.weekNumber)[0]\n  const year = Math.floor(currentScore.weekNumber / 100)\n  const week = currentScore.weekNumber % 100\n  \n  console.log(`Metric ${metricId}:`)\n  console.log(`  Actual Score: ${currentScore.score}`)\n  console.log(`  Week: ${week}/${year}`)\n})\n\n// Compare against targets to see goal achievement\nconst volumeScores = metricScores['2a2f499e-ae13-45d1-b501-aa1d25ff6a4a'] // Volume metric\nconst volumeTargets = targetScores['2a2f499e-ae13-45d1-b501-aa1d25ff6a4a']\nif (volumeScores && volumeTargets) {\n  const latestScore = volumeScores.sort((a, b) => b.weekNumber - a.weekNumber)[0]\n  const matchingTarget = volumeTargets.find(t => t.weekNumber === latestScore.weekNumber)\n  \n  if (matchingTarget) {\n    const achievementPercent = Math.round((latestScore.score / matchingTarget.target) * 100)\n    const inRange = latestScore.score >= matchingTarget.lowRange && latestScore.score <= matchingTarget.highRange\n    console.log(`Volume Achievement: ${achievementPercent}% of target (${inRange ? 'In Range' : 'Out of Range'})`)\n  }\n}\n\n// Calculate performance trends\nif (volumeScores && volumeScores.length >= 2) {\n  const sorted = volumeScores.sort((a, b) => a.weekNumber - b.weekNumber)\n  const firstScore = sorted[0].score\n  const lastScore = sorted[sorted.length - 1].score\n  const change = Math.round(((lastScore - firstScore) / firstScore) * 100)\n  console.log(`Volume performance trend: ${change > 0 ? '+' : ''}${change}% over ${sorted.length} weeks`)\n}\n```\n\n### Strength Scores\n\nTonal's headline Strength Score, per body region. This is a different metric from the weekly\n`Functional Strength Score` returned by `getGoalMetrics()` — that one measures goal progress\nfor a week, this one is the score the Tonal app shows you.\n\n```typescript\n// Current score for each region\nconst scores = await client.getCurrentStrengthScores()\nfor (const score of scores) {\n  // The Overall row is synthesized: bodyRegionDisplay is empty, familyActivity is absent,\n  // workoutActivityId is an all-zero uuid, and updatedAt is a zero date. Fall back to\n  // strengthBodyRegion for a label, and do not render its updatedAt.\n  const label = score.bodyRegionDisplay || score.strengthBodyRegion\n  console.log(`${label}: ${score.score}`)\n}\n// One row per region: Upper Body, Core, Lower Body, Overall\n\n// Per-workout history. Defaults to the whole account.\nconst history = await client.getStrengthScoreHistory()\nconsole.log(`${history.length} scored activities`)\nconsole.log(history[0]) // { upper, lower, core, overall, activityTime, workoutActivityId, ... }\n```\n\n**`days` is a calendar-day lookback, not a row count.** The underlying API parameter is named\n`limit`, but it selects a time window: a value smaller than the gap since your last workout\nreturns an **empty array**, not \"no results found\". Passing `30` on an account last used\n90 days ago yields nothing.\n\n```typescript\nawait client.getStrengthScoreHistory(365)   // activities in the last 365 days\nawait client.getStrengthScoreHistory('all') // explicit; same as the default\n```\n\nThe default `'all'` derives the window from your account creation date, so it stays correct as\nthe account ages rather than relying on a large magic number. If `createdAt` is missing,\nunparseable, or in the future it throws `TonalClientError` rather than guessing — pass an\nexplicit `days` in that case.\n\nEach history entry carries `workoutActivityId`, which makes this the only complete way to\nenumerate an account's activities: the list endpoints are capped at 50 records each.\n\n### Movements\n\n```typescript\n// Get all available movements\nconst movements = await client.getMovements()\nconsole.log(`${movements.length} movements available`)\n\n// Filter by muscle group\nconst chestMovements = movements.filter(m => \n  m.muscleGroups.includes('Chest')\n)\n```\n\n## Available Scripts\n\n- `npm run build` - Build the TypeScript client\n- `npm run typecheck` - Run TypeScript type checking\n- `npm run example:movements` - List all movements\n- `npm run example:user` - Show user information  \n- `npm run example:goals` - Show available goals\n- `npm run example:user-workouts` - List your workouts\n- `npm run example:workout:id <id>` - Get specific workout\n- `npm run example:workout:name <name>` - Search for workouts by name\n- `npm run example:workout:share <url>` - Get shared workout\n- `npm run example:estimate` - Estimate workout duration\n- `npm run example:create-workout` - Create a new workout\n- `npm run example:edit-workout` - Create and edit a workout\n- `npm run example:delete-workout` - Create and delete a workout\n- `npm run example:daily-lifts` - Get daily lifts with auto-detected timezone\n- `npm run example:training-effect-goals` - Get training effect goals and relationships\n- `npm run example:training-types` - Get all available training types\n- `npm run example:goal-metrics` - Get goal metrics and relationships\n- `npm run example:user-settings` - Get comprehensive user settings and preferences\n- `npm run example:daily-metrics` - Get daily fitness metrics with workout analytics\n- `npm run example:current-streak` - Get current workout streak and personal best\n- `npm run example:activity-summaries` - Get comprehensive workout activity history and analytics\n- `npm run example:user-statistics` - Get lifetime user statistics and achievement milestones\n- `npm run example:achievement-stats` - Get achievement progress and upcoming milestone targets\n- `npm run example:achievements` - Get complete earned achievement history with timeline analytics\n- `npm run example:home-calendar` - Get home calendar with workout history and personalized recommendations\n- `npm run example:muscle-readiness` - Get muscle readiness percentages and recovery recommendations\n- `npm run example:program-by-id` - Get comprehensive program details including all workouts and structure\n- `npm run example:target-scores` - Get weekly fitness targets with ranges and trend analysis for all metrics\n- `npm run example:metric-scores` - Get actual performance scores vs targets with comprehensive goal achievement analytics\n\n## Contributing\n\nContributions to this project are welcome, especially in the areas of error handling, expanding functionality, and improving the robustness of the client.\n\n## License\n\nThis project is open-sourced under the MIT License. See the [LICENSE](LICENSE) file for more details.\n\n## Contact\n\nFor any queries or further assistance, please contact [Derrick Wiest](mailto:me@dlwiest.com).\n","readmeFilename":"README.md"}