@arcblock/did-connect-service 4.0.4 → 4.0.6

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 (190) hide show
  1. package/assets/fonts/noto-sans-sc-regular.otf +0 -0
  2. package/dist/embedded.d.ts +32 -0
  3. package/dist/embedded.d.ts.map +1 -1
  4. package/dist/embedded.js +3 -0
  5. package/dist/embedded.js.map +1 -1
  6. package/dist/handlers/auth-handler.d.ts +5 -0
  7. package/dist/handlers/auth-handler.d.ts.map +1 -1
  8. package/dist/handlers/auth-handler.js +33 -0
  9. package/dist/handlers/auth-handler.js.map +1 -1
  10. package/dist/handlers/branding-handler.d.ts +17 -0
  11. package/dist/handlers/branding-handler.d.ts.map +1 -1
  12. package/dist/handlers/branding-handler.js +107 -5
  13. package/dist/handlers/branding-handler.js.map +1 -1
  14. package/dist/identity/csrf.d.ts +17 -0
  15. package/dist/identity/csrf.d.ts.map +1 -0
  16. package/dist/identity/csrf.js +56 -0
  17. package/dist/identity/csrf.js.map +1 -0
  18. package/dist/og/emoji.d.ts +12 -0
  19. package/dist/og/emoji.d.ts.map +1 -0
  20. package/dist/og/emoji.js +71 -0
  21. package/dist/og/emoji.js.map +1 -0
  22. package/dist/og/generator.d.ts +3 -0
  23. package/dist/og/generator.d.ts.map +1 -0
  24. package/dist/og/generator.js +338 -0
  25. package/dist/og/generator.js.map +1 -0
  26. package/dist/og/index.d.ts +6 -0
  27. package/dist/og/index.d.ts.map +1 -0
  28. package/dist/og/index.js +4 -0
  29. package/dist/og/index.js.map +1 -0
  30. package/dist/og/passport-svg.d.ts +52 -0
  31. package/dist/og/passport-svg.d.ts.map +1 -0
  32. package/dist/og/passport-svg.js +157 -0
  33. package/dist/og/passport-svg.js.map +1 -0
  34. package/dist/og/ssrf-guard.d.ts +38 -0
  35. package/dist/og/ssrf-guard.d.ts.map +1 -0
  36. package/dist/og/ssrf-guard.js +188 -0
  37. package/dist/og/ssrf-guard.js.map +1 -0
  38. package/dist/og/templates.d.ts +26 -0
  39. package/dist/og/templates.d.ts.map +1 -0
  40. package/dist/og/templates.js +302 -0
  41. package/dist/og/templates.js.map +1 -0
  42. package/dist/og/types.d.ts +74 -0
  43. package/dist/og/types.d.ts.map +1 -0
  44. package/dist/og/types.js +14 -0
  45. package/dist/og/types.js.map +1 -0
  46. package/package.json +18 -4
  47. package/dist/access-key-handler.d.ts +0 -37
  48. package/dist/access-key-handler.d.ts.map +0 -1
  49. package/dist/access-key-handler.js +0 -316
  50. package/dist/access-key-handler.js.map +0 -1
  51. package/dist/access-key-util.d.ts +0 -19
  52. package/dist/access-key-util.d.ts.map +0 -1
  53. package/dist/access-key-util.js +0 -45
  54. package/dist/access-key-util.js.map +0 -1
  55. package/dist/access-policy.d.ts +0 -53
  56. package/dist/access-policy.d.ts.map +0 -1
  57. package/dist/access-policy.js +0 -153
  58. package/dist/access-policy.js.map +0 -1
  59. package/dist/auth-client.d.ts +0 -20
  60. package/dist/auth-client.d.ts.map +0 -1
  61. package/dist/auth-client.js +0 -42
  62. package/dist/auth-client.js.map +0 -1
  63. package/dist/auth-entrypoint.d.ts +0 -45
  64. package/dist/auth-entrypoint.d.ts.map +0 -1
  65. package/dist/auth-entrypoint.js +0 -31
  66. package/dist/auth-entrypoint.js.map +0 -1
  67. package/dist/auth-handler.d.ts +0 -136
  68. package/dist/auth-handler.d.ts.map +0 -1
  69. package/dist/auth-handler.js +0 -408
  70. package/dist/auth-handler.js.map +0 -1
  71. package/dist/auth-rpc-types.d.ts +0 -139
  72. package/dist/auth-rpc-types.d.ts.map +0 -1
  73. package/dist/auth-rpc-types.js +0 -11
  74. package/dist/auth-rpc-types.js.map +0 -1
  75. package/dist/auth-rpc.d.ts +0 -80
  76. package/dist/auth-rpc.d.ts.map +0 -1
  77. package/dist/auth-rpc.js +0 -257
  78. package/dist/auth-rpc.js.map +0 -1
  79. package/dist/auth-worker.d.ts +0 -42
  80. package/dist/auth-worker.d.ts.map +0 -1
  81. package/dist/auth-worker.js +0 -120
  82. package/dist/auth-worker.js.map +0 -1
  83. package/dist/blocklet-js-handler.d.ts +0 -22
  84. package/dist/blocklet-js-handler.d.ts.map +0 -1
  85. package/dist/blocklet-js-handler.js +0 -205
  86. package/dist/blocklet-js-handler.js.map +0 -1
  87. package/dist/branding-handler.d.ts +0 -42
  88. package/dist/branding-handler.d.ts.map +0 -1
  89. package/dist/branding-handler.js +0 -326
  90. package/dist/branding-handler.js.map +0 -1
  91. package/dist/d1-token-storage.d.ts +0 -31
  92. package/dist/d1-token-storage.d.ts.map +0 -1
  93. package/dist/d1-token-storage.js +0 -83
  94. package/dist/d1-token-storage.js.map +0 -1
  95. package/dist/did-connect-handler.d.ts +0 -57
  96. package/dist/did-connect-handler.d.ts.map +0 -1
  97. package/dist/did-connect-handler.js +0 -182
  98. package/dist/did-connect-handler.js.map +0 -1
  99. package/dist/did.d.ts +0 -14
  100. package/dist/did.d.ts.map +0 -1
  101. package/dist/did.js +0 -17
  102. package/dist/did.js.map +0 -1
  103. package/dist/email-login-handler.d.ts +0 -50
  104. package/dist/email-login-handler.d.ts.map +0 -1
  105. package/dist/email-login-handler.js +0 -238
  106. package/dist/email-login-handler.js.map +0 -1
  107. package/dist/federation-utils.d.ts +0 -23
  108. package/dist/federation-utils.d.ts.map +0 -1
  109. package/dist/federation-utils.js +0 -25
  110. package/dist/federation-utils.js.map +0 -1
  111. package/dist/handler.d.ts +0 -90
  112. package/dist/handler.d.ts.map +0 -1
  113. package/dist/handler.js +0 -591
  114. package/dist/handler.js.map +0 -1
  115. package/dist/identity/invitation-util.d.ts +0 -7
  116. package/dist/identity/invitation-util.d.ts.map +0 -1
  117. package/dist/identity/invitation-util.js +0 -66
  118. package/dist/identity/invitation-util.js.map +0 -1
  119. package/dist/instance-role.d.ts +0 -10
  120. package/dist/instance-role.d.ts.map +0 -1
  121. package/dist/instance-role.js +0 -20
  122. package/dist/instance-role.js.map +0 -1
  123. package/dist/jwt.d.ts +0 -7
  124. package/dist/jwt.d.ts.map +0 -1
  125. package/dist/jwt.js +0 -72
  126. package/dist/jwt.js.map +0 -1
  127. package/dist/login-entry.d.ts +0 -9
  128. package/dist/login-entry.d.ts.map +0 -1
  129. package/dist/login-entry.js +0 -9
  130. package/dist/login-entry.js.map +0 -1
  131. package/dist/membership-handler.d.ts +0 -27
  132. package/dist/membership-handler.d.ts.map +0 -1
  133. package/dist/membership-handler.js +0 -111
  134. package/dist/membership-handler.js.map +0 -1
  135. package/dist/oauth-callback-page.d.ts +0 -9
  136. package/dist/oauth-callback-page.d.ts.map +0 -1
  137. package/dist/oauth-callback-page.js +0 -31
  138. package/dist/oauth-callback-page.js.map +0 -1
  139. package/dist/oauth-handler.d.ts +0 -72
  140. package/dist/oauth-handler.d.ts.map +0 -1
  141. package/dist/oauth-handler.js +0 -423
  142. package/dist/oauth-handler.js.map +0 -1
  143. package/dist/page.d.ts +0 -33
  144. package/dist/page.d.ts.map +0 -1
  145. package/dist/page.js +0 -59
  146. package/dist/page.js.map +0 -1
  147. package/dist/pages/auth-script.d.ts +0 -18
  148. package/dist/pages/auth-script.d.ts.map +0 -1
  149. package/dist/pages/auth-script.js +0 -185
  150. package/dist/pages/auth-script.js.map +0 -1
  151. package/dist/pages/design-tokens.d.ts +0 -86
  152. package/dist/pages/design-tokens.d.ts.map +0 -1
  153. package/dist/pages/design-tokens.js +0 -159
  154. package/dist/pages/design-tokens.js.map +0 -1
  155. package/dist/pages/did-connect-script.d.ts +0 -16
  156. package/dist/pages/did-connect-script.d.ts.map +0 -1
  157. package/dist/pages/did-connect-script.js +0 -105
  158. package/dist/pages/did-connect-script.js.map +0 -1
  159. package/dist/pages/shared-styles.d.ts +0 -6
  160. package/dist/pages/shared-styles.d.ts.map +0 -1
  161. package/dist/pages/shared-styles.js +0 -109
  162. package/dist/pages/shared-styles.js.map +0 -1
  163. package/dist/rbac.d.ts +0 -19
  164. package/dist/rbac.d.ts.map +0 -1
  165. package/dist/rbac.js +0 -76
  166. package/dist/rbac.js.map +0 -1
  167. package/dist/session-context.d.ts +0 -35
  168. package/dist/session-context.d.ts.map +0 -1
  169. package/dist/session-context.js +0 -39
  170. package/dist/session-context.js.map +0 -1
  171. package/dist/store.d.ts +0 -222
  172. package/dist/store.d.ts.map +0 -1
  173. package/dist/store.js +0 -1366
  174. package/dist/store.js.map +0 -1
  175. package/dist/team-handler.d.ts +0 -90
  176. package/dist/team-handler.d.ts.map +0 -1
  177. package/dist/team-handler.js +0 -1225
  178. package/dist/team-handler.js.map +0 -1
  179. package/dist/ticket-handler.d.ts +0 -28
  180. package/dist/ticket-handler.d.ts.map +0 -1
  181. package/dist/ticket-handler.js +0 -74
  182. package/dist/ticket-handler.js.map +0 -1
  183. package/dist/wallet-identity.d.ts +0 -32
  184. package/dist/wallet-identity.d.ts.map +0 -1
  185. package/dist/wallet-identity.js +0 -43
  186. package/dist/wallet-identity.js.map +0 -1
  187. package/dist/webauthn.d.ts +0 -65
  188. package/dist/webauthn.d.ts.map +0 -1
  189. package/dist/webauthn.js +0 -112
  190. package/dist/webauthn.js.map +0 -1
@@ -0,0 +1,56 @@
1
+ /**
2
+ * CSRF token — byte-for-byte compatible with blocklet-server's
3
+ * `@blocklet/sdk/lib/util/csrf` so tokens we issue verify under the same scheme:
4
+ *
5
+ * md5 = HMAC-MD5(secret, loginToken) → base64url
6
+ * signed = HMAC-SHA256(secret, md5) → base64url (input is the md5 string)
7
+ * csrf = `${md5}.${signed}`
8
+ *
9
+ * `secret` mirrors `getCsrfSecret()` (APP_ASK || APP_SK) → our `appSk`,
10
+ * falling back to `jwtSecret` when no app wallet is configured.
11
+ *
12
+ * WebCrypto has no MD5, so HMAC-MD5 is built on the pure-JS MD5 in gravatar.ts;
13
+ * HMAC-SHA256 uses crypto.subtle.
14
+ */
15
+ import { md5Bytes } from "./gravatar.js";
16
+ const BLOCK_SIZE = 64; // both MD5 and SHA-256 use a 64-byte block
17
+ const enc = new TextEncoder();
18
+ function concat(a, b) {
19
+ const out = new Uint8Array(a.length + b.length);
20
+ out.set(a);
21
+ out.set(b, a.length);
22
+ return out;
23
+ }
24
+ function base64url(bytes) {
25
+ let bin = "";
26
+ for (const b of bytes)
27
+ bin += String.fromCharCode(b);
28
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
29
+ }
30
+ function hmacMd5(keyBytes, msg) {
31
+ let key = keyBytes;
32
+ if (key.length > BLOCK_SIZE)
33
+ key = md5Bytes(key);
34
+ const ipad = new Uint8Array(BLOCK_SIZE);
35
+ const opad = new Uint8Array(BLOCK_SIZE);
36
+ for (let i = 0; i < BLOCK_SIZE; i++) {
37
+ const k = key[i] ?? 0;
38
+ ipad[i] = k ^ 0x36;
39
+ opad[i] = k ^ 0x5c;
40
+ }
41
+ const inner = md5Bytes(concat(ipad, msg));
42
+ return md5Bytes(concat(opad, inner));
43
+ }
44
+ async function hmacSha256(keyBytes, msg) {
45
+ const key = await crypto.subtle.importKey("raw", keyBytes, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
46
+ const sig = await crypto.subtle.sign("HMAC", key, msg);
47
+ return new Uint8Array(sig);
48
+ }
49
+ /** CSRF token compatible with `@blocklet/sdk` csrf.sign(secret, loginToken). */
50
+ export async function signCsrf(secret, loginToken) {
51
+ const keyBytes = enc.encode(secret);
52
+ const md5Part = base64url(hmacMd5(keyBytes, enc.encode(loginToken)));
53
+ const signedPart = base64url(await hmacSha256(keyBytes, enc.encode(md5Part)));
54
+ return `${md5Part}.${signedPart}`;
55
+ }
56
+ //# sourceMappingURL=csrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/identity/csrf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare function toCodePoint(unicodeSurrogates: string): string;
2
+ export declare function getIconCode(char: string): string;
3
+ export type EmojiType = "twemoji" | "openmoji" | "blobmoji" | "noto" | "fluent" | "fluentFlat";
4
+ export declare function getEmojiUrl(type: EmojiType, code: string): string;
5
+ export declare function loadEmoji(code: string, type: EmojiType): Promise<string>;
6
+ /**
7
+ * satori `loadAdditionalAsset` callback factory.
8
+ * Caches each (language, text) lookup; returns base64 data URL for emoji rendering.
9
+ */
10
+ export declare function loadDynamicAsset(emojiType?: EmojiType): (languageCode: string, text: string) => Promise<string | undefined>;
11
+ export declare const EMOJI_TYPES: readonly EmojiType[];
12
+ //# sourceMappingURL=emoji.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji.d.ts","sourceRoot":"","sources":["../../src/og/emoji.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAiB7D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC;AAc/F,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,GAAE,SAAqB,GAC/B,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmBrE;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAAwE,CAAC"}
@@ -0,0 +1,71 @@
1
+ const U200D = String.fromCharCode(8205); // zero-width joiner
2
+ const UFE0F_REGEX = /️/g; // variation selector
3
+ export function toCodePoint(unicodeSurrogates) {
4
+ const r = [];
5
+ let c = 0;
6
+ let p = 0;
7
+ let i = 0;
8
+ while (i < unicodeSurrogates.length) {
9
+ c = unicodeSurrogates.charCodeAt(i++);
10
+ if (p) {
11
+ r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));
12
+ p = 0;
13
+ }
14
+ else if (c >= 55296 && c <= 56319) {
15
+ p = c;
16
+ }
17
+ else {
18
+ r.push(c.toString(16));
19
+ }
20
+ }
21
+ return r.join("-");
22
+ }
23
+ export function getIconCode(char) {
24
+ return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0F_REGEX, "") : char);
25
+ }
26
+ const URL_BUILDERS = {
27
+ twemoji: (code) => `https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/svg/${code.toLowerCase()}.svg`,
28
+ openmoji: (code) => `https://cdn.jsdelivr.net/npm/@svgmoji/openmoji@2.0.0/svg/${code.toUpperCase()}.svg`,
29
+ blobmoji: (code) => `https://cdn.jsdelivr.net/npm/@svgmoji/blob@2.0.0/svg/${code.toUpperCase()}.svg`,
30
+ noto: (code) => `https://cdn.jsdelivr.net/gh/svgmoji/svgmoji/packages/svgmoji__noto/svg/${code.toUpperCase()}.svg`,
31
+ fluent: (code) => `https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${code.toLowerCase()}_color.svg`,
32
+ fluentFlat: (code) => `https://cdn.jsdelivr.net/gh/shuding/fluentui-emoji-unicode/assets/${code.toLowerCase()}_flat.svg`,
33
+ };
34
+ export function getEmojiUrl(type, code) {
35
+ const builder = URL_BUILDERS[type] ?? URL_BUILDERS.twemoji;
36
+ return builder(code);
37
+ }
38
+ export async function loadEmoji(code, type) {
39
+ const res = await fetch(getEmojiUrl(type, code));
40
+ if (!res.ok)
41
+ throw new Error(`emoji fetch failed: ${res.status} ${getEmojiUrl(type, code)}`);
42
+ return res.text();
43
+ }
44
+ /**
45
+ * satori `loadAdditionalAsset` callback factory.
46
+ * Caches each (language, text) lookup; returns base64 data URL for emoji rendering.
47
+ */
48
+ export function loadDynamicAsset(emojiType = "twemoji") {
49
+ const cache = new Map();
50
+ return async (languageCode, text) => {
51
+ if (languageCode !== "emoji")
52
+ return undefined;
53
+ const key = `${emojiType}:${text}`;
54
+ const cached = cache.get(key);
55
+ if (cached)
56
+ return cached;
57
+ const code = getIconCode(text);
58
+ try {
59
+ const svg = await loadEmoji(code, emojiType);
60
+ const dataUrl = `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}`;
61
+ cache.set(key, dataUrl);
62
+ return dataUrl;
63
+ }
64
+ catch (err) {
65
+ console.error(`Failed to fetch emoji ${text}:${code}`, err);
66
+ return undefined;
67
+ }
68
+ };
69
+ }
70
+ export const EMOJI_TYPES = ["twemoji", "openmoji", "blobmoji", "noto", "fluent", "fluentFlat"];
71
+ //# sourceMappingURL=emoji.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji.js","sourceRoot":"","sources":["../../src/og/emoji.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CreateOgGeneratorOptions, OgGenerator } from "./types.js";
2
+ export declare function createOgGenerator(options?: CreateOgGeneratorOptions): OgGenerator;
3
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/og/generator.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,wBAAwB,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAC;AAqS3F,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,WAAW,CA4HrF"}
@@ -0,0 +1,338 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import stringify from "fast-json-stable-stringify";
8
+ import { joinURL } from "ufo";
9
+ import * as v from "valibot";
10
+ import { EMOJI_TYPES, loadDynamicAsset } from "./emoji.js";
11
+ import { getPassportColor } from "./passport-svg.js";
12
+ import { assertFetchableUrl, readBodyCapped } from "./ssrf-guard.js";
13
+ import { getTemplate } from "./templates.js";
14
+ import { MAX_DESCRIPTION_LENGTH, MAX_IMAGE_DIMENSION, MAX_IMAGE_SIZE, MAX_TITLE_LENGTH, OgValidationError, } from "./types.js";
15
+ // ---------------------------------------------------------------------------
16
+ // Internals
17
+ // ---------------------------------------------------------------------------
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+ // dist/og/generator.js → ../../assets/fonts/…
20
+ const FONT_PATH = join(__dirname, "../../assets/fonts/noto-sans-sc-regular.otf");
21
+ // Keyed by fontUrl (or "bundled") so multiple generator instances share one
22
+ // in-memory copy. Rejections are evicted so transient network failures don't
23
+ // poison the cache forever.
24
+ const fontCache = new Map();
25
+ function loadFont(source) {
26
+ const key = source.fontUrl ?? "bundled";
27
+ let p = fontCache.get(key);
28
+ if (!p) {
29
+ p = loadFontUncached(source);
30
+ p.catch(() => fontCache.delete(key));
31
+ fontCache.set(key, p);
32
+ }
33
+ return p;
34
+ }
35
+ async function loadFontUncached({ fontUrl, fontCacheDir, fetchImpl }) {
36
+ if (!fontUrl)
37
+ return readFile(FONT_PATH);
38
+ const diskPath = join(fontCacheDir, `${md5(fontUrl)}.font`);
39
+ if (existsSync(diskPath))
40
+ return readFile(diskPath);
41
+ try {
42
+ const res = await fetchImpl(fontUrl);
43
+ if (!res.ok)
44
+ throw new Error(`font fetch failed: ${res.status} ${fontUrl}`);
45
+ const buf = Buffer.from(await res.arrayBuffer());
46
+ mkdirSync(dirname(diskPath), { recursive: true });
47
+ writeFileSync(diskPath, buf);
48
+ return buf;
49
+ }
50
+ catch (err) {
51
+ // Remote font unavailable — fall back to the bundled font so OG keeps
52
+ // rendering (with potentially stale glyph coverage) instead of failing.
53
+ if (existsSync(FONT_PATH)) {
54
+ console.error(`[og] remote font fetch failed (${err instanceof Error ? err.message : err}); using bundled font`);
55
+ return readFile(FONT_PATH);
56
+ }
57
+ throw err;
58
+ }
59
+ }
60
+ // ---------------------------------------------------------------------------
61
+ // Cache-file path (2-char directory shard)
62
+ // ---------------------------------------------------------------------------
63
+ function getCacheFilePath(dir, name) {
64
+ return join(dir, name.slice(0, 2), name.slice(2));
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // md5 helper
68
+ // ---------------------------------------------------------------------------
69
+ function md5(s) {
70
+ return createHash("md5").update(s).digest("hex");
71
+ }
72
+ /**
73
+ * Bump whenever template markup / decor / color math changes in a way that
74
+ * should invalidate previously cached renders. Without this, deploying new
75
+ * template code would keep serving disk-cached images generated by the old
76
+ * templates (cache keys are derived from request params only).
77
+ */
78
+ const OG_RENDER_VERSION = 2;
79
+ // ---------------------------------------------------------------------------
80
+ // Valibot schema
81
+ // ---------------------------------------------------------------------------
82
+ const schema = v.object({
83
+ template: v.optional(v.picklist(["default", "section", "cover", "banner"]), "default"),
84
+ title: v.optional(v.pipe(v.string(), v.maxLength(MAX_TITLE_LENGTH, `title too long: max ${MAX_TITLE_LENGTH} characters`)), ""),
85
+ description: v.optional(v.pipe(v.string(), v.maxLength(MAX_DESCRIPTION_LENGTH, `description too long: max ${MAX_DESCRIPTION_LENGTH} characters`)), ""),
86
+ section: v.optional(v.pipe(v.string(), v.maxLength(64, "section too long: max 64 characters")), ""),
87
+ cover: v.optional(v.pipe(v.string(), v.check((s) => s === "" || /^https:\/\//.test(s), "cover must be an https URL")), ""),
88
+ logo: v.optional(v.pipe(v.string(), v.check((s) => s === "" || /^https:\/\//.test(s), "logo must be an https URL")), ""),
89
+ logoRounded: v.optional(v.picklist(["0", "1"]), "0"),
90
+ emoji: v.optional(v.picklist([...EMOJI_TYPES]), "twemoji"),
91
+ nocache: v.optional(v.picklist(["1"])),
92
+ });
93
+ // ---------------------------------------------------------------------------
94
+ // Template constraints (Joi .when() equivalents)
95
+ // ---------------------------------------------------------------------------
96
+ function enforceTemplateConstraints(parsed) {
97
+ if (parsed.template === "section") {
98
+ if (!parsed.section)
99
+ throw new OgValidationError("section is required for template=section");
100
+ if (!parsed.title)
101
+ throw new OgValidationError("title is required for template=section");
102
+ if (!parsed.description)
103
+ throw new OgValidationError("description is required for template=section");
104
+ }
105
+ else if (parsed.template === "cover") {
106
+ if (!parsed.cover)
107
+ throw new OgValidationError("cover is required for template=cover");
108
+ if (!parsed.title)
109
+ throw new OgValidationError("title is required for template=cover");
110
+ }
111
+ else if (parsed.template === "banner") {
112
+ if (!parsed.logo)
113
+ throw new OgValidationError("logo is required for template=banner");
114
+ if (!parsed.title)
115
+ throw new OgValidationError("title is required for template=banner");
116
+ }
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // External image fetching / caching
120
+ // ---------------------------------------------------------------------------
121
+ async function convertExternalImage(url, dest, height, fetchImpl, lookupImpl) {
122
+ const { default: sharp } = await import("sharp");
123
+ const tmpUrl = new URL(url);
124
+ if (!url.endsWith(".svg")) {
125
+ tmpUrl.searchParams.set("imageFilter", "convert");
126
+ tmpUrl.searchParams.set("f", "png");
127
+ tmpUrl.searchParams.set("h", height.toString());
128
+ }
129
+ // SSRF guard: only fetch public https targets; a host resolving to a
130
+ // private/loopback/link-local/metadata address is blocked.
131
+ await assertFetchableUrl(tmpUrl.toString(), lookupImpl);
132
+ const controller = new AbortController();
133
+ const timeout = setTimeout(() => controller.abort(), 10_000);
134
+ let res;
135
+ try {
136
+ res = await fetchImpl(tmpUrl.toString(), {
137
+ headers: { Accept: "image/*" },
138
+ signal: controller.signal,
139
+ redirect: "error", // a 3xx could redirect to a private target — refuse
140
+ });
141
+ }
142
+ finally {
143
+ clearTimeout(timeout);
144
+ }
145
+ if (!res.ok) {
146
+ throw new OgValidationError(`unexpected external image status: ${res.status} ${url}`);
147
+ }
148
+ const contentType = res.headers.get("content-type") ?? "";
149
+ if (!contentType.startsWith("image/")) {
150
+ throw new OgValidationError(`unexpected external image format: ${contentType}`);
151
+ }
152
+ // Read with a hard byte cap — do NOT trust Content-Length.
153
+ const arrayBuffer = await readBodyCapped(res, MAX_IMAGE_SIZE);
154
+ // Downscale to the slot's target height before embedding. Without this a
155
+ // full-resolution upload (e.g. a 4000px photo background) gets inlined into
156
+ // the SVG as a lossless PNG, ballooning the final card to ~1MB. Resizing to
157
+ // the render height (630 background / 120 logo) + max compression keeps the
158
+ // card small. `withoutEnlargement` avoids upscaling already-small assets.
159
+ const pngBuffer = await sharp(Buffer.from(arrayBuffer), { animated: false })
160
+ .resize({ height, withoutEnlargement: true })
161
+ .png({ compressionLevel: 9, force: true })
162
+ .toBuffer();
163
+ mkdirSync(dirname(dest), { recursive: true });
164
+ writeFileSync(dest, pngBuffer);
165
+ }
166
+ // 1×1 fully-transparent PNG — used as an invisible placeholder when an
167
+ // <img>-bound asset (logo/cover) can't be fetched, so satori still renders.
168
+ const TRANSPARENT_PNG_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
169
+ async function ensureExternalImages(params, tmpDir, fetchImpl, lookupImpl) {
170
+ for (const key of ["cover", "logo", "background"]) {
171
+ const url = params[key];
172
+ if (typeof url !== "string" || !url)
173
+ continue;
174
+ const cacheKey = md5(url);
175
+ const destPath = getCacheFilePath(tmpDir, `${cacheKey}.png`);
176
+ try {
177
+ if (!existsSync(destPath)) {
178
+ await convertExternalImage(url, destPath, key === "logo" ? 120 : 630, fetchImpl, lookupImpl);
179
+ }
180
+ // Satori does not support file:// URLs — convert to data URI.
181
+ const pngBuf = readFileSync(destPath);
182
+ params[key] = `data:image/png;base64,${pngBuf.toString("base64")}`;
183
+ }
184
+ catch (err) {
185
+ // A single unreachable/invalid asset must NOT fail the whole card —
186
+ // crawlers would get nothing. Degrade per slot:
187
+ // - background → "" so templates fall back to the brand-color gradient
188
+ // - logo/cover → an invisible transparent pixel, because satori rejects
189
+ // an empty <img> src ("Image source is not provided").
190
+ console.error(`[og] external image "${key}" unavailable (${url}): ${err instanceof Error ? err.message : err}`);
191
+ params[key] = key === "background" ? "" : TRANSPARENT_PNG_DATA_URI;
192
+ }
193
+ }
194
+ }
195
+ // ---------------------------------------------------------------------------
196
+ // Core image generation
197
+ // ---------------------------------------------------------------------------
198
+ async function generateOgImage(params, tmpDir, emojiType, fetchImpl, lookupImpl, fontSource) {
199
+ const { default: satori } = await import("satori");
200
+ const { default: sharp } = await import("sharp");
201
+ await ensureExternalImages(params, tmpDir, fetchImpl, lookupImpl);
202
+ const raw = await getTemplate(params);
203
+ if (params.format === "html")
204
+ return Buffer.from(raw);
205
+ const fontData = await loadFont(fontSource);
206
+ const svg = await satori(raw, {
207
+ width: Math.min(params.width, MAX_IMAGE_DIMENSION),
208
+ height: Math.min(params.height, MAX_IMAGE_DIMENSION),
209
+ fonts: [{ name: "Noto", data: fontData, weight: 400, style: "normal" }],
210
+ // loadDynamicAsset may return undefined for non-emoji segments;
211
+ // satori expects string | FontOptions[] so we coerce undefined → "".
212
+ loadAdditionalAsset: async (lang, segment) => {
213
+ const result = await loadDynamicAsset(emojiType)(lang, segment);
214
+ return result ?? "";
215
+ },
216
+ });
217
+ if (params.format === "svg")
218
+ return Buffer.from(svg);
219
+ const pipeline = sharp(Buffer.from(svg));
220
+ // Format by content: a photographic background compresses ~10× better as
221
+ // JPEG (a lossless PNG of a photo is ~1MB; JPEG q82 is ~100KB). Flat
222
+ // gradient/text cards stay PNG so text edges remain crisp. Both formats are
223
+ // universally accepted by social crawlers; serveOg sets the Content-Type
224
+ // from the file's magic bytes, so the encoder choice is self-describing.
225
+ return params.background
226
+ ? pipeline.jpeg({ quality: 82, mozjpeg: true }).toBuffer()
227
+ : pipeline.png({ compressionLevel: 9 }).toBuffer();
228
+ }
229
+ // ---------------------------------------------------------------------------
230
+ // Public factory
231
+ // ---------------------------------------------------------------------------
232
+ export function createOgGenerator(options = {}) {
233
+ const fetchImpl = options.fetchImpl ?? fetch;
234
+ const lookupImpl = options.lookupImpl;
235
+ const fontSource = {
236
+ fontUrl: options.fontUrl ?? process.env.OG_FONT_URL,
237
+ fontCacheDir: options.fontCacheDir ?? join(tmpdir(), "og-fonts"),
238
+ fetchImpl,
239
+ };
240
+ const generateTasks = new Map();
241
+ async function generate(opts) {
242
+ const { input, info, format, cacheDir, tmpDir } = opts;
243
+ mkdirSync(cacheDir, { recursive: true });
244
+ mkdirSync(tmpDir, { recursive: true });
245
+ // 1. Validate input
246
+ let parsed;
247
+ try {
248
+ parsed = v.parse(schema, input);
249
+ }
250
+ catch (err) {
251
+ const msg = err instanceof Error ? err.message : String(err);
252
+ throw new OgValidationError(`open graph service params invalid: ${msg}`);
253
+ }
254
+ // Trim title and description (Joi did this automatically via .trim()).
255
+ if (parsed.title)
256
+ parsed.title = parsed.title.trim();
257
+ if (parsed.description)
258
+ parsed.description = parsed.description.trim();
259
+ // 2. Apply conditional template constraints (Joi's .when() rules)
260
+ enforceTemplateConstraints(parsed);
261
+ // 3. Defaults from info context (matches source lines 95-124)
262
+ if (parsed.template === "cover" && parsed.title && !parsed.description) {
263
+ parsed.description = parsed.title;
264
+ parsed.title = info.name;
265
+ }
266
+ if (!parsed.title)
267
+ parsed.title = info.name;
268
+ if (!parsed.description)
269
+ parsed.description = info.description;
270
+ // 4. Derive logo/background URLs from info (matches source lines 107-124)
271
+ let logo = parsed.logo;
272
+ if (!logo) {
273
+ logo = joinURL(info.appUrl, "/.well-known/service", `/blocklet/logo?imageFilter=convert&f=png&w=120&hash=${info.logoHash ?? ""}`);
274
+ }
275
+ // Background: only reference the blocklet's uploaded og-image when one
276
+ // actually exists (signalled by info.ogImageHash). Without an upload the
277
+ // BrandingHandler fallback is a tiny letter-SVG that satori would stretch
278
+ // to 1200×630 (blurry); an empty background makes the templates render a
279
+ // brand-color gradient instead. The banner template's legacy
280
+ // /static/images/banner.png asset does not ship with connect-service, so
281
+ // banner always uses the gradient.
282
+ const background = parsed.template !== "banner" && info.ogImageHash
283
+ ? joinURL(info.appUrl, "/.well-known/service", `/blocklet/og-image?imageFilter=resize&w=1200&h=630&hash=${info.ogImageHash}`)
284
+ : "";
285
+ // 5. Compute color via passport-svg
286
+ const color = getPassportColor(info.passportColor, info.did);
287
+ // 6. Build full params for template
288
+ const width = parsed.template === "banner" ? 1280 : 1200;
289
+ const height = parsed.template === "banner" ? 441 : 630;
290
+ const logoRounded = parsed.logoRounded === "1";
291
+ const template = parsed.template;
292
+ const emojiType = parsed.emoji;
293
+ const fullParams = {
294
+ width,
295
+ height,
296
+ logo,
297
+ background,
298
+ logoRounded,
299
+ color,
300
+ title: parsed.title,
301
+ description: parsed.description,
302
+ section: parsed.section ?? "",
303
+ cover: parsed.cover ?? "",
304
+ template,
305
+ format,
306
+ };
307
+ // 7. Cache lookup
308
+ const cacheKey = md5(stringify({
309
+ v: OG_RENDER_VERSION,
310
+ ...parsed,
311
+ logo,
312
+ background,
313
+ width,
314
+ height,
315
+ color,
316
+ format,
317
+ info: { name: info.name, did: info.did, appUrl: info.appUrl },
318
+ }));
319
+ const nocache = input.nocache === "1";
320
+ const destPath = getCacheFilePath(cacheDir, `${cacheKey}.${format}`);
321
+ if (!nocache && existsSync(destPath))
322
+ return destPath;
323
+ // 8. Dedup concurrent generation
324
+ let task = generateTasks.get(cacheKey);
325
+ if (!task) {
326
+ task = generateOgImage(fullParams, tmpDir, emojiType, fetchImpl, lookupImpl, fontSource).finally(() => {
327
+ setTimeout(() => generateTasks.delete(cacheKey), 1000);
328
+ });
329
+ generateTasks.set(cacheKey, task);
330
+ }
331
+ const buffer = await task;
332
+ mkdirSync(dirname(destPath), { recursive: true });
333
+ writeFileSync(destPath, buffer);
334
+ return destPath;
335
+ }
336
+ return { generate };
337
+ }
338
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/og/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAmB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,8CAA8C;AAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,6CAA6C,CAAC,CAAC;AAQjF,4EAA4E;AAC5E,6EAA6E;AAC7E,4BAA4B;AAC5B,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;AAErD,SAAS,QAAQ,CAAC,MAAkB;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC;IACxC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAc;IAC9E,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QAC5E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,sEAAsE;QACtE,wEAAwE;QACxE,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,kCAAkC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC;YACjH,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,2CAA2C;AAC3C,8EAA8E;AAE9E,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACjD,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC,EAAE,SAAS,CAAC;IAC/F,KAAK,EAAE,CAAC,CAAC,QAAQ,CACf,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE,uBAAuB,gBAAgB,aAAa,CAAC,CAAC,EACvG,EAAE,CACH;IACD,WAAW,EAAE,CAAC,CAAC,QAAQ,CACrB,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,SAAS,CAAC,sBAAsB,EAAE,6BAA6B,sBAAsB,aAAa,CAAC,CACtG,EACD,EAAE,CACH;IACD,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,qCAAqC,CAAC,CAAC,EAAE,EAAE,CAAC;IACnG,KAAK,EAAE,CAAC,CAAC,QAAQ,CACf,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAChF,EACD,EAAE,CACH;IACD,IAAI,EAAE,CAAC,CAAC,QAAQ,CACd,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAC/E,EACD,EAAE,CACH;IACD,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,CAAU,CAAC,EAAE,GAAG,CAAC;IAC7D,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,WAAW,CAAgC,CAAC,EAAE,SAAS,CAAC;IACzF,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAU,CAAC,CAAC;CAChD,CAAC,CAAC;AAIH,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,SAAS,0BAA0B,CAAC,MAAmB;IACrD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,iBAAiB,CAAC,0CAA0C,CAAC,CAAC;QAC7F,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,IAAI,iBAAiB,CAAC,wCAAwC,CAAC,CAAC;QACzF,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,MAAM,IAAI,iBAAiB,CAAC,8CAA8C,CAAC,CAAC;IACvG,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;QACvF,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;IACzF,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;QACtF,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,IAAI,iBAAiB,CAAC,uCAAuC,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E,KAAK,UAAU,oBAAoB,CACjC,GAAW,EACX,IAAY,EACZ,MAAc,EACd,SAAuB,EACvB,UAAkC;IAElC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,qEAAqE;IACrE,2DAA2D;IAC3D,MAAM,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,UAAU,CAAC,CAAC;IAExD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE;YACvC,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;YAC9B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,QAAQ,EAAE,OAAO,EAAE,oDAAoD;SACxE,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,iBAAiB,CAAC,qCAAqC,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC1D,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,iBAAiB,CAAC,qCAAqC,WAAW,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,2DAA2D;IAC3D,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC9D,yEAAyE;IACzE,4EAA4E;IAC5E,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;SACzE,MAAM,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;SAC5C,GAAG,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SACzC,QAAQ,EAAE,CAAC;IAEd,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACjC,CAAC;AAED,uEAAuE;AACvE,4EAA4E;AAC5E,MAAM,wBAAwB,GAC5B,oHAAoH,CAAC;AAEvH,KAAK,UAAU,oBAAoB,CACjC,MAA+B,EAC/B,MAAc,EACd,SAAuB,EACvB,UAAkC;IAElC,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAU,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG;YAAE,SAAS;QAE9C,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC;QAE7D,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,MAAM,oBAAoB,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YAC/F,CAAC;YACD,8DAA8D;YAC9D,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACtC,MAAM,CAAC,GAAG,CAAC,GAAG,yBAAyB,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oEAAoE;YACpE,gDAAgD;YAChD,wEAAwE;YACxE,yEAAyE;YACzE,0DAA0D;YAC1D,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,kBAAkB,GAAG,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAChH,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC;QACrE,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,KAAK,UAAU,eAAe,CAC5B,MAA+B,EAC/B,MAAc,EACd,SAAoB,EACpB,SAAuB,EACvB,UAAkC,EAClC,UAAsB;IAEtB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAElE,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAqC,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAmC,EAAE;QAC5D,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAe,EAAE,mBAAmB,CAAC;QAC5D,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAgB,EAAE,mBAAmB,CAAC;QAC9D,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACvE,gEAAgE;QAChE,qEAAqE;QACrE,mBAAmB,EAAE,KAAK,EAAE,IAAY,EAAE,OAAe,EAAE,EAAE;YAC3D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAChE,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,yEAAyE;IACzE,qEAAqE;IACrE,4EAA4E;IAC5E,yEAAyE;IACzE,yEAAyE;IACzE,OAAO,MAAM,CAAC,UAAU;QACtB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC1D,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AACvD,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,UAAU,iBAAiB,CAAC,UAAoC,EAAE;IACtE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,UAAU,GAAe;QAC7B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QACnD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC;QAChE,SAAS;KACV,CAAC;IACF,MAAM,aAAa,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEzD,KAAK,UAAU,QAAQ,CAAC,IAAuB;QAC7C,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,oBAAoB;QACpB,IAAI,MAAmB,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,uEAAuE;QACvE,IAAI,MAAM,CAAC,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACrD,IAAI,MAAM,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAEvE,kEAAkE;QAClE,0BAA0B,CAAC,MAAM,CAAC,CAAC;QAEnC,8DAA8D;QAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACvE,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;YAClC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QAE/D,0EAA0E;QAC1E,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,OAAO,CACZ,IAAI,CAAC,MAAM,EACX,sBAAsB,EACtB,uDAAuD,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAC7E,CAAC;QACJ,CAAC;QAED,uEAAuE;QACvE,yEAAyE;QACzE,0EAA0E;QAC1E,yEAAyE;QACzE,6DAA6D;QAC7D,yEAAyE;QACzE,mCAAmC;QACnC,MAAM,UAAU,GACd,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW;YAC9C,CAAC,CAAC,OAAO,CACL,IAAI,CAAC,MAAM,EACX,sBAAsB,EACtB,2DAA2D,IAAI,CAAC,WAAW,EAAE,CAC9E;YACH,CAAC,CAAC,EAAE,CAAC;QAET,oCAAoC;QACpC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7D,oCAAoC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACxD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,KAAK,GAAG,CAAC;QAC/C,MAAM,QAAQ,GAAe,MAAM,CAAC,QAAsB,CAAC;QAC3D,MAAM,SAAS,GAAc,MAAM,CAAC,KAAkB,CAAC;QAEvD,MAAM,UAAU,GAA4B;YAC1C,KAAK;YACL,MAAM;YACN,IAAI;YACJ,UAAU;YACV,WAAW;YACX,KAAK;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,QAAQ;YACR,MAAM;SACP,CAAC;QAEF,kBAAkB;QAClB,MAAM,QAAQ,GAAG,GAAG,CAClB,SAAS,CAAC;YACR,CAAC,EAAE,iBAAiB;YACpB,GAAG,MAAM;YACT,IAAI;YACJ,UAAU;YACV,KAAK;YACL,MAAM;YACN,KAAK;YACL,MAAM;YACN,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SAC9D,CAAC,CACH,CAAC;QACF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,GAAG,CAAC;QACtC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,IAAI,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;QAEtD,iCAAiC;QACjC,IAAI,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;gBACpG,UAAU,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YACH,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type { EmojiType } from "./emoji.js";
2
+ export { EMOJI_TYPES } from "./emoji.js";
3
+ export { createOgGenerator } from "./generator.js";
4
+ export type { OgFormat, OgGenerateInput, OgGenerateOptions, OgGenerator, OgInfoContext, OgTemplate, } from "./types.js";
5
+ export { MAX_DESCRIPTION_LENGTH, MAX_IMAGE_DIMENSION, MAX_IMAGE_SIZE, MAX_TITLE_LENGTH, OG_TEMPLATES, OgValidationError, } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/og/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EACV,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { EMOJI_TYPES } from "./emoji.js";
2
+ export { createOgGenerator } from "./generator.js";
3
+ export { MAX_DESCRIPTION_LENGTH, MAX_IMAGE_DIMENSION, MAX_IMAGE_SIZE, MAX_TITLE_LENGTH, OG_TEMPLATES, OgValidationError, } from "./types.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/og/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AASnD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,52 @@
1
+ export interface NFTColor {
2
+ start: string;
3
+ end: string;
4
+ }
5
+ export declare const DEFAULT_COLORS: Record<string, NFTColor>;
6
+ /**
7
+ * Convert RGB color to HSL color.
8
+ * @param rgbString - The RGB color value (e.g. "#FF0000").
9
+ * @returns A [h, s, l] tuple with values in [0, 1].
10
+ */
11
+ export declare function rgbToHsl(rgbString: string): [number, number, number];
12
+ /**
13
+ * Convert HSL color value to an RGB hex string.
14
+ * @param h - Hue in [0, 1].
15
+ * @param s - Saturation in [0, 1].
16
+ * @param l - Lightness in [0, 1].
17
+ * @returns A hex color string like "#rrggbb".
18
+ */
19
+ export declare function hslToRgb(h: number, s: number, l: number): string;
20
+ /**
21
+ * Convert a single color to usable NFT gradient background colors.
22
+ * Clamps saturation to ≤0.7 and lightness to [0.3, 0.6].
23
+ * @param rgbString - The background color in RGB hex format.
24
+ * @returns An NFTColor with clamped start and end gradient colors.
25
+ */
26
+ export declare function getNftBGColor(rgbString: string): NFTColor;
27
+ /**
28
+ * Derive a deterministic passport color hex string from a DID.
29
+ * @param did - The DID string.
30
+ * @returns A 7-character hex color string like "#rrggbb".
31
+ */
32
+ export declare function getPassportColorFromDid(did: string): string;
33
+ /**
34
+ * Get NFT background color derived from a DID.
35
+ * @param did - The DID string.
36
+ * @returns An NFTColor with start and end gradient colors.
37
+ */
38
+ export declare function getNftBGColorFromDid(did: string): NFTColor;
39
+ /**
40
+ * Get the passport gradient color for display.
41
+ * @param preferredColor - "default" | "auto" | a hex color string | undefined
42
+ * @param did - The DID string (used when preferredColor is "auto").
43
+ * @returns An NFTColor with start and end gradient colors.
44
+ */
45
+ export declare function getPassportColor(preferredColor: string | undefined, did: string): NFTColor;
46
+ /**
47
+ * Choose readable text color based on background luminance.
48
+ * @param background - A hex color string like "#rrggbb".
49
+ * @returns "#111" for light backgrounds, "#EEE" for dark backgrounds.
50
+ */
51
+ export declare function getTextColor(background: string): "#111" | "#EEE";
52
+ //# sourceMappingURL=passport-svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passport-svg.d.ts","sourceRoot":"","sources":["../../src/og/passport-svg.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAMnD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAkCpE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BhE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAqBzD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAQ1F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMhE"}