memobirdsdk 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/README.md +483 -0
- package/dist/api/bind.d.ts +24 -0
- package/dist/api/bind.d.ts.map +1 -0
- package/dist/api/bind.js +49 -0
- package/dist/api/bind.js.map +1 -0
- package/dist/api/image.d.ts +25 -0
- package/dist/api/image.d.ts.map +1 -0
- package/dist/api/image.js +46 -0
- package/dist/api/image.js.map +1 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +9 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/print.d.ts +71 -0
- package/dist/api/print.d.ts.map +1 -0
- package/dist/api/print.js +147 -0
- package/dist/api/print.js.map +1 -0
- package/dist/api/status.d.ts +24 -0
- package/dist/api/status.d.ts.map +1 -0
- package/dist/api/status.js +47 -0
- package/dist/api/status.js.map +1 -0
- package/dist/client.d.ts +204 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +250 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +23 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors/APIError.d.ts +16 -0
- package/dist/errors/APIError.d.ts.map +1 -0
- package/dist/errors/APIError.js +21 -0
- package/dist/errors/APIError.js.map +1 -0
- package/dist/errors/MemobirdError.d.ts +13 -0
- package/dist/errors/MemobirdError.d.ts.map +1 -0
- package/dist/errors/MemobirdError.js +18 -0
- package/dist/errors/MemobirdError.js.map +1 -0
- package/dist/errors/NetworkError.d.ts +14 -0
- package/dist/errors/NetworkError.d.ts.map +1 -0
- package/dist/errors/NetworkError.js +18 -0
- package/dist/errors/NetworkError.js.map +1 -0
- package/dist/errors/ValidationError.d.ts +14 -0
- package/dist/errors/ValidationError.d.ts.map +1 -0
- package/dist/errors/ValidationError.js +18 -0
- package/dist/errors/ValidationError.js.map +1 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +9 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/types/api.d.ts +122 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +2 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/common.d.ts +27 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +15 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/config.d.ts +32 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/content-formatter.d.ts +49 -0
- package/dist/utils/content-formatter.d.ts.map +1 -0
- package/dist/utils/content-formatter.js +65 -0
- package/dist/utils/content-formatter.js.map +1 -0
- package/dist/utils/encoding.d.ts +32 -0
- package/dist/utils/encoding.d.ts.map +1 -0
- package/dist/utils/encoding.js +50 -0
- package/dist/utils/encoding.js.map +1 -0
- package/dist/utils/image.d.ts +42 -0
- package/dist/utils/image.d.ts.map +1 -0
- package/dist/utils/image.js +58 -0
- package/dist/utils/image.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/retry.d.ts +70 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +132 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/timestamp.d.ts +27 -0
- package/dist/utils/timestamp.d.ts.map +1 -0
- package/dist/utils/timestamp.js +38 -0
- package/dist/utils/timestamp.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# Memobird SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for [Memobird (咕咕机)](http://www.memobird.cn) thermal printer API. This SDK provides a complete, type-safe interface for controlling Memobird devices with comprehensive error handling and automatic retry capabilities.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Full TypeScript support** with comprehensive type definitions
|
|
8
|
+
- ✅ **Automatic GBK encoding** for Chinese characters
|
|
9
|
+
- ✅ **Retry mechanism** with exponential backoff
|
|
10
|
+
- ✅ **Image processing** utilities for converting JPG/PNG to monochrome bitmap
|
|
11
|
+
- ✅ **Complete JSDoc** documentation for all functions
|
|
12
|
+
- ✅ **ESM module** format
|
|
13
|
+
- ✅ **Error handling** with custom error classes
|
|
14
|
+
- ✅ **Promise-based** async/await API
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install memobirdsdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For examples, also install dotenv to manage environment variables:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install dotenv
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { MemobirdClient } from 'memobirdsdk';
|
|
32
|
+
|
|
33
|
+
// Initialize the client
|
|
34
|
+
const client = new MemobirdClient({
|
|
35
|
+
ak: 'your-access-key-from-open.memobird.cn'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Bind user to device
|
|
39
|
+
const bindResult = await client.bindUser('device-id', 'user-123');
|
|
40
|
+
const userId = bindResult.showapi_userid!;
|
|
41
|
+
|
|
42
|
+
// Print text (auto-converts Chinese to GBK)
|
|
43
|
+
await client.printText('Hello World! 你好世界!', 'device-id', userId);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Using Environment Variables (Recommended)
|
|
47
|
+
|
|
48
|
+
For better security, use environment variables to store sensitive information:
|
|
49
|
+
|
|
50
|
+
1. Create a `.env` file in your project root:
|
|
51
|
+
|
|
52
|
+
```env
|
|
53
|
+
MEMOBIRD_AK=your-access-key-here
|
|
54
|
+
MEMOBIRD_DEVICE_ID=your-device-id-here
|
|
55
|
+
MEMOBIRD_USER_ID=your-user-identifier-here
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. Use dotenv in your code:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import 'dotenv/config';
|
|
62
|
+
import { MemobirdClient } from 'memobirdsdk';
|
|
63
|
+
|
|
64
|
+
const client = new MemobirdClient({
|
|
65
|
+
ak: process.env.MEMOBIRD_AK!
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const deviceId = process.env.MEMOBIRD_DEVICE_ID!;
|
|
69
|
+
const userId = process.env.MEMOBIRD_USER_ID!;
|
|
70
|
+
|
|
71
|
+
await client.printText('Hello!', deviceId, parseInt(userId, 10));
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Important**: Add `.env` to your `.gitignore` to avoid committing sensitive credentials!
|
|
75
|
+
|
|
76
|
+
## Testing Your Setup
|
|
77
|
+
|
|
78
|
+
To quickly test if everything is working, use the built-in test function:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm test
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This will:
|
|
85
|
+
- ✅ Verify your environment variables are set
|
|
86
|
+
- ✅ Test the API connection and user binding
|
|
87
|
+
- ✅ Print a debug slip with system information
|
|
88
|
+
- ✅ Display detailed status and error messages
|
|
89
|
+
|
|
90
|
+
The printed slip will include:
|
|
91
|
+
- Current date and time
|
|
92
|
+
- System information (hostname, platform, Node.js version)
|
|
93
|
+
- Network status
|
|
94
|
+
- Device and user IDs
|
|
95
|
+
- API call results
|
|
96
|
+
|
|
97
|
+
### Available Scripts
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm test # Run test and print debug slip
|
|
101
|
+
npm run example:basic # Run basic usage example
|
|
102
|
+
npm run example:text # Run text printing examples
|
|
103
|
+
npm run example:image # Run image printing examples
|
|
104
|
+
npm run example:advanced # Run advanced usage examples
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Getting Started
|
|
108
|
+
|
|
109
|
+
### 1. Get Your Access Key
|
|
110
|
+
|
|
111
|
+
1. Visit [open.memobird.cn](http://open.memobird.cn)
|
|
112
|
+
2. Register as a developer
|
|
113
|
+
3. Get your Access Key (ak) from your user dashboard
|
|
114
|
+
|
|
115
|
+
### 2. Get Your Device ID
|
|
116
|
+
|
|
117
|
+
Double-click your Memobird device to print out the device ID.
|
|
118
|
+
|
|
119
|
+
### 3. Bind User to Device
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const client = new MemobirdClient({ ak: 'your-access-key' });
|
|
123
|
+
|
|
124
|
+
const bindResult = await client.bindUser('fb93bfff504c020a', 'user-123');
|
|
125
|
+
console.log('User ID:', bindResult.showapi_userid);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## API Reference
|
|
129
|
+
|
|
130
|
+
### MemobirdClient
|
|
131
|
+
|
|
132
|
+
#### Constructor
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
new MemobirdClient(config: MemobirdConfig)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Parameters:**
|
|
139
|
+
- `config.ak` (required): Access Key from open.memobird.cn
|
|
140
|
+
- `config.baseUrl` (optional): API base URL (default: `'http://open.memobird.cn/home'`)
|
|
141
|
+
- `config.timeout` (optional): Request timeout in milliseconds (default: `30000`)
|
|
142
|
+
- `config.retry` (optional): Retry configuration
|
|
143
|
+
- `maxRetries`: Maximum retry attempts (default: `3`)
|
|
144
|
+
- `initialDelay`: Initial delay before first retry in ms (default: `1000`)
|
|
145
|
+
- `backoffMultiplier`: Exponential backoff multiplier (default: `2`)
|
|
146
|
+
- `maxDelay`: Maximum delay between retries in ms (default: `10000`)
|
|
147
|
+
- `retryStatusCodes`: HTTP status codes to retry (default: `[408, 429, 500, 502, 503, 504]`)
|
|
148
|
+
|
|
149
|
+
**Example:**
|
|
150
|
+
```typescript
|
|
151
|
+
const client = new MemobirdClient({
|
|
152
|
+
ak: 'your-access-key',
|
|
153
|
+
timeout: 60000,
|
|
154
|
+
retry: {
|
|
155
|
+
maxRetries: 5,
|
|
156
|
+
initialDelay: 2000
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Methods
|
|
162
|
+
|
|
163
|
+
##### bindUser(memobirdID, useridentifying)
|
|
164
|
+
|
|
165
|
+
Binds a user identifier to a device.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
await client.bindUser(memobirdID: string, useridentifying: string): Promise<BindUserResponse>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Returns:** `{ showapi_res_code, showapi_res_error, showapi_userid }`
|
|
172
|
+
|
|
173
|
+
##### printText(text, memobirdID, userID)
|
|
174
|
+
|
|
175
|
+
Prints text content. Automatically converts UTF-8 to GBK encoding for Chinese characters.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
await client.printText(text: string, memobirdID: string, userID: number): Promise<PrintResponse>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Returns:** `{ showapi_res_code, showapi_res_error, result, printcontentid, smartGuid }`
|
|
182
|
+
|
|
183
|
+
##### printImage(base64Image, memobirdID, userID)
|
|
184
|
+
|
|
185
|
+
Prints monochrome bitmap image.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
await client.printImage(base64Image: string, memobirdID: string, userID: number): Promise<PrintResponse>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Note:** Image must be converted to monochrome bitmap first using `convertImageToMonochrome()`.
|
|
192
|
+
|
|
193
|
+
##### printFromUrl(url, memobirdID, userID)
|
|
194
|
+
|
|
195
|
+
Prints content from a web URL.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
await client.printFromUrl(url: string, memobirdID: string, userID: number): Promise<PrintResponse>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Note:** Works best with static or server-rendered pages. Images must use complete URLs.
|
|
202
|
+
|
|
203
|
+
##### printFromHtml(html, memobirdID, userID)
|
|
204
|
+
|
|
205
|
+
Prints content from HTML source.
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
await client.printFromHtml(html: string, memobirdID: string, userID: number): Promise<PrintResponse>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Note:** CSS must be inline, images must use complete URLs.
|
|
212
|
+
|
|
213
|
+
##### getPrintStatus(printcontentid)
|
|
214
|
+
|
|
215
|
+
Gets print status of a submitted job.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
await client.getPrintStatus(printcontentid: string | number): Promise<PrintStatusResponse>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Returns:** `{ showapi_res_code, showapi_res_error, printflag, printcontentID }`
|
|
222
|
+
- `printflag === 1`: Printed successfully
|
|
223
|
+
- `printflag === 0`: Pending or failed
|
|
224
|
+
|
|
225
|
+
##### convertImageToMonochrome(base64Image)
|
|
226
|
+
|
|
227
|
+
Converts JPG/PNG to monochrome bitmap for printing.
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
await client.convertImageToMonochrome(base64Image: string): Promise<ConvertImageResponse>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Returns:** `{ showapi_res_code, showapi_res_error, result }`
|
|
234
|
+
|
|
235
|
+
## Examples
|
|
236
|
+
|
|
237
|
+
### Print Text
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { MemobirdClient } from 'memobirdsdk';
|
|
241
|
+
|
|
242
|
+
const client = new MemobirdClient({ ak: 'your-ak' });
|
|
243
|
+
|
|
244
|
+
// Simple text
|
|
245
|
+
await client.printText('Hello World!', 'device-id', userId);
|
|
246
|
+
|
|
247
|
+
// Chinese text (auto-converts to GBK)
|
|
248
|
+
await client.printText('你好世界!', 'device-id', userId);
|
|
249
|
+
|
|
250
|
+
// Multiline text
|
|
251
|
+
await client.printText(`Line 1
|
|
252
|
+
Line 2
|
|
253
|
+
Line 3`, 'device-id', userId);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Print Image
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { MemobirdClient, imageFileToBase64 } from 'memobirdsdk';
|
|
260
|
+
|
|
261
|
+
const client = new MemobirdClient({ ak: 'your-ak' });
|
|
262
|
+
|
|
263
|
+
// Load image from file
|
|
264
|
+
const jpgBase64 = await imageFileToBase64('./image.jpg');
|
|
265
|
+
|
|
266
|
+
// Convert to monochrome bitmap
|
|
267
|
+
const converted = await client.convertImageToMonochrome(jpgBase64);
|
|
268
|
+
|
|
269
|
+
// Print the image
|
|
270
|
+
await client.printImage(converted.result!, 'device-id', userId);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Print HTML
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const html = `
|
|
277
|
+
<!DOCTYPE html>
|
|
278
|
+
<html>
|
|
279
|
+
<head>
|
|
280
|
+
<style>
|
|
281
|
+
body { font-family: Arial; }
|
|
282
|
+
h1 { font-size: 24px; }
|
|
283
|
+
</style>
|
|
284
|
+
</head>
|
|
285
|
+
<body>
|
|
286
|
+
<h1>Receipt</h1>
|
|
287
|
+
<p>Total: $10.00</p>
|
|
288
|
+
</body>
|
|
289
|
+
</html>
|
|
290
|
+
`;
|
|
291
|
+
|
|
292
|
+
await client.printFromHtml(html, 'device-id', userId);
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Error Handling
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { MemobirdClient, APIError, NetworkError } from 'memobirdsdk';
|
|
299
|
+
|
|
300
|
+
const client = new MemobirdClient({ ak: 'your-ak' });
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
await client.printText('Hello', 'device-id', userId);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (error instanceof APIError) {
|
|
306
|
+
console.error('API Error:', error.resError);
|
|
307
|
+
console.error('Code:', error.resCode);
|
|
308
|
+
} else if (error instanceof NetworkError) {
|
|
309
|
+
console.error('Network Error:', error.message);
|
|
310
|
+
} else {
|
|
311
|
+
console.error('Unknown Error:', error);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Poll Print Status
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
const printResult = await client.printText('Test', 'device-id', userId);
|
|
320
|
+
const printId = printResult.printcontentid!;
|
|
321
|
+
|
|
322
|
+
// Poll until printed
|
|
323
|
+
let printed = false;
|
|
324
|
+
while (!printed) {
|
|
325
|
+
const status = await client.getPrintStatus(printId);
|
|
326
|
+
|
|
327
|
+
if (status.printflag === 1) {
|
|
328
|
+
console.log('Printed successfully!');
|
|
329
|
+
printed = true;
|
|
330
|
+
} else {
|
|
331
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Utility Functions
|
|
337
|
+
|
|
338
|
+
### Text Encoding
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import { textToGBKBase64, gbkBase64ToText } from 'memobirdsdk';
|
|
342
|
+
|
|
343
|
+
// Convert to GBK Base64
|
|
344
|
+
const encoded = textToGBKBase64('你好');
|
|
345
|
+
|
|
346
|
+
// Decode back to UTF-8
|
|
347
|
+
const decoded = gbkBase64ToText(encoded);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Content Formatting
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { formatTextContent, formatImageContent, formatMixedContent } from 'memobirdsdk';
|
|
354
|
+
|
|
355
|
+
// Format text with T: prefix
|
|
356
|
+
const textContent = formatTextContent('Hello');
|
|
357
|
+
// Returns: 'T:SGVsbG8='
|
|
358
|
+
|
|
359
|
+
// Format image with P: prefix
|
|
360
|
+
const imageContent = formatImageContent('base64-image-data');
|
|
361
|
+
// Returns: 'P:base64-image-data'
|
|
362
|
+
|
|
363
|
+
// Format mixed content
|
|
364
|
+
const mixed = formatMixedContent([
|
|
365
|
+
{ type: 'text', content: 'Hello' },
|
|
366
|
+
{ type: 'image', content: 'image-data' },
|
|
367
|
+
{ type: 'text', content: 'World' }
|
|
368
|
+
]);
|
|
369
|
+
// Returns: 'T:SGVsbG8=|P:image-data|T:V29ybGQ='
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Image Utilities
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import {
|
|
376
|
+
imageFileToBase64,
|
|
377
|
+
stripDataUrlPrefix,
|
|
378
|
+
isValidBase64Image
|
|
379
|
+
} from 'memobirdsdk';
|
|
380
|
+
|
|
381
|
+
// Load image from file
|
|
382
|
+
const base64 = await imageFileToBase64('./image.jpg');
|
|
383
|
+
|
|
384
|
+
// Strip data URL prefix
|
|
385
|
+
const clean = stripDataUrlPrefix('data:image/png;base64,iVBORw0...');
|
|
386
|
+
|
|
387
|
+
// Validate Base64
|
|
388
|
+
if (isValidBase64Image(base64)) {
|
|
389
|
+
console.log('Valid Base64');
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Timestamp
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { generateTimestamp, isValidTimestamp } from 'memobirdsdk';
|
|
397
|
+
|
|
398
|
+
// Generate timestamp in Memobird format
|
|
399
|
+
const timestamp = generateTimestamp();
|
|
400
|
+
// Returns: '2025-12-29 14:30:45'
|
|
401
|
+
|
|
402
|
+
// Validate timestamp format
|
|
403
|
+
if (isValidTimestamp('2025-12-29 14:30:45')) {
|
|
404
|
+
console.log('Valid format');
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Error Types
|
|
409
|
+
|
|
410
|
+
### MemobirdError
|
|
411
|
+
|
|
412
|
+
Base error class for all SDK errors.
|
|
413
|
+
|
|
414
|
+
### APIError
|
|
415
|
+
|
|
416
|
+
Thrown when API returns an error response (`showapi_res_code !== 1`).
|
|
417
|
+
|
|
418
|
+
**Properties:**
|
|
419
|
+
- `resCode`: The API response code
|
|
420
|
+
- `resError`: The API error message
|
|
421
|
+
|
|
422
|
+
### NetworkError
|
|
423
|
+
|
|
424
|
+
Thrown when network request fails.
|
|
425
|
+
|
|
426
|
+
**Properties:**
|
|
427
|
+
- `originalError`: The original error that caused the failure
|
|
428
|
+
|
|
429
|
+
### ValidationError
|
|
430
|
+
|
|
431
|
+
Thrown when input validation fails.
|
|
432
|
+
|
|
433
|
+
**Properties:**
|
|
434
|
+
- `field`: The field that failed validation
|
|
435
|
+
|
|
436
|
+
## Image Printing Tips
|
|
437
|
+
|
|
438
|
+
For best results with image printing:
|
|
439
|
+
|
|
440
|
+
1. **Image width**: Use 384 pixels (Memobird paper width)
|
|
441
|
+
2. **High contrast**: Black and white images work best
|
|
442
|
+
3. **Simple designs**: Complex images may not render well on thermal printers
|
|
443
|
+
4. **Conversion required**: Always convert JPG/PNG to monochrome bitmap using `convertImageToMonochrome()`
|
|
444
|
+
|
|
445
|
+
## HTML/URL Printing Tips
|
|
446
|
+
|
|
447
|
+
For HTML and URL printing:
|
|
448
|
+
|
|
449
|
+
1. **Inline CSS**: Don't use external stylesheets
|
|
450
|
+
2. **Complete URLs**: Use absolute URLs for images (not relative paths)
|
|
451
|
+
3. **Static content**: AJAX-rendered pages may not work properly
|
|
452
|
+
4. **Server-rendered**: Works best with server-rendered pages
|
|
453
|
+
5. **Content size**: Keep content size reasonable
|
|
454
|
+
|
|
455
|
+
## TypeScript Support
|
|
456
|
+
|
|
457
|
+
This SDK is written in TypeScript and provides complete type definitions. All functions, parameters, and return values are fully typed.
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
import type {
|
|
461
|
+
MemobirdConfig,
|
|
462
|
+
PrintResponse,
|
|
463
|
+
BindUserResponse
|
|
464
|
+
} from 'memobirdsdk';
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## License
|
|
468
|
+
|
|
469
|
+
ISC
|
|
470
|
+
|
|
471
|
+
## Links
|
|
472
|
+
|
|
473
|
+
- [Memobird Official Website](http://www.memobird.cn)
|
|
474
|
+
- [Memobird Open Platform](http://open.memobird.cn)
|
|
475
|
+
- [API Documentation](http://open.memobird.cn) (Chinese)
|
|
476
|
+
|
|
477
|
+
## Support
|
|
478
|
+
|
|
479
|
+
For issues and feature requests, please create an issue on the GitHub repository.
|
|
480
|
+
|
|
481
|
+
## Contributing
|
|
482
|
+
|
|
483
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Got } from 'got';
|
|
2
|
+
import type { BindUserResponse } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Binds a user identifier to a Memobird device
|
|
5
|
+
*
|
|
6
|
+
* This creates an association between your user ID and a physical device,
|
|
7
|
+
* enabling you to send print jobs to that device.
|
|
8
|
+
*
|
|
9
|
+
* @param client - Got HTTP client instance
|
|
10
|
+
* @param ak - Access Key from open.memobird.cn
|
|
11
|
+
* @param memobirdID - Device ID (obtain by double-clicking the device to print it)
|
|
12
|
+
* @param useridentifying - Your unique user identifier
|
|
13
|
+
* @returns Promise resolving to binding response with user ID
|
|
14
|
+
* @throws {APIError} If API returns error response
|
|
15
|
+
* @throws {NetworkError} If network request fails
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const response = await bindUser(client, 'your-ak', 'device-id', 'user-123');
|
|
20
|
+
* console.log('User ID:', response.showapi_userid);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function bindUser(client: Got, ak: string, memobirdID: string, useridentifying: string): Promise<BindUserResponse>;
|
|
24
|
+
//# sourceMappingURL=bind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../src/api/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAK3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,GAAG,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAkC3B"}
|
package/dist/api/bind.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { APIError, NetworkError } from '../errors/index.js';
|
|
2
|
+
import { generateTimestamp } from '../utils/index.js';
|
|
3
|
+
import { API_SUCCESS_CODE } from '../constants.js';
|
|
4
|
+
/**
|
|
5
|
+
* Binds a user identifier to a Memobird device
|
|
6
|
+
*
|
|
7
|
+
* This creates an association between your user ID and a physical device,
|
|
8
|
+
* enabling you to send print jobs to that device.
|
|
9
|
+
*
|
|
10
|
+
* @param client - Got HTTP client instance
|
|
11
|
+
* @param ak - Access Key from open.memobird.cn
|
|
12
|
+
* @param memobirdID - Device ID (obtain by double-clicking the device to print it)
|
|
13
|
+
* @param useridentifying - Your unique user identifier
|
|
14
|
+
* @returns Promise resolving to binding response with user ID
|
|
15
|
+
* @throws {APIError} If API returns error response
|
|
16
|
+
* @throws {NetworkError} If network request fails
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const response = await bindUser(client, 'your-ak', 'device-id', 'user-123');
|
|
21
|
+
* console.log('User ID:', response.showapi_userid);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export async function bindUser(client, ak, memobirdID, useridentifying) {
|
|
25
|
+
try {
|
|
26
|
+
const requestData = {
|
|
27
|
+
ak,
|
|
28
|
+
timestamp: generateTimestamp(),
|
|
29
|
+
memobirdID,
|
|
30
|
+
useridentifying,
|
|
31
|
+
};
|
|
32
|
+
const response = await client.post('setuserbind', {
|
|
33
|
+
form: requestData,
|
|
34
|
+
});
|
|
35
|
+
const data = response.body;
|
|
36
|
+
// Check if API returned success
|
|
37
|
+
if (data.showapi_res_code !== API_SUCCESS_CODE) {
|
|
38
|
+
throw new APIError(`Failed to bind user: ${data.showapi_res_error}`, data.showapi_res_code, data.showapi_res_error);
|
|
39
|
+
}
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof APIError) {
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
throw new NetworkError(`Network error while binding user: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../../src/api/bind.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAW,EACX,EAAU,EACV,UAAkB,EAClB,eAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,WAAW,GAAoB;YACnC,EAAE;YACF,SAAS,EAAE,iBAAiB,EAAE;YAC9B,UAAU;YACV,eAAe;SAChB,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAmB,aAAa,EAAE;YAClE,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAE3B,gCAAgC;QAChC,IAAI,IAAI,CAAC,gBAAgB,KAAK,gBAAgB,EAAE,CAAC;YAC/C,MAAM,IAAI,QAAQ,CAChB,wBAAwB,IAAI,CAAC,iBAAiB,EAAE,EAChD,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,iBAAiB,CACvB,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,YAAY,CACpB,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAC7F,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Got } from 'got';
|
|
2
|
+
import type { ConvertImageResponse } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a JPG or PNG image to monochrome bitmap format for printing
|
|
5
|
+
*
|
|
6
|
+
* The Memobird API requires images to be in monochrome bitmap format.
|
|
7
|
+
* This endpoint converts standard JPG/PNG images to the required format.
|
|
8
|
+
*
|
|
9
|
+
* @param client - Got HTTP client instance
|
|
10
|
+
* @param ak - Access Key
|
|
11
|
+
* @param imgBase64String - JPG or PNG image as Base64 string
|
|
12
|
+
* @returns Promise resolving to converted image response
|
|
13
|
+
* @throws {APIError} If API returns error response
|
|
14
|
+
* @throws {NetworkError} If network request fails
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const jpgBase64 = '...'; // Your JPG image
|
|
19
|
+
* const response = await convertToMonochrome(client, ak, jpgBase64);
|
|
20
|
+
* const monochromeBase64 = response.result;
|
|
21
|
+
* // Now use monochromeBase64 for printing
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function convertToMonochrome(client: Got, ak: string, imgBase64String: string): Promise<ConvertImageResponse>;
|
|
25
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/api/image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EAAuB,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAInF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,GAAG,EACX,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,CAAC,CA+B/B"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { APIError, NetworkError } from '../errors/index.js';
|
|
2
|
+
import { API_SUCCESS_CODE } from '../constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a JPG or PNG image to monochrome bitmap format for printing
|
|
5
|
+
*
|
|
6
|
+
* The Memobird API requires images to be in monochrome bitmap format.
|
|
7
|
+
* This endpoint converts standard JPG/PNG images to the required format.
|
|
8
|
+
*
|
|
9
|
+
* @param client - Got HTTP client instance
|
|
10
|
+
* @param ak - Access Key
|
|
11
|
+
* @param imgBase64String - JPG or PNG image as Base64 string
|
|
12
|
+
* @returns Promise resolving to converted image response
|
|
13
|
+
* @throws {APIError} If API returns error response
|
|
14
|
+
* @throws {NetworkError} If network request fails
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const jpgBase64 = '...'; // Your JPG image
|
|
19
|
+
* const response = await convertToMonochrome(client, ak, jpgBase64);
|
|
20
|
+
* const monochromeBase64 = response.result;
|
|
21
|
+
* // Now use monochromeBase64 for printing
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export async function convertToMonochrome(client, ak, imgBase64String) {
|
|
25
|
+
try {
|
|
26
|
+
const requestData = {
|
|
27
|
+
ak,
|
|
28
|
+
imgBase64String,
|
|
29
|
+
};
|
|
30
|
+
const response = await client.post('getSignalBase64Pic', {
|
|
31
|
+
form: requestData,
|
|
32
|
+
});
|
|
33
|
+
const data = response.body;
|
|
34
|
+
if (data.showapi_res_code !== API_SUCCESS_CODE) {
|
|
35
|
+
throw new APIError(`Failed to convert image: ${data.showapi_res_error}`, data.showapi_res_code, data.showapi_res_error);
|
|
36
|
+
}
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error instanceof APIError) {
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
throw new NetworkError(`Network error while converting image: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/api/image.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAW,EACX,EAAU,EACV,eAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,WAAW,GAAwB;YACvC,EAAE;YACF,eAAe;SAChB,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAuB,oBAAoB,EAAE;YAC7E,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAE3B,IAAI,IAAI,CAAC,gBAAgB,KAAK,gBAAgB,EAAE,CAAC;YAC/C,MAAM,IAAI,QAAQ,CAChB,4BAA4B,IAAI,CAAC,iBAAiB,EAAE,EACpD,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,iBAAiB,CACvB,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,YAAY,CACpB,yCAAyC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|