mayar 0.2.0 → 1.0.1
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 +117 -46
- package/package.json +1 -1
- package/src/cli.js +114 -32
- package/src/commands/balance.js +1 -1
- package/src/commands/bundling.js +36 -0
- package/src/commands/credit.js +72 -0
- package/src/commands/customer.js +5 -7
- package/src/commands/discount.js +52 -0
- package/src/commands/installment.js +44 -0
- package/src/commands/invoice.js +53 -25
- package/src/commands/membership.js +92 -0
- package/src/commands/payment-link.js +23 -0
- package/src/commands/payment.js +30 -14
- package/src/commands/product.js +97 -18
- package/src/commands/qrcode.js +35 -5
- package/src/commands/review.js +90 -18
- package/src/commands/saas.js +18 -0
- package/src/commands/software.js +17 -0
- package/src/commands/transaction.js +39 -12
- package/src/commands/webhook.js +46 -13
- package/src/util.js +28 -1
- package/node_modules/@mayaross/auth/README.md +0 -204
- package/node_modules/@mayaross/auth/index.js +0 -146
- package/node_modules/@mayaross/auth/package.json +0 -10
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @mayarid/auth-cli
|
|
3
|
-
* SDK for mayar-cli to authenticate via mayar auth service.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* const { MayarAuth } = require('@mayarid/auth-cli');
|
|
7
|
-
* const auth = new MayarAuth('https://auth.mayar.id');
|
|
8
|
-
* const token = await auth.login(); // opens browser, waits for SSE token
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const https = require('https');
|
|
12
|
-
const http = require('http');
|
|
13
|
-
const { spawn } = require('child_process');
|
|
14
|
-
|
|
15
|
-
class MayarAuth {
|
|
16
|
-
/**
|
|
17
|
-
* @param {string} baseUrl - Auth server base URL, e.g. 'https://auth.mayar.id'
|
|
18
|
-
* @param {object} [opts]
|
|
19
|
-
* @param {number} [opts.timeoutMs=300000] - How long to wait for login (default 5 min)
|
|
20
|
-
*/
|
|
21
|
-
constructor(baseUrl = 'https://auth.mayar.id', opts = {}) {
|
|
22
|
-
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
23
|
-
this.timeoutMs = opts.timeoutMs ?? 5 * 60 * 1000;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Step 1: Ask the server for a fresh appid + auth URL.
|
|
28
|
-
* @returns {Promise<{ appid: string, url: string }>}
|
|
29
|
-
*/
|
|
30
|
-
async initiate() {
|
|
31
|
-
return new Promise((resolve, reject) => {
|
|
32
|
-
const endpoint = new URL(`${this.baseUrl}/token/cli/initiate`);
|
|
33
|
-
const lib = endpoint.protocol === 'https:' ? https : http;
|
|
34
|
-
|
|
35
|
-
lib.get(endpoint.href, (res) => {
|
|
36
|
-
let body = '';
|
|
37
|
-
res.on('data', (chunk) => (body += chunk));
|
|
38
|
-
res.on('end', () => {
|
|
39
|
-
try {
|
|
40
|
-
resolve(JSON.parse(body));
|
|
41
|
-
} catch (e) {
|
|
42
|
-
reject(new Error(`Invalid response from server: ${body}`));
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}).on('error', reject);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Step 2: Open system browser at the given URL.
|
|
51
|
-
* @param {string} url
|
|
52
|
-
*/
|
|
53
|
-
openBrowser(url) {
|
|
54
|
-
const platform = process.platform;
|
|
55
|
-
const cmd = platform === 'darwin' ? 'open'
|
|
56
|
-
: platform === 'win32' ? 'start'
|
|
57
|
-
: 'xdg-open';
|
|
58
|
-
|
|
59
|
-
spawn(cmd, [url], { detached: true, stdio: 'ignore' }).unref();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Step 3: Subscribe to SSE stream and wait for the token event.
|
|
64
|
-
* Resolves with the token pair string "authToken,refreshToken".
|
|
65
|
-
* @param {string} appid
|
|
66
|
-
* @returns {Promise<string>}
|
|
67
|
-
*/
|
|
68
|
-
listenForToken(appid) {
|
|
69
|
-
return new Promise((resolve, reject) => {
|
|
70
|
-
const endpoint = new URL(`${this.baseUrl}/token/cli/stream?appid=${encodeURIComponent(appid)}`);
|
|
71
|
-
const lib = endpoint.protocol === 'https:' ? https : http;
|
|
72
|
-
|
|
73
|
-
const timer = setTimeout(() => {
|
|
74
|
-
req.destroy();
|
|
75
|
-
reject(new Error('Login timed out. Please try again.'));
|
|
76
|
-
}, this.timeoutMs);
|
|
77
|
-
|
|
78
|
-
const req = lib.get(endpoint.href, (res) => {
|
|
79
|
-
if (res.statusCode !== 200) {
|
|
80
|
-
clearTimeout(timer);
|
|
81
|
-
reject(new Error(`SSE stream returned ${res.statusCode}`));
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let buf = '';
|
|
86
|
-
let eventName = '';
|
|
87
|
-
|
|
88
|
-
res.setEncoding('utf8');
|
|
89
|
-
res.on('data', (chunk) => {
|
|
90
|
-
buf += chunk;
|
|
91
|
-
const lines = buf.split('\n');
|
|
92
|
-
buf = lines.pop(); // keep incomplete last line
|
|
93
|
-
|
|
94
|
-
for (const line of lines) {
|
|
95
|
-
if (line.startsWith('event:')) {
|
|
96
|
-
eventName = line.replace('event:', '').trim();
|
|
97
|
-
} else if (line.startsWith('data:')) {
|
|
98
|
-
const raw = line.replace('data:', '').trim();
|
|
99
|
-
if (eventName === 'token') {
|
|
100
|
-
clearTimeout(timer);
|
|
101
|
-
req.destroy();
|
|
102
|
-
try {
|
|
103
|
-
const { token } = JSON.parse(raw);
|
|
104
|
-
resolve(token);
|
|
105
|
-
} catch {
|
|
106
|
-
reject(new Error('Failed to parse token from server'));
|
|
107
|
-
}
|
|
108
|
-
} else if (eventName === 'timeout') {
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
req.destroy();
|
|
111
|
-
reject(new Error('Login timed out on server side. Please try again.'));
|
|
112
|
-
}
|
|
113
|
-
eventName = '';
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
res.on('error', (e) => { clearTimeout(timer); reject(e); });
|
|
119
|
-
res.on('end', () => { clearTimeout(timer); reject(new Error('SSE stream closed unexpectedly')); });
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
req.on('error', (e) => { clearTimeout(timer); reject(e); });
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Full login flow: initiate → open browser → listen for SSE token.
|
|
128
|
-
* @param {object} [opts]
|
|
129
|
-
* @param {boolean} [opts.openBrowser=true] - Set false to print URL instead of opening browser
|
|
130
|
-
* @param {function} [opts.onUrl] - Called with { appid, url } before waiting for token
|
|
131
|
-
* @returns {Promise<string>} token pair "authToken,refreshToken"
|
|
132
|
-
*/
|
|
133
|
-
async login({ openBrowser = true, onUrl } = {}) {
|
|
134
|
-
const { appid, url } = await this.initiate();
|
|
135
|
-
|
|
136
|
-
if (typeof onUrl === 'function') onUrl({ appid, url });
|
|
137
|
-
|
|
138
|
-
if (openBrowser) {
|
|
139
|
-
this.openBrowser(url);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return this.listenForToken(appid);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
module.exports = { MayarAuth };
|