@casfa/client 0.2.0 → 0.3.0

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 (66) hide show
  1. package/README.md +201 -0
  2. package/README.zh-CN.md +201 -0
  3. package/dist/api/claim.d.ts +21 -0
  4. package/dist/api/claim.d.ts.map +1 -0
  5. package/dist/api/delegates.d.ts +39 -0
  6. package/dist/api/delegates.d.ts.map +1 -0
  7. package/dist/api/depots.d.ts +68 -0
  8. package/dist/api/depots.d.ts.map +1 -0
  9. package/dist/api/filesystem.d.ts +55 -0
  10. package/dist/api/filesystem.d.ts.map +1 -0
  11. package/dist/api/index.d.ts +13 -3
  12. package/dist/api/index.d.ts.map +1 -0
  13. package/dist/api/index.js +355 -207
  14. package/dist/api/index.js.map +19 -1
  15. package/dist/api/info.d.ts +16 -0
  16. package/dist/api/info.d.ts.map +1 -0
  17. package/dist/api/nodes.d.ts +42 -0
  18. package/dist/api/nodes.d.ts.map +1 -0
  19. package/dist/api/oauth.d.ts +54 -0
  20. package/dist/api/oauth.d.ts.map +1 -0
  21. package/dist/api/requests.d.ts +33 -0
  22. package/dist/api/requests.d.ts.map +1 -0
  23. package/dist/api/tokens.d.ts +19 -0
  24. package/dist/api/tokens.d.ts.map +1 -0
  25. package/dist/client/delegates.d.ts +26 -0
  26. package/dist/client/delegates.d.ts.map +1 -0
  27. package/dist/client/depots.d.ts +28 -0
  28. package/dist/client/depots.d.ts.map +1 -0
  29. package/dist/client/filesystem.d.ts +39 -0
  30. package/dist/client/filesystem.d.ts.map +1 -0
  31. package/dist/client/helpers.d.ts +27 -0
  32. package/dist/client/helpers.d.ts.map +1 -0
  33. package/dist/client/index.d.ts +49 -0
  34. package/dist/client/index.d.ts.map +1 -0
  35. package/dist/client/nodes.d.ts +30 -0
  36. package/dist/client/nodes.d.ts.map +1 -0
  37. package/dist/client/oauth.d.ts +24 -0
  38. package/dist/client/oauth.d.ts.map +1 -0
  39. package/dist/client/tokens.d.ts +23 -0
  40. package/dist/client/tokens.d.ts.map +1 -0
  41. package/dist/index.d.ts +14 -294
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +414 -515
  44. package/dist/index.js.map +32 -1
  45. package/dist/store/index.d.ts +8 -0
  46. package/dist/store/index.d.ts.map +1 -0
  47. package/dist/store/jwt-refresh.d.ts +31 -0
  48. package/dist/store/jwt-refresh.d.ts.map +1 -0
  49. package/dist/store/token-checks.d.ts +33 -0
  50. package/dist/store/token-checks.d.ts.map +1 -0
  51. package/dist/store/token-selector.d.ts +29 -0
  52. package/dist/store/token-selector.d.ts.map +1 -0
  53. package/dist/store/token-store.d.ts +30 -0
  54. package/dist/store/token-store.d.ts.map +1 -0
  55. package/dist/types/client.d.ts +64 -0
  56. package/dist/types/client.d.ts.map +1 -0
  57. package/dist/types/index.d.ts +5 -142
  58. package/dist/types/index.d.ts.map +1 -0
  59. package/dist/types/index.js +14 -3
  60. package/dist/types/index.js.map +10 -1
  61. package/dist/types/tokens.d.ts +86 -0
  62. package/dist/types/tokens.d.ts.map +1 -0
  63. package/dist/utils/http.d.ts +32 -0
  64. package/dist/utils/http.d.ts.map +1 -0
  65. package/package.json +7 -3
  66. package/dist/index-cPO-6GxE.d.ts +0 -338
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Token selector — ensures the client has valid auth for API calls.
3
+ *
4
+ * The server auto-creates the root delegate on first JWT request,
5
+ * so the client just needs a valid user JWT. No explicit root delegate
6
+ * creation step is required.
7
+ */
8
+ import type { StoredAccessToken } from "../types/tokens.ts";
9
+ import type { TokenStore } from "./token-store.ts";
10
+ export type TokenSelectorConfig = {
11
+ store: TokenStore;
12
+ baseUrl: string;
13
+ realm: string;
14
+ };
15
+ export type TokenSelector = {
16
+ /**
17
+ * Get an auth token for realm API calls.
18
+ *
19
+ * Returns a StoredAccessToken where `tokenBase64` is the user's JWT.
20
+ * The server's unified auth middleware detects JWT (contains '.') and
21
+ * auto-creates the root delegate if needed.
22
+ */
23
+ ensureAccessToken: () => Promise<StoredAccessToken | null>;
24
+ };
25
+ /**
26
+ * Create a token selector instance.
27
+ */
28
+ export declare const createTokenSelector: (config: TokenSelectorConfig) => TokenSelector;
29
+ //# sourceMappingURL=token-selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-selector.d.ts","sourceRoot":"","sources":["../../src/store/token-selector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CAC5D,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,mBAAmB,KAAG,aAuBjE,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Token store - manages the two-tier token state.
3
+ *
4
+ * Provides a closure-based store for token state management with
5
+ * automatic persistence and change notifications.
6
+ */
7
+ import type { OnAuthRequiredCallback, OnTokenChangeCallback, TokenStorageProvider } from "../types/client.ts";
8
+ import type { StoredRootDelegate, StoredUserToken, TokenState } from "../types/tokens.ts";
9
+ export type TokenStore = {
10
+ /** Get current token state (immutable snapshot) */
11
+ getState: () => TokenState;
12
+ /** Set user JWT token */
13
+ setUser: (token: StoredUserToken | null) => void;
14
+ /** Set root delegate (RT + AT pair) */
15
+ setRootDelegate: (delegate: StoredRootDelegate | null) => void;
16
+ /** Clear all tokens */
17
+ clear: () => void;
18
+ /** Initialize from storage provider */
19
+ initialize: () => Promise<void>;
20
+ };
21
+ export type TokenStoreConfig = {
22
+ storage?: TokenStorageProvider;
23
+ onTokenChange?: OnTokenChangeCallback;
24
+ onAuthRequired?: OnAuthRequiredCallback;
25
+ };
26
+ /**
27
+ * Create a token store instance.
28
+ */
29
+ export declare const createTokenStore: (config?: TokenStoreConfig) => TokenStore;
30
+ //# sourceMappingURL=token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/store/token-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAO1F,MAAM,MAAM,UAAU,GAAG;IACvB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,UAAU,CAAC;IAE3B,yBAAyB;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAEjD,uCAAuC;IACvC,eAAe,EAAE,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IAE/D,uBAAuB;IACvB,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB,uCAAuC;IACvC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAQ,gBAAqB,KAAG,UAiDhE,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Client configuration and callback types.
3
+ */
4
+ import type { TokenState } from "./tokens.ts";
5
+ /**
6
+ * Token storage provider for persistence.
7
+ * Allows users to persist tokens to localStorage, file, etc.
8
+ */
9
+ export type TokenStorageProvider = {
10
+ /** Load persisted token state */
11
+ load: () => Promise<TokenState | null>;
12
+ /** Save token state */
13
+ save: (state: TokenState) => Promise<void>;
14
+ /** Clear all persisted tokens */
15
+ clear: () => Promise<void>;
16
+ };
17
+ /**
18
+ * Callback when token state changes.
19
+ * Called after any token is added, removed, or refreshed.
20
+ */
21
+ export type OnTokenChangeCallback = (state: TokenState) => void;
22
+ /**
23
+ * Callback when authentication is required.
24
+ * Called when token refresh fails and user needs to re-login.
25
+ */
26
+ export type OnAuthRequiredCallback = () => void;
27
+ /**
28
+ * Configuration for creating a CASFA client.
29
+ */
30
+ export type ClientConfig = {
31
+ /** Base URL of the CASFA server (e.g., "https://api.casfa.app") */
32
+ baseUrl: string;
33
+ /** Realm ID this client operates on (e.g., "usr_abc123") */
34
+ realm: string;
35
+ /** Optional token storage provider for persistence */
36
+ tokenStorage?: TokenStorageProvider;
37
+ /** Default TTL for auto-issued tokens (seconds). If not set, uses server max. */
38
+ defaultTokenTtl?: number;
39
+ /** Callback when token state changes */
40
+ onTokenChange?: OnTokenChangeCallback;
41
+ /** Callback when auth is required (refresh failed) */
42
+ onAuthRequired?: OnAuthRequiredCallback;
43
+ };
44
+ /**
45
+ * Fetch result type.
46
+ */
47
+ export type FetchResult<T> = {
48
+ ok: true;
49
+ data: T;
50
+ status: number;
51
+ } | {
52
+ ok: false;
53
+ error: ClientError;
54
+ };
55
+ /**
56
+ * Client error type.
57
+ */
58
+ export type ClientError = {
59
+ code: string;
60
+ message: string;
61
+ status?: number;
62
+ details?: unknown;
63
+ };
64
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/types/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,iCAAiC;IACjC,IAAI,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvC,uBAAuB;IACvB,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,iCAAiC;IACjC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAMF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC;AAMhD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,sDAAsD;IACtD,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC,CAAC;AAMF;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC"}
@@ -1,144 +1,7 @@
1
1
  /**
2
- * Token types for the stateful client.
3
- *
4
- * Three-tier token hierarchy:
5
- * - User JWT: OAuth login token, highest authority
6
- * - Delegate Token: Re-delegation token, can issue child tokens
7
- * - Access Token: Data access token, used for CAS operations
2
+ * Type exports for @casfa/client
8
3
  */
9
- /**
10
- * User JWT token with refresh capability.
11
- */
12
- type StoredUserToken = {
13
- /** JWT access token */
14
- accessToken: string;
15
- /** Refresh token for token renewal */
16
- refreshToken: string;
17
- /** User ID (usr_xxx format) */
18
- userId: string;
19
- /** Token expiration time (epoch ms) */
20
- expiresAt: number;
21
- };
22
- /**
23
- * Delegate Token (re-delegation token).
24
- */
25
- type StoredDelegateToken = {
26
- /** Token ID (dlt1_xxx format) */
27
- tokenId: string;
28
- /** Token binary as Base64 */
29
- tokenBase64: string;
30
- /** Token type: always "delegate" */
31
- type: "delegate";
32
- /** Issuer ID (usr_xxx or dlt1_xxx) */
33
- issuerId: string;
34
- /** Token expiration time (epoch ms) */
35
- expiresAt: number;
36
- /** Whether the token can upload nodes */
37
- canUpload: boolean;
38
- /** Whether the token can manage depots */
39
- canManageDepot: boolean;
40
- };
41
- /**
42
- * Access Token (data access token).
43
- */
44
- type StoredAccessToken = {
45
- /** Token ID (dlt1_xxx format) */
46
- tokenId: string;
47
- /** Token binary as Base64 */
48
- tokenBase64: string;
49
- /** Token type: always "access" */
50
- type: "access";
51
- /** Issuer ID (usr_xxx or dlt1_xxx) */
52
- issuerId: string;
53
- /** Token expiration time (epoch ms) */
54
- expiresAt: number;
55
- /** Whether the token can upload nodes */
56
- canUpload: boolean;
57
- /** Whether the token can manage depots */
58
- canManageDepot: boolean;
59
- };
60
- /**
61
- * Complete token state held by the client.
62
- */
63
- type TokenState = {
64
- /** User JWT (optional) */
65
- user: StoredUserToken | null;
66
- /** Delegate Token (optional) */
67
- delegate: StoredDelegateToken | null;
68
- /** Access Token (optional) */
69
- access: StoredAccessToken | null;
70
- };
71
- /**
72
- * Empty token state.
73
- */
74
- declare const emptyTokenState: () => TokenState;
75
- /**
76
- * Token requirement for API calls.
77
- */
78
- type TokenRequirement = "none" | "user" | "delegate" | "access";
79
-
80
- /**
81
- * Client configuration and callback types.
82
- */
83
-
84
- /**
85
- * Token storage provider for persistence.
86
- * Allows users to persist tokens to localStorage, file, etc.
87
- */
88
- type TokenStorageProvider = {
89
- /** Load persisted token state */
90
- load: () => Promise<TokenState | null>;
91
- /** Save token state */
92
- save: (state: TokenState) => Promise<void>;
93
- /** Clear all persisted tokens */
94
- clear: () => Promise<void>;
95
- };
96
- /**
97
- * Callback when token state changes.
98
- * Called after any token is added, removed, or refreshed.
99
- */
100
- type OnTokenChangeCallback = (state: TokenState) => void;
101
- /**
102
- * Callback when authentication is required.
103
- * Called when token refresh fails and user needs to re-login.
104
- */
105
- type OnAuthRequiredCallback = () => void;
106
- /**
107
- * Configuration for creating a CASFA client.
108
- */
109
- type ClientConfig = {
110
- /** Base URL of the CASFA server (e.g., "https://api.casfa.app") */
111
- baseUrl: string;
112
- /** Realm ID this client operates on (e.g., "usr_abc123") */
113
- realm: string;
114
- /** Optional token storage provider for persistence */
115
- tokenStorage?: TokenStorageProvider;
116
- /** Default TTL for auto-issued tokens (seconds). If not set, uses server max. */
117
- defaultTokenTtl?: number;
118
- /** Callback when token state changes */
119
- onTokenChange?: OnTokenChangeCallback;
120
- /** Callback when auth is required (refresh failed) */
121
- onAuthRequired?: OnAuthRequiredCallback;
122
- };
123
- /**
124
- * Fetch result type.
125
- */
126
- type FetchResult<T> = {
127
- ok: true;
128
- data: T;
129
- status: number;
130
- } | {
131
- ok: false;
132
- error: ClientError;
133
- };
134
- /**
135
- * Client error type.
136
- */
137
- type ClientError = {
138
- code: string;
139
- message: string;
140
- status?: number;
141
- details?: unknown;
142
- };
143
-
144
- export { type ClientConfig, type ClientError, type FetchResult, type OnAuthRequiredCallback, type OnTokenChangeCallback, type StoredAccessToken, type StoredDelegateToken, type StoredUserToken, type TokenRequirement, type TokenState, type TokenStorageProvider, emptyTokenState };
4
+ export type { ClientConfig, ClientError, FetchResult, OnAuthRequiredCallback, OnTokenChangeCallback, TokenStorageProvider, } from "./client.ts";
5
+ export type { StoredAccessToken, StoredRootDelegate, StoredUserToken, TokenRequirement, TokenState, } from "./tokens.ts";
6
+ export { emptyTokenState } from "./tokens.ts";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -1,10 +1,21 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+
1
12
  // src/types/tokens.ts
2
13
  var emptyTokenState = () => ({
3
14
  user: null,
4
- delegate: null,
5
- access: null
15
+ rootDelegate: null
6
16
  });
7
17
  export {
8
18
  emptyTokenState
9
19
  };
10
- //# sourceMappingURL=index.js.map
20
+
21
+ //# debugId=A0C6D6CF107A032564756E2164756E21
@@ -1 +1,10 @@
1
- {"version":3,"sources":["../../src/types/tokens.ts"],"sourcesContent":["/**\n * Token types for the stateful client.\n *\n * Three-tier token hierarchy:\n * - User JWT: OAuth login token, highest authority\n * - Delegate Token: Re-delegation token, can issue child tokens\n * - Access Token: Data access token, used for CAS operations\n */\n\n// ============================================================================\n// Stored Token Types\n// ============================================================================\n\n/**\n * User JWT token with refresh capability.\n */\nexport type StoredUserToken = {\n /** JWT access token */\n accessToken: string;\n /** Refresh token for token renewal */\n refreshToken: string;\n /** User ID (usr_xxx format) */\n userId: string;\n /** Token expiration time (epoch ms) */\n expiresAt: number;\n};\n\n/**\n * Delegate Token (re-delegation token).\n */\nexport type StoredDelegateToken = {\n /** Token ID (dlt1_xxx format) */\n tokenId: string;\n /** Token binary as Base64 */\n tokenBase64: string;\n /** Token type: always \"delegate\" */\n type: \"delegate\";\n /** Issuer ID (usr_xxx or dlt1_xxx) */\n issuerId: string;\n /** Token expiration time (epoch ms) */\n expiresAt: number;\n /** Whether the token can upload nodes */\n canUpload: boolean;\n /** Whether the token can manage depots */\n canManageDepot: boolean;\n};\n\n/**\n * Access Token (data access token).\n */\nexport type StoredAccessToken = {\n /** Token ID (dlt1_xxx format) */\n tokenId: string;\n /** Token binary as Base64 */\n tokenBase64: string;\n /** Token type: always \"access\" */\n type: \"access\";\n /** Issuer ID (usr_xxx or dlt1_xxx) */\n issuerId: string;\n /** Token expiration time (epoch ms) */\n expiresAt: number;\n /** Whether the token can upload nodes */\n canUpload: boolean;\n /** Whether the token can manage depots */\n canManageDepot: boolean;\n};\n\n/**\n * Complete token state held by the client.\n */\nexport type TokenState = {\n /** User JWT (optional) */\n user: StoredUserToken | null;\n /** Delegate Token (optional) */\n delegate: StoredDelegateToken | null;\n /** Access Token (optional) */\n access: StoredAccessToken | null;\n};\n\n/**\n * Empty token state.\n */\nexport const emptyTokenState = (): TokenState => ({\n user: null,\n delegate: null,\n access: null,\n});\n\n// ============================================================================\n// Token Requirement Types\n// ============================================================================\n\n/**\n * Token requirement for API calls.\n */\nexport type TokenRequirement = \"none\" | \"user\" | \"delegate\" | \"access\";\n\n/**\n * Auth header format.\n */\nexport type AuthHeader = {\n Authorization: string;\n};\n\n/**\n * Get issuer ID from current state (for signing new tokens).\n * Priority: User JWT > Delegate Token\n */\nexport const getMaxIssuerId = (state: TokenState): string | null => {\n if (state.user) {\n return state.user.userId;\n }\n if (state.delegate) {\n return state.delegate.tokenId;\n }\n return null;\n};\n\n/**\n * Check if Access Token was issued by the current max issuer.\n */\nexport const isAccessTokenFromMaxIssuer = (state: TokenState): boolean => {\n if (!state.access) return false;\n\n const maxIssuerId = getMaxIssuerId(state);\n if (!maxIssuerId) return false;\n\n return state.access.issuerId === maxIssuerId;\n};\n\n/**\n * Check if Delegate Token was issued by current user.\n */\nexport const isDelegateTokenFromCurrentUser = (state: TokenState): boolean => {\n if (!state.delegate || !state.user) return false;\n return state.delegate.issuerId === state.user.userId;\n};\n"],"mappings":";AAkFO,IAAM,kBAAkB,OAAmB;AAAA,EAChD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AACV;","names":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/types/tokens.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Token types for the stateful client.\n *\n * Two-tier hierarchy:\n * - User JWT: OAuth login token, highest authority, used for all root operations\n * - Root Delegate: metadata-only entity (no RT/AT), anchor of the delegate tree\n *\n * Root operations use JWT directly via the server's unified auth middleware.\n * Child delegates (created via Delegate API) use their own AT/RT pairs.\n */\n\n// ============================================================================\n// Stored Token Types\n// ============================================================================\n\n/**\n * User JWT token with refresh capability.\n */\nexport type StoredUserToken = {\n /** JWT access token */\n accessToken: string;\n /** Refresh token for token renewal */\n refreshToken: string;\n /** User ID (usr_xxx format) */\n userId: string;\n /** Token expiration time (epoch ms) */\n expiresAt: number;\n};\n\n/**\n * Root Delegate metadata (no RT/AT — root uses JWT directly).\n *\n * Auto-created by the server's auth middleware on first JWT request.\n * All root realm operations use the user's JWT as the Bearer token;\n * the server's unified auth middleware resolves the root delegate automatically.\n */\nexport type StoredRootDelegate = {\n /** Delegate entity ID */\n delegateId: string;\n /** Realm this delegate belongs to */\n realm: string;\n /** Delegate depth (0 = root) */\n depth: number;\n /** Whether the delegate can upload nodes */\n canUpload: boolean;\n /** Whether the delegate can manage depots */\n canManageDepot: boolean;\n};\n\n/**\n * Complete token state held by the client.\n */\nexport type TokenState = {\n /** User JWT (optional) */\n user: StoredUserToken | null;\n /** Root Delegate metadata (optional) */\n rootDelegate: StoredRootDelegate | null;\n};\n\n/**\n * Empty token state.\n */\nexport const emptyTokenState = (): TokenState => ({\n user: null,\n rootDelegate: null,\n});\n\n// ============================================================================\n// Token Requirement Types\n// ============================================================================\n\n/**\n * Token requirement for API calls.\n */\nexport type TokenRequirement = \"none\" | \"user\" | \"access\";\n\n/**\n * Auth header format.\n */\nexport type AuthHeader = {\n Authorization: string;\n};\n\n// ============================================================================\n// Access Token View (for client module API surface)\n// ============================================================================\n\n/**\n * Stored Access Token — used by client methods for API calls.\n *\n * In root mode: `tokenBase64` is the user's JWT string, `tokenBytes` is empty.\n * In child delegate mode: `tokenBase64` is AT base64, `tokenBytes` is raw AT bytes.\n *\n * The server's unified auth middleware detects JWT vs AT automatically.\n */\nexport type StoredAccessToken = {\n /** Token string (JWT or AT base64) to use in Authorization: Bearer header */\n tokenBase64: string;\n /** Raw token bytes (empty for JWT mode, 32 bytes for AT mode) */\n tokenBytes: Uint8Array;\n /** Token expiration time (epoch ms) */\n expiresAt: number;\n /** Whether the delegate can upload nodes */\n canUpload: boolean;\n /** Whether the delegate can manage depots */\n canManageDepot: boolean;\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;AA8DO,IAAM,kBAAkB,OAAmB;AAAA,EAChD,MAAM;AAAA,EACN,cAAc;AAChB;",
8
+ "debugId": "A0C6D6CF107A032564756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Token types for the stateful client.
3
+ *
4
+ * Two-tier hierarchy:
5
+ * - User JWT: OAuth login token, highest authority, used for all root operations
6
+ * - Root Delegate: metadata-only entity (no RT/AT), anchor of the delegate tree
7
+ *
8
+ * Root operations use JWT directly via the server's unified auth middleware.
9
+ * Child delegates (created via Delegate API) use their own AT/RT pairs.
10
+ */
11
+ /**
12
+ * User JWT token with refresh capability.
13
+ */
14
+ export type StoredUserToken = {
15
+ /** JWT access token */
16
+ accessToken: string;
17
+ /** Refresh token for token renewal */
18
+ refreshToken: string;
19
+ /** User ID (usr_xxx format) */
20
+ userId: string;
21
+ /** Token expiration time (epoch ms) */
22
+ expiresAt: number;
23
+ };
24
+ /**
25
+ * Root Delegate metadata (no RT/AT — root uses JWT directly).
26
+ *
27
+ * Auto-created by the server's auth middleware on first JWT request.
28
+ * All root realm operations use the user's JWT as the Bearer token;
29
+ * the server's unified auth middleware resolves the root delegate automatically.
30
+ */
31
+ export type StoredRootDelegate = {
32
+ /** Delegate entity ID */
33
+ delegateId: string;
34
+ /** Realm this delegate belongs to */
35
+ realm: string;
36
+ /** Delegate depth (0 = root) */
37
+ depth: number;
38
+ /** Whether the delegate can upload nodes */
39
+ canUpload: boolean;
40
+ /** Whether the delegate can manage depots */
41
+ canManageDepot: boolean;
42
+ };
43
+ /**
44
+ * Complete token state held by the client.
45
+ */
46
+ export type TokenState = {
47
+ /** User JWT (optional) */
48
+ user: StoredUserToken | null;
49
+ /** Root Delegate metadata (optional) */
50
+ rootDelegate: StoredRootDelegate | null;
51
+ };
52
+ /**
53
+ * Empty token state.
54
+ */
55
+ export declare const emptyTokenState: () => TokenState;
56
+ /**
57
+ * Token requirement for API calls.
58
+ */
59
+ export type TokenRequirement = "none" | "user" | "access";
60
+ /**
61
+ * Auth header format.
62
+ */
63
+ export type AuthHeader = {
64
+ Authorization: string;
65
+ };
66
+ /**
67
+ * Stored Access Token — used by client methods for API calls.
68
+ *
69
+ * In root mode: `tokenBase64` is the user's JWT string, `tokenBytes` is empty.
70
+ * In child delegate mode: `tokenBase64` is AT base64, `tokenBytes` is raw AT bytes.
71
+ *
72
+ * The server's unified auth middleware detects JWT vs AT automatically.
73
+ */
74
+ export type StoredAccessToken = {
75
+ /** Token string (JWT or AT base64) to use in Authorization: Bearer header */
76
+ tokenBase64: string;
77
+ /** Raw token bytes (empty for JWT mode, 32 bytes for AT mode) */
78
+ tokenBytes: Uint8Array;
79
+ /** Token expiration time (epoch ms) */
80
+ expiresAt: number;
81
+ /** Whether the delegate can upload nodes */
82
+ canUpload: boolean;
83
+ /** Whether the delegate can manage depots */
84
+ canManageDepot: boolean;
85
+ };
86
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/types/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,0BAA0B;IAC1B,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7B,wCAAwC;IACxC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,QAAO,UAGjC,CAAC;AAMH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAMF;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,UAAU,EAAE,UAAU,CAAC;IACvB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Fetch utilities for the stateful client.
3
+ */
4
+ import type { ClientError, FetchResult } from "../types/client.ts";
5
+ /**
6
+ * Map HTTP status to error code.
7
+ */
8
+ export declare const statusToErrorCode: (status: number) => string;
9
+ /**
10
+ * Create error from HTTP response.
11
+ */
12
+ export declare const createErrorFromResponse: (response: Response) => Promise<ClientError>;
13
+ /**
14
+ * Create a network error.
15
+ */
16
+ export declare const createNetworkError: (err: unknown) => ClientError;
17
+ export type FetchOptions = {
18
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
19
+ headers?: Record<string, string>;
20
+ body?: unknown;
21
+ /** Expected response type */
22
+ responseType?: "json" | "blob" | "text" | "none";
23
+ };
24
+ /**
25
+ * Make a fetch request with error handling.
26
+ */
27
+ export declare const fetchApi: <T>(url: string, options?: FetchOptions) => Promise<FetchResult<T>>;
28
+ /**
29
+ * Make an authenticated fetch request.
30
+ */
31
+ export declare const fetchWithAuth: <T>(url: string, authHeader: string | null, options?: FetchOptions) => Promise<FetchResult<T>>;
32
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMnE;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,KAAG,MAkBlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAU,UAAU,QAAQ,KAAG,OAAO,CAAC,WAAW,CA+BrF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,OAAO,KAAG,WAIhD,CAAC;AAMH,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,EAC9B,KAAK,MAAM,EACX,UAAS,YAAiB,KACzB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CA2CxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,GAAU,CAAC,EACnC,KAAK,MAAM,EACX,YAAY,MAAM,GAAG,IAAI,EACzB,UAAS,YAAiB,KACzB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAQxB,CAAC"}
package/package.json CHANGED
@@ -1,20 +1,23 @@
1
1
  {
2
2
  "name": "@casfa/client",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "CASFA client library with unified authorization strategies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
+ "bun": "./src/index.ts",
10
11
  "types": "./dist/index.d.ts",
11
12
  "import": "./dist/index.js"
12
13
  },
13
14
  "./types": {
15
+ "bun": "./src/types/index.ts",
14
16
  "types": "./dist/types/index.d.ts",
15
17
  "import": "./dist/types/index.js"
16
18
  },
17
19
  "./api": {
20
+ "bun": "./src/api/index.ts",
18
21
  "types": "./dist/api/index.d.ts",
19
22
  "import": "./dist/api/index.js"
20
23
  }
@@ -23,8 +26,9 @@
23
26
  "dist"
24
27
  ],
25
28
  "scripts": {
26
- "build": "tsup",
27
- "dev": "tsup --watch",
29
+ "build": "bun ../../scripts/build-pkg.ts",
30
+ "test": "bun run test:unit",
31
+ "test:unit": "bun test src/",
28
32
  "typecheck": "tsc --noEmit",
29
33
  "lint": "biome check .",
30
34
  "lint:fix": "biome check --write .",