@readystack/green-claim-lint-empco 1.0.0 → 1.0.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 +0 -2
- package/license.js +20 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Green Claim Lint - EU EmpCo 2026
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
|
|
5
3
|
Reads your HTML and Markdown product copy and flags the environmental claims Directive (EU) 2024/825 turns into banned practices on 27 September 2026, with the clause and a compliant rewrite for each hit.
|
|
6
4
|
|
|
7
5
|
## Install
|
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(
|
|
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/green-claim-lint-empco",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Reads your HTML and Markdown product copy and flags the environmental claims Directive (EU) 2024/825 turns into banned practices on 27 September 2026, with the clause and a compliant rewrite for each ",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"publishConfig": {
|