@dofek/zepp-client 0.1.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 +21 -0
- package/README.md +133 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +182 -0
- package/dist/client.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Asher Cohen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# @dofek/zepp-client
|
|
2
|
+
|
|
3
|
+
Unofficial TypeScript authentication client for the private Zepp/Amazfit cloud
|
|
4
|
+
API.
|
|
5
|
+
|
|
6
|
+
This package is not affiliated with, endorsed by, or supported by Zepp Health.
|
|
7
|
+
It reproduces a mobile-client login flow observed from Zepp applications, not a
|
|
8
|
+
supported public API contract. Private endpoints, encryption parameters,
|
|
9
|
+
headers, and response shapes may change without notice.
|
|
10
|
+
|
|
11
|
+
Review the [Zepp Terms and Conditions](https://www.zepp.com/terms-and-conditions)
|
|
12
|
+
and obtain any authorization required for your use case. Use only your own
|
|
13
|
+
account and protect all returned credentials.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Node.js 22.14 or newer
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npm install @dofek/zepp-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import {
|
|
29
|
+
signInToZepp,
|
|
30
|
+
ZeppInvalidCredentialsError,
|
|
31
|
+
ZeppLoginExchangeError,
|
|
32
|
+
} from "@dofek/zepp-client";
|
|
33
|
+
import type { ZeppSignInResult } from "@dofek/zepp-client/types";
|
|
34
|
+
|
|
35
|
+
const email = process.env.ZEPP_EMAIL;
|
|
36
|
+
const password = process.env.ZEPP_PASSWORD;
|
|
37
|
+
if (!email || !password) {
|
|
38
|
+
throw new Error("Set ZEPP_EMAIL and ZEPP_PASSWORD");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let session: ZeppSignInResult;
|
|
42
|
+
try {
|
|
43
|
+
session = await signInToZepp(email, password);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (error instanceof ZeppInvalidCredentialsError) {
|
|
46
|
+
throw new Error("Zepp rejected the email or password", { cause: error });
|
|
47
|
+
}
|
|
48
|
+
if (error instanceof ZeppLoginExchangeError) {
|
|
49
|
+
throw new Error(`Zepp token exchange failed with HTTP ${error.status}`, {
|
|
50
|
+
cause: error,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log({
|
|
57
|
+
userId: session.userId,
|
|
58
|
+
hasLoginToken: session.loginToken !== null,
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Never print `appToken` or `loginToken`. Both should be treated as secrets.
|
|
63
|
+
|
|
64
|
+
## Result and credential lifecycle
|
|
65
|
+
|
|
66
|
+
`signInToZepp(email, password, fetch?)` returns:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
interface ZeppSignInResult {
|
|
70
|
+
appToken: string;
|
|
71
|
+
userId: string;
|
|
72
|
+
loginToken: string | null;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The observed registration exchange asks Zepp for access and refresh material,
|
|
77
|
+
but this package's final token exchange exposes only `appToken`, `userId`, and
|
|
78
|
+
an optional `loginToken`. It does not expose expiry metadata, MFA handling, or a
|
|
79
|
+
refresh method. When Zepp rejects stored credentials, sign in again.
|
|
80
|
+
|
|
81
|
+
An optional compatible `fetch` implementation can be passed as the third
|
|
82
|
+
argument.
|
|
83
|
+
|
|
84
|
+
## Public API
|
|
85
|
+
|
|
86
|
+
The package root exports:
|
|
87
|
+
|
|
88
|
+
- `signInToZepp(email, password, fetch?)`
|
|
89
|
+
- `ZeppInvalidCredentialsError`
|
|
90
|
+
- `ZeppLoginExchangeError`, including its numeric `status`
|
|
91
|
+
- `ZEPP_REGISTRATION_REDIRECT_URI`
|
|
92
|
+
- `ZEPP_ENCRYPTED_REGISTRATION_URL`
|
|
93
|
+
|
|
94
|
+
The result type is a deep import:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import type { ZeppSignInResult } from "@dofek/zepp-client/types";
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Errors and rate limits
|
|
101
|
+
|
|
102
|
+
Actual package behavior:
|
|
103
|
+
|
|
104
|
+
- A rejected registration response or malformed redirect throws
|
|
105
|
+
`ZeppInvalidCredentialsError`.
|
|
106
|
+
- A non-success token-exchange response throws `ZeppLoginExchangeError` with
|
|
107
|
+
the HTTP status.
|
|
108
|
+
- Registration HTTP `429` throws a generic `Error` containing Zepp's response
|
|
109
|
+
body. The client does not parse `Retry-After`, sleep, or retry.
|
|
110
|
+
- Unexpected non-JSON token responses throw a generic `Error`.
|
|
111
|
+
- A success response with the wrong shape throws a Zod validation error.
|
|
112
|
+
- Network errors from `fetch` propagate unchanged.
|
|
113
|
+
|
|
114
|
+
## Observed private protocol
|
|
115
|
+
|
|
116
|
+
The current implementation is specifically an observed US/US2 flow:
|
|
117
|
+
|
|
118
|
+
- encrypted registration at
|
|
119
|
+
`https://api-user-us2.zepp.com/v2/registrations/tokens`
|
|
120
|
+
- an AES-128-CBC registration body matching an observed Android client
|
|
121
|
+
- manual redirect parsing to obtain an access code and country code
|
|
122
|
+
- access-code exchange at an observed US2 Mi Fit endpoint
|
|
123
|
+
- generated device identifiers and observed Zepp/Huami client headers
|
|
124
|
+
|
|
125
|
+
Country selection, client versions, and server routes are currently fixed in
|
|
126
|
+
the implementation. These details are observations, not guarantees from Zepp.
|
|
127
|
+
|
|
128
|
+
## Project
|
|
129
|
+
|
|
130
|
+
- [Source](https://github.com/Asherlc/dofek/tree/main/packages/zepp-client)
|
|
131
|
+
- [Issues](https://github.com/Asherlc/dofek/issues)
|
|
132
|
+
- [Pull requests](https://github.com/Asherlc/dofek/pulls)
|
|
133
|
+
- [MIT License](./LICENSE)
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ZeppSignInResult } from "./types.ts";
|
|
2
|
+
export declare const ZEPP_REGISTRATION_REDIRECT_URI = "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html";
|
|
3
|
+
export declare const ZEPP_ENCRYPTED_REGISTRATION_URL = "https://api-user-us2.zepp.com/v2/registrations/tokens";
|
|
4
|
+
export declare class ZeppInvalidCredentialsError extends Error {
|
|
5
|
+
constructor(options?: ErrorOptions);
|
|
6
|
+
}
|
|
7
|
+
export declare class ZeppLoginExchangeError extends Error {
|
|
8
|
+
readonly status: number;
|
|
9
|
+
constructor(status: number, options?: ErrorOptions);
|
|
10
|
+
}
|
|
11
|
+
export declare function signInToZepp(email: string, password: string, fetchFn?: typeof globalThis.fetch): Promise<ZeppSignInResult>;
|
|
12
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,eAAO,MAAM,8BAA8B,0EAC8B,CAAC;AAC1E,eAAO,MAAM,+BAA+B,0DACa,CAAC;AA0B1D,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,CAAC,EAAE,YAAY;CAInC;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKnD;AAgMD,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,OAAO,UAAU,CAAC,KAAwB,GAClD,OAAO,CAAC,gBAAgB,CAAC,CAG3B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { createCipheriv, randomUUID } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export const ZEPP_REGISTRATION_REDIRECT_URI = "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html";
|
|
4
|
+
export const ZEPP_ENCRYPTED_REGISTRATION_URL = "https://api-user-us2.zepp.com/v2/registrations/tokens";
|
|
5
|
+
const ZEPP_AES_KEY = "xeNtBVqzDc6tuNTh";
|
|
6
|
+
const ZEPP_AES_IV = "MAAAYAAAAAAAAABg";
|
|
7
|
+
const CURRENT_ZEPP_APP_NAME = "com.huami.midong";
|
|
8
|
+
const CURRENT_ZEPP_APP_VERSION = "9.12.5";
|
|
9
|
+
const CURRENT_ZEPP_CLIENT_VERSION = "151689";
|
|
10
|
+
const CURRENT_ZEPP_BUILD_VERSION = "202509151347";
|
|
11
|
+
const CURRENT_ZEPP_LOGIN_URL = "https://api-mifit-us2.zepp.com/v2/client/login";
|
|
12
|
+
const CURRENT_ZEPP_DN = "api-mifit.zepp.com,api-user.zepp.com,api-mifit.zepp.com,api-watch.zepp.com,app-analytics.zepp.com,auth.zepp.com,api-analytics.zepp.com";
|
|
13
|
+
const zeppTokenInfoSchema = z.object({
|
|
14
|
+
app_token: z.string(),
|
|
15
|
+
user_id: z.union([z.string(), z.number()]).transform(String),
|
|
16
|
+
login_token: z.string().optional(),
|
|
17
|
+
});
|
|
18
|
+
const zeppLoginResponseSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
token_info: zeppTokenInfoSchema.optional(),
|
|
21
|
+
result: z.string().optional(),
|
|
22
|
+
message: z.string().optional(),
|
|
23
|
+
})
|
|
24
|
+
.passthrough();
|
|
25
|
+
export class ZeppInvalidCredentialsError extends Error {
|
|
26
|
+
constructor(options) {
|
|
27
|
+
super("Amazfit/Zepp login failed: invalid email or password", options);
|
|
28
|
+
this.name = new.target.name;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class ZeppLoginExchangeError extends Error {
|
|
32
|
+
status;
|
|
33
|
+
constructor(status, options) {
|
|
34
|
+
super(`Amazfit/Zepp login error (${status})`, options);
|
|
35
|
+
this.name = new.target.name;
|
|
36
|
+
this.status = status;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function parseRedirectCredentials(location, baseUrl) {
|
|
40
|
+
const redirectUrl = new URL(location, baseUrl);
|
|
41
|
+
const accessCode = redirectUrl.searchParams.get("access");
|
|
42
|
+
const countryCode = redirectUrl.searchParams.get("country_code");
|
|
43
|
+
if (!accessCode || !countryCode) {
|
|
44
|
+
throw new ZeppInvalidCredentialsError();
|
|
45
|
+
}
|
|
46
|
+
return { accessCode, countryCode };
|
|
47
|
+
}
|
|
48
|
+
function encryptZeppRegistrationBody(body) {
|
|
49
|
+
const cipher = createCipheriv("aes-128-cbc", Buffer.from(ZEPP_AES_KEY), Buffer.from(ZEPP_AES_IV));
|
|
50
|
+
const encrypted = Buffer.concat([cipher.update(body.toString(), "utf8"), cipher.final()]);
|
|
51
|
+
return new Uint8Array(encrypted);
|
|
52
|
+
}
|
|
53
|
+
function currentZeppRegistrationHeaders() {
|
|
54
|
+
return {
|
|
55
|
+
"accept-encoding": "gzip",
|
|
56
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
57
|
+
"user-agent": `Zepp/${CURRENT_ZEPP_APP_VERSION} (Pixel 4; Android 12; Density/2.75)`,
|
|
58
|
+
app_name: CURRENT_ZEPP_APP_NAME,
|
|
59
|
+
appname: CURRENT_ZEPP_APP_NAME,
|
|
60
|
+
appplatform: "android_phone",
|
|
61
|
+
cv: `${CURRENT_ZEPP_CLIENT_VERSION}_${CURRENT_ZEPP_APP_VERSION}`,
|
|
62
|
+
v: "2.0",
|
|
63
|
+
vb: CURRENT_ZEPP_BUILD_VERSION,
|
|
64
|
+
vn: CURRENT_ZEPP_APP_VERSION,
|
|
65
|
+
"x-hm-ekv": "1",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function currentZeppLoginHeaders() {
|
|
69
|
+
return {
|
|
70
|
+
"accept-language": "en-US,en;q=0.5",
|
|
71
|
+
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
72
|
+
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
|
|
73
|
+
accept: "application/json, text/plain, */*",
|
|
74
|
+
app_name: "com.huami.webapp",
|
|
75
|
+
appname: "com.huami.webapp",
|
|
76
|
+
origin: "https://user.zepp.com",
|
|
77
|
+
referer: "https://user.zepp.com/",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function invalidCredentialsError(options) {
|
|
81
|
+
return new ZeppInvalidCredentialsError(options);
|
|
82
|
+
}
|
|
83
|
+
function rateLimitError(responseBody) {
|
|
84
|
+
return new Error(`Amazfit/Zepp login failed: ${responseBody}`);
|
|
85
|
+
}
|
|
86
|
+
async function getEncryptedRegistrationCredentials(email, password, fetchFn) {
|
|
87
|
+
const registrationBody = new URLSearchParams({
|
|
88
|
+
emailOrPhone: email,
|
|
89
|
+
password,
|
|
90
|
+
state: "REDIRECTION",
|
|
91
|
+
client_id: "HuaMi",
|
|
92
|
+
region: "us-west-2",
|
|
93
|
+
country_code: "US",
|
|
94
|
+
redirect_uri: ZEPP_REGISTRATION_REDIRECT_URI,
|
|
95
|
+
});
|
|
96
|
+
registrationBody.append("token", "access");
|
|
97
|
+
registrationBody.append("token", "refresh");
|
|
98
|
+
const registrationResponse = await fetchFn(ZEPP_ENCRYPTED_REGISTRATION_URL, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: currentZeppRegistrationHeaders(),
|
|
101
|
+
body: encryptZeppRegistrationBody(registrationBody),
|
|
102
|
+
redirect: "manual",
|
|
103
|
+
});
|
|
104
|
+
if (registrationResponse.status === 429) {
|
|
105
|
+
throw rateLimitError(await registrationResponse.text());
|
|
106
|
+
}
|
|
107
|
+
if (registrationResponse.status !== 302 && registrationResponse.status !== 303) {
|
|
108
|
+
await registrationResponse.text();
|
|
109
|
+
throw invalidCredentialsError();
|
|
110
|
+
}
|
|
111
|
+
const location = registrationResponse.headers.get("location");
|
|
112
|
+
if (!location) {
|
|
113
|
+
throw invalidCredentialsError();
|
|
114
|
+
}
|
|
115
|
+
const { accessCode, countryCode } = parseRedirectCredentials(location, ZEPP_ENCRYPTED_REGISTRATION_URL);
|
|
116
|
+
return {
|
|
117
|
+
accessCode,
|
|
118
|
+
appName: CURRENT_ZEPP_APP_NAME,
|
|
119
|
+
appVersion: CURRENT_ZEPP_APP_VERSION,
|
|
120
|
+
countryCode,
|
|
121
|
+
countryState: "US-NY",
|
|
122
|
+
deviceId: randomUUID(),
|
|
123
|
+
headers: currentZeppLoginHeaders(),
|
|
124
|
+
loginUrl: CURRENT_ZEPP_LOGIN_URL,
|
|
125
|
+
thirdName: "huami",
|
|
126
|
+
source: `com.huami.watch.hmwatchmanager:${CURRENT_ZEPP_APP_VERSION}:${CURRENT_ZEPP_CLIENT_VERSION}`,
|
|
127
|
+
dn: CURRENT_ZEPP_DN,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
async function performTokenExchange(credentials, fetchFn) {
|
|
131
|
+
const loginBody = new URLSearchParams({
|
|
132
|
+
app_name: credentials.appName,
|
|
133
|
+
dn: credentials.dn,
|
|
134
|
+
device_id: credentials.deviceId,
|
|
135
|
+
device_model: "android_phone",
|
|
136
|
+
app_version: credentials.appVersion,
|
|
137
|
+
allow_registration: "false",
|
|
138
|
+
third_name: credentials.thirdName,
|
|
139
|
+
grant_type: "access_token",
|
|
140
|
+
country_code: credentials.countryCode,
|
|
141
|
+
code: credentials.accessCode,
|
|
142
|
+
});
|
|
143
|
+
if (credentials.source) {
|
|
144
|
+
loginBody.set("source", credentials.source);
|
|
145
|
+
loginBody.set("lang", "en");
|
|
146
|
+
}
|
|
147
|
+
loginBody.set("countryState", credentials.countryState);
|
|
148
|
+
const loginResponse = await fetchFn(credentials.loginUrl, {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers: credentials.headers,
|
|
151
|
+
body: loginBody.toString(),
|
|
152
|
+
});
|
|
153
|
+
const responseBody = await loginResponse.text();
|
|
154
|
+
if (!loginResponse.ok) {
|
|
155
|
+
throw new ZeppLoginExchangeError(loginResponse.status);
|
|
156
|
+
}
|
|
157
|
+
let parsedBody;
|
|
158
|
+
try {
|
|
159
|
+
parsedBody = JSON.parse(responseBody);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
throw new Error("Amazfit/Zepp login error: unexpected non-JSON response from Zepp");
|
|
163
|
+
}
|
|
164
|
+
const payload = zeppLoginResponseSchema.parse(parsedBody);
|
|
165
|
+
const tokenInfo = payload.token_info;
|
|
166
|
+
if (!tokenInfo) {
|
|
167
|
+
throw new Error(payload.message ?? payload.result ?? "Amazfit/Zepp login failed: missing token_info");
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
appToken: tokenInfo.app_token,
|
|
171
|
+
userId: tokenInfo.user_id,
|
|
172
|
+
loginToken: tokenInfo.login_token ?? null,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
async function exchangeAccessCodeForToken(credentials, fetchFn) {
|
|
176
|
+
return await performTokenExchange(credentials, fetchFn);
|
|
177
|
+
}
|
|
178
|
+
export async function signInToZepp(email, password, fetchFn = globalThis.fetch) {
|
|
179
|
+
const encryptedCredentials = await getEncryptedRegistrationCredentials(email, password, fetchFn);
|
|
180
|
+
return await exchangeAccessCodeForToken(encryptedCredentials, fetchFn);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dofek/zepp-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unofficial Zepp/Amazfit API client using reverse-engineered Huami authentication",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Asherlc/dofek.git",
|
|
10
|
+
"directory": "packages/zepp-client"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Asherlc/dofek/tree/main/packages/zepp-client#readme",
|
|
13
|
+
"bugs": "https://github.com/Asherlc/dofek/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"zepp",
|
|
16
|
+
"amazfit",
|
|
17
|
+
"huami",
|
|
18
|
+
"api-client",
|
|
19
|
+
"unofficial"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22.14.0"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/client.d.ts",
|
|
33
|
+
"import": "./dist/client.js"
|
|
34
|
+
},
|
|
35
|
+
"./*": {
|
|
36
|
+
"types": "./dist/*.d.ts",
|
|
37
|
+
"import": "./dist/*.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest --watch",
|
|
46
|
+
"build": "tsc",
|
|
47
|
+
"prepack": "pnpm run build",
|
|
48
|
+
"lint": "biome check .",
|
|
49
|
+
"typecheck": "tsc --noEmit"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"zod": "4.4.3"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "22.19.15",
|
|
56
|
+
"typescript": "6.0.3",
|
|
57
|
+
"vitest": "3.2.6"
|
|
58
|
+
},
|
|
59
|
+
"gitHead": "ac95258c753c7e75b57da7ae47426d22b78e8c01"
|
|
60
|
+
}
|