@hadoku/task-ui-components 4.23.0 → 4.23.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","sources":["../../../../../node_modules/.pnpm/@wolffm+prefs-client@1.1.7_react@19.2.8_zod@4.6.7/node_modules/@wolffm/prefs-client/dist/avatar.js"],"sourcesContent":["// src/constants.ts\nvar PREFS_API_BASE = \"https://hadoku.me/prefs\";\n\n// src/avatar-contract.ts\nvar AVATAR_SOURCES = [\"sprite\", \"discord\", \"steam\", \"upload\"];\nvar LINK_PROVIDERS = [\"discord\", \"steam\"];\nvar LINK_MESSAGE_TYPE = \"hadoku-avatar-link\";\nvar RESOLVE_MAX_IDS = 100;\nvar SPRITE_ID_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;\nvar LINK_CALLBACK_PATH = \"/account/link/callback\";\n\n// src/avatar.ts\nvar LINK_WINDOW_NAME = \"hadoku-avatar-link\";\nvar LINK_POPUP_MARK = \"hadoku-avatar-link-popup\";\nfunction markPopup(on) {\n try {\n if (on) sessionStorage.setItem(LINK_POPUP_MARK, \"1\");\n else sessionStorage.removeItem(LINK_POPUP_MARK);\n } catch {\n }\n}\nvar AvatarError = class extends Error {\n constructor(status, message) {\n super(message);\n this.status = status;\n this.name = \"AvatarError\";\n }\n status;\n};\nasync function readJson(res) {\n if (!res.ok) {\n const body = await res.json().catch(() => null);\n throw new AvatarError(res.status, body?.message ?? `HTTP ${res.status}`);\n }\n return await res.json();\n}\nfunction createAvatarClient(opts = {}) {\n const base = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar`;\n const f = opts.fetch ?? fetch;\n const call = (path, init = {}) => f(`${base}${path}`, { credentials: \"include\", ...init }).then(readJson);\n const send = (path, method, body) => call(path, {\n method,\n ...body === void 0 ? {} : { headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(body) }\n });\n const getSettings = () => call(\"\");\n async function linkInPopup(provider) {\n markPopup(true);\n const popup = window.open(\"about:blank\", LINK_WINDOW_NAME, \"popup,width=520,height=760\");\n markPopup(false);\n if (!popup)\n throw new AvatarError(0, \"The sign-in window was blocked: allow pop-ups for hadoku.me\");\n let authorizeUrl;\n try {\n ({ authorizeUrl } = await send(`/link/${provider}`, \"POST\", {}));\n } catch (err) {\n popup.close();\n throw err;\n }\n popup.location.href = authorizeUrl;\n return new Promise((resolve, reject) => {\n const channel = new BroadcastChannel(LINK_MESSAGE_TYPE);\n let settled = false;\n const finish = (failure) => {\n if (settled) return;\n settled = true;\n channel.close();\n clearInterval(closedPoll);\n clearTimeout(giveUp);\n if (failure) reject(new AvatarError(400, failure));\n else getSettings().then(resolve, reject);\n };\n channel.onmessage = (e) => {\n if (e.data?.type !== LINK_MESSAGE_TYPE) return;\n finish(e.data.ok ? void 0 : e.data.error);\n };\n const closedPoll = setInterval(() => {\n if (!popup.closed) return;\n clearInterval(closedPoll);\n setTimeout(() => finish(), 1500);\n }, 500);\n const giveUp = setTimeout(() => finish(), 10 * 60 * 1e3);\n });\n }\n return {\n /** The caller's settings, including the resolved avatar. */\n get: getSettings,\n /** Pick a source. 409 when it is not available (not linked, nothing uploaded). */\n choose: (source) => send(\"\", \"PUT\", { source }),\n /** Set the source, the character, or both in one write. */\n update: (u) => send(\"\", \"PUT\", u),\n /**\n * Begin linking. Navigate the browser to the returned URL; the provider\n * returns it to hadoku.me/account/link/callback, which completes the link.\n * Call this only from the user's own click: nothing is fetched from\n * Discord or Steam before they ask.\n */\n startLink: (provider) => send(`/link/${provider}`, \"POST\", {}),\n /**\n * Link in a popup, so the page never navigates. Call it straight from the\n * click handler: the window is opened before the first await, which is\n * what popup blockers allow. Resolves with fresh settings once the popup\n * reports back or is closed (closing is not an error: the settings say\n * whether the link landed). Rejects only when the popup could not open\n * or the link could not start.\n */\n linkInPopup: (provider) => linkInPopup(provider),\n /** Finish a link from the callback page's query string (`location.search`). */\n completeLink: (query) => send(\"/link/complete\", \"POST\", { query: query.replace(/^\\?/, \"\") }),\n /** Delete the linked id and its cached avatar URL. */\n unlink: (provider) => send(`/link/${provider}`, \"DELETE\"),\n /** Upload an image (PNG, JPEG, WebP or GIF). It is re-encoded and becomes the chosen source. */\n upload: (image) => call(\"/upload\", { method: \"POST\", body: image }),\n removeUpload: () => send(\"/upload\", \"DELETE\")\n };\n}\nasync function resolveAvatars(opts, userIds) {\n const f = opts.fetch ?? fetch;\n const url = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar/resolve`;\n const unique = [...new Set(userIds)];\n const out = {};\n for (let i = 0; i < unique.length; i += RESOLVE_MAX_IDS) {\n const res = await f(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"X-User-Key\": opts.serviceKey },\n body: JSON.stringify({ userIds: unique.slice(i, i + RESOLVE_MAX_IDS) })\n });\n Object.assign(out, (await readJson(res)).avatars);\n }\n return out;\n}\nexport {\n AVATAR_SOURCES,\n AvatarError,\n LINK_CALLBACK_PATH,\n LINK_MESSAGE_TYPE,\n LINK_POPUP_MARK,\n LINK_PROVIDERS,\n RESOLVE_MAX_IDS,\n SPRITE_ID_PATTERN,\n createAvatarClient,\n resolveAvatars\n};\n"],"names":[],"mappings":"AACA,IAAI,iBAAiB;AAKlB,IAAC,oBAAoB;AAMxB,IAAI,mBAAmB;AACpB,IAAC,kBAAkB;AACtB,SAAS,UAAU,IAAI;AACrB,MAAI;AACF,QAAI,GAAI,gBAAe,QAAQ,iBAAiB,GAAG;AAAA,QAC9C,gBAAe,WAAW,eAAe;AAAA,EAChD,QAAQ;AAAA,EACR;AACF;AACG,IAAC,cAAc,cAAc,MAAM;AAAA,EACpC,YAAY,QAAQ,SAAS;AAC3B,UAAM,OAAO;AACb,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AAAA,EACA;AACF;AACA,eAAe,SAAS,KAAK;AAC3B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAI,EAAG,MAAM,MAAM,IAAI;AAC9C,UAAM,IAAI,YAAY,IAAI,QAAQ,MAAM,WAAW,QAAQ,IAAI,MAAM,EAAE;AAAA,EACzE;AACA,SAAO,MAAM,IAAI,KAAI;AACvB;AACA,SAAS,mBAAmB,OAAO,IAAI;AACrC,QAAM,OAAO,GAAG,KAAK,WAAW,cAAc;AAC9C,QAAM,IAAI,KAAK,SAAS;AACxB,QAAM,OAAO,CAAC,MAAM,OAAO,CAAA,MAAO,EAAE,GAAG,IAAI,GAAG,IAAI,IAAI,EAAE,aAAa,WAAW,GAAG,MAAM,EAAE,KAAK,QAAQ;AACxG,QAAM,OAAO,CAAC,MAAM,QAAQ,SAAS,KAAK,MAAM;AAAA,IAC9C;AAAA,IACA,GAAG,SAAS,SAAS,CAAA,IAAK,EAAE,SAAS,EAAE,gBAAgB,mBAAkB,GAAI,MAAM,KAAK,UAAU,IAAI,EAAC;AAAA,EAC3G,CAAG;AACD,QAAM,cAAc,MAAM,KAAK,EAAE;AACjC,iBAAe,YAAY,UAAU;AACnC,cAAU,IAAI;AACd,UAAM,QAAQ,OAAO,KAAK,eAAe,kBAAkB,4BAA4B;AACvF,cAAU,KAAK;AACf,QAAI,CAAC;AACH,YAAM,IAAI,YAAY,GAAG,6DAA6D;AACxF,QAAI;AACJ,QAAI;AACF,OAAC,EAAE,iBAAiB,MAAM,KAAK,SAAS,QAAQ,IAAI,QAAQ,EAAE;AAAA,IAChE,SAAS,KAAK;AACZ,YAAM,MAAK;AACX,YAAM;AAAA,IACR;AACA,UAAM,SAAS,OAAO;AACtB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,UAAU,IAAI,iBAAiB,iBAAiB;AACtD,UAAI,UAAU;AACd,YAAM,SAAS,CAAC,YAAY;AAC1B,YAAI,QAAS;AACb,kBAAU;AACV,gBAAQ,MAAK;AACb,sBAAc,UAAU;AACxB,qBAAa,MAAM;AACnB,YAAI,QAAS,QAAO,IAAI,YAAY,KAAK,OAAO,CAAC;AAAA,YAC5C,eAAc,KAAK,SAAS,MAAM;AAAA,MACzC;AACA,cAAQ,YAAY,CAAC,MAAM;AACzB,YAAI,EAAE,MAAM,SAAS,kBAAmB;AACxC,eAAO,EAAE,KAAK,KAAK,SAAS,EAAE,KAAK,KAAK;AAAA,MAC1C;AACA,YAAM,aAAa,YAAY,MAAM;AACnC,YAAI,CAAC,MAAM,OAAQ;AACnB,sBAAc,UAAU;AACxB,mBAAW,MAAM,OAAM,GAAI,IAAI;AAAA,MACjC,GAAG,GAAG;AACN,YAAM,SAAS,WAAW,MAAM,OAAM,GAAI,KAAK,KAAK,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AACA,SAAO;AAAA;AAAA,IAEL,KAAK;AAAA;AAAA,IAEL,QAAQ,CAAC,WAAW,KAAK,IAAI,OAAO,EAAE,QAAQ;AAAA;AAAA,IAE9C,QAAQ,CAAC,MAAM,KAAK,IAAI,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOhC,WAAW,CAAC,aAAa,KAAK,SAAS,QAAQ,IAAI,QAAQ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAS7D,aAAa,CAAC,aAAa,YAAY,QAAQ;AAAA;AAAA,IAE/C,cAAc,CAAC,UAAU,KAAK,kBAAkB,QAAQ,EAAE,OAAO,MAAM,QAAQ,OAAO,EAAE,EAAC,CAAE;AAAA;AAAA,IAE3F,QAAQ,CAAC,aAAa,KAAK,SAAS,QAAQ,IAAI,QAAQ;AAAA;AAAA,IAExD,QAAQ,CAAC,UAAU,KAAK,WAAW,EAAE,QAAQ,QAAQ,MAAM,OAAO;AAAA,IAClE,cAAc,MAAM,KAAK,WAAW,QAAQ;AAAA,EAChD;AACA;","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"avatar.js","sources":["../../../../../node_modules/.pnpm/@wolffm+prefs-client@1.1.8_react@19.2.8_zod@4.6.7/node_modules/@wolffm/prefs-client/dist/avatar.js"],"sourcesContent":["// src/constants.ts\nvar PREFS_API_BASE = \"https://hadoku.me/prefs\";\n\n// src/avatar-contract.ts\nvar AVATAR_SOURCES = [\"sprite\", \"discord\", \"steam\", \"upload\"];\nvar LINK_PROVIDERS = [\"discord\", \"steam\"];\nvar LINK_MESSAGE_TYPE = \"hadoku-avatar-link\";\nvar RESOLVE_MAX_IDS = 100;\nvar SPRITE_ID_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;\nvar LINK_CALLBACK_PATH = \"/account/link/callback\";\n\n// src/avatar.ts\nvar LINK_WINDOW_NAME = \"hadoku-avatar-link\";\nvar LINK_POPUP_MARK = \"hadoku-avatar-link-popup\";\nfunction markPopup(on) {\n try {\n if (on) sessionStorage.setItem(LINK_POPUP_MARK, \"1\");\n else sessionStorage.removeItem(LINK_POPUP_MARK);\n } catch {\n }\n}\nvar AvatarError = class extends Error {\n constructor(status, message) {\n super(message);\n this.status = status;\n this.name = \"AvatarError\";\n }\n status;\n};\nasync function readJson(res) {\n if (!res.ok) {\n const body = await res.json().catch(() => null);\n throw new AvatarError(res.status, body?.message ?? `HTTP ${res.status}`);\n }\n return await res.json();\n}\nfunction createAvatarClient(opts = {}) {\n const base = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar`;\n const f = opts.fetch ?? fetch;\n const call = (path, init = {}) => f(`${base}${path}`, { credentials: \"include\", ...init }).then(readJson);\n const send = (path, method, body) => call(path, {\n method,\n ...body === void 0 ? {} : { headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(body) }\n });\n const getSettings = () => call(\"\");\n async function linkInPopup(provider) {\n markPopup(true);\n const popup = window.open(\"about:blank\", LINK_WINDOW_NAME, \"popup,width=520,height=760\");\n markPopup(false);\n if (!popup)\n throw new AvatarError(0, \"The sign-in window was blocked: allow pop-ups for hadoku.me\");\n let authorizeUrl;\n try {\n ({ authorizeUrl } = await send(`/link/${provider}`, \"POST\", {}));\n } catch (err) {\n popup.close();\n throw err;\n }\n popup.location.href = authorizeUrl;\n return new Promise((resolve, reject) => {\n const channel = new BroadcastChannel(LINK_MESSAGE_TYPE);\n let settled = false;\n const finish = (failure) => {\n if (settled) return;\n settled = true;\n channel.close();\n clearInterval(closedPoll);\n clearTimeout(giveUp);\n if (failure) reject(new AvatarError(400, failure));\n else getSettings().then(resolve, reject);\n };\n channel.onmessage = (e) => {\n if (e.data?.type !== LINK_MESSAGE_TYPE) return;\n finish(e.data.ok ? void 0 : e.data.error);\n };\n const closedPoll = setInterval(() => {\n if (!popup.closed) return;\n clearInterval(closedPoll);\n setTimeout(() => finish(), 1500);\n }, 500);\n const giveUp = setTimeout(() => finish(), 10 * 60 * 1e3);\n });\n }\n return {\n /** The caller's settings, including the resolved avatar. */\n get: getSettings,\n /** Pick a source. 409 when it is not available (not linked, nothing uploaded). */\n choose: (source) => send(\"\", \"PUT\", { source }),\n /** Set the source, the character, or both in one write. */\n update: (u) => send(\"\", \"PUT\", u),\n /**\n * Begin linking. Navigate the browser to the returned URL; the provider\n * returns it to hadoku.me/account/link/callback, which completes the link.\n * Call this only from the user's own click: nothing is fetched from\n * Discord or Steam before they ask.\n */\n startLink: (provider) => send(`/link/${provider}`, \"POST\", {}),\n /**\n * Link in a popup, so the page never navigates. Call it straight from the\n * click handler: the window is opened before the first await, which is\n * what popup blockers allow. Resolves with fresh settings once the popup\n * reports back or is closed (closing is not an error: the settings say\n * whether the link landed). Rejects only when the popup could not open\n * or the link could not start.\n */\n linkInPopup: (provider) => linkInPopup(provider),\n /** Finish a link from the callback page's query string (`location.search`). */\n completeLink: (query) => send(\"/link/complete\", \"POST\", { query: query.replace(/^\\?/, \"\") }),\n /** Delete the linked id and its cached avatar URL. */\n unlink: (provider) => send(`/link/${provider}`, \"DELETE\"),\n /** Upload an image (PNG, JPEG, WebP or GIF). It is re-encoded and becomes the chosen source. */\n upload: (image) => call(\"/upload\", { method: \"POST\", body: image }),\n removeUpload: () => send(\"/upload\", \"DELETE\")\n };\n}\nasync function resolveAvatars(opts, userIds) {\n const f = opts.fetch ?? fetch;\n const url = `${opts.baseUrl ?? PREFS_API_BASE}/api/v1/_avatar/resolve`;\n const unique = [...new Set(userIds)];\n const out = {};\n for (let i = 0; i < unique.length; i += RESOLVE_MAX_IDS) {\n const res = await f(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"X-User-Key\": opts.serviceKey },\n body: JSON.stringify({ userIds: unique.slice(i, i + RESOLVE_MAX_IDS) })\n });\n Object.assign(out, (await readJson(res)).avatars);\n }\n return out;\n}\nexport {\n AVATAR_SOURCES,\n AvatarError,\n LINK_CALLBACK_PATH,\n LINK_MESSAGE_TYPE,\n LINK_POPUP_MARK,\n LINK_PROVIDERS,\n RESOLVE_MAX_IDS,\n SPRITE_ID_PATTERN,\n createAvatarClient,\n resolveAvatars\n};\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hadoku/task-ui-components",
3
- "version": "4.23.0",
3
+ "version": "4.23.1",
4
4
  "description": "Reusable UI components with Bento grid and metallic gradient support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",