@readystack/einvoice-mandate-lint 1.0.2 → 1.0.4

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.
Files changed (2) hide show
  1. package/license.js +20 -2
  2. package/package.json +1 -1
package/license.js CHANGED
@@ -10,10 +10,14 @@ const RECHECK_MS = 7 * 24 * 3600 * 1000; // re-ask Polar every 7 days (refunds
10
10
  function storePath() { return path.join(process.env.READYSTACK_HOME || path.join(os.homedir(), '.config', 'readystack'), SLUG + '.json'); }
11
11
  function load() { try { return JSON.parse(fs.readFileSync(storePath(), 'utf8')); } catch (e) { return {}; } }
12
12
  function save(o) { try { fs.mkdirSync(path.dirname(storePath()), { recursive: true }); fs.writeFileSync(storePath(), JSON.stringify(o)); } catch (e) { /* read-only home: still works for this run */ } }
13
+ const ALL_BENEFIT_ID = '22692551-5203-4467-b1a3-e33cdba6589d'; // s149 2026-09-17 — 팀 키(전 린터 한 키 · Polar benefit) · 상품 benefit 다음에 한 번 더 묻는다
13
14
  function validate(key) {
15
+ return validate1(key, BENEFIT_ID).then(function (r) { return (r.ok || r.offline || !/^[0-9a-f-]{36}$/.test(ALL_BENEFIT_ID)) ? r : validate1(key, ALL_BENEFIT_ID); });
16
+ }
17
+ function validate1(key, ben) {
14
18
  return new Promise(function (resolve) {
15
19
  if (!ORG_ID) return resolve({ ok: false, offline: false });
16
- const body = JSON.stringify(/^[0-9a-f-]{36}$/.test(BENEFIT_ID) ? { key: key, organization_id: ORG_ID, benefit_id: BENEFIT_ID } : { key: key, organization_id: ORG_ID });
20
+ const body = JSON.stringify(/^[0-9a-f-]{36}$/.test(ben) ? { key: key, organization_id: ORG_ID, benefit_id: ben } : { key: key, organization_id: ORG_ID });
17
21
  const req = https.request({ hostname: 'api.polar.sh', path: '/v1/customer-portal/license-keys/validate', method: 'POST', timeout: 8000,
18
22
  headers: { 'content-type': 'application/json', 'polar-version': '2026-04', 'content-length': Buffer.byteLength(body) } }, function (res) {
19
23
  let buf = ''; res.on('data', function (d) { buf += d; });
@@ -28,15 +32,29 @@ function validate(key) {
28
32
  req.write(body); req.end();
29
33
  });
30
34
  }
35
+ // ★s151 2026-09-19 — 키 판(키가 없거나 거절된 순간)을 익명으로 센다 (슬러그·출처·이유만) · DO_NOT_TRACK=1 · READYSTACK_NO_TELEMETRY 면 안 보낸다 · 실패는 조용히 · 프로세스당 한 번.
36
+ let _pinged = false;
37
+ function pingPaywall(why) {
38
+ try {
39
+ if (_pinged) return; _pinged = true;
40
+ if (process.env.DO_NOT_TRACK === '1' || process.env.READYSTACK_NO_TELEMETRY) return;
41
+ const body = JSON.stringify({ t: 'paywall', slug: SLUG, src: 'cli', why: why || 'no_key' });
42
+ const req = https.request({ hostname: 'getreadystack.com', path: '/api/ev', method: 'POST', timeout: 3000,
43
+ headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(body), 'user-agent': 'readystack-cli/' + SLUG } }, function (res) { res.resume(); });
44
+ req.on('timeout', function () { req.destroy(); }); req.on('error', function () {});
45
+ req.write(body); req.end();
46
+ } catch (e) { /* 세는 것이 실패해도 상품은 돈다 */ }
47
+ }
31
48
  async function ensure(explicitKey) {
32
49
  const st = load();
33
50
  const key = explicitKey || process.env.READYSTACK_LICENSE || st.key;
34
- if (!key) return { ok: false, why: 'no_key' };
51
+ if (!key) { pingPaywall('no_key'); return { ok: false, why: 'no_key' }; } // s151
35
52
  const age = Date.now() - (st.okAt || 0);
36
53
  if (!explicitKey && st.key === key && age < RECHECK_MS) return { ok: true, cached: true };
37
54
  const r = await validate(String(key).trim());
38
55
  if (r.ok) { save({ key: String(key).trim(), okAt: Date.now() }); return { ok: true }; }
39
56
  if (r.offline && st.key === key && age < GRACE_MS) return { ok: true, offline: true };
57
+ if (!r.offline) pingPaywall('invalid'); // s151
40
58
  return { ok: false, why: r.offline ? 'offline' : 'invalid' };
41
59
  }
42
60
  // ★s134 — 구독 규칙 피드(층3 "바뀌면 업데이트"): 키 있는 손님만 · 7일마다 · 오프라인은 캐시. 워커 GET /api/rules/<slug>?key=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@readystack/einvoice-mandate-lint",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Lints UBL and CII invoice XML against EN 16931 and the national e-invoicing mandates that are live in 2026",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "publishConfig": {