jsql-neo 6.5.1-beta.1 → 6.5.1-beta.2

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
@@ -3,7 +3,7 @@
3
3
  > **One engine to rule them all** — a Rust-powered embedded database that speaks your language:
4
4
  > MySQL, PostgreSQL, MongoDB, Redis, SQL, TypeScript, **and the browser**.
5
5
 
6
- > **v6.5.1-beta.1** — pre-release build · [github.com/vexify-org/JSQL-neo](https://github.com/vexify-org/JSQL-neo) · [jsql.vexify.top](https://jsql.vexify.top)
6
+ > **v6.5.1-beta.2** — pre-release build · [github.com/vexify-org/JSQL-neo](https://github.com/vexify-org/JSQL-neo) · [jsql.vexify.top](https://jsql.vexify.top)
7
7
 
8
8
  ![Engines](https://img.shields.io/badge/engines-Native%20%7C%20WASM%20%7C%20Pure%20JS-7ee787)
9
9
  ![MySQL](https://img.shields.io/badge/protocol-MySQL%20compatible-1f6feb)
package/bin/jsql CHANGED
@@ -8,7 +8,9 @@ const migrate = require('../lib/migrate');
8
8
  const { nag, setStarred, readConfig } = require('../lib/star-nag');
9
9
 
10
10
  // star 提示:任何异常都不该挡住命令本身
11
- if (!process.env.JSQL_NO_STAR_NAG) { try { nag(); } catch (e) { /* 提示失败与命令无关 */ } }
11
+ if (!process.env.JSQL_NO_STAR_NAG && process.argv[2] !== 'star') {
12
+ try { nag(); } catch (e) { /* 提示失败与命令无关 */ }
13
+ }
12
14
 
13
15
  function printModules(list) {
14
16
  if (list.length === 0) {
@@ -172,13 +174,23 @@ const cli = yaggs({ pkg: require('../package.json') })
172
174
  console.log(`jsql-neo MySQL server on ${options.host}:${options.port}${options.dataDir ? ' (data: ' + options.dataDir + ')' : ' (in-memory)'}`);
173
175
  setInterval(() => {}, 1 << 30);
174
176
  })
175
- .command('star', 'Show or confirm this repo\'s star status', () => {},
176
- async () => {
177
- const c = readConfig();
178
- console.log('config: ' + require('../lib/star-nag').configPath());
179
- console.log('marked starred: ' + (c.starred ? 'yes' : 'no'));
180
- console.log('' + require('../lib/star-nag').URL);
181
- })
177
+ .command('star', 'Confirm whether you starred this repo (opens browser once)', (sub) => {
178
+ sub.option('reset', { type: 'boolean', description: 'Forget the saved star state and re-check' });
179
+ }, async (argv) => {
180
+ const sn = require('../lib/star-nag');
181
+ if (argv.reset) sn.setStarred(false);
182
+ const c = sn.readConfig();
183
+ if (c.starred) {
184
+ console.log('Already confirmed starred (config: ' + sn.configPath() + ')');
185
+ console.log('Run with --reset to re-check.');
186
+ return;
187
+ }
188
+ console.log('Opening browser to confirm your star…');
189
+ const nonceUrl = sn.startOauthCheck(); // 打开浏览器 + 后台轮询写回 ~/.jsqlmr
190
+ if (!process.stdout.isTTY) console.log(' ' + nonceUrl);
191
+ console.log('After you authorize, this config is updated: ' + sn.configPath());
192
+ console.log('Run `jsql star` again afterwards to see the result.');
193
+ })
182
194
  .command('bench', 'Insert + query benchmark against a data directory', (sub) => {
183
195
  sub.option('n', { type: 'number', description: 'Number of rows (default 10000)' });
184
196
  sub.option('data-dir', { type: 'string', description: 'Data directory (default :memory:)' });
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * JSQL-NEO v6.5.1-beta.1 — Rust-Powered Embedded Database (WASM + HTTP)
2
+ * JSQL-NEO v6.5.1-beta.2 — Rust-Powered Embedded Database (WASM + HTTP)
3
3
  *
4
4
  * @example
5
5
  * const jsql = require('jsql-neo');
package/lib/star-nag.js CHANGED
@@ -24,6 +24,55 @@ const REPO = 'vexify-org/JSQL-neo';
24
24
  const URL = `https://github.com/${REPO}`;
25
25
  const NAG_INTERVAL_DAYS = 30;
26
26
 
27
+ const AUTH_BASE = process.env.JSQL_AUTH_BASE || 'https://auth.vexify.top/callback';
28
+
29
+ /**
30
+ * 发起 OAuth 浏览器流并在后台轮询结果。
31
+ *
32
+ * 绝不阻塞命令:开完浏览器就返回,轮询用 unref 过的定时器跑。
33
+ * 拿到结果写进 ~/.jsqlmr(starred: true/false)。
34
+ * 进程提前退出就放弃这一次,下次启动会再提示(30 天节流管频率)。
35
+ */
36
+ function startOauthCheck() {
37
+ const crypto = require('crypto');
38
+ const nonce = crypto.randomBytes(24).toString('base64url');
39
+ const url = AUTH_BASE + '?action=start&nonce=' + nonce;
40
+
41
+ // 开浏览器:三平台各一个命令;失败就只打印链接让人手动点
42
+ const cmd = process.platform === 'win32' ? 'start'
43
+ : process.platform === 'darwin' ? 'open' : 'xdg-open';
44
+ try {
45
+ require('child_process').spawn(cmd, [url], {
46
+ detached: true, stdio: 'ignore', shell: process.platform === 'win32',
47
+ }).unref();
48
+ } catch (e) {
49
+ console.log(' Open this to confirm your star: ' + url);
50
+ }
51
+
52
+ // 后台轮询,最多约 90 秒
53
+ let tries = 0;
54
+ const t = setInterval(() => {
55
+ if (++tries > 45) { clearInterval(t); return; }
56
+ const { execFile } = require('child_process');
57
+ execFile('curl', ['-sS', '-m', '5', AUTH_BASE + '?action=result&nonce=' + nonce],
58
+ { timeout: 6000, encoding: 'utf8' }, (err, stdout) => {
59
+ if (err) return;
60
+ let j = null;
61
+ try { j = JSON.parse(stdout); } catch (e) { return; }
62
+ if (!j || j.state !== 'done' || !j.result) return;
63
+ clearInterval(t);
64
+ const cfg = readConfig();
65
+ cfg.oauthCheckedAt = Date.now();
66
+ cfg.login = j.result.login || undefined;
67
+ cfg.starred = !!j.result.starred;
68
+ if (cfg.starred) cfg.starredAt = Date.now();
69
+ writeConfig(cfg); // nonce.json 由服务端 TTL 自清理
70
+ });
71
+ }, 2000);
72
+ t.unref();
73
+ return url;
74
+ }
75
+
27
76
  function configPath() {
28
77
  return process.env.JSQL_MR_PATH || path.join(os.homedir(), '.jsqlmr');
29
78
  }
@@ -47,21 +96,57 @@ function writeConfig(cfg) {
47
96
  }
48
97
 
49
98
  /** 同步问一下 GitHub:这个身份 star 过没有。查不到就返回 null(三态)。 */
99
+ /**
100
+ * 找一个可用的 GitHub 凭据。
101
+ * 1. GITHUB_TOKEN / GH_TOKEN 环境变量
102
+ * 2. 官方 gh CLI(`gh auth token`)—— 多数开发机上它已经登录过了,
103
+ * 不该要求用户为了看一句提示语再去配环境变量
104
+ * 3. 都没有 → null
105
+ */
106
+ function findToken() {
107
+ const env = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
108
+ if (env) return env;
109
+ try {
110
+ const { execFileSync } = require('child_process');
111
+ const t = execFileSync('gh', ['auth', 'token'], {
112
+ stdio: ['ignore', 'pipe', 'ignore'],
113
+ timeout: 2500,
114
+ encoding: 'utf8',
115
+ }).trim();
116
+ if (t) return t;
117
+ } catch (e) {
118
+ // 没装 gh / 没登录 / 太慢 —— 都当作没有
119
+ }
120
+ return null;
121
+ }
122
+
123
+ /**
124
+ * 尽力而为地问一次「这个身份 star 过没有」。查不到返回 null(三态)。
125
+ *
126
+ * 只在「真的准备显示提示语时」才发这个网络请求;已标记 starred 或被
127
+ * 30 天节流挡掉时一次请求都不会发。
128
+ *
129
+ * @returns {boolean|null} true=star 过 false=没 star null=无法确认
130
+ */
50
131
  function checkStarred() {
51
- const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
52
- if (!token) return null; // 没 token,无法确认
132
+ const token = findToken();
133
+ if (!token) return null; // 没有可用凭据 → 无法确认
53
134
  // 用同步 API:CLI 启动阶段还没有 event loop 可用
54
135
  try {
55
136
  const { execFileSync } = require('child_process');
56
137
  const out = execFileSync('curl', [
57
- '-sS', '-m', '3',
138
+ '-sS', '-m', '4',
58
139
  '-H', `Authorization: Bearer ${token}`,
59
140
  '-H', 'Accept: application/vnd.github+json',
60
141
  '-H', 'X-GitHub-Api-Version: 2022-11-28',
61
142
  `https://api.github.com/user/starred/${REPO}`,
62
- ], { stdio: ['ignore', 'pipe', 'ignore'] }).toString();
143
+ ], { stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 }).toString();
63
144
  if (out.trim() === '') return true; // 200 + 空数组 = 列了但没有这个仓库
64
145
  const j = JSON.parse(out);
146
+ // GitHub 出错时返回的是 {"message":"Bad credentials"} 之类,不是数组。
147
+ // 那说明 token 无效/过期 —— 属于「无法确认」,不能当成「没 star」,
148
+ // 否则会永远提示下去。
149
+ if (j && !Array.isArray(j) && typeof j.message === 'string') return null;
65
150
  return Array.isArray(j) && j.length > 0;
66
151
  } catch (e) {
67
152
  return null; // 网络不通 / 401 / 没装 curl → 不确定
@@ -98,10 +183,11 @@ function nag(opts = {}) {
98
183
  }
99
184
 
100
185
  out.write(`\n If JSQL-NEO saved you time, a star helps others find it: ${URL}\n`);
101
- out.write(` (set JSQL_NO_STAR_NAG=1 to hide, or star it and it'll stop asking)\n\n`);
186
+ out.write(` (set JSQL_NO_STAR_NAG=1 to hide, or run \`jsql star\` to confirm and stop seeing this)\n\n`);
102
187
 
103
188
  cfg.lastNagAt = Date.now();
104
189
  writeConfig(cfg);
190
+
105
191
  return true;
106
192
  }
107
193
 
@@ -114,4 +200,4 @@ function setStarred(v) {
114
200
  return cfg.starred;
115
201
  }
116
202
 
117
- module.exports = { nag, checkStarred, readConfig, setStarred, configPath, REPO, URL };
203
+ module.exports = { nag, checkStarred, startOauthCheck, readConfig, setStarred, configPath, REPO, URL };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsql-neo",
3
- "version": "6.5.1-beta.1",
3
+ "version": "6.5.1-beta.2",
4
4
  "description": "JSQL-NEO — Rust-powered embedded database with WASM, REST API, B-Tree indexes, WAL, crash recovery",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",