@cmichel/healthlog 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +10 -2
  2. package/dist/cli.js +4 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/dump.js +1 -1
  5. package/dist/commands/dump.js.map +1 -1
  6. package/dist/commands/setup-withings.js +87 -0
  7. package/dist/commands/setup-withings.js.map +1 -0
  8. package/dist/db/body-measurements.js +130 -0
  9. package/dist/db/body-measurements.js.map +1 -0
  10. package/dist/db/provider-state.js +20 -17
  11. package/dist/db/provider-state.js.map +1 -1
  12. package/dist/db/schema.js +28 -4
  13. package/dist/db/schema.js.map +1 -1
  14. package/dist/domain/body-measurement.js +7 -0
  15. package/dist/domain/body-measurement.js.map +1 -0
  16. package/dist/domain/dump.js.map +1 -1
  17. package/dist/domain/provider.js +3 -1
  18. package/dist/domain/provider.js.map +1 -1
  19. package/dist/domain/workout.js.map +1 -1
  20. package/dist/providers/garmin/sync.js +2 -2
  21. package/dist/providers/garmin/sync.js.map +1 -1
  22. package/dist/providers/hevy/sync.js +2 -2
  23. package/dist/providers/hevy/sync.js.map +1 -1
  24. package/dist/providers/withings/client.js +115 -0
  25. package/dist/providers/withings/client.js.map +1 -0
  26. package/dist/providers/withings/normalize.js +76 -0
  27. package/dist/providers/withings/normalize.js.map +1 -0
  28. package/dist/providers/withings/oauth.js +28 -0
  29. package/dist/providers/withings/oauth.js.map +1 -0
  30. package/dist/providers/withings/sync.js +66 -0
  31. package/dist/providers/withings/sync.js.map +1 -0
  32. package/dist/providers/withings/types.js +113 -0
  33. package/dist/providers/withings/types.js.map +1 -0
  34. package/dist/services/dump-service.js +24 -0
  35. package/dist/services/dump-service.js.map +1 -1
  36. package/dist/services/setup-service.js +6 -2
  37. package/dist/services/setup-service.js.map +1 -1
  38. package/dist/services/sync-service.js +18 -6
  39. package/dist/services/sync-service.js.map +1 -1
  40. package/package.json +20 -12
@@ -1,11 +1,15 @@
1
1
  import { upsertProviderState } from "../db/provider-state.js";
2
2
  import { initialGarminCursor } from "../providers/garmin/types.js";
3
3
  import { initialHevyCursor } from "../providers/hevy/types.js";
4
+ import { initialWithingsCursor, } from "../providers/withings/types.js";
4
5
  import { stringifyJson } from "../utils/parse.js";
5
6
  export function storeGarminCredentials(db, tokens) {
6
- upsertProviderState(db, "garmin", stringifyJson(tokens), stringifyJson(initialGarminCursor), null);
7
+ upsertProviderState(db, "garmin", stringifyJson(tokens), stringifyJson(initialGarminCursor));
7
8
  }
8
9
  export function storeHevyCredentials(db, apiKey) {
9
- upsertProviderState(db, "hevy", stringifyJson({ apiKey }), stringifyJson(initialHevyCursor), null);
10
+ upsertProviderState(db, "hevy", stringifyJson({ apiKey }), stringifyJson(initialHevyCursor));
11
+ }
12
+ export function storeWithingsCredentials(db, credentials) {
13
+ upsertProviderState(db, "withings", stringifyJson(credentials), stringifyJson(initialWithingsCursor));
10
14
  }
11
15
  //# sourceMappingURL=setup-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup-service.js","sourceRoot":"","sources":["../../src/services/setup-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,MAAoB;IAEpB,mBAAmB,CACjB,EAAE,EACF,QAAQ,EACR,aAAa,CAAC,MAAM,CAAC,EACrB,aAAa,CAAC,mBAAmB,CAAC,EAClC,IAAI,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,MAAc;IAEd,mBAAmB,CACjB,EAAE,EACF,MAAM,EACN,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC,EACzB,aAAa,CAAC,iBAAiB,CAAC,EAChC,IAAI,CACL,CAAC;AACJ,CAAC","sourcesContent":["import type { HealthlogDatabase } from \"../db/database.js\";\nimport { upsertProviderState } from \"../db/provider-state.js\";\nimport type { GarminTokens } from \"../providers/garmin/types.js\";\nimport { initialGarminCursor } from \"../providers/garmin/types.js\";\nimport { initialHevyCursor } from \"../providers/hevy/types.js\";\nimport { stringifyJson } from \"../utils/parse.js\";\n\nexport function storeGarminCredentials(\n db: HealthlogDatabase,\n tokens: GarminTokens,\n): void {\n upsertProviderState(\n db,\n \"garmin\",\n stringifyJson(tokens),\n stringifyJson(initialGarminCursor),\n null,\n );\n}\n\nexport function storeHevyCredentials(\n db: HealthlogDatabase,\n apiKey: string,\n): void {\n upsertProviderState(\n db,\n \"hevy\",\n stringifyJson({ apiKey }),\n stringifyJson(initialHevyCursor),\n null,\n );\n}\n"]}
1
+ {"version":3,"file":"setup-service.js","sourceRoot":"","sources":["../../src/services/setup-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EACL,qBAAqB,GAEtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,MAAoB;IAEpB,mBAAmB,CACjB,EAAE,EACF,QAAQ,EACR,aAAa,CAAC,MAAM,CAAC,EACrB,aAAa,CAAC,mBAAmB,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,MAAc;IAEd,mBAAmB,CACjB,EAAE,EACF,MAAM,EACN,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC,EACzB,aAAa,CAAC,iBAAiB,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,WAAgC;IAEhC,mBAAmB,CACjB,EAAE,EACF,UAAU,EACV,aAAa,CAAC,WAAW,CAAC,EAC1B,aAAa,CAAC,qBAAqB,CAAC,CACrC,CAAC;AACJ,CAAC","sourcesContent":["import type { HealthlogDatabase } from \"../db/database.js\";\nimport { upsertProviderState } from \"../db/provider-state.js\";\nimport type { GarminTokens } from \"../providers/garmin/types.js\";\nimport { initialGarminCursor } from \"../providers/garmin/types.js\";\nimport { initialHevyCursor } from \"../providers/hevy/types.js\";\nimport {\n initialWithingsCursor,\n type WithingsCredentials,\n} from \"../providers/withings/types.js\";\nimport { stringifyJson } from \"../utils/parse.js\";\n\nexport function storeGarminCredentials(\n db: HealthlogDatabase,\n tokens: GarminTokens,\n): void {\n upsertProviderState(\n db,\n \"garmin\",\n stringifyJson(tokens),\n stringifyJson(initialGarminCursor),\n );\n}\n\nexport function storeHevyCredentials(\n db: HealthlogDatabase,\n apiKey: string,\n): void {\n upsertProviderState(\n db,\n \"hevy\",\n stringifyJson({ apiKey }),\n stringifyJson(initialHevyCursor),\n );\n}\n\nexport function storeWithingsCredentials(\n db: HealthlogDatabase,\n credentials: WithingsCredentials,\n): void {\n upsertProviderState(\n db,\n \"withings\",\n stringifyJson(credentials),\n stringifyJson(initialWithingsCursor),\n );\n}\n"]}
@@ -1,32 +1,44 @@
1
1
  import { getProviderState } from "../db/provider-state.js";
2
2
  import { syncGarmin } from "../providers/garmin/sync.js";
3
3
  import { syncHevy } from "../providers/hevy/sync.js";
4
+ import { syncWithings } from "../providers/withings/sync.js";
4
5
  import { logger } from "../utils/logger.js";
5
6
  export async function syncConfiguredProviders(db) {
6
- let totalNewWorkoutCount = 0;
7
+ let totalNewCount = 0;
7
8
  let configuredProviderCount = 0;
8
9
  const garminState = getProviderState(db, "garmin");
9
10
  if (garminState && garminState.credentialsJson.trim() !== "") {
10
11
  configuredProviderCount += 1;
11
12
  logger.info("Syncing Garmin...");
12
13
  const result = await syncGarmin(db, garminState);
13
- totalNewWorkoutCount += result.newWorkoutCount;
14
- logger.success(`Garmin sync done: ${formatWorkoutCount(result.newWorkoutCount)}.`);
14
+ totalNewCount += result.newCount;
15
+ logger.success(`Garmin sync done: ${formatWorkoutCount(result.newCount)}.`);
15
16
  }
16
17
  const hevyState = getProviderState(db, "hevy");
17
18
  if (hevyState && hevyState.credentialsJson.trim() !== "") {
18
19
  configuredProviderCount += 1;
19
20
  logger.info("Syncing Hevy...");
20
21
  const result = await syncHevy(db, hevyState);
21
- totalNewWorkoutCount += result.newWorkoutCount;
22
- logger.success(`Hevy sync done: ${formatWorkoutCount(result.newWorkoutCount)}.`);
22
+ totalNewCount += result.newCount;
23
+ logger.success(`Hevy sync done: ${formatWorkoutCount(result.newCount)}.`);
24
+ }
25
+ const withingsState = getProviderState(db, "withings");
26
+ if (withingsState && withingsState.credentialsJson.trim() !== "") {
27
+ configuredProviderCount += 1;
28
+ logger.info("Syncing Withings...");
29
+ const result = await syncWithings(db, withingsState);
30
+ totalNewCount += result.newCount;
31
+ logger.success(`Withings sync done: ${formatBodyMeasurementCount(result.newCount)}.`);
23
32
  }
24
33
  if (configuredProviderCount === 0) {
25
34
  logger.info("No providers configured; skipping sync.");
26
35
  }
27
- return { newWorkoutCount: totalNewWorkoutCount };
36
+ return { newCount: totalNewCount };
28
37
  }
29
38
  function formatWorkoutCount(count) {
30
39
  return `${count} new ${count === 1 ? "workout" : "workouts"}`;
31
40
  }
41
+ function formatBodyMeasurementCount(count) {
42
+ return `${count} new ${count === 1 ? "body measurement" : "body measurements"}`;
43
+ }
32
44
  //# sourceMappingURL=sync-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../../src/services/sync-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,EAAqB;IAErB,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,uBAAuB,GAAG,CAAC,CAAC;IAEhC,MAAM,WAAW,GAAG,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnD,IAAI,WAAW,IAAI,WAAW,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7D,uBAAuB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjD,oBAAoB,IAAI,MAAM,CAAC,eAAe,CAAC;QAC/C,MAAM,CAAC,OAAO,CACZ,qBAAqB,kBAAkB,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CACnE,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/C,IAAI,SAAS,IAAI,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,uBAAuB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAC7C,oBAAoB,IAAI,MAAM,CAAC,eAAe,CAAC;QAC/C,MAAM,CAAC,OAAO,CACZ,mBAAmB,kBAAkB,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CACjE,CAAC;IACJ,CAAC;IAED,IAAI,uBAAuB,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,CAAC;AACnD,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AAChE,CAAC","sourcesContent":["import type { HealthlogDatabase } from \"../db/database.js\";\nimport { getProviderState } from \"../db/provider-state.js\";\nimport type { ProviderSyncResult } from \"../domain/provider.js\";\nimport { syncGarmin } from \"../providers/garmin/sync.js\";\nimport { syncHevy } from \"../providers/hevy/sync.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport async function syncConfiguredProviders(\n db: HealthlogDatabase,\n): Promise<ProviderSyncResult> {\n let totalNewWorkoutCount = 0;\n let configuredProviderCount = 0;\n\n const garminState = getProviderState(db, \"garmin\");\n if (garminState && garminState.credentialsJson.trim() !== \"\") {\n configuredProviderCount += 1;\n logger.info(\"Syncing Garmin...\");\n const result = await syncGarmin(db, garminState);\n totalNewWorkoutCount += result.newWorkoutCount;\n logger.success(\n `Garmin sync done: ${formatWorkoutCount(result.newWorkoutCount)}.`,\n );\n }\n\n const hevyState = getProviderState(db, \"hevy\");\n if (hevyState && hevyState.credentialsJson.trim() !== \"\") {\n configuredProviderCount += 1;\n logger.info(\"Syncing Hevy...\");\n const result = await syncHevy(db, hevyState);\n totalNewWorkoutCount += result.newWorkoutCount;\n logger.success(\n `Hevy sync done: ${formatWorkoutCount(result.newWorkoutCount)}.`,\n );\n }\n\n if (configuredProviderCount === 0) {\n logger.info(\"No providers configured; skipping sync.\");\n }\n\n return { newWorkoutCount: totalNewWorkoutCount };\n}\n\nfunction formatWorkoutCount(count: number): string {\n return `${count} new ${count === 1 ? \"workout\" : \"workouts\"}`;\n}\n"]}
1
+ {"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../../src/services/sync-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,EAAqB;IAErB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,uBAAuB,GAAG,CAAC,CAAC;IAEhC,MAAM,WAAW,GAAG,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnD,IAAI,WAAW,IAAI,WAAW,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7D,uBAAuB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACjD,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,qBAAqB,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/C,IAAI,SAAS,IAAI,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,uBAAuB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAC7C,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,mBAAmB,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IACvD,IAAI,aAAa,IAAI,aAAa,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjE,uBAAuB,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACrD,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,CAAC,OAAO,CACZ,uBAAuB,0BAA0B,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CACtE,CAAC;IACJ,CAAC;IAED,IAAI,uBAAuB,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAa;IAC/C,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC;AAClF,CAAC","sourcesContent":["import type { HealthlogDatabase } from \"../db/database.js\";\nimport { getProviderState } from \"../db/provider-state.js\";\nimport type { ProviderSyncResult } from \"../domain/provider.js\";\nimport { syncGarmin } from \"../providers/garmin/sync.js\";\nimport { syncHevy } from \"../providers/hevy/sync.js\";\nimport { syncWithings } from \"../providers/withings/sync.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport async function syncConfiguredProviders(\n db: HealthlogDatabase,\n): Promise<ProviderSyncResult> {\n let totalNewCount = 0;\n let configuredProviderCount = 0;\n\n const garminState = getProviderState(db, \"garmin\");\n if (garminState && garminState.credentialsJson.trim() !== \"\") {\n configuredProviderCount += 1;\n logger.info(\"Syncing Garmin...\");\n const result = await syncGarmin(db, garminState);\n totalNewCount += result.newCount;\n logger.success(`Garmin sync done: ${formatWorkoutCount(result.newCount)}.`);\n }\n\n const hevyState = getProviderState(db, \"hevy\");\n if (hevyState && hevyState.credentialsJson.trim() !== \"\") {\n configuredProviderCount += 1;\n logger.info(\"Syncing Hevy...\");\n const result = await syncHevy(db, hevyState);\n totalNewCount += result.newCount;\n logger.success(`Hevy sync done: ${formatWorkoutCount(result.newCount)}.`);\n }\n\n const withingsState = getProviderState(db, \"withings\");\n if (withingsState && withingsState.credentialsJson.trim() !== \"\") {\n configuredProviderCount += 1;\n logger.info(\"Syncing Withings...\");\n const result = await syncWithings(db, withingsState);\n totalNewCount += result.newCount;\n logger.success(\n `Withings sync done: ${formatBodyMeasurementCount(result.newCount)}.`,\n );\n }\n\n if (configuredProviderCount === 0) {\n logger.info(\"No providers configured; skipping sync.\");\n }\n\n return { newCount: totalNewCount };\n}\n\nfunction formatWorkoutCount(count: number): string {\n return `${count} new ${count === 1 ? \"workout\" : \"workouts\"}`;\n}\n\nfunction formatBodyMeasurementCount(count: number): string {\n return `${count} new ${count === 1 ? \"body measurement\" : \"body measurements\"}`;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@cmichel/healthlog",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
+ "packageManager": "pnpm@10.10.0",
5
6
  "engines": {
6
7
  "node": ">=22"
7
8
  },
@@ -15,6 +16,19 @@
15
16
  "publishConfig": {
16
17
  "access": "public"
17
18
  },
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "check": "biome check .",
22
+ "ci": "pnpm run check && pnpm run typecheck && pnpm test && pnpm run build",
23
+ "format": "biome format --write .",
24
+ "pack:check": "npm pack --dry-run",
25
+ "prepack": "pnpm run build",
26
+ "prepublishOnly": "pnpm run ci",
27
+ "start": "tsx src/cli.ts",
28
+ "test": "vitest run",
29
+ "test:integration": "HEALTHLOG_INTEGRATION=1 vitest run integration",
30
+ "typecheck": "tsc --noEmit -p tsconfig.json"
31
+ },
18
32
  "dependencies": {
19
33
  "@inquirer/prompts": "^7.8.4",
20
34
  "better-sqlite3": "^12.2.0",
@@ -31,15 +45,9 @@
31
45
  "typescript": "^5.9.3",
32
46
  "vitest": "^4.1.9"
33
47
  },
34
- "scripts": {
35
- "build": "tsc -p tsconfig.build.json",
36
- "check": "biome check .",
37
- "ci": "pnpm run check && pnpm run typecheck && pnpm test && pnpm run build",
38
- "format": "biome format --write .",
39
- "pack:check": "npm pack --dry-run",
40
- "start": "tsx src/cli.ts",
41
- "test": "vitest run",
42
- "test:integration": "HEALTHLOG_INTEGRATION=1 vitest run integration",
43
- "typecheck": "tsc --noEmit -p tsconfig.json"
48
+ "pnpm": {
49
+ "onlyBuiltDependencies": [
50
+ "better-sqlite3"
51
+ ]
44
52
  }
45
- }
53
+ }