@sky.ui.pro/core 0.0.2 → 0.0.3
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/LICENSE.md +212 -212
- package/README.md +96 -94
- package/package.json +23 -12
- package/scripts/merge-manifest.mjs +81 -0
- package/scripts/postinstall.mjs +149 -61
- package/scripts/project-env.mjs +150 -0
- package/scripts/token.mjs +147 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Shared token resolution and online license validation for @sky.ui.pro postinstall.
|
|
4
|
+
*/
|
|
5
|
+
import { access, readFile } from "node:fs/promises";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
export { loadConsumerProjectEnv, loadInstallProjectEnv } from "./project-env.mjs";
|
|
10
|
+
|
|
11
|
+
export const SKY_UI_HOME = join(homedir(), ".sky.ui");
|
|
12
|
+
export const LEGACY_SKY_UI_HOME = join(homedir(), ".sky-ui");
|
|
13
|
+
export const cacheRoot = join(SKY_UI_HOME, "cache");
|
|
14
|
+
export const legacyCacheRoot = join(LEGACY_SKY_UI_HOME, "cache");
|
|
15
|
+
export const ENTITLEMENT_MARKER = ".sky-ui-pro-installed.json";
|
|
16
|
+
|
|
17
|
+
export async function exists(p) {
|
|
18
|
+
try {
|
|
19
|
+
await access(p);
|
|
20
|
+
return true;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function resolveApiBase(pkg) {
|
|
27
|
+
const fromEnv = process.env.SKY_UI_API_URL?.trim();
|
|
28
|
+
if (fromEnv) return fromEnv.replace(/\/api\/?$/, "").replace(/\/$/, "");
|
|
29
|
+
const fromPkg = pkg?.skyUiPro?.apiBase?.trim();
|
|
30
|
+
if (fromPkg) return fromPkg.replace(/\/$/, "");
|
|
31
|
+
return "https://library.sky-ui.com";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function licenseValidateUrl(apiBase) {
|
|
35
|
+
const host = String(apiBase).replace(/\/api\/?$/, "").replace(/\/$/, "");
|
|
36
|
+
return `${host}/api/license/validate`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function resolveToken() {
|
|
40
|
+
const envCi = process.env.SKY_UI_AUTH_TOKEN?.trim();
|
|
41
|
+
if (envCi) return envCi;
|
|
42
|
+
const envPersonal = process.env.SKY_UI_PERSONAL_TOKEN?.trim();
|
|
43
|
+
if (envPersonal) return envPersonal;
|
|
44
|
+
for (const credPath of [
|
|
45
|
+
join(SKY_UI_HOME, "credentials.json"),
|
|
46
|
+
join(LEGACY_SKY_UI_HOME, "credentials.json"),
|
|
47
|
+
]) {
|
|
48
|
+
if (!(await exists(credPath))) continue;
|
|
49
|
+
const creds = JSON.parse(await readFile(credPath, "utf8"));
|
|
50
|
+
if (typeof creds.personalToken === "string" && creds.personalToken.trim()) {
|
|
51
|
+
return creds.personalToken.trim();
|
|
52
|
+
}
|
|
53
|
+
if (typeof creds.authToken === "string" && creds.authToken.trim()) {
|
|
54
|
+
return creds.authToken.trim();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isAccessTokenFormat(token) {
|
|
61
|
+
return typeof token === "string" && (token.startsWith("sk_pt_") || token.startsWith("sk_ci_"));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @returns {{ active: boolean, status?: string, error?: string, renewalEmailSent?: boolean }}
|
|
66
|
+
*/
|
|
67
|
+
export async function validateAccessTokenOnline(token, apiBase) {
|
|
68
|
+
if (!token || !isAccessTokenFormat(token)) {
|
|
69
|
+
return { active: false, status: "missing" };
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const res = await fetch(licenseValidateUrl(apiBase), {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: {
|
|
75
|
+
Authorization: `Bearer ${token}`,
|
|
76
|
+
"Content-Type": "application/json",
|
|
77
|
+
Accept: "application/json",
|
|
78
|
+
},
|
|
79
|
+
body: "{}",
|
|
80
|
+
});
|
|
81
|
+
const data = await res.json().catch(() => ({}));
|
|
82
|
+
if (res.ok && data.active) {
|
|
83
|
+
return { active: true, status: "active", ...data };
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
active: false,
|
|
87
|
+
status: data.status ?? (res.status === 401 ? "invalid" : "inactive"),
|
|
88
|
+
error: data.error,
|
|
89
|
+
renewalEmailSent: Boolean(data.renewalEmailSent),
|
|
90
|
+
};
|
|
91
|
+
} catch (err) {
|
|
92
|
+
return {
|
|
93
|
+
active: false,
|
|
94
|
+
status: "network_error",
|
|
95
|
+
error: err instanceof Error ? err.message : String(err),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function formatRenewalEmailHint(result) {
|
|
101
|
+
if (!result?.renewalEmailSent) return "";
|
|
102
|
+
return "\n Renewal instructions were sent to your account email.\n https://library.sky-ui.com/pricing";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isInstallStrict() {
|
|
106
|
+
if (process.env.SKY_UI_PRO_LENIENT === "1") return false;
|
|
107
|
+
if (process.env.SKY_UI_PRO_STRICT === "0") return false;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function entitlementMarkerPath(pkgRoot) {
|
|
112
|
+
return join(pkgRoot, ENTITLEMENT_MARKER);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function writeEntitlementMarker(pkgRoot, { name, version, status = "active" }) {
|
|
116
|
+
const { writeFile } = await import("node:fs/promises");
|
|
117
|
+
await writeFile(
|
|
118
|
+
entitlementMarkerPath(pkgRoot),
|
|
119
|
+
`${JSON.stringify(
|
|
120
|
+
{
|
|
121
|
+
name,
|
|
122
|
+
version,
|
|
123
|
+
status,
|
|
124
|
+
validatedAt: new Date().toISOString(),
|
|
125
|
+
},
|
|
126
|
+
null,
|
|
127
|
+
2,
|
|
128
|
+
)}\n`,
|
|
129
|
+
"utf8",
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** True when package was not hydrated (stub-only install). */
|
|
134
|
+
export async function isStubOnlyPackage(pkgRoot) {
|
|
135
|
+
const pluginsDir = join(pkgRoot, "plugins", "vite-plugin.js");
|
|
136
|
+
if (await exists(pluginsDir)) return false;
|
|
137
|
+
const distIndex = join(pkgRoot, "dist", "index.js");
|
|
138
|
+
if (await exists(distIndex)) return false;
|
|
139
|
+
const stubPath = join(pkgRoot, "dist", "stub", "index.js");
|
|
140
|
+
if (!(await exists(stubPath))) return true;
|
|
141
|
+
try {
|
|
142
|
+
const stub = await readFile(stubPath, "utf8");
|
|
143
|
+
return /export\s+default\s+\{\s*\}/.test(stub);
|
|
144
|
+
} catch {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
}
|