ts-watches 0.1.2 → 0.1.3

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.
package/README.md CHANGED
@@ -172,6 +172,7 @@ const userId = await garmin.getUserId(tokens.accessToken) // the key push notifi
172
172
  const legacy = new GarminConnectClient()
173
173
  await legacy.login('email@example.com', 'password')
174
174
  const activities = await legacy.getActivities(new Date('2024-01-01'))
175
+ const { bytes, filename } = await legacy.downloadOriginalActivity(activityId) // "Export Original" zip, in memory
175
176
 
176
177
  // Strava
177
178
  const strava = new StravaClient({
package/dist/bin/cli.js CHANGED
@@ -28,7 +28,7 @@ Received ${i}, cleaning up...`),e)try{await e()}catch(s){console.error("Error du
28
28
  ✗ Command "${e}" not found.
29
29
  `)),this.enableDidYouMean){let t=[];for(let s of this.commands){if(s.displayName)t.push(s.displayName);if(s.aliasNames)t.push(...s.aliasNames)}let i=K(e,t);if(i.length>0)console.log(S.yellow("Did you mean one of these?")),i.forEach((s)=>console.log(` ${S.dim("•")} ${this.name} ${s}`)),console.log("")}console.log(S.dim("Run"),`${this.name} --help`,S.dim("to see all available commands")),w.exit(1)}async parse(e=H,t={}){let{run:i=!0,exitOnError:s=!1}=t;if(s)try{return await this.parse(e,{run:i})}catch(r){throw this.handleUsageError(r),r}if(this.rawArgs=e,!this.name)this.name=e[1]?oe(e[1]):"cli";let n=!0,o=e.slice(2),c=o[0];if(c&&!c.startsWith("-")){for(let r of this.commands)if(r.isMatched(c)){let u=this.mri(o,r);n=!1;let h={...u,args:u.args.slice(1)};this.setParsedInfo(h,r,c),this.emit(`command:${c}`,r);break}}if(n){for(let r of this.commands)if(r.name===""){n=!1;let u=this.mri(o,r);this.setParsedInfo(u,r),this.emit("command:!",r);break}}if(n){let r=this.mri(e.slice(2));this.setParsedInfo(r)}if(this.options.verbose)this.isVerbose=!0;if(this.options.quiet)this.isQuiet=!0;if(this.options.debug)this.isDebug=!0;if(this.options.noInteraction)this.isNoInteraction=!0;if(this.options.env)this.environment=String(this.options.env);if(this.options.dryRun)this.isDryRun=!0;if(this.options.force)this.isForce=!0;if(this.options.noEmoji!==void 0)this.useEmoji=!this.options.noEmoji;if(this.options.theme)this.theme=String(this.options.theme);if(this.options.noCache!==void 0)this.isNoCache=Boolean(this.options.noCache);if(this.options.help&&this.showHelpOnExit)this.outputHelp(),i=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),i=!1,this.unsetMatchedCommand();let a={args:this.args,options:this.options};if(i)await this.runMatchedCommand();if(!this.matchedCommand&&this.args[0]){if(this.emit("command:*"),!(this.listenerCount("command:*")>0))this.showCommandNotFound(this.args[0])}return a}mri(e,t){let i=[...this.globalCommand.options,...t?t.options:[]],s=se(i),n=[],o=e.indexOf("--");if(o>-1)n=e.slice(o+1),e=e.slice(0,o);let c=ee(e,s),a={_:c._};for(let m of Object.keys(c))if(m!=="_")a[U(m)]=c[m];let r=a._,u={"--":n},h=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,d=Object.create(null);for(let m of i){if(!h&&m.config.default!==void 0)for(let f of m.names)u[f]=m.config.default;if(Array.isArray(m.config.type)){if(d[m.name]===void 0)d[m.name]={shouldTransform:!0,transformFunction:m.config.type[0]}}}for(let m of Object.keys(a))if(m!=="_"){let f=m.split(".");ne(u,f,a[m]),re(u,d)}return{args:r,options:u}}async run(e=H){return this.parse(e,{run:!0,exitOnError:!0})}handleUsageError(e){if(!(!!e&&typeof e==="object"&&e.name==="ClappError"&&e.isUsageError!==!1))return;let s=e,n=s.message??"command-line error",o=this.name?`${this.name}: `:"",c=/--help/.test(n)?"":`
30
30
  Run \`${this.name??"cli"} --help\` for usage.`;w.stderr.write(`${o}${n}${c}
31
- `),w.exit(s.exitCode??2)}async runMatchedCommand(){let{args:e,options:t,matchedCommand:i}=this;if(!i||!i.commandAction)return;i.checkUnknownOptions(),i.checkOptionValue(),i.checkRequiredArgs();let s=[];i.args.forEach((a,r)=>{if(a.variadic)s.push(e.slice(r));else s.push(e[r])}),s.push(t);let n={command:i,args:s,options:t};for(let a of i.beforeHooks)await a(n);let o,c=async()=>{let a=i.commandAction.apply(this,s);if(a instanceof Promise)o=await a;else o=a;return o};if(i.middleware.length>0){let a=0,r=async()=>{if(a<i.middleware.length){let u=i.middleware[a++];await u({...n,next:r})}else await c()};await r()}else await c();for(let a of i.afterHooks)await a(n);return o}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return w.removeAllListeners("SIGINT"),w.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Y{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(e){if(!this.enabled){this.misses++;return}let t=this.cache.get(e);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(e),this.misses++;return}return this.hits++,t.value}set(e,t,i=5000){if(!this.enabled)return;this.cache.set(e,{value:t,timestamp:Date.now(),ttl:i})}has(e){if(!this.enabled)return!1;let t=this.cache.get(e);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(e),!1;return!0}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let e=Date.now();for(let[t,i]of this.cache.entries())if(e-i.timestamp>i.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var at=new Y;function fe(){if("FORCE_COLOR"in O.env)return O.env.FORCE_COLOR!=="0";if("NO_COLOR"in O.env||O.env.TERM==="dumb")return!1;if(O.platform==="win32")return!0;return z.isatty(1)&&z.isatty(2)}var J=fe();function g(e,t){if(!J)return(i)=>i;return(i)=>e+i+t}var pe=g("\x1B[0m","\x1B[0m"),ge=g("\x1B[31m","\x1B[39m"),$e=g("\x1B[32m","\x1B[39m"),ve=g("\x1B[33m","\x1B[39m"),we=g("\x1B[34m","\x1B[39m"),be=g("\x1B[35m","\x1B[39m"),ye=g("\x1B[36m","\x1B[39m"),xe=g("\x1B[37m","\x1B[39m"),Ce=g("\x1B[90m","\x1B[39m"),Se=g("\x1B[1m","\x1B[22m"),Oe=g("\x1B[3m","\x1B[23m"),Ie=g("\x1B[4m","\x1B[24m"),_e=g("\x1B[2m","\x1B[22m"),Ee=g("\x1B[7m","\x1B[27m"),Be=g("\x1B[8m","\x1B[28m"),ke=g("\x1B[9m","\x1B[29m"),Te=g("\x1B[41m","\x1B[49m"),Me=g("\x1B[42m","\x1B[49m"),Ae=g("\x1B[43m","\x1B[49m"),je=g("\x1B[44m","\x1B[49m"),Re=g("\x1B[45m","\x1B[49m"),Ve=g("\x1B[46m","\x1B[49m"),De=g("\x1B[47m","\x1B[49m"),Ne=J,Le={reset:pe,red:ge,green:$e,yellow:ve,blue:we,magenta:be,cyan:ye,white:xe,gray:Ce,bold:Se,italic:Oe,underline:Ie,dim:_e,inverse:Ee,hidden:Be,strikethrough:ke,bgRed:Te,bgGreen:Me,bgYellow:Ae,bgBlue:je,bgMagenta:Re,bgCyan:Ve,bgWhite:De,isColorSupported:Ne},Pe=Le,Fe=["up","down","left","right","space","enter","cancel"],mt={actions:new Set(Fe),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ft=We.platform.startsWith("win"),pt=Symbol("clapp:cancel");var He=ae();var p=(e,t)=>He?e:t,gt=p("◆","*"),$t=p("■","x"),vt=p("▲","x"),wt=p("◇","o"),bt=p("┌","T"),ze=p("│","|"),yt=p("└","—"),xt=p("●",">"),Ct=p("○"," "),St=p("◻","[•]"),Ot=p("◼","[+]"),It=p("◻","[ ]"),_t=p("▪","•"),Et=p("─","-"),Bt=p("╮","+"),kt=p("├","+"),Tt=p("╯","+"),Mt=p("●","•"),At=p("◆","*"),jt=p("▲","!"),Rt=p("■","x");var Vt={light:p("─","-"),heavy:p("━","="),block:p("█","#")};function Ge(){return`${Pe.gray(ze)} `}var Dt=Ge();var D="0.1.2";var y=new V("watch");y.command("detect","Detect connected watch devices").option("--verbose","Enable verbose output").action(async(e)=>{let t=l();if(e.verbose)console.log(`Searching for connected watch devices...
31
+ `),w.exit(s.exitCode??2)}async runMatchedCommand(){let{args:e,options:t,matchedCommand:i}=this;if(!i||!i.commandAction)return;i.checkUnknownOptions(),i.checkOptionValue(),i.checkRequiredArgs();let s=[];i.args.forEach((a,r)=>{if(a.variadic)s.push(e.slice(r));else s.push(e[r])}),s.push(t);let n={command:i,args:s,options:t};for(let a of i.beforeHooks)await a(n);let o,c=async()=>{let a=i.commandAction.apply(this,s);if(a instanceof Promise)o=await a;else o=a;return o};if(i.middleware.length>0){let a=0,r=async()=>{if(a<i.middleware.length){let u=i.middleware[a++];await u({...n,next:r})}else await c()};await r()}else await c();for(let a of i.afterHooks)await a(n);return o}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return w.removeAllListeners("SIGINT"),w.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Y{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(e){if(!this.enabled){this.misses++;return}let t=this.cache.get(e);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(e),this.misses++;return}return this.hits++,t.value}set(e,t,i=5000){if(!this.enabled)return;this.cache.set(e,{value:t,timestamp:Date.now(),ttl:i})}has(e){if(!this.enabled)return!1;let t=this.cache.get(e);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(e),!1;return!0}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let e=Date.now();for(let[t,i]of this.cache.entries())if(e-i.timestamp>i.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var at=new Y;function fe(){if("FORCE_COLOR"in O.env)return O.env.FORCE_COLOR!=="0";if("NO_COLOR"in O.env||O.env.TERM==="dumb")return!1;if(O.platform==="win32")return!0;return z.isatty(1)&&z.isatty(2)}var J=fe();function g(e,t){if(!J)return(i)=>i;return(i)=>e+i+t}var pe=g("\x1B[0m","\x1B[0m"),ge=g("\x1B[31m","\x1B[39m"),$e=g("\x1B[32m","\x1B[39m"),ve=g("\x1B[33m","\x1B[39m"),we=g("\x1B[34m","\x1B[39m"),be=g("\x1B[35m","\x1B[39m"),ye=g("\x1B[36m","\x1B[39m"),xe=g("\x1B[37m","\x1B[39m"),Ce=g("\x1B[90m","\x1B[39m"),Se=g("\x1B[1m","\x1B[22m"),Oe=g("\x1B[3m","\x1B[23m"),Ie=g("\x1B[4m","\x1B[24m"),_e=g("\x1B[2m","\x1B[22m"),Ee=g("\x1B[7m","\x1B[27m"),Be=g("\x1B[8m","\x1B[28m"),ke=g("\x1B[9m","\x1B[29m"),Te=g("\x1B[41m","\x1B[49m"),Me=g("\x1B[42m","\x1B[49m"),Ae=g("\x1B[43m","\x1B[49m"),je=g("\x1B[44m","\x1B[49m"),Re=g("\x1B[45m","\x1B[49m"),Ve=g("\x1B[46m","\x1B[49m"),De=g("\x1B[47m","\x1B[49m"),Ne=J,Le={reset:pe,red:ge,green:$e,yellow:ve,blue:we,magenta:be,cyan:ye,white:xe,gray:Ce,bold:Se,italic:Oe,underline:Ie,dim:_e,inverse:Ee,hidden:Be,strikethrough:ke,bgRed:Te,bgGreen:Me,bgYellow:Ae,bgBlue:je,bgMagenta:Re,bgCyan:Ve,bgWhite:De,isColorSupported:Ne},Pe=Le,Fe=["up","down","left","right","space","enter","cancel"],mt={actions:new Set(Fe),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ft=We.platform.startsWith("win"),pt=Symbol("clapp:cancel");var He=ae();var p=(e,t)=>He?e:t,gt=p("◆","*"),$t=p("■","x"),vt=p("▲","x"),wt=p("◇","o"),bt=p("┌","T"),ze=p("│","|"),yt=p("└","—"),xt=p("●",">"),Ct=p("○"," "),St=p("◻","[•]"),Ot=p("◼","[+]"),It=p("◻","[ ]"),_t=p("▪","•"),Et=p("─","-"),Bt=p("╮","+"),kt=p("├","+"),Tt=p("╯","+"),Mt=p("●","•"),At=p("◆","*"),jt=p("▲","!"),Rt=p("■","x");var Vt={light:p("─","-"),heavy:p("━","="),block:p("█","#")};function Ge(){return`${Pe.gray(ze)} `}var Dt=Ge();var D="0.1.3";var y=new V("watch");y.command("detect","Detect connected watch devices").option("--verbose","Enable verbose output").action(async(e)=>{let t=l();if(e.verbose)console.log(`Searching for connected watch devices...
32
32
  `);let i=await t.detectDevices();if(i.length===0){console.log("No watch devices found."),console.log(`
33
33
  Make sure your watch is:`),console.log(" 1. Connected via USB, or"),console.log(" 2. Synced via Garmin Express (data will be read from cache)");return}console.log(`Found ${i.length} device(s):
34
34
  `);for(let s of i){if(console.log(` ${s.name}`),console.log(` Type: ${s.type}`),s.isGarminExpress)console.log(" Source: Garmin Express cache");else console.log(` Path: ${s.path}`);if(s.model)console.log(` Model: ${s.model}`);if(s.serial)console.log(` Serial: ${s.serial}`);if(s.firmware)console.log(` Firmware: ${s.firmware}`);console.log()}});y.command("download","Download data from connected watch").option("-o, --output <dir>","Output directory",{default:"./watch-data"}).option("--since <date>","Only download data after this date (YYYY-MM-DD)").option("--until <date>","Only download data before this date (YYYY-MM-DD)").option("--activities","Download activity data only").option("--monitoring","Download monitoring data only").option("--no-raw","Do not copy raw FIT files").option("--verbose","Enable verbose output").action(async(e)=>{let t=l();console.log("Detecting devices...");let i=await t.detectDevices();if(i.length===0)console.error("No watch devices found."),console.error(`
@@ -12,6 +12,11 @@ export declare interface GarminConnectConfig {
12
12
  username: string
13
13
  password: string
14
14
  }
15
+ /** A downloaded activity file, held in memory. */
16
+ export declare interface OriginalActivityFile {
17
+ bytes: Uint8Array
18
+ filename: string
19
+ }
15
20
  export declare interface GarminActivitySummary {
16
21
  activityId: number
17
22
  activityName: string
@@ -64,6 +69,11 @@ export declare interface ActivityDetailSample {
64
69
  power: number | null
65
70
  speed: number | null
66
71
  }
72
+ /**
73
+ * What Connect can export an activity as. `zip` is "Export Original", the
74
+ * device's own recording; the rest are Garmin's conversions.
75
+ */
76
+ export type GarminExportFormat = 'zip' | 'tcx' | 'gpx' | 'kml';
67
77
  export declare class GarminConnectClient {
68
78
  constructor(config?: GarminConnectConfig);
69
79
  login(username?: string, password?: string): Promise<void>;
@@ -71,7 +81,8 @@ export declare class GarminConnectClient {
71
81
  getActivities(start?: number, limit?: number): Promise<GarminActivitySummary[]>;
72
82
  getActivity(activityId: number): Promise<Activity>;
73
83
  getActivityDetails(activityId: number, maxSamples?: number): Promise<ActivityDetailSample[]>;
74
- downloadActivityFit(activityId: number, outputDir: string): Promise<void>;
84
+ downloadOriginalActivity(activityId: number, format?: GarminExportFormat): Promise<OriginalActivityFile>;
85
+ downloadActivityFit(activityId: number, outputDir: string): Promise<string>;
75
86
  getDailySummary(date: Date): Promise<DailySummary>;
76
87
  getHeartRateData(date: Date): Promise<DailyHeartRate | undefined>;
77
88
  getSleepData(date: Date): Promise<SleepData | undefined>;
@@ -8,6 +8,8 @@ export {
8
8
  type DailySummary,
9
9
  type GarminActivitySummary as GarminConnectActivitySummary,
10
10
  type GarminConnectConfig,
11
+ type GarminExportFormat,
12
+ type OriginalActivityFile,
11
13
  } from './garmin-connect';
12
14
  export * from './strava';
13
15
  export * from './trainingpeaks';