@alwith/module-auth 0.1.5 → 0.1.7
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 +21 -1
- package/THIRD_PARTY_NOTICES.md +3 -2
- package/dist/oauth.js +1 -1
- package/dist/pets/assets.d.ts +34 -3
- package/dist/pets/assets.js +1 -1
- package/dist/pets/client.d.ts +1 -0
- package/dist/pets/client.js +1 -1
- package/dist/pets/core/engine.js +1 -1
- package/dist/pets/core/host.d.ts +26 -25
- package/dist/pets/core/lib/account-state.js +1 -1
- package/dist/pets/core/lib/draw-result.js +1 -1
- package/dist/pets/core/lib/endpoints.d.ts +28 -1
- package/dist/pets/core/lib/gacha-pools.js +1 -1
- package/dist/pets/core/lib/loading-progress.d.ts +0 -1
- package/dist/pets/core/lib/loading-progress.js +1 -1
- package/dist/pets/core/lib/pet-animation-sync.d.ts +1 -1
- package/dist/pets/core/lib/pet-drag.d.ts +1 -1
- package/dist/pets/core/lib/pet-presentation.d.ts +1 -1
- package/dist/pets/core/lib/preload-images.js +1 -1
- package/dist/pets/core/lib/presentation-readiness.js +1 -1
- package/dist/pets/core/lib/rarity.js +1 -1
- package/dist/pets/core/lib/resource-sync.js +1 -1
- package/dist/pets/core/lib/settings.js +1 -1
- package/dist/pets/core/lib/sprite-config.js +1 -1
- package/dist/pets/core/lib/vibemon-resources.js +1 -1
- package/dist/pets/core/types.d.ts +2 -4
- package/dist/pets/host.d.ts +13 -10
- package/dist/pets/react/assets.js +1 -1
- package/dist/pets/react/components/album-view.js +1 -1
- package/dist/pets/react/components/back-to-home.js +1 -1
- package/dist/pets/react/components/equip-view.js +1 -1
- package/dist/pets/react/components/gem-balance.js +1 -1
- package/dist/pets/react/components/home-view.js +1 -1
- package/dist/pets/react/components/insufficient-points-dialog.js +1 -1
- package/dist/pets/react/components/loading-view.js +1 -1
- package/dist/pets/react/components/lounge-burst.css +0 -2
- package/dist/pets/react/components/onboarding-guide.js +1 -1
- package/dist/pets/react/components/pet-bubble-background.js +1 -1
- package/dist/pets/react/components/pet-window.js +1 -1
- package/dist/pets/react/components/pull-overlay.js +1 -1
- package/dist/pets/react/components/pull-view.js +1 -1
- package/dist/pets/react/components/quick-reply.js +2 -2
- package/dist/pets/react/components/single-pet-toast.js +1 -1
- package/dist/pets/react/components/sprite-renderer.d.ts +2 -1
- package/dist/pets/react/components/sprite-renderer.js +1 -1
- package/dist/pets/react/components/vibemon-header.js +1 -1
- package/dist/pets/react/components/vibemon-page.js +1 -1
- package/dist/pets/react/components/video-fader.d.ts +1 -4
- package/dist/pets/react/components/video-fader.js +1 -1
- package/dist/pets/react/components/wish-button.js +1 -1
- package/dist/pets/react/ui/button.d.ts +1 -1
- package/dist/pets/react/ui/button.js +1 -1
- package/dist/pets/react/ui/card.d.ts +1 -1
- package/dist/pets/react/ui/card.js +1 -1
- package/dist/pets/react/ui/input-group.d.ts +1 -1
- package/dist/pets/react/ui/input-group.js +1 -1
- package/dist/pets/resource-package.d.ts +27 -0
- package/dist/pets/resource-package.js +1 -0
- package/dist/pets/resources.d.ts +16 -16
- package/dist/pets/resources.js +1 -1
- package/dist/pets/selection.d.ts +1 -1
- package/dist/pets/selection.js +1 -1
- package/dist/pets/sheet-layout.d.ts +10 -0
- package/dist/pets/sheet-layout.js +1 -0
- package/dist/pets/types.d.ts +21 -9
- package/dist/state.d.ts +1 -1
- package/dist/state.js +1 -1
- package/dist/token-storage.d.ts +9 -9
- package/dist/token-storage.js +1 -1
- package/licenses/fflate-MIT.txt +21 -0
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t}from"react/jsx-runtime";import{cn as d}from"cn";function c({className:a,size:r="default",...e}){return t("div",{"data-slot":"card","data-size":r,className:d("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl
|
|
1
|
+
import{jsx as t}from"react/jsx-runtime";import{cn as d}from"cn";function c({className:a,size:r="default",...e}){return t("div",{"data-slot":"card","data-size":r,className:d("group/card bg-card text-card-foreground ring-foreground/10 flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl py-(--card-spacing) text-sm shadow-xs ring-1 [--card-spacing:--spacing(6)] has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",a),...e})}function n({className:a,...r}){return t("div",{"data-slot":"card-header",className:d("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",a),...r})}function i({className:a,...r}){return t("div",{"data-slot":"card-title",className:d("font-heading text-base leading-normal font-medium group-data-[size=sm]/card:text-sm",a),...r})}function l({className:a,...r}){return t("div",{"data-slot":"card-description",className:d("text-muted-foreground text-sm",a),...r})}function u({className:a,...r}){return t("div",{"data-slot":"card-action",className:d("col-start-2 row-span-2 row-start-1 self-start justify-self-end",a),...r})}function g({className:a,...r}){return t("div",{"data-slot":"card-content",className:d("flex flex-col gap-3 px-(--card-spacing)",a),...r})}function p({className:a,...r}){return t("div",{"data-slot":"card-footer",className:d("flex items-center rounded-b-xl px-(--card-spacing) [.border-t]:pt-(--card-spacing)",a),...r})}export{c as Card,u as CardAction,g as CardContent,l as CardDescription,p as CardFooter,n as CardHeader,i as CardTitle};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
1
|
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
4
|
declare function InputGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
5
5
|
declare const inputGroupAddonVariants: (props?: ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as n}from"react/jsx-runtime";import{cva as s}from"class-variance-authority";import{cn as o}from"cn";import{Button as u}from"./button.js";import{Textarea as l}from"./textarea.js";function m({className:a,...t}){return n("div",{"data-slot":"input-group",role:"group",className:o("group/input-group border-input has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 relative flex h-9 w-full min-w-0 items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",a),...t})}var d=s("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium
|
|
1
|
+
import{jsx as n}from"react/jsx-runtime";import{cva as s}from"class-variance-authority";import{cn as o}from"cn";import{Button as u}from"./button.js";import{Textarea as l}from"./textarea.js";function m({className:a,...t}){return n("div",{"data-slot":"input-group",role:"group",className:o("group/input-group border-input has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-destructive/20 dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 relative flex h-9 w-full min-w-0 items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",a),...t})}var d=s("text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",{variants:{align:{"inline-start":"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]","inline-end":"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]","block-start":"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2","block-end":"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"}},defaultVariants:{align:"inline-start"}});function x({className:a,align:t="inline-start",...i}){return n("div",{role:"group","data-slot":"input-group-addon","data-align":t,className:o(d({align:t}),a),onClick:(r)=>{if(r.target.closest("button"))return;r.currentTarget.parentElement?.querySelector("input")?.focus()},...i})}var p=s("flex items-center gap-2 text-sm shadow-none",{variants:{size:{xs:"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",sm:"","icon-xs":"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0","icon-sm":"size-8 p-0 has-[>svg]:p-0"}},defaultVariants:{size:"xs"}});function v({className:a,type:t="button",variant:i="ghost",size:r="xs",...e}){return n(u,{type:t,"data-size":r,variant:i,className:o(p({size:r}),a),...e})}function k({className:a,...t}){return n(l,{"data-slot":"input-group-control",className:o("flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",a),...t})}export{m as InputGroup,x as InputGroupAddon,v as InputGroupButton,k as InputGroupTextarea};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PetAssetsHost } from "./host.js";
|
|
2
|
+
import { type SheetLayout } from "./sheet-layout.js";
|
|
3
|
+
export declare const IMAGE_ASSETS: readonly ["cover", "gacha", "multi_draw", "icon", "background", "pool_card", "sidebar_selected", "sidebar_hover", "sidebar_unselected"];
|
|
4
|
+
export type ImageAsset = (typeof IMAGE_ASSETS)[number];
|
|
5
|
+
export interface PackageAsset {
|
|
6
|
+
path: string;
|
|
7
|
+
sha256: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PackageManifest {
|
|
10
|
+
format_version: 1;
|
|
11
|
+
assets: Record<string, PackageAsset>;
|
|
12
|
+
}
|
|
13
|
+
export declare const PACKAGE_LIMIT: number;
|
|
14
|
+
export declare function resourcePath(path: string): boolean;
|
|
15
|
+
export declare function sha256(bytes: Uint8Array): Promise<string>;
|
|
16
|
+
export declare function parseManifest(bytes: Uint8Array): PackageManifest;
|
|
17
|
+
export declare function imageInfo(bytes: Uint8Array): {
|
|
18
|
+
mime: string;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function validatePackageFiles(manifest: PackageManifest, read: (path: string) => Promise<Uint8Array | null>, validateImage?: PetAssetsHost["validateImage"]): Promise<SheetLayout | null>;
|
|
23
|
+
export declare function unpackResourcePackage(bytes: Uint8Array, validateImage?: PetAssetsHost["validateImage"]): Promise<{
|
|
24
|
+
files: Map<string, Uint8Array<ArrayBufferLike>>;
|
|
25
|
+
manifest: PackageManifest;
|
|
26
|
+
layout: SheetLayout | null;
|
|
27
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Unzip as j,UnzipInflate as k}from"fflate";import{parseSheetLayout as A}from"./sheet-layout.js";var z=["cover","gacha","multi_draw","icon","background","pool_card","sidebar_selected","sidebar_hover","sidebar_unselected"],g=209715200,d=65536,E=new TextDecoder("utf-8",{fatal:!0});function P(e){return e.length>0&&!/[\\\u0000-\u001f:]/.test(e)&&e.split("/").every((n)=>n!==""&&n!=="."&&n!=="..")}async function Z(e){let n=await crypto.subtle.digest("SHA-256",new Uint8Array(e).buffer);return Array.from(new Uint8Array(n),(a)=>a.toString(16).padStart(2,"0")).join("")}function _(e){if(e.length>d)throw Error("Vibemon manifest exceeds 64 KiB");let n=JSON.parse(E.decode(e));if(n?.format_version!==1||!n.assets||typeof n.assets!=="object"||Array.isArray(n.assets))throw Error("Invalid Vibemon package manifest");let a=Object.entries(n.assets);if(a.length>11)throw Error("Too many Vibemon assets");let o=new Set;for(let[,t]of a){if(!t||typeof t.path!=="string"||!P(t.path)||t.path==="manifest.json"||typeof t.sha256!=="string"||!/^[a-f0-9]{64}$/.test(t.sha256)||o.has(t.path))throw Error("Invalid Vibemon asset reference");o.add(t.path)}if(Boolean(n.assets.sheet)!==Boolean(n.assets.layout))throw Error("Vibemon animation requires both sheet and layout");return n}function M(e){let n=new DataView(e.buffer,e.byteOffset,e.byteLength),a=(r,f)=>String.fromCharCode(...e.subarray(r,r+f)),o="",t=0,s=0;if(e.length>=24&&e[0]===137&&a(1,3)==="PNG")o="image/png",t=n.getUint32(16),s=n.getUint32(20);else if(e.length>=10&&/GIF8[79]a/.test(a(0,6)))o="image/gif",t=n.getUint16(6,!0),s=n.getUint16(8,!0);else if(e.length>=30&&a(0,4)==="RIFF"&&a(8,4)==="WEBP"){o="image/webp";let r=a(12,4);if(r==="VP8X")t=1+(n.getUint32(24,!0)&16777215),s=1+(e[27]|e[28]<<8|e[29]<<16);else if(r==="VP8L"&&e[20]===47){let f=n.getUint32(21,!0);t=1+(f&16383),s=1+(f>>>14&16383)}else if(r==="VP8 "&&e[23]===157&&e[24]===1&&e[25]===42)t=n.getUint16(26,!0)&16383,s=n.getUint16(28,!0)&16383}else if(e.length>4&&e[0]===255&&e[1]===216){o="image/jpeg";for(let r=2;r+8<e.length;){if(e[r++]!==255)break;while(e[r]===255)r++;let f=e[r++];if(f===217||f===218)break;if(f===1||f>=208&&f<=215)continue;let c=n.getUint16(r);if(c<2||r+c>e.length)break;if([192,193,194,195,197,198,199,201,202,203,205,206,207].includes(f)){s=n.getUint16(r+3),t=n.getUint16(r+5);break}r+=c}}if(!t||!s||t>16384||s>16384)throw Error("Invalid or unsupported Vibemon image dimensions");return{mime:o,width:t,height:s}}async function O(e,n,a){let o=0,t=null,s=null;for(let[r,f]of Object.entries(e.assets)){let c=await n(f.path);if(c===null||await Z(c)!==f.sha256)throw Error(`Vibemon asset checksum mismatch: ${r}`);if(o+=c.length,o>g)throw Error("Vibemon resource expansion limit exceeded");if(r==="layout"){if(c.length>d)throw Error("Vibemon layout exceeds 64 KiB");t=A(E.decode(c))}else if(r==="sheet"||z.includes(r)){let h=M(c);if(await a?.(c,h.mime),r==="sheet")s=h}}if(t&&s&&t.states.some((r)=>r.frames*t.frameWidth>s.width||(r.row+1)*t.frameHeight>s.height))throw Error("Vibemon animation exceeds the spritesheet");return t}async function L(e,n){if(e.length>g)throw Error("Vibemon ZIP exceeds 200 MiB");let a=new DataView(e.buffer,e.byteOffset,e.byteLength),o=e.length-22;while(o>=Math.max(0,e.length-65557)&&a.getUint32(o,!0)!==101010256)o--;if(o<0||e.length<22||a.getUint32(o,!0)!==101010256||o+22+a.getUint16(o+20,!0)!==e.length||a.getUint16(o+4,!0)!==0||a.getUint16(o+6,!0)!==0||a.getUint32(o+16,!0)+a.getUint32(o+12,!0)!==o)throw Error("Incomplete or unsupported Vibemon ZIP");let t=new Map,s=new Set,r=0,f=0,c=new j((i)=>{let l=i.name.endsWith("/"),u=l?i.name.slice(0,-1):i.name;if(!P(u)||s.has(u)||s.size>=44)throw Error("Invalid or duplicate Vibemon ZIP path");if((i.originalSize??0)>g)throw Error("Vibemon ZIP expansion limit exceeded");s.add(u);let p=[],m=0;i.ondata=(x,w,S)=>{if(x)throw x;if(r+=w.length,m+=w.length,r>g||(i.name==="manifest.json"||i.name.endsWith(".json"))&&m>d)throw Error("Vibemon ZIP expansion limit exceeded");if(p.push(w),S){let I=new Uint8Array(m),U=0;for(let V of p)I.set(V,U),U+=V.length;if(l){if(m!==0)throw Error("Invalid Vibemon ZIP directory")}else{if(t.size>=12)throw Error("Too many Vibemon ZIP files");t.set(i.name,I)}f++}},i.start()});c.register(k);for(let i=0;i<e.length;i+=65536)if(c.push(e.subarray(i,i+65536),i+65536>=e.length),i>0&&i%1048576===0)await new Promise((l)=>setTimeout(l,0));if(f!==s.size||s.size!==a.getUint16(o+10,!0)||!t.has("manifest.json"))throw Error("Incomplete Vibemon ZIP");let h=_(t.get("manifest.json")),b=new Set(["manifest.json",...Object.values(h.assets).map((i)=>i.path)]);if([...t.keys()].some((i)=>!b.has(i)))throw Error("Unexpected Vibemon ZIP file");let v=await O(h,(i)=>Promise.resolve(t.get(i)??null),n);return{files:t,manifest:h,layout:v}}export{z as IMAGE_ASSETS,g as PACKAGE_LIMIT,M as imageInfo,_ as parseManifest,P as resourcePath,Z as sha256,L as unpackResourcePackage,O as validatePackageFiles};
|
package/dist/pets/resources.d.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { type PetAssetsHost } from "./host.js";
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
states: {
|
|
7
|
-
id: string;
|
|
8
|
-
row: number;
|
|
9
|
-
frames: number;
|
|
10
|
-
}[];
|
|
11
|
-
}
|
|
2
|
+
import { type ImageAsset, type PackageManifest } from "./resource-package.js";
|
|
3
|
+
import { type SheetLayout } from "./sheet-layout.js";
|
|
4
|
+
import type { VibemonResourceDescriptor } from "./types.js";
|
|
5
|
+
export { parseSheetLayout, type SheetLayout } from "./sheet-layout.js";
|
|
12
6
|
export interface CachedPetMetadata {
|
|
13
7
|
directory: string;
|
|
14
|
-
sheetName: string;
|
|
8
|
+
sheetName: string | null;
|
|
15
9
|
name?: string;
|
|
16
|
-
layout: SheetLayout;
|
|
17
|
-
version: number;
|
|
10
|
+
layout: SheetLayout | null;
|
|
11
|
+
version: number | null;
|
|
12
|
+
format?: number;
|
|
13
|
+
sourceUrl?: string | null;
|
|
14
|
+
manifest?: PackageManifest;
|
|
15
|
+
archiveSha256?: string;
|
|
18
16
|
config?: Record<string, unknown>;
|
|
19
17
|
}
|
|
20
18
|
export interface CachedPetResource extends CachedPetMetadata {
|
|
21
|
-
sheet: Uint8Array;
|
|
19
|
+
sheet: Uint8Array | null;
|
|
22
20
|
}
|
|
23
|
-
export declare function
|
|
21
|
+
export declare function matchesResource(cached: CachedPetMetadata, item: VibemonResourceDescriptor): boolean;
|
|
24
22
|
export declare function createPetResources(host: PetAssetsHost): {
|
|
25
23
|
inspect: (petId: string) => Promise<CachedPetMetadata | null>;
|
|
24
|
+
visuals: (metadata: CachedPetMetadata) => Promise<Partial<Record<ImageAsset, string | null>>>;
|
|
25
|
+
preview(metadata: CachedPetMetadata): Promise<Uint8Array<ArrayBufferLike> | null>;
|
|
26
26
|
cached: (petId: string) => Promise<CachedPetResource | null>;
|
|
27
|
-
ensure: (item:
|
|
27
|
+
ensure: (item: VibemonResourceDescriptor) => Promise<CachedPetResource>;
|
|
28
28
|
cancel: () => void;
|
|
29
29
|
dispose(): void;
|
|
30
30
|
};
|
package/dist/pets/resources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertAccount as i}from"./host.js";var
|
|
1
|
+
import{assertAccount as i}from"./host.js";import{IMAGE_ASSETS as W,imageInfo as q,parseManifest as B,resourcePath as D,sha256 as J,unpackResourcePackage as F,validatePackageFiles as Z}from"./resource-package.js";import{parseSheetLayout as I}from"./sheet-layout.js";import{parseSheetLayout as ne}from"./sheet-layout.js";var R=new TextEncoder,N=new TextDecoder;function G(r,w){let p=w.resource_package_format??0;return(r.format??0)===p&&r.version===(w.resource_version??null)&&(r.sourceUrl===void 0?p===0:r.sourceUrl===(p===1?w.resource_url:w.sheet_url))}function Y(r){let w=!1,p=new Map,_=new Map,V=new Map,S=new Map,k=new Set,O=Promise.resolve();function U(e){if(w)throw Error("Vibemon resources disposed");let o=r.account();if(o===null)throw Error("Sign in to load Vibemon resources");if(!/^[a-zA-Z0-9_-]+$/.test(e)||!/^[a-zA-Z0-9.-]+$/.test(o.apiHost))throw Error("Invalid resource identity");return`vibemon/catalog/${o.apiHost}/${e}`}function P(e){let o=r.account();if(o===null)return Promise.reject(Error("Sign in to load Vibemon resources"));let n=`${U(e)}/${o.userId}/${o.revision}`,a=_.get(n);if(a)return a;let s=H(e).finally(()=>{if(_.get(n)===s)_.delete(n)});return _.set(n,s),s}async function H(e){let o=r.account();if(o===null)throw Error("Sign in to load Vibemon resources");let n=U(e),a=await r.resources.read(`${n}/resource.json`);if(a===null){for(let l of[n,`vibemon/${o.apiHost}/${o.userId}/${e}`]){let f=await r.resources.read(`${l}/config.json`);if(f===null)continue;let t=JSON.parse(N.decode(f));if(!/^sprite-sheet\.(webp|png)$/.test(t.spritesheet))throw Error("Invalid legacy sprite filename");let v=I(JSON.stringify({frameWidth:t.frameSize,frameHeight:t.frameSize,states:t.states}));if(await r.resources.exists(`${l}/${t.spritesheet}`)){let y=await r.storage.get("vibemon.resourceVersion");return i(r,o),{directory:l,sheetName:t.spritesheet,layout:v,version:y?.[o.apiHost]?.[e]??0,config:t}}}return null}let s;try{s=JSON.parse(N.decode(a))}catch{return null}if(!s||s.format!==void 0&&s.format!==0&&s.format!==1)return null;if(s.format===1)try{let l=await r.resources.read(`${n}/manifest.json`),f=await r.resources.read(`${n}/resource.zip`);if(!l||!f||await J(f)!==s.archiveSha256)return null;let t=B(l),v=await Z(t,(y)=>r.resources.read(`${n}/${y}`));return i(r,o),{...s,directory:n,manifest:t,layout:v,sheetName:t.assets.sheet?.path??null}}catch{return i(r,o),null}let c=JSON.parse(N.decode(a));if(I(JSON.stringify(c.layout)),!/^sprite-sheet\.(webp|png)$/.test(c.sheet))throw Error("Invalid sprite filename");let u=await r.resources.exists(`${n}/${c.sheet}`);i(r,o);let g=await r.resources.read(`${n}/config.json`);return i(r,o),!u?null:{directory:n,sheetName:c.sheet,name:c.name,layout:c.layout,version:c.version,format:0,sourceUrl:s.sourceUrl,config:g===null?void 0:JSON.parse(N.decode(g))}}async function L(e){let o=r.account();if(o===null)throw Error("Sign in to load Vibemon resources");let n=await P(e);if(n===null)return null;if(n.sheetName===null)return{...n,sheet:null};let a=await r.resources.read(`${n.directory}/${n.sheetName}`);return i(r,o),a===null?null:{...n,sheet:a}}function M(e){let o=r.account();if(o===null)return Promise.reject(Error("Sign in to download Vibemon resources"));if(e.resource_package_format!=null&&(!Number.isInteger(e.resource_package_format)||e.resource_package_format<0))return Promise.reject(Error("Invalid Vibemon resource format"));if(e.resource_version!=null&&(!Number.isInteger(e.resource_version)||e.resource_version<0))return Promise.reject(Error("Invalid Vibemon resource version"));let n=U(e.uuid),a=JSON.stringify([o.revision,e.resource_package_format??0,e.resource_version??null,e.resource_url,e.sheet_url,e.layout]),s=p.get(n);if(s?.key===a)return s.work;let c=(V.get(n)??0)+1;V.set(n,c);let u=()=>{if(i(r,o),w||V.get(n)!==c)throw Error("Vibemon resource request superseded")},l=(async()=>{await s?.work.catch(()=>{}),u();let f=await L(e.uuid);if(i(r,o),f!==null&&G(f,e))return{...f,name:e.name};let t=e.resource_package_format??0;if(t!==0&&t!==1)throw Error(`Unsupported Vibemon resource format: ${t}`);if(t===1&&!e.resource_url)throw Error("Vibemon package URL is missing");if(t===0&&(!e.sheet_url||!e.layout))throw Error("Vibemon animation is unavailable");let v=t===0?I(e.layout):null,y=new URL(t===1?e.resource_url:e.sheet_url);if(y.protocol!=="https:")throw Error("Vibemon sprites require HTTPS");let j=y.pathname.toLowerCase().endsWith(".png")?"sprite-sheet.png":"sprite-sheet.webp",h=new AbortController;k.add(h);let d=`${n}.${crypto.randomUUID()}.tmp`;try{let b=await r.download(y.href,h.signal);if(u(),t===1){let m=await F(b,r.validateImage);u();for(let[T,C]of m.files)await r.resources.write(`${d}/${T}`,C);await r.resources.write(`${d}/resource.zip`,b);let E={directory:n,format:1,sourceUrl:e.resource_url,version:e.resource_version??null,name:e.name,manifest:m.manifest,layout:m.layout,sheetName:m.manifest.assets.sheet?.path??null,archiveSha256:await J(b)};return await r.resources.write(`${d}/resource.json`,R.encode(JSON.stringify(E))),u(),h.signal.throwIfAborted(),await r.resources.replace(d,n),{...E,sheet:E.sheetName?m.files.get(E.sheetName):null}}if(b.byteLength===0)throw Error("Empty Vibemon spritesheet");await r.resources.write(`${d}/${j}`,b),await r.resources.write(`${d}/resource.json`,R.encode(JSON.stringify({layout:v,version:e.resource_version??null,sheet:j,name:e.name,sourceUrl:e.sheet_url}))),i(r,o),h.signal.throwIfAborted(),u(),await r.resources.replace(d,n),i(r,o);let A=O.catch(()=>{}).then(async()=>{i(r,o);let m=await r.storage.get("vibemon.resourceVersion")??{};i(r,o),await r.storage.set("vibemon.resourceVersion",{...m,[o.apiHost]:{...m[o.apiHost],[e.uuid]:e.resource_version??0}})});return O=A,await A,i(r,o),{directory:n,sheetName:j,sheet:b,name:e.name,layout:v,version:e.resource_version??null,format:0,sourceUrl:e.sheet_url}}finally{k.delete(h),await r.resources.remove(d)}})().finally(()=>{if(p.get(n)?.work===l)p.delete(n)});return p.set(n,{key:a,generation:c,work:l}),l}async function z(e){if(e.format!==1||!e.manifest)return{};let o=e.manifest,n={};return await Promise.all(W.map(async(a)=>{let s=o.assets[a];if(!s){n[a]=null;return}if(!D(s.path))throw Error("Invalid cached Vibemon path");if(r.resources.url)n[a]=`${await r.resources.url(`${e.directory}/${s.path}`)}?v=${s.sha256}`;else{let c=`${e.directory}/${s.sha256}`,u=S.get(c);if(!u){let g=await r.resources.read(`${e.directory}/${s.path}`);if(g===null)throw Error("Cached Vibemon image is missing");u=URL.createObjectURL(new Blob([new Uint8Array(g).buffer],{type:q(g).mime})),S.set(c,u)}n[a]=u}})),n}function x(){for(let e of k)e.abort();k.clear()}return{inspect:P,visuals:z,async preview(e){let o=e.manifest?.assets.cover??e.manifest?.assets.icon;return o?r.resources.read(`${e.directory}/${o.path}`):null},cached:L,ensure:M,cancel:x,dispose(){w=!0,x();for(let e of S.values())URL.revokeObjectURL(e);S.clear()}}}export{Y as createPetResources,G as matchesResource,ne as parseSheetLayout};
|
package/dist/pets/selection.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { type PetAssetsHost } from "./host.js";
|
|
|
2
2
|
export declare function createPetSelection(host: PetAssetsHost, owned: (petId: string) => Promise<readonly {
|
|
3
3
|
vibemon_uuid: string;
|
|
4
4
|
}[]>): {
|
|
5
|
-
get()
|
|
5
|
+
get: () => Promise<string | null>;
|
|
6
6
|
select(petId: string | null): Promise<void>;
|
|
7
7
|
};
|
package/dist/pets/selection.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{accountKey as u,assertAccount as c}from"./host.js";function w(n,s){let a=Promise.resolve();return{async
|
|
1
|
+
import{accountKey as u,assertAccount as c}from"./host.js";function w(n,s){let a=Promise.resolve();return{get:async()=>{let e=n.account();if(e===null)return null;let t=await n.storage.get("vibemon.accounts");return c(n,e),t?.[u(e)]?.pet||null},async select(e){let t=n.account();if(t===null)throw Error("Sign in to select a Vibemon");if(e!==null&&!(await s(e)).some((o)=>o.vibemon_uuid===e))throw Error("This account does not own the selected Vibemon");c(n,t);let r=a.catch(()=>{}).then(async()=>{c(n,t);let o=await n.storage.get("vibemon.accounts")??{};c(n,t);let i=u(t);await n.storage.set("vibemon.accounts",{...o,[i]:{...o[i],pet:e??""}}),c(n,t)});a=r,await r}}}export{w as createPetSelection};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function i(t){let e=JSON.parse(t);if(!e||!Number.isInteger(e.frameWidth)||e.frameWidth<1||e.frameWidth>4096||!Number.isInteger(e.frameHeight)||e.frameHeight<1||e.frameHeight>4096||!Array.isArray(e.states)||e.states.length<1||e.states.length>32||e.states.some((r)=>!r||typeof r.id!=="string"||!r.id||!Number.isInteger(r.row)||r.row<0||!Number.isInteger(r.frames)||r.frames<1||r.frames>128)||new Set(e.states.map((r)=>r.id)).size!==e.states.length||e.states.reduce((r,s)=>r+s.frames,0)>512)throw Error("Invalid Vibemon sprite layout");return e}export{i as parseSheetLayout};
|
package/dist/pets/types.d.ts
CHANGED
|
@@ -53,10 +53,11 @@ interface GachaPoolItemBase {
|
|
|
53
53
|
updated_time: string;
|
|
54
54
|
}
|
|
55
55
|
export interface GachaPoolVibemonItem extends GachaPoolItemBase {
|
|
56
|
-
reward_type
|
|
56
|
+
reward_type?: "VIBEMON" | null;
|
|
57
57
|
exchange_points: null;
|
|
58
58
|
vibemon_uuid: string;
|
|
59
59
|
vibemon_name: string;
|
|
60
|
+
vibemon_resource_url?: string | null;
|
|
60
61
|
vibemon_cover_url: string;
|
|
61
62
|
vibemon_icon_url: string | null;
|
|
62
63
|
vibemon_background_url: string | null;
|
|
@@ -116,7 +117,7 @@ interface DrawResultItemBase {
|
|
|
116
117
|
is_pity_hit: boolean;
|
|
117
118
|
}
|
|
118
119
|
export interface VibemonDrawResultItem extends DrawResultItemBase {
|
|
119
|
-
reward_type
|
|
120
|
+
reward_type?: "VIBEMON" | null;
|
|
120
121
|
exchange_points: null;
|
|
121
122
|
vibemon_uuid: string;
|
|
122
123
|
vibemon_name: string;
|
|
@@ -165,7 +166,22 @@ export interface DrawResponse {
|
|
|
165
166
|
results: DrawResultItem[];
|
|
166
167
|
state: UserGachaStateResponse;
|
|
167
168
|
}
|
|
169
|
+
export interface VibemonResourceDescriptor {
|
|
170
|
+
uuid: string;
|
|
171
|
+
name: string;
|
|
172
|
+
resource_url?: string | null;
|
|
173
|
+
resource_package_format?: number | null;
|
|
174
|
+
resource_version?: number | null;
|
|
175
|
+
sheet_url?: string | null;
|
|
176
|
+
layout?: string | null;
|
|
177
|
+
}
|
|
168
178
|
export interface MyVibemonItem {
|
|
179
|
+
resource_url?: string | null;
|
|
180
|
+
resource_package_format?: number | null;
|
|
181
|
+
resource_version?: number | null;
|
|
182
|
+
sheet_url?: string | null;
|
|
183
|
+
layout?: string | null;
|
|
184
|
+
multi_draw_url?: string | null;
|
|
169
185
|
vibemon_uuid: string;
|
|
170
186
|
name: string;
|
|
171
187
|
description: string | null;
|
|
@@ -187,7 +203,7 @@ export interface MyVibemonItem {
|
|
|
187
203
|
obtained_time: string;
|
|
188
204
|
duplicate_count: number;
|
|
189
205
|
}
|
|
190
|
-
export interface VibemonCatalogItem {
|
|
206
|
+
export interface VibemonCatalogItem extends VibemonResourceDescriptor {
|
|
191
207
|
uuid: string;
|
|
192
208
|
name: string;
|
|
193
209
|
description: string | null;
|
|
@@ -205,16 +221,12 @@ export interface VibemonCatalogItem {
|
|
|
205
221
|
sidebar_selected_url: string | null;
|
|
206
222
|
sidebar_hover_url: string | null;
|
|
207
223
|
sidebar_unselected_url: string | null;
|
|
208
|
-
resource_url: string;
|
|
209
|
-
sheet_url: string;
|
|
210
|
-
layout: string;
|
|
211
|
-
resource_version: number;
|
|
212
224
|
is_limited: number;
|
|
213
225
|
status: number;
|
|
214
226
|
}
|
|
215
227
|
export interface GetMyVibemonsParams {
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
rarityUuid?: string;
|
|
229
|
+
categoryUuid?: string;
|
|
218
230
|
equipped?: boolean;
|
|
219
231
|
scene?: string;
|
|
220
232
|
}
|
package/dist/state.d.ts
CHANGED
package/dist/state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function w(e){let{tokenStorage:l,loadUser:d,saveUser:s,clearAllAuth:f}=e.storage,n=0;return(r,
|
|
1
|
+
function w(e){let{tokenStorage:l,loadUser:d,saveUser:s,clearAllAuth:f}=e.storage,n=0;return(r,o)=>({user:null,isAuthenticated:!1,isLoading:!0,_initialized:!1,init:()=>{if(o()._initialized)return;r({_initialized:!0}),e.onInit();let a=n;(async()=>{try{let i=await l.getAccess(),t=await l.getRefresh();if(a!==n)return;if(!i||!t){await e.handleUnauthenticated(),r({isLoading:!1});return}let v=e.validateProfile(),c=await d();if(a!==n)return;if(!v){if(c)r({user:c,isAuthenticated:!0}),e.loadProviders();return}if(c)r({user:c,isAuthenticated:!0,isLoading:!1}),e.onSignedIn(c,"restore");e.loadProviders();try{let u=await e.getProfile();if(a!==n)return;let g={user_uuid:u.uuid,nickname:u.nickname,login_email:u.login_email,avatar:u.avatar};r({user:g,isAuthenticated:!0}),await s(g),e.onProfileRestored()}catch{let u=await d();if(a!==n)return;if(u)r({user:u,isAuthenticated:!0});else await f(),e.clearProviders(),r({user:null,isAuthenticated:!1})}if(!c)r({isLoading:!1})}catch(i){console.error("[auth] session restore failed unexpectedly",i)}finally{if(o().isLoading)r({isLoading:!1})}})(),e.subscribeExpired(()=>{n++,e.clearAccountConversation(o().user).then(e.handleUnauthenticated).then((i)=>{if(i)return;r({user:null,isAuthenticated:!1})})}),e.subscribeState((i)=>{if(i.action==="logout")n++,e.clearAccountConversation(o().user).then(e.handleUnauthenticated).then((t)=>{if(t)return;e.clearProviders(),r({user:null,isAuthenticated:!1})});else if(i.action==="login"&&i.user)n++,r({user:i.user,isAuthenticated:!0}),e.loadProviders();else if(i.action==="update"&&i.user)r({user:i.user})})},login:async(a)=>{n++,await l.save(a.access_token,a.refresh_token);let i={user_uuid:a.user_uuid,nickname:a.nickname,login_email:a.login_email};await s(i),r({user:i,isAuthenticated:!0}),e.loadProviders(),await e.broadcast({action:"login",user:i}),e.onSignedIn(i,"login")},logout:async()=>{if(n++,e.clearProviders(),await e.logoutApi(),await e.clearAccountConversation(o().user),await f(),await e.broadcast({action:"logout"}),await e.handleUnauthenticated())return;r({user:null,isAuthenticated:!1})},refreshUser:async()=>{try{let a=await e.getProfile(),i={user_uuid:a.uuid,nickname:a.nickname,login_email:a.login_email,avatar:a.avatar};r({user:i}),await s(i)}catch(a){console.warn("[auth] refreshUser failed",a)}},updateUser:(a)=>{let i=o().user;if(!i)return;let t={...i,...a};r({user:t}),s(t),e.broadcast({action:"update",user:t})}})}export{w as createAuthState};
|
package/dist/token-storage.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { AuthUser } from "./types.js";
|
|
2
2
|
export interface AuthStore {
|
|
3
|
-
get<T>(key: string)
|
|
4
|
-
set(key: string, value: unknown)
|
|
5
|
-
delete(key: string)
|
|
3
|
+
get: <T>(key: string) => Promise<T | undefined>;
|
|
4
|
+
set: (key: string, value: unknown) => Promise<void>;
|
|
5
|
+
delete: (key: string) => Promise<void>;
|
|
6
6
|
}
|
|
7
7
|
export declare function authStoreName(apiBaseUrl: string): string;
|
|
8
8
|
export declare function createTokenStorage(store: AuthStore): {
|
|
9
9
|
tokenStorage: {
|
|
10
|
-
save(accessToken: string, refreshToken: string)
|
|
11
|
-
getAccess()
|
|
12
|
-
getRefresh()
|
|
13
|
-
updateAccess(token: string)
|
|
14
|
-
clear()
|
|
15
|
-
getDeviceId()
|
|
10
|
+
save: (accessToken: string, refreshToken: string) => Promise<void>;
|
|
11
|
+
getAccess: () => Promise<string>;
|
|
12
|
+
getRefresh: () => Promise<string>;
|
|
13
|
+
updateAccess: (token: string) => Promise<void>;
|
|
14
|
+
clear: () => Promise<void>;
|
|
15
|
+
getDeviceId: () => Promise<string>;
|
|
16
16
|
};
|
|
17
17
|
saveUser: (user: AuthUser) => Promise<void>;
|
|
18
18
|
loadUser: () => Promise<AuthUser | null>;
|
package/dist/token-storage.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function r(a){return`auth.${new URL(a).host}`}function u(a){let e={ACCESS:"access_token",REFRESH:"refresh_token",DEVICE_ID:"device_id",USER:"user"},n={async
|
|
1
|
+
function r(a){return`auth.${new URL(a).host}`}function u(a){let e={ACCESS:"access_token",REFRESH:"refresh_token",DEVICE_ID:"device_id",USER:"user"},n={save:async(t,S)=>{await a.set(e.ACCESS,t),await a.set(e.REFRESH,S)},getAccess:async()=>await a.get(e.ACCESS)??"",getRefresh:async()=>await a.get(e.REFRESH)??"",updateAccess:async(t)=>{await a.set(e.ACCESS,t)},clear:async()=>{await a.delete(e.ACCESS),await a.delete(e.REFRESH)},getDeviceId:async()=>{let t=await a.get(e.DEVICE_ID);if(!t)t=crypto.randomUUID(),await a.set(e.DEVICE_ID,t);return t}};async function i(t){await a.set(e.USER,t)}async function E(){return await a.get(e.USER)??null}async function c(){await a.delete(e.USER)}async function s(){await n.clear(),await c()}return{tokenStorage:n,saveUser:i,loadUser:E,clearUser:c,clearAllAuth:s}}export{r as authStoreName,u as createTokenStorage};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arjun Barrett
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwith/module-auth",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
],
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"typescript": "^7.0.2",
|
|
74
|
-
"@types/bun": "^1.4.
|
|
74
|
+
"@types/bun": "^1.4.3",
|
|
75
75
|
"@types/react": "^19.3.0",
|
|
76
76
|
"@types/react-dom": "^19.3.0"
|
|
77
77
|
},
|
|
@@ -94,11 +94,12 @@
|
|
|
94
94
|
"dependencies": {
|
|
95
95
|
"@base-ui/react": "^1.8.0",
|
|
96
96
|
"class-variance-authority": "^0.7.1",
|
|
97
|
-
"cn": "^0.
|
|
97
|
+
"cn": "^0.5.0",
|
|
98
|
+
"fflate": "0.8.3",
|
|
99
|
+
"i18next": "^26.4.2",
|
|
98
100
|
"lucide-react": "^1.49.0",
|
|
99
101
|
"motion": "^13.4.6",
|
|
100
102
|
"react-i18next": "^17.0.15",
|
|
101
|
-
"i18next": "^26.4.2",
|
|
102
103
|
"sonner": "^2.0.8",
|
|
103
104
|
"zustand": "^5.0.15"
|
|
104
105
|
},
|