@molecule/api-wearable-fitbit 1.0.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.
- package/LICENSE +115 -0
- package/dist/browser-guard.d.ts +2 -0
- package/dist/browser-guard.d.ts.map +1 -0
- package/dist/browser-guard.js +19 -0
- package/dist/browser-guard.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +175 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +605 -0
- package/dist/provider.js.map +1 -0
- package/dist/secrets.d.ts +16 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +30 -0
- package/dist/secrets.js.map +1 -0
- package/dist/types.d.ts +165 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/dist/secrets.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fitbit wearable bond secret definitions — self-registered at import time so the
|
|
3
|
+
* runtime secrets registry (`@molecule/api-secrets`) can drive boot-time
|
|
4
|
+
* configuration reports and actionable "not configured" errors.
|
|
5
|
+
*
|
|
6
|
+
* Content is derived MECHANICALLY from this package's mlcl registry secrets
|
|
7
|
+
* entry (label/instructions/setupUrl/example) via the fleet formula, so
|
|
8
|
+
* packages sharing a key register byte-identical definitions and
|
|
9
|
+
* registration order never matters.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { registerSecrets } from '@molecule/api-secrets';
|
|
14
|
+
/** Secret definitions required by the Fitbit wearable bond. */
|
|
15
|
+
export const wearableFitbitSecretDefinitions = [
|
|
16
|
+
{
|
|
17
|
+
key: 'OAUTH_FITBIT_CLIENT_ID',
|
|
18
|
+
description: 'Fitbit OAuth client ID — Register an application at dev.fitbit.com and copy the OAuth 2.0 Client ID.',
|
|
19
|
+
helpUrl: 'https://dev.fitbit.com/apps',
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
key: 'OAUTH_FITBIT_CLIENT_SECRET',
|
|
24
|
+
description: 'Fitbit client secret — Shown on your registered Fitbit application page.',
|
|
25
|
+
helpUrl: 'https://dev.fitbit.com/apps',
|
|
26
|
+
required: false,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
registerSecrets(wearableFitbitSecretDefinitions);
|
|
30
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,+BAA+B,GAAuB;IACjE;QACE,GAAG,EAAE,wBAAwB;QAC7B,WAAW,EACT,sGAAsG;QACxG,OAAO,EAAE,6BAA6B;QACtC,QAAQ,EAAE,IAAI;KACf;IACD;QACE,GAAG,EAAE,4BAA4B;QACjC,WAAW,EAAE,0EAA0E;QACvF,OAAO,EAAE,6BAA6B;QACtC,QAAQ,EAAE,KAAK;KAChB;CACF,CAAA;AAED,eAAe,CAAC,+BAA+B,CAAC,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fitbit wearable bond types for molecule.dev.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { UserConnection as WearableUserConnection, WearableCredentialsStore, WearableProvider as WearableProviderType } from '@molecule/api-wearable';
|
|
7
|
+
export type { DailyActivity, HeartRateSummary, HeartRateZone, SleepSession, SleepStage, SleepStageSegment, SleepStageSummary, UserConnection, WearableCredentialsStore, WearableDate, WearableDateRange, WearableProvider, WeightEntry, } from '@molecule/api-wearable';
|
|
8
|
+
declare global {
|
|
9
|
+
namespace NodeJS {
|
|
10
|
+
/**
|
|
11
|
+
* Process Env interface.
|
|
12
|
+
*/
|
|
13
|
+
interface ProcessEnv {
|
|
14
|
+
/**
|
|
15
|
+
* The Fitbit OAuth client ID. Required to mint and refresh access
|
|
16
|
+
* tokens. Treated as a public identifier — sent in `client_id`
|
|
17
|
+
* during PKCE — but still configured as a secret for symmetry.
|
|
18
|
+
*
|
|
19
|
+
* @see https://dev.fitbit.com/build/reference/web-api/authorization/
|
|
20
|
+
*/
|
|
21
|
+
OAUTH_FITBIT_CLIENT_ID?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The Fitbit OAuth client secret. Required for confidential-client
|
|
24
|
+
* apps to refresh tokens via Basic auth. PKCE-only public clients
|
|
25
|
+
* may omit it (the bond falls back to the PKCE-only token call when
|
|
26
|
+
* absent).
|
|
27
|
+
*
|
|
28
|
+
* @see https://dev.fitbit.com/build/reference/web-api/authorization/
|
|
29
|
+
*/
|
|
30
|
+
OAUTH_FITBIT_CLIENT_SECRET?: string;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Cache of `code_verifier` strings keyed by the in-flight authorization
|
|
36
|
+
* `code` string they were paired with.
|
|
37
|
+
*
|
|
38
|
+
* The Fitbit OAuth callback hands the bond an authorization `code` but
|
|
39
|
+
* not the `code_verifier` it was created with — the bond needs to store
|
|
40
|
+
* the verifier between {@link FitbitProvider.startAuthorize} and
|
|
41
|
+
* {@link FitbitProvider.connect}. The store contract leaves the choice
|
|
42
|
+
* of backing storage (Redis, Postgres, in-memory for tests) to the host.
|
|
43
|
+
*/
|
|
44
|
+
export interface FitbitCodeVerifierStore {
|
|
45
|
+
/**
|
|
46
|
+
* Persists the verifier indexed by the `state` value the bond will
|
|
47
|
+
* round-trip through Fitbit's authorize redirect.
|
|
48
|
+
*
|
|
49
|
+
* @param state - Opaque CSRF-protection token returned in the redirect.
|
|
50
|
+
* @param verifier - The PKCE `code_verifier` to retrieve later.
|
|
51
|
+
*/
|
|
52
|
+
put(state: string, verifier: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Retrieves and deletes the verifier associated with `state`.
|
|
55
|
+
* Implementations MUST delete on read so a verifier is never reused.
|
|
56
|
+
*
|
|
57
|
+
* @param state - The `state` value extracted from the OAuth callback.
|
|
58
|
+
* @returns The verifier, or `null` if no entry exists.
|
|
59
|
+
*/
|
|
60
|
+
take(state: string): Promise<string | null>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Configuration options for {@link createProvider}.
|
|
64
|
+
*/
|
|
65
|
+
export interface FitbitProviderOptions {
|
|
66
|
+
/**
|
|
67
|
+
* OAuth client id. Defaults to `process.env.OAUTH_FITBIT_CLIENT_ID`.
|
|
68
|
+
*/
|
|
69
|
+
clientId?: string;
|
|
70
|
+
/**
|
|
71
|
+
* OAuth client secret. Defaults to
|
|
72
|
+
* `process.env.OAUTH_FITBIT_CLIENT_SECRET`. Optional — PKCE-only public
|
|
73
|
+
* clients omit it.
|
|
74
|
+
*/
|
|
75
|
+
clientSecret?: string;
|
|
76
|
+
/**
|
|
77
|
+
* OAuth redirect URI registered with the Fitbit application. Required
|
|
78
|
+
* to complete the authorization-code exchange.
|
|
79
|
+
*/
|
|
80
|
+
redirectUri: string;
|
|
81
|
+
/**
|
|
82
|
+
* Persists user connections (access + refresh tokens). Required.
|
|
83
|
+
*/
|
|
84
|
+
credentialsStore: WearableCredentialsStore;
|
|
85
|
+
/**
|
|
86
|
+
* Optional store for PKCE `code_verifier` strings keyed by `state`.
|
|
87
|
+
* Required if the bond's `startAuthorize` / `connect` helpers are used
|
|
88
|
+
* to drive the OAuth flow; the host may omit it when wiring the OAuth
|
|
89
|
+
* exchange themselves.
|
|
90
|
+
*/
|
|
91
|
+
codeVerifierStore?: FitbitCodeVerifierStore;
|
|
92
|
+
/**
|
|
93
|
+
* OAuth scopes to request when starting authorization. Defaults to the
|
|
94
|
+
* union needed for activity, sleep, heart-rate, and weight reads.
|
|
95
|
+
*/
|
|
96
|
+
scopes?: readonly string[];
|
|
97
|
+
/**
|
|
98
|
+
* Override the Fitbit Web API base URL. Defaults to
|
|
99
|
+
* `https://api.fitbit.com/1`.
|
|
100
|
+
*/
|
|
101
|
+
apiBaseUrl?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Override the Fitbit OAuth authorize endpoint. Defaults to
|
|
104
|
+
* `https://www.fitbit.com/oauth2/authorize`.
|
|
105
|
+
*/
|
|
106
|
+
authorizeUrl?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Override the Fitbit OAuth token endpoint. Defaults to
|
|
109
|
+
* `https://api.fitbit.com/oauth2/token`.
|
|
110
|
+
*/
|
|
111
|
+
tokenUrl?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Override the Fitbit OAuth token-revoke endpoint. Defaults to
|
|
114
|
+
* `https://api.fitbit.com/oauth2/revoke`.
|
|
115
|
+
*/
|
|
116
|
+
revokeUrl?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Request timeout in milliseconds. Defaults to `15_000`.
|
|
119
|
+
*/
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
/**
|
|
122
|
+
* Optional override for the random-bytes generator used by PKCE / CSRF.
|
|
123
|
+
* Tests inject a deterministic generator.
|
|
124
|
+
*/
|
|
125
|
+
randomBytes?: (size: number) => Uint8Array;
|
|
126
|
+
/**
|
|
127
|
+
* Optional clock override, primarily for tests. Defaults to `Date.now`.
|
|
128
|
+
*/
|
|
129
|
+
now?: () => number;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Result of {@link FitbitProvider.startAuthorize} — the URL the host
|
|
133
|
+
* should redirect the user to plus the `state` value to round-trip.
|
|
134
|
+
*/
|
|
135
|
+
export interface FitbitAuthorizeStart {
|
|
136
|
+
/** Fitbit OAuth authorize URL. */
|
|
137
|
+
url: string;
|
|
138
|
+
/** Opaque `state` value the host MUST verify on the callback. */
|
|
139
|
+
state: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Public surface returned by {@link createProvider}. Extends the
|
|
143
|
+
* stack-neutral {@link import('@molecule/api-wearable').WearableProvider}
|
|
144
|
+
* with Fitbit-specific OAuth-flow helpers.
|
|
145
|
+
*/
|
|
146
|
+
export interface FitbitProvider extends WearableProviderType {
|
|
147
|
+
/**
|
|
148
|
+
* Builds the Fitbit authorize URL and persists a fresh PKCE verifier.
|
|
149
|
+
*
|
|
150
|
+
* @returns The URL to redirect to and the round-trip `state` value.
|
|
151
|
+
*/
|
|
152
|
+
startAuthorize(): Promise<FitbitAuthorizeStart>;
|
|
153
|
+
/**
|
|
154
|
+
* Performs the authorization-code → token exchange with an explicit
|
|
155
|
+
* PKCE `code_verifier`. Use this when the host wires the OAuth flow
|
|
156
|
+
* itself (no `codeVerifierStore` configured).
|
|
157
|
+
*
|
|
158
|
+
* @param userId - Host-app user identifier.
|
|
159
|
+
* @param code - OAuth authorization `code` from the redirect callback.
|
|
160
|
+
* @param verifier - The PKCE `code_verifier` used to derive the challenge.
|
|
161
|
+
* @returns The freshly-minted user connection (already persisted).
|
|
162
|
+
*/
|
|
163
|
+
connectWithVerifier(userId: string, code: string, verifier: string): Promise<WearableUserConnection>;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,cAAc,IAAI,sBAAsB,EACxC,wBAAwB,EACxB,gBAAgB,IAAI,oBAAoB,EACzC,MAAM,wBAAwB,CAAA;AAE/B,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,GACZ,MAAM,wBAAwB,CAAA;AAE/B,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,MAAM,CAAC;QACf;;WAEG;QACH,UAAiB,UAAU;YACzB;;;;;;eAMG;YACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;YAE/B;;;;;;;eAOG;YACH,0BAA0B,CAAC,EAAE,MAAM,CAAA;SACpC;KACF;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,gBAAgB,EAAE,wBAAwB,CAAA;IAC1C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,CAAA;IAC3C;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,CAAA;IAC1C;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC1D;;;;OAIG;IACH,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC/C;;;;;;;;;OASG;IACH,mBAAmB,CACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,CAAC,CAAA;CACnC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@molecule/api-wearable-fitbit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fitbit Web API bond for molecule.dev — daily activity, sleep, heart-rate, and weight ingestion via OAuth 2.0 PKCE",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:watch": "vitest"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"molecule",
|
|
24
|
+
"wearable",
|
|
25
|
+
"fitbit",
|
|
26
|
+
"fitness",
|
|
27
|
+
"sleep",
|
|
28
|
+
"heart-rate",
|
|
29
|
+
"oauth"
|
|
30
|
+
],
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@molecule/api-bond": "^1.0.0",
|
|
34
|
+
"@molecule/api-http": "^1.0.0",
|
|
35
|
+
"@molecule/api-secrets": "^1.0.0",
|
|
36
|
+
"@molecule/api-wearable": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@molecule/api-bond": "1.0.0",
|
|
40
|
+
"@molecule/api-http": "1.0.0",
|
|
41
|
+
"@molecule/api-wearable": "1.0.0",
|
|
42
|
+
"@types/node": "26.1.2",
|
|
43
|
+
"typescript": "6.0.3",
|
|
44
|
+
"vitest": "4.1.10"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/molecule-dev/molecule.git",
|
|
49
|
+
"directory": "packages/api/bonds/wearable/fitbit"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/molecule-dev/molecule/tree/main/packages/api/bonds/wearable/fitbit",
|
|
52
|
+
"bugs": "https://github.com/molecule-dev/molecule/issues",
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
}
|
|
56
|
+
}
|