@lumi.new/sdk 0.1.11 → 0.2.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.
- package/README.md +91 -0
- package/dist/index.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,10 +29,39 @@ export const lumi = createClient({
|
|
|
29
29
|
})
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
### Usage on the Server (Deno)
|
|
33
|
+
|
|
34
|
+
Here is an example of how to use the Lumi SDK in a Deno environment. Make sure to handle secrets like your authorization token securely, for example, by using environment variables.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
Deno.serve(async (req) => {
|
|
38
|
+
const authorization = req.headers.get('Authorization')
|
|
39
|
+
const lumi = createClient({
|
|
40
|
+
projectId: 'YOUR_PROJECT_ID',
|
|
41
|
+
apiBaseUrl: 'YOUR_API_BASE_URL',
|
|
42
|
+
authOrigin: '',
|
|
43
|
+
authorization,
|
|
44
|
+
})
|
|
45
|
+
const user = await lumi.auth.refreshUser()
|
|
46
|
+
return lumi.auth.user
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
32
50
|
## Authentication
|
|
33
51
|
|
|
34
52
|
The Lumi SDK provides methods to handle user authentication.
|
|
35
53
|
|
|
54
|
+
### Server-side Usage and Limitations
|
|
55
|
+
|
|
56
|
+
When using the SDK in a server-side environment (like Node.js), please note the following differences:
|
|
57
|
+
|
|
58
|
+
- **Initialization**: You must provide an `authorization` token when creating the client. See the `createClient` API Reference for more details.
|
|
59
|
+
- **Disabled Methods**: Methods that rely on a browser environment are disabled and will throw an error if called. This includes:
|
|
60
|
+
- `lumi.auth.signIn()`
|
|
61
|
+
- `lumi.auth.signOut()`
|
|
62
|
+
- `lumi.auth.onAuthChange()`
|
|
63
|
+
- **Fetching User Data**: On the server, `lumi.auth.user` is `null` by default. You must explicitly call `await lumi.auth.refreshUser()` to fetch the user's profile based on the token provided during initialization.
|
|
64
|
+
|
|
36
65
|
### Sign In
|
|
37
66
|
|
|
38
67
|
To sign in a user, call the `signIn` method. This will open a popup window for the user to authenticate. Upon successful authentication, the access token and user information will be automatically stored.
|
|
@@ -335,6 +364,38 @@ const filesToDelete = [
|
|
|
335
364
|
deleteFiles(filesToDelete);
|
|
336
365
|
```
|
|
337
366
|
|
|
367
|
+
## Functions
|
|
368
|
+
|
|
369
|
+
The `functions` client allows you to invoke serverless functions deployed in your Lumi project.
|
|
370
|
+
|
|
371
|
+
### Invoke a Function
|
|
372
|
+
|
|
373
|
+
You can call a function by its full endpoint URL and pass options like `method`, `query`, and `body`. This is essentially a wrapper around `fetch` that automatically includes the user's authentication token if available.
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
async function callMyFunction() {
|
|
377
|
+
try {
|
|
378
|
+
const result = await lumi.functions.invoke('https://YOUR_FUNCTION_URL', {
|
|
379
|
+
method: 'POST',
|
|
380
|
+
query: {
|
|
381
|
+
param1: 'value1'
|
|
382
|
+
},
|
|
383
|
+
body: {
|
|
384
|
+
message: 'Hello from SDK'
|
|
385
|
+
},
|
|
386
|
+
headers: {
|
|
387
|
+
'X-Custom-Header': 'custom-value'
|
|
388
|
+
}
|
|
389
|
+
})
|
|
390
|
+
console.log('Function result:', result)
|
|
391
|
+
} catch (error) {
|
|
392
|
+
console.error('Failed to invoke function:', error)
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
callMyFunction();
|
|
397
|
+
```
|
|
398
|
+
|
|
338
399
|
---
|
|
339
400
|
|
|
340
401
|
## API Reference
|
|
@@ -349,6 +410,7 @@ Initializes the Lumi client.
|
|
|
349
410
|
- `projectId` (`string`): Your Lumi project ID.
|
|
350
411
|
- `apiBaseUrl` (`string`): The base URL of the Lumi API.
|
|
351
412
|
- `authOrigin` (`string`): The origin URL for the authentication popup.
|
|
413
|
+
- `authorization` (`string`, optional): An authorization token (e.g., `Bearer YOUR_TOKEN`). Recommended for server-side usage.
|
|
352
414
|
|
|
353
415
|
**Returns:**
|
|
354
416
|
|
|
@@ -360,6 +422,8 @@ Provides methods for user authentication.
|
|
|
360
422
|
|
|
361
423
|
#### `signIn()`
|
|
362
424
|
|
|
425
|
+
> **Note:** This method is not available in server-side environments and will throw an error if called.
|
|
426
|
+
|
|
363
427
|
Initiates the sign-in process by opening a popup window.
|
|
364
428
|
|
|
365
429
|
**Returns:**
|
|
@@ -370,11 +434,14 @@ Initiates the sign-in process by opening a popup window.
|
|
|
370
434
|
- `userId` (`string`): The user's unique identifier.
|
|
371
435
|
- `email` (`string`): The user's email address.
|
|
372
436
|
- `userName` (`string`): The user's name.
|
|
437
|
+
- `userRole` (`'ADMIN' | 'USER'`): The user's role.
|
|
373
438
|
- `createdTime` (`string`): The timestamp of when the user was created.
|
|
374
439
|
- `accessToken` (`string`): The access token for the session.
|
|
375
440
|
|
|
376
441
|
#### `signOut()`
|
|
377
442
|
|
|
443
|
+
> **Note:** This method is not available in server-side environments and will throw an error if called.
|
|
444
|
+
|
|
378
445
|
Signs out the current user by clearing the stored access token and user data.
|
|
379
446
|
|
|
380
447
|
#### `refreshUser()`
|
|
@@ -387,6 +454,7 @@ Fetches the latest profile of the currently authenticated user and updates the l
|
|
|
387
454
|
- `userId` (`string`): The user's unique identifier.
|
|
388
455
|
- `email` (`string`): The user's email address.
|
|
389
456
|
- `userName` (`string`): The user's name.
|
|
457
|
+
- `userRole` (`'ADMIN' | 'USER'`): The user's role.
|
|
390
458
|
- `createdTime` (`string`): The timestamp of when the user was created.
|
|
391
459
|
|
|
392
460
|
#### `accessToken`
|
|
@@ -411,6 +479,8 @@ A getter that checks if a user is currently authenticated.
|
|
|
411
479
|
|
|
412
480
|
#### `onAuthChange(callback)`
|
|
413
481
|
|
|
482
|
+
> **Note:** This method is not available in server-side environments and will throw an error if called.
|
|
483
|
+
|
|
414
484
|
Listens for changes in the authentication state. It triggers when `signIn()` or `signOut()` is called, or when `accessToken` or `user` are modified directly. This works across different browser tabs and within the same page.
|
|
415
485
|
|
|
416
486
|
**Parameters:**
|
|
@@ -582,3 +652,24 @@ Deletes one or more files based on their URLs.
|
|
|
582
652
|
**Returns:**
|
|
583
653
|
|
|
584
654
|
- `Promise<void>`: A promise that resolves when the delete operation is complete.
|
|
655
|
+
|
|
656
|
+
### Functions (`lumi.functions`)
|
|
657
|
+
|
|
658
|
+
Provides a method for invoking serverless functions.
|
|
659
|
+
|
|
660
|
+
#### `invoke(uri, options)`
|
|
661
|
+
|
|
662
|
+
Invokes a serverless function by its endpoint URI.
|
|
663
|
+
|
|
664
|
+
**Parameters:**
|
|
665
|
+
|
|
666
|
+
- `uri` (`string`): The full endpoint URL of the function to invoke.
|
|
667
|
+
- `options` (`object`, optional): Fetch options compatible with `ofetch`, including:
|
|
668
|
+
- `method` (`string`, optional): The HTTP method (e.g., `'GET'`, `'POST'`).
|
|
669
|
+
- `query` (`object`, optional): An object of query parameters to be appended to the URI.
|
|
670
|
+
- `body` (`object` | `FormData`, optional): The request body.
|
|
671
|
+
- `headers` (`object`, optional): Custom request headers.
|
|
672
|
+
|
|
673
|
+
**Returns:**
|
|
674
|
+
|
|
675
|
+
- `Promise<any>`: A promise that resolves with the response from the function.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FetchOptions } from 'ofetch';
|
|
2
|
+
|
|
1
3
|
interface PaginationData<T> {
|
|
2
4
|
total: number;
|
|
3
5
|
list: T[];
|
|
@@ -38,6 +40,12 @@ declare class EntitiesClient {
|
|
|
38
40
|
constructor(lumi: LumiClient);
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
declare class FunctionsClient {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(lumi: LumiClient);
|
|
46
|
+
invoke(uri: string, options?: FetchOptions<'json'>): Promise<any>;
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
declare class EmailTool {
|
|
42
50
|
#private;
|
|
43
51
|
constructor(lumi: LumiClient);
|
|
@@ -78,12 +86,14 @@ interface LumiClientConfig {
|
|
|
78
86
|
projectId: string;
|
|
79
87
|
apiBaseUrl: string;
|
|
80
88
|
authOrigin: string;
|
|
89
|
+
authorization?: string;
|
|
81
90
|
}
|
|
82
91
|
declare class LumiClient {
|
|
83
92
|
config: LumiClientConfig;
|
|
84
93
|
auth: LumiAuthClient;
|
|
85
94
|
entities: EntitiesClient;
|
|
86
95
|
tools: ToolsClient;
|
|
96
|
+
functions: FunctionsClient;
|
|
87
97
|
constructor(config: LumiClientConfig);
|
|
88
98
|
}
|
|
89
99
|
declare function createClient(config: LumiClientConfig): LumiClient;
|
|
@@ -98,6 +108,7 @@ interface User {
|
|
|
98
108
|
userId: string;
|
|
99
109
|
email: string;
|
|
100
110
|
userName: string;
|
|
111
|
+
userRole: 'ADMIN' | 'USER';
|
|
101
112
|
createdTime: string;
|
|
102
113
|
}
|
|
103
114
|
interface MessageSignInData {
|
|
@@ -143,4 +154,4 @@ declare class LumiAuthClient {
|
|
|
143
154
|
}) => void): () => void;
|
|
144
155
|
}
|
|
145
156
|
|
|
146
|
-
export { EmailTool, EntitiesClient, type Entity, EntityClient, FileTool, LumiAuthClient, LumiClient, type LumiClientConfig, type MessageDataReceive, type MessageDataSend, type MessageInitData, type MessageSignInData, ToolsClient, type UploadItem, type User, createClient };
|
|
157
|
+
export { EmailTool, EntitiesClient, type Entity, EntityClient, FileTool, FunctionsClient, LumiAuthClient, LumiClient, type LumiClientConfig, type MessageDataReceive, type MessageDataSend, type MessageInitData, type MessageSignInData, ToolsClient, type UploadItem, type User, createClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FetchOptions } from 'ofetch';
|
|
2
|
+
|
|
1
3
|
interface PaginationData<T> {
|
|
2
4
|
total: number;
|
|
3
5
|
list: T[];
|
|
@@ -38,6 +40,12 @@ declare class EntitiesClient {
|
|
|
38
40
|
constructor(lumi: LumiClient);
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
declare class FunctionsClient {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(lumi: LumiClient);
|
|
46
|
+
invoke(uri: string, options?: FetchOptions<'json'>): Promise<any>;
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
declare class EmailTool {
|
|
42
50
|
#private;
|
|
43
51
|
constructor(lumi: LumiClient);
|
|
@@ -78,12 +86,14 @@ interface LumiClientConfig {
|
|
|
78
86
|
projectId: string;
|
|
79
87
|
apiBaseUrl: string;
|
|
80
88
|
authOrigin: string;
|
|
89
|
+
authorization?: string;
|
|
81
90
|
}
|
|
82
91
|
declare class LumiClient {
|
|
83
92
|
config: LumiClientConfig;
|
|
84
93
|
auth: LumiAuthClient;
|
|
85
94
|
entities: EntitiesClient;
|
|
86
95
|
tools: ToolsClient;
|
|
96
|
+
functions: FunctionsClient;
|
|
87
97
|
constructor(config: LumiClientConfig);
|
|
88
98
|
}
|
|
89
99
|
declare function createClient(config: LumiClientConfig): LumiClient;
|
|
@@ -98,6 +108,7 @@ interface User {
|
|
|
98
108
|
userId: string;
|
|
99
109
|
email: string;
|
|
100
110
|
userName: string;
|
|
111
|
+
userRole: 'ADMIN' | 'USER';
|
|
101
112
|
createdTime: string;
|
|
102
113
|
}
|
|
103
114
|
interface MessageSignInData {
|
|
@@ -143,4 +154,4 @@ declare class LumiAuthClient {
|
|
|
143
154
|
}) => void): () => void;
|
|
144
155
|
}
|
|
145
156
|
|
|
146
|
-
export { EmailTool, EntitiesClient, type Entity, EntityClient, FileTool, LumiAuthClient, LumiClient, type LumiClientConfig, type MessageDataReceive, type MessageDataSend, type MessageInitData, type MessageSignInData, ToolsClient, type UploadItem, type User, createClient };
|
|
157
|
+
export { EmailTool, EntitiesClient, type Entity, EntityClient, FileTool, FunctionsClient, LumiAuthClient, LumiClient, type LumiClientConfig, type MessageDataReceive, type MessageDataSend, type MessageInitData, type MessageSignInData, ToolsClient, type UploadItem, type User, createClient };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`),
|
|
3
|
-
`),d=
|
|
1
|
+
"use strict";var me=Object.create;var L=Object.defineProperty,pe=Object.defineProperties,he=Object.getOwnPropertyDescriptor,de=Object.getOwnPropertyDescriptors,ge=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,fe=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty,ye=Object.prototype.propertyIsEnumerable;var V=i=>{throw TypeError(i)};var J=(i,e,t)=>e in i?L(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t,S=(i,e)=>{for(var t in e||(e={}))G.call(e,t)&&J(i,t,e[t]);if(Q)for(var t of Q(e))ye.call(e,t)&&J(i,t,e[t]);return i},H=(i,e)=>pe(i,de(e));var we=(i,e)=>{for(var t in e)L(i,t,{get:e[t],enumerable:!0})},Y=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ge(e))!G.call(i,s)&&s!==t&&L(i,s,{get:()=>e[s],enumerable:!(r=he(e,s))||r.enumerable});return i};var x=(i,e,t)=>(t=i!=null?me(fe(i)):{},Y(e||!i||!i.__esModule?L(t,"default",{value:i,enumerable:!0}):t,i)),Ee=i=>Y(L({},"__esModule",{value:!0}),i);var Z=(i,e,t)=>e.has(i)||V("Cannot "+t);var n=(i,e,t)=>(Z(i,e,"read from private field"),t?t.call(i):e.get(i)),a=(i,e,t)=>e.has(i)?V("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(i):e.set(i,t),u=(i,e,t,r)=>(Z(i,e,"write to private field"),r?r.call(i,t):e.set(i,t),t);var m=(i,e,t)=>new Promise((r,s)=>{var o=h=>{try{f(t.next(h))}catch(y){s(y)}},l=h=>{try{f(t.throw(h))}catch(y){s(y)}},f=h=>h.done?r(h.value):Promise.resolve(h.value).then(o,l);f((t=t.apply(i,e)).next())});var Te={};we(Te,{EmailTool:()=>U,EntitiesClient:()=>O,EntityClient:()=>P,FileTool:()=>k,FunctionsClient:()=>M,LumiAuthClient:()=>R,LumiClient:()=>B,ToolsClient:()=>q,createClient:()=>Ce});module.exports=Ee(Te);var ce=require("uuid");var ie=x(require("crypto-js/enc-base64")),re=x(require("crypto-js/enc-hex")),ne=x(require("crypto-js/hmac-sha256")),oe=x(require("crypto-js/sha256")),se=x(require("object-hash")),ae=require("ofetch");var b=class extends Error{constructor(t,r){super(r);this.name="LumiError";this.code=t}};function X(){var i,e;return(e=(i=document.querySelector('link[rel="icon"]'))==null?void 0:i.href)!=null?e:null}function W(){var i;return(i=document.title)!=null?i:null}var w=typeof window=="undefined";var be="6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ==";function ee(i){return encodeURIComponent(i).replace(/[!'()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}function Se(i){return e=>{let{options:t}=e,r=Math.floor(Date.now()/1e3).toString(),s=Math.random().toString(36).substring(2,15),o=S({},t.query),l=Object.keys(o).sort().map(E=>`${ee(E)}=${ee(String(o[E]))}`).join("&"),f={"x-timestamp":r,"x-nonce":s},h=Object.keys(f).sort().map(E=>`${E}:${f[E]}`).join(`
|
|
2
|
+
`),y=t.body&&!(t.body instanceof FormData)?JSON.stringify(t.body):"",$=(0,oe.default)(y).toString(re.default),N=[l,h,$].join(`
|
|
3
|
+
`),d=ie.default.stringify((0,ne.default)(N,i)),I=new Headers(t.headers);Object.entries(f).forEach(([E,ue])=>{I.set(E,ue)}),I.set("X-Sign",d),t.headers=I}}var te=new Map;function _(i,e){var o;e.body instanceof FormData&&(e=H(S({},e),{body:Array.from(e.body.entries())}));let t=(0,se.default)([i,e]),r=Date.now(),s=((o=te.get(t))==null?void 0:o.filter(l=>r-l<1e3))||[];if(s.length>=4)throw new b(429,"Too many requests");s.push(r),te.set(t,s)}function c(i,e,t={}){i.auth.accessToken&&(t.headers=S({Authorization:`Bearer ${i.auth.accessToken}`},t.headers)),_(e,t);let r=i.auth.isAuthenticated;return(0,ae.ofetch)(e,H(S({baseURL:i.config.apiBaseUrl},t),{onRequest:Se(be),onResponse:({response:s})=>{var o;!w&&r&&((o=s._data)==null?void 0:o.code)===2100&&i.auth.signOut()}}))}function z(i,e,t=localStorage){let r=t.getItem(i),s=e?JSON.stringify(e):null;s?t.setItem(i,s):t.removeItem(i),window.dispatchEvent(new StorageEvent("storage",{key:i,oldValue:r,newValue:s,storageArea:t}))}function K(i,e=localStorage){let t=e.getItem(i);try{return t?JSON.parse(t):null}catch(r){return null}}var g,j,v,R=class{constructor(e){a(this,g);a(this,j,`lumi-auth-${(0,ce.v4)()}`);a(this,v,null);u(this,g,e),Promise.resolve().then(()=>{!w&&this.isAuthenticated&&this.refreshUser()})}get accessToken(){if(w){let e=n(this,g).config.authorization;return e?e.replace("Bearer ",""):null}return K("lumi-access-token")}set accessToken(e){if(w){n(this,g).config.authorization=e?`Bearer ${e}`:void 0;return}z("lumi-access-token",e)}get user(){return w?n(this,v):K("lumi-user")}set user(e){if(w){u(this,v,e);return}z("lumi-user",e)}get isAuthenticated(){return!!this.accessToken}signIn(){if(w)throw new Error("auth.signIn() can only be called on the client side");let e=800,t=600,r=(window.screen.width-e)/2,s=(window.screen.height-t)/2,o=window.open(n(this,g).config.authOrigin,n(this,j),`width=${e},height=${t},left=${r},top=${s}`),l;return new Promise((f,h)=>{if(!o)return h(new Error("Open auth window failed"));let y=setInterval(()=>{o.closed&&h(new Error("Auth window closed"))},1e3),$=d=>{o.closed||(o.focus(),d.stopPropagation(),d.preventDefault())},N=({data:d,origin:I,source:E})=>{if(!(I!==n(this,g).config.authOrigin||E!==o))switch(d==null?void 0:d.type){case"lumi-ready":{o.postMessage({type:"lumi-init",data:{projectId:n(this,g).config.projectId,icon:X(),title:W()}},n(this,g).config.authOrigin);break}case"lumi-sign-in":{if(d.data.projectId!==n(this,g).config.projectId)break;o.close(),window.focus(),this.accessToken=d.data.accessToken,this.user=d.data.user,f(d.data);break}}};window.addEventListener("message",N),document.addEventListener("click",$,!0),l=()=>{clearInterval(y),window.removeEventListener("message",N),document.removeEventListener("click",$,!0)}}).finally(()=>l==null?void 0:l())}signOut(){if(w)throw new Error("auth.signOut() can only be called on the client side");this.accessToken=null,this.user=null}refreshUser(){return m(this,null,function*(){let e=yield c(n(this,g),"/lm/user/info",{method:"POST"});if(e.code!==200)throw new Error(e.message);return this.user=e.data,e.data})}onAuthChange(e){if(w)throw new Error("auth.onAuthChange() can only be called on the client side");let t=r=>{(r.key==="lumi-access-token"||r.key==="lumi-user"||r.key===null)&&e({isAuthenticated:this.isAuthenticated,user:this.user})};return window.addEventListener("storage",t),()=>{window.removeEventListener("storage",t)}}};g=new WeakMap,j=new WeakMap,v=new WeakMap;var p,P=class{constructor(e,t){a(this,p);u(this,p,e),this.entityName=t}list(){return m(this,arguments,function*({filter:e,sort:t,limit:r,skip:s}={}){if(r){let o=yield c(n(this,p),this.uri("/find"),{method:"POST",body:{filter:e,sort:t,limit:r,skip:s}});if(o.code!==200)throw new Error(o.message);return o.data}else{let o=yield c(n(this,p),this.uri("/list"),{method:"POST",body:{filter:e,sort:t}});if(o.code!==200)throw new Error(o.message);return{total:o.data.length,list:o.data}}})}get(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(`/${e}`),{method:"GET"});if(t.code!==200)throw new Error(t.message);return t.data})}create(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(),{method:"POST",body:e});if(t.code!==200)throw new Error(t.message);return t.data})}createMany(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri("/batch"),{method:"POST",body:e});if(t.code!==200)throw new Error(t.message);return t.data})}update(e,t){return m(this,null,function*(){let r=yield c(n(this,p),this.uri(),{method:"PUT",body:{filter:{_id:e},update:t}});if(r.code!==200)throw new Error(r.message);return r.data})}delete(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(`/${e}`),{method:"DELETE"});if(t.code!==200)throw new Error(t.message)})}deleteMany(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri("/batch-by-ids"),{method:"DELETE",params:{ids:e}});if(t.code!==200)throw new Error(t.message)})}uri(e=""){return`/lm/${n(this,p).config.projectId}/${this.entityName}/documents${e}`}};p=new WeakMap;var D,O=class{constructor(e){a(this,D);return u(this,D,e),new Proxy(this,{get(t,r){return r in t||(t[r]=new P(n(t,D),r)),t[r]}})}};D=new WeakMap;var le=require("ofetch");var T,M=class{constructor(e){a(this,T);u(this,T,e)}invoke(e,t={}){return n(this,T).auth.accessToken&&(t.headers=S({Authorization:`Bearer ${n(this,T).auth.accessToken}`},t.headers)),_(e,t),(0,le.ofetch)(e,S({},t))}};T=new WeakMap;var A,U=class{constructor(e){a(this,A);u(this,A,e)}send(h){return m(this,arguments,function*({to:e,subject:t,fromName:r,html:s,text:o="",replyTo:l,scheduledAt:f}){if(!e||!t||!s&&!o)throw new Error("Failed to send email: Missing required parameters.");typeof e=="string"&&(e=[e]),typeof l=="string"&&(l=[l]);let y=yield c(n(this,A),`/lm/${n(this,A).config.projectId}/email/send`,{method:"POST",body:{to:e,subject:t,fromName:r,html:s,text:o,replyTo:l,scheduledAt:f}});if(y.code!==200)throw new b(y.code,y.message)})}};A=new WeakMap;var C,k=class{constructor(e){a(this,C);u(this,C,e)}upload(e){return m(this,null,function*(){let t=new FormData;e.forEach(s=>{t.append("files",s)});let r=yield c(n(this,C),`/lm/${n(this,C).config.projectId}/file/batch`,{method:"POST",body:t});if(r.code!==200)throw new b(r.code,r.message);return r.data})}delete(e){return m(this,null,function*(){let t=yield c(n(this,C),`/lm/${n(this,C).config.projectId}/file/batch`,{method:"DELETE",body:{fileUrls:e}});if(t.code!==200)throw new b(t.code,t.message)})}};C=new WeakMap;var F,q=class{constructor(e){a(this,F);u(this,F,e),this.email=new U(e),this.file=new k(e)}};F=new WeakMap;var B=class{constructor(e){this.config=e,this.auth=new R(this),this.entities=new O(this),this.tools=new q(this),this.functions=new M(this)}};function Ce(i){return new B(i)}0&&(module.exports={EmailTool,EntitiesClient,EntityClient,FileTool,FunctionsClient,LumiAuthClient,LumiClient,ToolsClient,createClient});
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/auth-client.ts","../src/lib/request.ts","../src/lib/error.ts","../src/utils/common.ts","../src/utils/storage.ts","../src/core/entity-client.ts","../src/core/entities-client.ts","../src/tools/email-tool.ts","../src/tools/file-tool.ts","../src/core/tools-client.ts","../src/core/lumi-client.ts"],"sourcesContent":["export * from './core/auth-client'\nexport * from './core/entities-client'\nexport * from './core/entity-client'\nexport * from './core/lumi-client'\nexport * from './core/tools-client'\nexport * from './tools'\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { v4 } from 'uuid'\nimport { MessageType, StorageKey } from '@/constants'\nimport { request } from '@/lib/request'\nimport { getIcon, getTitle } from '@/utils/common'\nimport { getStorage, setStorage } from '@/utils/storage'\n\nexport interface User {\n userId: string\n email: string\n userName: string\n createdTime: string\n}\n\nexport interface MessageSignInData {\n projectId: string\n accessToken: string\n user: User\n}\n\nexport type MessageDataReceive = {\n type: MessageType.READY\n} | {\n type: MessageType.SIGN_IN\n data: MessageSignInData\n}\n\nexport interface MessageInitData {\n projectId: string\n icon: string | null\n title: string | null\n}\n\nexport interface MessageDataSend {\n type: MessageType.INIT\n data: MessageInitData\n}\n\nexport class LumiAuthClient {\n readonly #lumi: LumiClient\n readonly #popupName: string = `lumi-auth-${v4()}`\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n Promise.resolve().then(() => {\n if (this.isAuthenticated)\n void this.refreshUser()\n })\n }\n\n /** 访问令牌 */\n public get accessToken(): string | null {\n return getStorage<string>(StorageKey.ACCESS_TOKEN)\n }\n\n public set accessToken(accessToken: string | null) {\n setStorage(StorageKey.ACCESS_TOKEN, accessToken)\n }\n\n /** 用户 */\n public get user(): User | null {\n return getStorage<User>(StorageKey.USER)\n }\n\n public set user(user: User | null) {\n setStorage(StorageKey.USER, user)\n }\n\n public get isAuthenticated(): boolean {\n return !!this.accessToken\n }\n\n /** 登录 */\n public signIn(): Promise<MessageSignInData> {\n const width = 800\n const height = 600\n const left = (window.screen.width - width) / 2\n const top = (window.screen.height - height) / 2\n const popup = window.open(this.#lumi.config.authOrigin, this.#popupName, `width=${width},height=${height},left=${left},top=${top}`)\n\n let cleanup: () => void\n return new Promise<MessageSignInData>((resolve, reject) => {\n if (!popup)\n return reject(new Error('Open auth window failed'))\n\n const timer = setInterval(() => {\n if (popup.closed)\n reject(new Error('Auth window closed'))\n }, 1000)\n\n // 全局点击事件处理函数 - 重新聚焦popup并阻止事件传播\n const handleGlobalClick = (event: MouseEvent): void => {\n if (!popup.closed) {\n popup.focus()\n event.stopPropagation()\n event.preventDefault()\n }\n }\n\n const handleMessage = ({ data, origin, source }: MessageEvent<MessageDataReceive | null>): void => {\n if (origin !== this.#lumi.config.authOrigin || source !== popup)\n return\n\n switch (data?.type) {\n case MessageType.READY: {\n popup.postMessage({\n type: MessageType.INIT,\n data: {\n projectId: this.#lumi.config.projectId,\n icon: getIcon(),\n title: getTitle(),\n },\n } satisfies MessageDataSend, this.#lumi.config.authOrigin)\n break\n }\n case MessageType.SIGN_IN: {\n if (data.data.projectId !== this.#lumi.config.projectId)\n break\n popup.close()\n window.focus()\n this.accessToken = data.data.accessToken\n this.user = data.data.user\n resolve(data.data)\n break\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n // 添加全局点击事件监听器,使用捕获阶段确保优先处理\n document.addEventListener('click', handleGlobalClick, true)\n\n cleanup = () => {\n clearInterval(timer)\n window.removeEventListener('message', handleMessage)\n document.removeEventListener('click', handleGlobalClick, true)\n }\n }).finally(() => cleanup?.())\n }\n\n /** 退出登录 */\n public signOut(): void {\n this.accessToken = null\n this.user = null\n }\n\n /** 获取当前用户 */\n public async refreshUser(): Promise<User> {\n const res = await request<ApiResponse<User>>(this.#lumi, '/lm/user/info', {\n method: 'POST',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n this.user = res.data\n return res.data\n }\n\n /** 监听登录状态变化 */\n public onAuthChange(callback: (args: {\n isAuthenticated: boolean\n user: User | null\n }) => void): () => void {\n const handleStorageChange = (event: StorageEvent): void => {\n if (event.key === StorageKey.ACCESS_TOKEN || event.key === StorageKey.USER || event.key === null) {\n callback({\n isAuthenticated: this.isAuthenticated,\n user: this.user,\n })\n }\n }\n\n window.addEventListener('storage', handleStorageChange)\n\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n }\n }\n}\n","import type { FetchContext, FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport Base64 from 'crypto-js/enc-base64'\nimport Hex from 'crypto-js/enc-hex'\nimport HmacSHA256 from 'crypto-js/hmac-sha256'\nimport SHA256 from 'crypto-js/sha256'\nimport hash from 'object-hash'\nimport { ofetch } from 'ofetch'\nimport { LumiError } from '@/lib/error'\n\nconst SECRET_KEY = '6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ=='\n\n/** RFC 3986 compliant URI encoding */\nfunction rfc3986Encode(str: string): string {\n return encodeURIComponent(str).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n}\n\n/** 创建签名拦截器函数 */\nexport function createSignatureInterceptor(secretKey: string) {\n return (context: FetchContext) => {\n const { options } = context\n // 生成签名\n const timestamp = Math.floor(Date.now() / 1000).toString()\n const nonce = Math.random().toString(36).substring(2, 15)\n\n // 构建查询字符串\n const queryParams: Record<string, string> = { ...options.query }\n const canonicalQueryString = Object.keys(queryParams).sort().map(key => `${rfc3986Encode(key)}=${rfc3986Encode(String(queryParams[key]))}`).join('&')\n\n // 构建签名头\n const headersToSign: Record<string, string> = {\n 'x-timestamp': timestamp,\n 'x-nonce': nonce,\n }\n const canonicalHeaders = Object.keys(headersToSign).sort().map(key => `${key}:${headersToSign[key]}`).join('\\n')\n\n // 构建载荷哈希\n const payload = (options.body && !(options.body instanceof FormData)) ? JSON.stringify(options.body) : ''\n const hashedPayload = SHA256(payload).toString(Hex)\n\n // 构建规范请求\n const canonicalRequest = [canonicalQueryString, canonicalHeaders, hashedPayload].join('\\n')\n\n // 生成签名\n const signature = Base64.stringify(HmacSHA256(canonicalRequest, secretKey))\n\n // 添加签名头到请求\n const headers = new Headers(options.headers)\n Object.entries(headersToSign).forEach(([key, value]) => {\n headers.set(key, value)\n })\n headers.set('X-Sign', signature)\n options.headers = headers\n }\n}\n\nexport interface ApiResponse<T> {\n code: number\n message: string\n data: T\n}\n\nexport interface PaginationData<T> {\n total: number\n list: T[]\n}\n\nconst requestMap = new Map<string, number[]>()\n\n/** 限制请求频率,相同参数的请求每秒只能发送4次 */\nfunction checkRateLimit(uri: string, options: FetchOptions<'json'>): void {\n if (options.body instanceof FormData) {\n options = {\n ...options,\n body: Array.from(options.body.entries()),\n }\n }\n const requestHash = hash([uri, options])\n const now = Date.now()\n const requestQueue = requestMap.get(requestHash)?.filter(time => now - time < 1000) || []\n if (requestQueue.length >= 4)\n throw new LumiError(429, 'Too many requests')\n requestQueue.push(now)\n requestMap.set(requestHash, requestQueue)\n}\n\nexport function request<T>(lumi: LumiClient, uri: string, options: FetchOptions<'json'> = {}): Promise<T> {\n // 添加认证头(如果存在)\n if (lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n // 限制请求频率\n checkRateLimit(uri, options)\n\n const isAuthenticated = lumi.auth.isAuthenticated\n\n return ofetch<T>(uri, {\n baseURL: lumi.config.apiBaseUrl,\n ...options,\n onRequest: createSignatureInterceptor(SECRET_KEY),\n onResponse: ({ response }) => {\n // 若 Token 失效则退出登录\n if (isAuthenticated && (response._data as ApiResponse<any>)?.code === 2100)\n lumi.auth.signOut()\n },\n })\n}\n","export class LumiError extends Error {\n name: string = 'LumiError'\n code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.code = code\n }\n}\n","export function getIcon(): string | null {\n return document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]')?.href ?? null\n}\n\nexport function getTitle(): string | null {\n return document.title ?? null\n}\n","import type { StorageKey } from '@/constants'\n\nexport function setStorage<T>(key: StorageKey, value: T, storage: Storage = localStorage): void {\n const oldValue = storage.getItem(key)\n const newValue = value ? JSON.stringify(value) : null\n if (newValue)\n storage.setItem(key, newValue)\n else\n storage.removeItem(key)\n\n window.dispatchEvent(new StorageEvent('storage', {\n key,\n oldValue,\n newValue,\n storageArea: storage,\n }))\n}\n\nexport function getStorage<T>(key: StorageKey, storage: Storage = localStorage): T | null {\n const value = storage.getItem(key)\n try {\n return value ? JSON.parse(value) : null\n }\n catch (_e) {\n return null\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse, PaginationData } from '@/lib/request'\nimport { request } from '@/lib/request'\n\nexport interface Entity extends Record<string, any> {\n id: string\n}\n\nexport class EntityClient {\n readonly #lumi: LumiClient\n public readonly entityName: string\n\n constructor(lumi: LumiClient, entityName: string) {\n this.#lumi = lumi\n this.entityName = entityName\n }\n\n /** 查询文档列表 */\n public async list({ filter, sort, limit, skip }: {\n filter?: any\n sort?: Record<string, 1 | -1>\n limit?: number\n skip?: number\n } = {}): Promise<PaginationData<Entity>> {\n if (!limit) {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/list'), {\n method: 'POST',\n body: { filter, sort },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return {\n total: res.data.length,\n list: res.data,\n }\n }\n else {\n const res = await request<ApiResponse<PaginationData<Entity>>>(this.#lumi, this.uri('/find'), {\n method: 'POST',\n body: { filter, sort, limit, skip },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n }\n\n /** 获取单个文档 */\n public async get(id: string): Promise<Entity | null> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(`/${id}`), {\n method: 'GET',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 创建文档 */\n public async create(data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 批量创建文档 */\n public async createMany(data: Record<string, any>[]): Promise<Entity[]> {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/batch'), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 更新文档 */\n public async update(id: string, data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'PUT',\n body: { filter: { _id: id }, update: data },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 删除文档 */\n public async delete(id: string): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri(`/${id}`), {\n method: 'DELETE',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n /** 批量删除文档 */\n public async deleteMany(ids: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri('/batch-by-ids'), {\n method: 'DELETE',\n params: { ids },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n private uri(suffix = ''): string {\n return `/lm/${this.#lumi.config.projectId}/${this.entityName}/documents${suffix}`\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EntityClient } from '@/core/entity-client'\n\nexport class EntitiesClient {\n readonly #lumi: LumiClient\n [key: string]: EntityClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n return new Proxy(this, {\n get(target: EntitiesClient, p: string) {\n if (!(p in target))\n target[p] = new EntityClient(target.#lumi, p)\n return target[p]\n },\n }) as this\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport class EmailTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 发送邮件 */\n public async send({ to, subject, fromName, html, text = '', replyTo, scheduledAt }: {\n to: string | string[]\n subject: string\n fromName?: string\n html?: string\n text?: string\n replyTo?: string | string[]\n scheduledAt?: string\n }): Promise<void> {\n if (!to || !subject || (!html && !text))\n throw new Error('Failed to send email: Missing required parameters.')\n\n if (typeof to === 'string')\n to = [to]\n if (typeof replyTo === 'string')\n replyTo = [replyTo]\n\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/email/send`, {\n method: 'POST',\n body: { to, subject, fromName, html, text, replyTo, scheduledAt },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport interface UploadItem {\n fileName: string\n fileUrl?: string\n uploadError?: string\n}\n\nexport class FileTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 上传文件 */\n public async upload(files: File[]): Promise<UploadItem[]> {\n const formData = new FormData()\n files.forEach((file) => {\n formData.append('files', file)\n })\n\n const res = await request<ApiResponse<UploadItem[]>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'POST',\n body: formData,\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n\n return res.data\n }\n\n /** 批量删除文件 */\n public async delete(fileUrls: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'DELETE',\n body: { fileUrls },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EmailTool, FileTool } from '@/tools'\n\nexport class ToolsClient {\n readonly #lumi: LumiClient\n\n public email: EmailTool\n public file: FileTool\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n this.email = new EmailTool(lumi)\n this.file = new FileTool(lumi)\n }\n}\n","import { LumiAuthClient } from '@/core/auth-client'\nimport { EntitiesClient } from '@/core/entities-client'\nimport { ToolsClient } from '@/core/tools-client'\n\nexport interface LumiClientConfig {\n projectId: string\n apiBaseUrl: string\n authOrigin: string\n}\n\nexport class LumiClient {\n public config: LumiClientConfig\n\n public auth: LumiAuthClient\n public entities: EntitiesClient\n public tools: ToolsClient\n\n constructor(config: LumiClientConfig) {\n this.config = config\n this.auth = new LumiAuthClient(this)\n this.entities = new EntitiesClient(this)\n this.tools = new ToolsClient(this)\n }\n}\n\nexport function createClient(config: LumiClientConfig): LumiClient {\n return new LumiClient(config)\n}\n"],"mappings":"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","names":["index_exports","__export","EmailTool","EntitiesClient","EntityClient","FileTool","LumiAuthClient","LumiClient","ToolsClient","createClient","__toCommonJS","import_uuid","import_enc_base64","import_enc_hex","import_hmac_sha256","import_sha256","import_object_hash","import_ofetch","LumiError","code","message","SECRET_KEY","rfc3986Encode","str","c","createSignatureInterceptor","secretKey","context","options","timestamp","nonce","queryParams","__spreadValues","canonicalQueryString","key","headersToSign","canonicalHeaders","payload","hashedPayload","SHA256","Hex","canonicalRequest","signature","Base64","HmacSHA256","headers","value","requestMap","checkRateLimit","uri","_a","__spreadProps","requestHash","hash","now","requestQueue","time","LumiError","request","lumi","isAuthenticated","response","getIcon","_a","_b","getTitle","setStorage","key","value","storage","oldValue","newValue","getStorage","_e","_lumi","_popupName","LumiAuthClient","lumi","__privateAdd","__privateSet","getStorage","accessToken","setStorage","user","left","top","popup","__privateGet","cleanup","resolve","reject","timer","handleGlobalClick","event","handleMessage","data","origin","source","getIcon","getTitle","__async","res","request","callback","handleStorageChange","_lumi","EntityClient","lumi","entityName","__privateAdd","__privateSet","__async","filter","sort","limit","skip","res","request","__privateGet","id","data","ids","suffix","_lumi","EntitiesClient","lumi","__privateAdd","__privateSet","target","p","EntityClient","__privateGet","_lumi","EmailTool","lumi","__privateAdd","__privateSet","_0","__async","to","subject","fromName","html","text","replyTo","scheduledAt","res","request","__privateGet","LumiError","_lumi","FileTool","lumi","__privateAdd","__privateSet","files","__async","formData","file","res","request","__privateGet","LumiError","fileUrls","_lumi","ToolsClient","lumi","__privateAdd","__privateSet","EmailTool","FileTool","LumiClient","config","LumiAuthClient","EntitiesClient","ToolsClient","createClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/auth-client.ts","../src/lib/request.ts","../src/lib/error.ts","../src/utils/common.ts","../src/utils/storage.ts","../src/core/entity-client.ts","../src/core/entities-client.ts","../src/core/functions-client.ts","../src/tools/email-tool.ts","../src/tools/file-tool.ts","../src/core/tools-client.ts","../src/core/lumi-client.ts"],"sourcesContent":["export * from './core/auth-client'\nexport * from './core/entities-client'\nexport * from './core/entity-client'\nexport * from './core/functions-client'\nexport * from './core/lumi-client'\nexport * from './core/tools-client'\nexport * from './tools'\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { v4 } from 'uuid'\nimport { MessageType, StorageKey } from '@/constants'\nimport { request } from '@/lib/request'\nimport { getIcon, getTitle, isServer } from '@/utils/common'\nimport { getStorage, setStorage } from '@/utils/storage'\n\nexport interface User {\n userId: string\n email: string\n userName: string\n userRole: 'ADMIN' | 'USER'\n createdTime: string\n}\n\nexport interface MessageSignInData {\n projectId: string\n accessToken: string\n user: User\n}\n\nexport type MessageDataReceive = {\n type: MessageType.READY\n} | {\n type: MessageType.SIGN_IN\n data: MessageSignInData\n}\n\nexport interface MessageInitData {\n projectId: string\n icon: string | null\n title: string | null\n}\n\nexport interface MessageDataSend {\n type: MessageType.INIT\n data: MessageInitData\n}\n\nexport class LumiAuthClient {\n readonly #lumi: LumiClient\n readonly #popupName: string = `lumi-auth-${v4()}`\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n Promise.resolve().then(() => {\n if (!isServer && this.isAuthenticated)\n void this.refreshUser()\n })\n }\n\n /** 访问令牌 */\n public get accessToken(): string | null {\n if (isServer) {\n const authorization = this.#lumi.config.authorization\n return authorization ? authorization.replace('Bearer ', '') : null\n }\n return getStorage<string>(StorageKey.ACCESS_TOKEN)\n }\n\n public set accessToken(accessToken: string | null) {\n if (isServer) {\n this.#lumi.config.authorization = accessToken ? `Bearer ${accessToken}` : undefined\n return\n }\n setStorage(StorageKey.ACCESS_TOKEN, accessToken)\n }\n\n #user: User | null = null\n\n /** 用户 */\n public get user(): User | null {\n if (isServer)\n return this.#user\n return getStorage<User>(StorageKey.USER)\n }\n\n public set user(user: User | null) {\n if (isServer) {\n this.#user = user\n return\n }\n setStorage(StorageKey.USER, user)\n }\n\n public get isAuthenticated(): boolean {\n return !!this.accessToken\n }\n\n /** 登录 */\n public signIn(): Promise<MessageSignInData> {\n if (isServer)\n throw new Error('auth.signIn() can only be called on the client side')\n\n const width = 800\n const height = 600\n const left = (window.screen.width - width) / 2\n const top = (window.screen.height - height) / 2\n const popup = window.open(this.#lumi.config.authOrigin, this.#popupName, `width=${width},height=${height},left=${left},top=${top}`)\n\n let cleanup: () => void\n return new Promise<MessageSignInData>((resolve, reject) => {\n if (!popup)\n return reject(new Error('Open auth window failed'))\n\n const timer = setInterval(() => {\n if (popup.closed)\n reject(new Error('Auth window closed'))\n }, 1000)\n\n // 全局点击事件处理函数 - 重新聚焦popup并阻止事件传播\n const handleGlobalClick = (event: MouseEvent): void => {\n if (!popup.closed) {\n popup.focus()\n event.stopPropagation()\n event.preventDefault()\n }\n }\n\n const handleMessage = ({ data, origin, source }: MessageEvent<MessageDataReceive | null>): void => {\n if (origin !== this.#lumi.config.authOrigin || source !== popup)\n return\n\n switch (data?.type) {\n case MessageType.READY: {\n popup.postMessage({\n type: MessageType.INIT,\n data: {\n projectId: this.#lumi.config.projectId,\n icon: getIcon(),\n title: getTitle(),\n },\n } satisfies MessageDataSend, this.#lumi.config.authOrigin)\n break\n }\n case MessageType.SIGN_IN: {\n if (data.data.projectId !== this.#lumi.config.projectId)\n break\n popup.close()\n window.focus()\n this.accessToken = data.data.accessToken\n this.user = data.data.user\n resolve(data.data)\n break\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n // 添加全局点击事件监听器,使用捕获阶段确保优先处理\n document.addEventListener('click', handleGlobalClick, true)\n\n cleanup = () => {\n clearInterval(timer)\n window.removeEventListener('message', handleMessage)\n document.removeEventListener('click', handleGlobalClick, true)\n }\n }).finally(() => cleanup?.())\n }\n\n /** 退出登录 */\n public signOut(): void {\n if (isServer)\n throw new Error('auth.signOut() can only be called on the client side')\n\n this.accessToken = null\n this.user = null\n }\n\n /** 获取当前用户 */\n public async refreshUser(): Promise<User> {\n const res = await request<ApiResponse<User>>(this.#lumi, '/lm/user/info', {\n method: 'POST',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n this.user = res.data\n return res.data\n }\n\n /** 监听登录状态变化 */\n public onAuthChange(callback: (args: {\n isAuthenticated: boolean\n user: User | null\n }) => void): () => void {\n if (isServer)\n throw new Error('auth.onAuthChange() can only be called on the client side')\n\n const handleStorageChange = (event: StorageEvent): void => {\n if (event.key === StorageKey.ACCESS_TOKEN || event.key === StorageKey.USER || event.key === null) {\n callback({\n isAuthenticated: this.isAuthenticated,\n user: this.user,\n })\n }\n }\n\n window.addEventListener('storage', handleStorageChange)\n\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n }\n }\n}\n","import type { FetchContext, FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport Base64 from 'crypto-js/enc-base64'\nimport Hex from 'crypto-js/enc-hex'\nimport HmacSHA256 from 'crypto-js/hmac-sha256'\nimport SHA256 from 'crypto-js/sha256'\nimport hash from 'object-hash'\nimport { ofetch } from 'ofetch'\nimport { LumiError } from '@/lib/error'\nimport { isServer } from '@/utils/common'\n\nconst SECRET_KEY = '6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ=='\n\n/** RFC 3986 compliant URI encoding */\nfunction rfc3986Encode(str: string): string {\n return encodeURIComponent(str).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n}\n\n/** 创建签名拦截器函数 */\nexport function createSignatureInterceptor(secretKey: string) {\n return (context: FetchContext) => {\n const { options } = context\n // 生成签名\n const timestamp = Math.floor(Date.now() / 1000).toString()\n const nonce = Math.random().toString(36).substring(2, 15)\n\n // 构建查询字符串\n const queryParams: Record<string, string> = { ...options.query }\n const canonicalQueryString = Object.keys(queryParams).sort().map(key => `${rfc3986Encode(key)}=${rfc3986Encode(String(queryParams[key]))}`).join('&')\n\n // 构建签名头\n const headersToSign: Record<string, string> = {\n 'x-timestamp': timestamp,\n 'x-nonce': nonce,\n }\n const canonicalHeaders = Object.keys(headersToSign).sort().map(key => `${key}:${headersToSign[key]}`).join('\\n')\n\n // 构建载荷哈希\n const payload = (options.body && !(options.body instanceof FormData)) ? JSON.stringify(options.body) : ''\n const hashedPayload = SHA256(payload).toString(Hex)\n\n // 构建规范请求\n const canonicalRequest = [canonicalQueryString, canonicalHeaders, hashedPayload].join('\\n')\n\n // 生成签名\n const signature = Base64.stringify(HmacSHA256(canonicalRequest, secretKey))\n\n // 添加签名头到请求\n const headers = new Headers(options.headers)\n Object.entries(headersToSign).forEach(([key, value]) => {\n headers.set(key, value)\n })\n headers.set('X-Sign', signature)\n options.headers = headers\n }\n}\n\nexport interface ApiResponse<T> {\n code: number\n message: string\n data: T\n}\n\nexport interface PaginationData<T> {\n total: number\n list: T[]\n}\n\nconst requestMap = new Map<string, number[]>()\n\n/** 限制请求频率,相同参数的请求每秒只能发送4次 */\nexport function checkRateLimit(uri: string, options: FetchOptions<'json'>): void {\n if (options.body instanceof FormData) {\n options = {\n ...options,\n body: Array.from(options.body.entries()),\n }\n }\n const requestHash = hash([uri, options])\n const now = Date.now()\n const requestQueue = requestMap.get(requestHash)?.filter(time => now - time < 1000) || []\n if (requestQueue.length >= 4)\n throw new LumiError(429, 'Too many requests')\n requestQueue.push(now)\n requestMap.set(requestHash, requestQueue)\n}\n\nexport function request<T>(lumi: LumiClient, uri: string, options: FetchOptions<'json'> = {}): Promise<T> {\n // 添加认证头(如果存在)\n if (lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n // 限制请求频率\n checkRateLimit(uri, options)\n\n const isAuthenticated = lumi.auth.isAuthenticated\n\n return ofetch<T>(uri, {\n baseURL: lumi.config.apiBaseUrl,\n ...options,\n onRequest: createSignatureInterceptor(SECRET_KEY),\n onResponse: ({ response }) => {\n // 若 Token 失效则退出登录\n if (!isServer && isAuthenticated && (response._data as ApiResponse<any>)?.code === 2100)\n lumi.auth.signOut()\n },\n })\n}\n","export class LumiError extends Error {\n name: string = 'LumiError'\n code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.code = code\n }\n}\n","export function getIcon(): string | null {\n return document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]')?.href ?? null\n}\n\nexport function getTitle(): string | null {\n return document.title ?? null\n}\n\nexport const isServer = typeof window === 'undefined'\n","import type { StorageKey } from '@/constants'\n\nexport function setStorage<T>(key: StorageKey, value: T, storage: Storage = localStorage): void {\n const oldValue = storage.getItem(key)\n const newValue = value ? JSON.stringify(value) : null\n if (newValue)\n storage.setItem(key, newValue)\n else\n storage.removeItem(key)\n\n window.dispatchEvent(new StorageEvent('storage', {\n key,\n oldValue,\n newValue,\n storageArea: storage,\n }))\n}\n\nexport function getStorage<T>(key: StorageKey, storage: Storage = localStorage): T | null {\n const value = storage.getItem(key)\n try {\n return value ? JSON.parse(value) : null\n }\n catch (_e) {\n return null\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse, PaginationData } from '@/lib/request'\nimport { request } from '@/lib/request'\n\nexport interface Entity extends Record<string, any> {\n id: string\n}\n\nexport class EntityClient {\n readonly #lumi: LumiClient\n public readonly entityName: string\n\n constructor(lumi: LumiClient, entityName: string) {\n this.#lumi = lumi\n this.entityName = entityName\n }\n\n /** 查询文档列表 */\n public async list({ filter, sort, limit, skip }: {\n filter?: any\n sort?: Record<string, 1 | -1>\n limit?: number\n skip?: number\n } = {}): Promise<PaginationData<Entity>> {\n if (!limit) {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/list'), {\n method: 'POST',\n body: { filter, sort },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return {\n total: res.data.length,\n list: res.data,\n }\n }\n else {\n const res = await request<ApiResponse<PaginationData<Entity>>>(this.#lumi, this.uri('/find'), {\n method: 'POST',\n body: { filter, sort, limit, skip },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n }\n\n /** 获取单个文档 */\n public async get(id: string): Promise<Entity | null> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(`/${id}`), {\n method: 'GET',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 创建文档 */\n public async create(data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 批量创建文档 */\n public async createMany(data: Record<string, any>[]): Promise<Entity[]> {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/batch'), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 更新文档 */\n public async update(id: string, data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'PUT',\n body: { filter: { _id: id }, update: data },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 删除文档 */\n public async delete(id: string): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri(`/${id}`), {\n method: 'DELETE',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n /** 批量删除文档 */\n public async deleteMany(ids: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri('/batch-by-ids'), {\n method: 'DELETE',\n params: { ids },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n private uri(suffix = ''): string {\n return `/lm/${this.#lumi.config.projectId}/${this.entityName}/documents${suffix}`\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EntityClient } from '@/core/entity-client'\n\nexport class EntitiesClient {\n readonly #lumi: LumiClient\n [key: string]: EntityClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n return new Proxy(this, {\n get(target: EntitiesClient, p: string) {\n if (!(p in target))\n target[p] = new EntityClient(target.#lumi, p)\n return target[p]\n },\n }) as this\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport { ofetch } from 'ofetch'\nimport { checkRateLimit } from '@/lib/request'\n\nexport class FunctionsClient {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n public invoke(uri: string, options: FetchOptions<'json'> = {}): Promise<any> {\n if (this.#lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${this.#lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n checkRateLimit(uri, options)\n\n return ofetch(uri, {\n ...options,\n })\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport class EmailTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 发送邮件 */\n public async send({ to, subject, fromName, html, text = '', replyTo, scheduledAt }: {\n to: string | string[]\n subject: string\n fromName?: string\n html?: string\n text?: string\n replyTo?: string | string[]\n scheduledAt?: string\n }): Promise<void> {\n if (!to || !subject || (!html && !text))\n throw new Error('Failed to send email: Missing required parameters.')\n\n if (typeof to === 'string')\n to = [to]\n if (typeof replyTo === 'string')\n replyTo = [replyTo]\n\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/email/send`, {\n method: 'POST',\n body: { to, subject, fromName, html, text, replyTo, scheduledAt },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport interface UploadItem {\n fileName: string\n fileUrl?: string\n uploadError?: string\n}\n\nexport class FileTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 上传文件 */\n public async upload(files: File[]): Promise<UploadItem[]> {\n const formData = new FormData()\n files.forEach((file) => {\n formData.append('files', file)\n })\n\n const res = await request<ApiResponse<UploadItem[]>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'POST',\n body: formData,\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n\n return res.data\n }\n\n /** 批量删除文件 */\n public async delete(fileUrls: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'DELETE',\n body: { fileUrls },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EmailTool, FileTool } from '@/tools'\n\nexport class ToolsClient {\n readonly #lumi: LumiClient\n\n public email: EmailTool\n public file: FileTool\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n this.email = new EmailTool(lumi)\n this.file = new FileTool(lumi)\n }\n}\n","import { LumiAuthClient } from '@/core/auth-client'\nimport { EntitiesClient } from '@/core/entities-client'\nimport { FunctionsClient } from '@/core/functions-client'\nimport { ToolsClient } from '@/core/tools-client'\n\nexport interface LumiClientConfig {\n projectId: string\n apiBaseUrl: string\n authOrigin: string\n authorization?: string\n}\n\nexport class LumiClient {\n public config: LumiClientConfig\n\n public auth: LumiAuthClient\n public entities: EntitiesClient\n public tools: ToolsClient\n public functions: FunctionsClient\n\n constructor(config: LumiClientConfig) {\n this.config = config\n this.auth = new LumiAuthClient(this)\n this.entities = new EntitiesClient(this)\n this.tools = new ToolsClient(this)\n this.functions = new FunctionsClient(this)\n }\n}\n\nexport function createClient(config: LumiClientConfig): LumiClient {\n return new LumiClient(config)\n}\n"],"mappings":"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","names":["index_exports","__export","EmailTool","EntitiesClient","EntityClient","FileTool","FunctionsClient","LumiAuthClient","LumiClient","ToolsClient","createClient","__toCommonJS","import_uuid","import_enc_base64","import_enc_hex","import_hmac_sha256","import_sha256","import_object_hash","import_ofetch","LumiError","code","message","getIcon","_a","_b","getTitle","isServer","SECRET_KEY","rfc3986Encode","str","c","createSignatureInterceptor","secretKey","context","options","timestamp","nonce","queryParams","__spreadValues","canonicalQueryString","key","headersToSign","canonicalHeaders","payload","hashedPayload","SHA256","Hex","canonicalRequest","signature","Base64","HmacSHA256","headers","value","requestMap","checkRateLimit","uri","_a","__spreadProps","requestHash","hash","now","requestQueue","time","LumiError","request","lumi","isAuthenticated","response","isServer","setStorage","key","value","storage","oldValue","newValue","getStorage","_e","_lumi","_popupName","_user","LumiAuthClient","lumi","__privateAdd","__privateSet","isServer","authorization","__privateGet","getStorage","accessToken","setStorage","user","width","height","left","top","popup","cleanup","resolve","reject","timer","handleGlobalClick","event","handleMessage","data","origin","source","getIcon","getTitle","__async","res","request","callback","handleStorageChange","_lumi","EntityClient","lumi","entityName","__privateAdd","__privateSet","__async","filter","sort","limit","skip","res","request","__privateGet","id","data","ids","suffix","_lumi","EntitiesClient","lumi","__privateAdd","__privateSet","target","p","EntityClient","__privateGet","import_ofetch","_lumi","FunctionsClient","lumi","__privateAdd","__privateSet","uri","options","__privateGet","__spreadValues","checkRateLimit","_lumi","EmailTool","lumi","__privateAdd","__privateSet","_0","__async","to","subject","fromName","html","text","replyTo","scheduledAt","res","request","__privateGet","LumiError","_lumi","FileTool","lumi","__privateAdd","__privateSet","files","__async","formData","file","res","request","__privateGet","LumiError","fileUrls","_lumi","ToolsClient","lumi","__privateAdd","__privateSet","EmailTool","FileTool","LumiClient","config","LumiAuthClient","EntitiesClient","ToolsClient","FunctionsClient","createClient"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),
|
|
3
|
-
`),d=
|
|
1
|
+
var W=Object.defineProperty,ee=Object.defineProperties;var te=Object.getOwnPropertyDescriptors;var z=Object.getOwnPropertySymbols;var ie=Object.prototype.hasOwnProperty,re=Object.prototype.propertyIsEnumerable;var Q=i=>{throw TypeError(i)};var K=(i,e,t)=>e in i?W(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t,S=(i,e)=>{for(var t in e||(e={}))ie.call(e,t)&&K(i,t,e[t]);if(z)for(var t of z(e))re.call(e,t)&&K(i,t,e[t]);return i},j=(i,e)=>ee(i,te(e));var J=(i,e,t)=>e.has(i)||Q("Cannot "+t);var n=(i,e,t)=>(J(i,e,"read from private field"),t?t.call(i):e.get(i)),a=(i,e,t)=>e.has(i)?Q("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(i):e.set(i,t),u=(i,e,t,r)=>(J(i,e,"write to private field"),r?r.call(i,t):e.set(i,t),t);var m=(i,e,t)=>new Promise((r,s)=>{var o=h=>{try{f(t.next(h))}catch(y){s(y)}},l=h=>{try{f(t.throw(h))}catch(y){s(y)}},f=h=>h.done?r(h.value):Promise.resolve(h.value).then(o,l);f((t=t.apply(i,e)).next())});import{v4 as pe}from"uuid";import ne from"crypto-js/enc-base64";import oe from"crypto-js/enc-hex";import se from"crypto-js/hmac-sha256";import ae from"crypto-js/sha256";import ce from"object-hash";import{ofetch as le}from"ofetch";var b=class extends Error{constructor(t,r){super(r);this.name="LumiError";this.code=t}};function G(){var i,e;return(e=(i=document.querySelector('link[rel="icon"]'))==null?void 0:i.href)!=null?e:null}function V(){var i;return(i=document.title)!=null?i:null}var w=typeof window=="undefined";var ue="6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ==";function Y(i){return encodeURIComponent(i).replace(/[!'()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}function me(i){return e=>{let{options:t}=e,r=Math.floor(Date.now()/1e3).toString(),s=Math.random().toString(36).substring(2,15),o=S({},t.query),l=Object.keys(o).sort().map(E=>`${Y(E)}=${Y(String(o[E]))}`).join("&"),f={"x-timestamp":r,"x-nonce":s},h=Object.keys(f).sort().map(E=>`${E}:${f[E]}`).join(`
|
|
2
|
+
`),y=t.body&&!(t.body instanceof FormData)?JSON.stringify(t.body):"",R=ae(y).toString(oe),v=[l,h,R].join(`
|
|
3
|
+
`),d=ne.stringify(se(v,i)),I=new Headers(t.headers);Object.entries(f).forEach(([E,X])=>{I.set(E,X)}),I.set("X-Sign",d),t.headers=I}}var Z=new Map;function F(i,e){var o;e.body instanceof FormData&&(e=j(S({},e),{body:Array.from(e.body.entries())}));let t=ce([i,e]),r=Date.now(),s=((o=Z.get(t))==null?void 0:o.filter(l=>r-l<1e3))||[];if(s.length>=4)throw new b(429,"Too many requests");s.push(r),Z.set(t,s)}function c(i,e,t={}){i.auth.accessToken&&(t.headers=S({Authorization:`Bearer ${i.auth.accessToken}`},t.headers)),F(e,t);let r=i.auth.isAuthenticated;return le(e,j(S({baseURL:i.config.apiBaseUrl},t),{onRequest:me(ue),onResponse:({response:s})=>{var o;!w&&r&&((o=s._data)==null?void 0:o.code)===2100&&i.auth.signOut()}}))}function B(i,e,t=localStorage){let r=t.getItem(i),s=e?JSON.stringify(e):null;s?t.setItem(i,s):t.removeItem(i),window.dispatchEvent(new StorageEvent("storage",{key:i,oldValue:r,newValue:s,storageArea:t}))}function H(i,e=localStorage){let t=e.getItem(i);try{return t?JSON.parse(t):null}catch(r){return null}}var g,O,L,P=class{constructor(e){a(this,g);a(this,O,`lumi-auth-${pe()}`);a(this,L,null);u(this,g,e),Promise.resolve().then(()=>{!w&&this.isAuthenticated&&this.refreshUser()})}get accessToken(){if(w){let e=n(this,g).config.authorization;return e?e.replace("Bearer ",""):null}return H("lumi-access-token")}set accessToken(e){if(w){n(this,g).config.authorization=e?`Bearer ${e}`:void 0;return}B("lumi-access-token",e)}get user(){return w?n(this,L):H("lumi-user")}set user(e){if(w){u(this,L,e);return}B("lumi-user",e)}get isAuthenticated(){return!!this.accessToken}signIn(){if(w)throw new Error("auth.signIn() can only be called on the client side");let e=800,t=600,r=(window.screen.width-e)/2,s=(window.screen.height-t)/2,o=window.open(n(this,g).config.authOrigin,n(this,O),`width=${e},height=${t},left=${r},top=${s}`),l;return new Promise((f,h)=>{if(!o)return h(new Error("Open auth window failed"));let y=setInterval(()=>{o.closed&&h(new Error("Auth window closed"))},1e3),R=d=>{o.closed||(o.focus(),d.stopPropagation(),d.preventDefault())},v=({data:d,origin:I,source:E})=>{if(!(I!==n(this,g).config.authOrigin||E!==o))switch(d==null?void 0:d.type){case"lumi-ready":{o.postMessage({type:"lumi-init",data:{projectId:n(this,g).config.projectId,icon:G(),title:V()}},n(this,g).config.authOrigin);break}case"lumi-sign-in":{if(d.data.projectId!==n(this,g).config.projectId)break;o.close(),window.focus(),this.accessToken=d.data.accessToken,this.user=d.data.user,f(d.data);break}}};window.addEventListener("message",v),document.addEventListener("click",R,!0),l=()=>{clearInterval(y),window.removeEventListener("message",v),document.removeEventListener("click",R,!0)}}).finally(()=>l==null?void 0:l())}signOut(){if(w)throw new Error("auth.signOut() can only be called on the client side");this.accessToken=null,this.user=null}refreshUser(){return m(this,null,function*(){let e=yield c(n(this,g),"/lm/user/info",{method:"POST"});if(e.code!==200)throw new Error(e.message);return this.user=e.data,e.data})}onAuthChange(e){if(w)throw new Error("auth.onAuthChange() can only be called on the client side");let t=r=>{(r.key==="lumi-access-token"||r.key==="lumi-user"||r.key===null)&&e({isAuthenticated:this.isAuthenticated,user:this.user})};return window.addEventListener("storage",t),()=>{window.removeEventListener("storage",t)}}};g=new WeakMap,O=new WeakMap,L=new WeakMap;var p,D=class{constructor(e,t){a(this,p);u(this,p,e),this.entityName=t}list(){return m(this,arguments,function*({filter:e,sort:t,limit:r,skip:s}={}){if(r){let o=yield c(n(this,p),this.uri("/find"),{method:"POST",body:{filter:e,sort:t,limit:r,skip:s}});if(o.code!==200)throw new Error(o.message);return o.data}else{let o=yield c(n(this,p),this.uri("/list"),{method:"POST",body:{filter:e,sort:t}});if(o.code!==200)throw new Error(o.message);return{total:o.data.length,list:o.data}}})}get(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(`/${e}`),{method:"GET"});if(t.code!==200)throw new Error(t.message);return t.data})}create(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(),{method:"POST",body:e});if(t.code!==200)throw new Error(t.message);return t.data})}createMany(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri("/batch"),{method:"POST",body:e});if(t.code!==200)throw new Error(t.message);return t.data})}update(e,t){return m(this,null,function*(){let r=yield c(n(this,p),this.uri(),{method:"PUT",body:{filter:{_id:e},update:t}});if(r.code!==200)throw new Error(r.message);return r.data})}delete(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri(`/${e}`),{method:"DELETE"});if(t.code!==200)throw new Error(t.message)})}deleteMany(e){return m(this,null,function*(){let t=yield c(n(this,p),this.uri("/batch-by-ids"),{method:"DELETE",params:{ids:e}});if(t.code!==200)throw new Error(t.message)})}uri(e=""){return`/lm/${n(this,p).config.projectId}/${this.entityName}/documents${e}`}};p=new WeakMap;var x,M=class{constructor(e){a(this,x);return u(this,x,e),new Proxy(this,{get(t,r){return r in t||(t[r]=new D(n(t,x),r)),t[r]}})}};x=new WeakMap;import{ofetch as he}from"ofetch";var T,U=class{constructor(e){a(this,T);u(this,T,e)}invoke(e,t={}){return n(this,T).auth.accessToken&&(t.headers=S({Authorization:`Bearer ${n(this,T).auth.accessToken}`},t.headers)),F(e,t),he(e,S({},t))}};T=new WeakMap;var A,k=class{constructor(e){a(this,A);u(this,A,e)}send(h){return m(this,arguments,function*({to:e,subject:t,fromName:r,html:s,text:o="",replyTo:l,scheduledAt:f}){if(!e||!t||!s&&!o)throw new Error("Failed to send email: Missing required parameters.");typeof e=="string"&&(e=[e]),typeof l=="string"&&(l=[l]);let y=yield c(n(this,A),`/lm/${n(this,A).config.projectId}/email/send`,{method:"POST",body:{to:e,subject:t,fromName:r,html:s,text:o,replyTo:l,scheduledAt:f}});if(y.code!==200)throw new b(y.code,y.message)})}};A=new WeakMap;var C,q=class{constructor(e){a(this,C);u(this,C,e)}upload(e){return m(this,null,function*(){let t=new FormData;e.forEach(s=>{t.append("files",s)});let r=yield c(n(this,C),`/lm/${n(this,C).config.projectId}/file/batch`,{method:"POST",body:t});if(r.code!==200)throw new b(r.code,r.message);return r.data})}delete(e){return m(this,null,function*(){let t=yield c(n(this,C),`/lm/${n(this,C).config.projectId}/file/batch`,{method:"DELETE",body:{fileUrls:e}});if(t.code!==200)throw new b(t.code,t.message)})}};C=new WeakMap;var N,$=class{constructor(e){a(this,N);u(this,N,e),this.email=new k(e),this.file=new q(e)}};N=new WeakMap;var _=class{constructor(e){this.config=e,this.auth=new P(this),this.entities=new M(this),this.tools=new $(this),this.functions=new U(this)}};function ot(i){return new _(i)}export{k as EmailTool,M as EntitiesClient,D as EntityClient,q as FileTool,U as FunctionsClient,P as LumiAuthClient,_ as LumiClient,$ as ToolsClient,ot as createClient};
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/auth-client.ts","../src/lib/request.ts","../src/lib/error.ts","../src/utils/common.ts","../src/utils/storage.ts","../src/core/entity-client.ts","../src/core/entities-client.ts","../src/tools/email-tool.ts","../src/tools/file-tool.ts","../src/core/tools-client.ts","../src/core/lumi-client.ts"],"sourcesContent":["import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { v4 } from 'uuid'\nimport { MessageType, StorageKey } from '@/constants'\nimport { request } from '@/lib/request'\nimport { getIcon, getTitle } from '@/utils/common'\nimport { getStorage, setStorage } from '@/utils/storage'\n\nexport interface User {\n userId: string\n email: string\n userName: string\n createdTime: string\n}\n\nexport interface MessageSignInData {\n projectId: string\n accessToken: string\n user: User\n}\n\nexport type MessageDataReceive = {\n type: MessageType.READY\n} | {\n type: MessageType.SIGN_IN\n data: MessageSignInData\n}\n\nexport interface MessageInitData {\n projectId: string\n icon: string | null\n title: string | null\n}\n\nexport interface MessageDataSend {\n type: MessageType.INIT\n data: MessageInitData\n}\n\nexport class LumiAuthClient {\n readonly #lumi: LumiClient\n readonly #popupName: string = `lumi-auth-${v4()}`\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n Promise.resolve().then(() => {\n if (this.isAuthenticated)\n void this.refreshUser()\n })\n }\n\n /** 访问令牌 */\n public get accessToken(): string | null {\n return getStorage<string>(StorageKey.ACCESS_TOKEN)\n }\n\n public set accessToken(accessToken: string | null) {\n setStorage(StorageKey.ACCESS_TOKEN, accessToken)\n }\n\n /** 用户 */\n public get user(): User | null {\n return getStorage<User>(StorageKey.USER)\n }\n\n public set user(user: User | null) {\n setStorage(StorageKey.USER, user)\n }\n\n public get isAuthenticated(): boolean {\n return !!this.accessToken\n }\n\n /** 登录 */\n public signIn(): Promise<MessageSignInData> {\n const width = 800\n const height = 600\n const left = (window.screen.width - width) / 2\n const top = (window.screen.height - height) / 2\n const popup = window.open(this.#lumi.config.authOrigin, this.#popupName, `width=${width},height=${height},left=${left},top=${top}`)\n\n let cleanup: () => void\n return new Promise<MessageSignInData>((resolve, reject) => {\n if (!popup)\n return reject(new Error('Open auth window failed'))\n\n const timer = setInterval(() => {\n if (popup.closed)\n reject(new Error('Auth window closed'))\n }, 1000)\n\n // 全局点击事件处理函数 - 重新聚焦popup并阻止事件传播\n const handleGlobalClick = (event: MouseEvent): void => {\n if (!popup.closed) {\n popup.focus()\n event.stopPropagation()\n event.preventDefault()\n }\n }\n\n const handleMessage = ({ data, origin, source }: MessageEvent<MessageDataReceive | null>): void => {\n if (origin !== this.#lumi.config.authOrigin || source !== popup)\n return\n\n switch (data?.type) {\n case MessageType.READY: {\n popup.postMessage({\n type: MessageType.INIT,\n data: {\n projectId: this.#lumi.config.projectId,\n icon: getIcon(),\n title: getTitle(),\n },\n } satisfies MessageDataSend, this.#lumi.config.authOrigin)\n break\n }\n case MessageType.SIGN_IN: {\n if (data.data.projectId !== this.#lumi.config.projectId)\n break\n popup.close()\n window.focus()\n this.accessToken = data.data.accessToken\n this.user = data.data.user\n resolve(data.data)\n break\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n // 添加全局点击事件监听器,使用捕获阶段确保优先处理\n document.addEventListener('click', handleGlobalClick, true)\n\n cleanup = () => {\n clearInterval(timer)\n window.removeEventListener('message', handleMessage)\n document.removeEventListener('click', handleGlobalClick, true)\n }\n }).finally(() => cleanup?.())\n }\n\n /** 退出登录 */\n public signOut(): void {\n this.accessToken = null\n this.user = null\n }\n\n /** 获取当前用户 */\n public async refreshUser(): Promise<User> {\n const res = await request<ApiResponse<User>>(this.#lumi, '/lm/user/info', {\n method: 'POST',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n this.user = res.data\n return res.data\n }\n\n /** 监听登录状态变化 */\n public onAuthChange(callback: (args: {\n isAuthenticated: boolean\n user: User | null\n }) => void): () => void {\n const handleStorageChange = (event: StorageEvent): void => {\n if (event.key === StorageKey.ACCESS_TOKEN || event.key === StorageKey.USER || event.key === null) {\n callback({\n isAuthenticated: this.isAuthenticated,\n user: this.user,\n })\n }\n }\n\n window.addEventListener('storage', handleStorageChange)\n\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n }\n }\n}\n","import type { FetchContext, FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport Base64 from 'crypto-js/enc-base64'\nimport Hex from 'crypto-js/enc-hex'\nimport HmacSHA256 from 'crypto-js/hmac-sha256'\nimport SHA256 from 'crypto-js/sha256'\nimport hash from 'object-hash'\nimport { ofetch } from 'ofetch'\nimport { LumiError } from '@/lib/error'\n\nconst SECRET_KEY = '6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ=='\n\n/** RFC 3986 compliant URI encoding */\nfunction rfc3986Encode(str: string): string {\n return encodeURIComponent(str).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n}\n\n/** 创建签名拦截器函数 */\nexport function createSignatureInterceptor(secretKey: string) {\n return (context: FetchContext) => {\n const { options } = context\n // 生成签名\n const timestamp = Math.floor(Date.now() / 1000).toString()\n const nonce = Math.random().toString(36).substring(2, 15)\n\n // 构建查询字符串\n const queryParams: Record<string, string> = { ...options.query }\n const canonicalQueryString = Object.keys(queryParams).sort().map(key => `${rfc3986Encode(key)}=${rfc3986Encode(String(queryParams[key]))}`).join('&')\n\n // 构建签名头\n const headersToSign: Record<string, string> = {\n 'x-timestamp': timestamp,\n 'x-nonce': nonce,\n }\n const canonicalHeaders = Object.keys(headersToSign).sort().map(key => `${key}:${headersToSign[key]}`).join('\\n')\n\n // 构建载荷哈希\n const payload = (options.body && !(options.body instanceof FormData)) ? JSON.stringify(options.body) : ''\n const hashedPayload = SHA256(payload).toString(Hex)\n\n // 构建规范请求\n const canonicalRequest = [canonicalQueryString, canonicalHeaders, hashedPayload].join('\\n')\n\n // 生成签名\n const signature = Base64.stringify(HmacSHA256(canonicalRequest, secretKey))\n\n // 添加签名头到请求\n const headers = new Headers(options.headers)\n Object.entries(headersToSign).forEach(([key, value]) => {\n headers.set(key, value)\n })\n headers.set('X-Sign', signature)\n options.headers = headers\n }\n}\n\nexport interface ApiResponse<T> {\n code: number\n message: string\n data: T\n}\n\nexport interface PaginationData<T> {\n total: number\n list: T[]\n}\n\nconst requestMap = new Map<string, number[]>()\n\n/** 限制请求频率,相同参数的请求每秒只能发送4次 */\nfunction checkRateLimit(uri: string, options: FetchOptions<'json'>): void {\n if (options.body instanceof FormData) {\n options = {\n ...options,\n body: Array.from(options.body.entries()),\n }\n }\n const requestHash = hash([uri, options])\n const now = Date.now()\n const requestQueue = requestMap.get(requestHash)?.filter(time => now - time < 1000) || []\n if (requestQueue.length >= 4)\n throw new LumiError(429, 'Too many requests')\n requestQueue.push(now)\n requestMap.set(requestHash, requestQueue)\n}\n\nexport function request<T>(lumi: LumiClient, uri: string, options: FetchOptions<'json'> = {}): Promise<T> {\n // 添加认证头(如果存在)\n if (lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n // 限制请求频率\n checkRateLimit(uri, options)\n\n const isAuthenticated = lumi.auth.isAuthenticated\n\n return ofetch<T>(uri, {\n baseURL: lumi.config.apiBaseUrl,\n ...options,\n onRequest: createSignatureInterceptor(SECRET_KEY),\n onResponse: ({ response }) => {\n // 若 Token 失效则退出登录\n if (isAuthenticated && (response._data as ApiResponse<any>)?.code === 2100)\n lumi.auth.signOut()\n },\n })\n}\n","export class LumiError extends Error {\n name: string = 'LumiError'\n code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.code = code\n }\n}\n","export function getIcon(): string | null {\n return document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]')?.href ?? null\n}\n\nexport function getTitle(): string | null {\n return document.title ?? null\n}\n","import type { StorageKey } from '@/constants'\n\nexport function setStorage<T>(key: StorageKey, value: T, storage: Storage = localStorage): void {\n const oldValue = storage.getItem(key)\n const newValue = value ? JSON.stringify(value) : null\n if (newValue)\n storage.setItem(key, newValue)\n else\n storage.removeItem(key)\n\n window.dispatchEvent(new StorageEvent('storage', {\n key,\n oldValue,\n newValue,\n storageArea: storage,\n }))\n}\n\nexport function getStorage<T>(key: StorageKey, storage: Storage = localStorage): T | null {\n const value = storage.getItem(key)\n try {\n return value ? JSON.parse(value) : null\n }\n catch (_e) {\n return null\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse, PaginationData } from '@/lib/request'\nimport { request } from '@/lib/request'\n\nexport interface Entity extends Record<string, any> {\n id: string\n}\n\nexport class EntityClient {\n readonly #lumi: LumiClient\n public readonly entityName: string\n\n constructor(lumi: LumiClient, entityName: string) {\n this.#lumi = lumi\n this.entityName = entityName\n }\n\n /** 查询文档列表 */\n public async list({ filter, sort, limit, skip }: {\n filter?: any\n sort?: Record<string, 1 | -1>\n limit?: number\n skip?: number\n } = {}): Promise<PaginationData<Entity>> {\n if (!limit) {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/list'), {\n method: 'POST',\n body: { filter, sort },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return {\n total: res.data.length,\n list: res.data,\n }\n }\n else {\n const res = await request<ApiResponse<PaginationData<Entity>>>(this.#lumi, this.uri('/find'), {\n method: 'POST',\n body: { filter, sort, limit, skip },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n }\n\n /** 获取单个文档 */\n public async get(id: string): Promise<Entity | null> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(`/${id}`), {\n method: 'GET',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 创建文档 */\n public async create(data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 批量创建文档 */\n public async createMany(data: Record<string, any>[]): Promise<Entity[]> {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/batch'), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 更新文档 */\n public async update(id: string, data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'PUT',\n body: { filter: { _id: id }, update: data },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 删除文档 */\n public async delete(id: string): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri(`/${id}`), {\n method: 'DELETE',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n /** 批量删除文档 */\n public async deleteMany(ids: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri('/batch-by-ids'), {\n method: 'DELETE',\n params: { ids },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n private uri(suffix = ''): string {\n return `/lm/${this.#lumi.config.projectId}/${this.entityName}/documents${suffix}`\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EntityClient } from '@/core/entity-client'\n\nexport class EntitiesClient {\n readonly #lumi: LumiClient\n [key: string]: EntityClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n return new Proxy(this, {\n get(target: EntitiesClient, p: string) {\n if (!(p in target))\n target[p] = new EntityClient(target.#lumi, p)\n return target[p]\n },\n }) as this\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport class EmailTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 发送邮件 */\n public async send({ to, subject, fromName, html, text = '', replyTo, scheduledAt }: {\n to: string | string[]\n subject: string\n fromName?: string\n html?: string\n text?: string\n replyTo?: string | string[]\n scheduledAt?: string\n }): Promise<void> {\n if (!to || !subject || (!html && !text))\n throw new Error('Failed to send email: Missing required parameters.')\n\n if (typeof to === 'string')\n to = [to]\n if (typeof replyTo === 'string')\n replyTo = [replyTo]\n\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/email/send`, {\n method: 'POST',\n body: { to, subject, fromName, html, text, replyTo, scheduledAt },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport interface UploadItem {\n fileName: string\n fileUrl?: string\n uploadError?: string\n}\n\nexport class FileTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 上传文件 */\n public async upload(files: File[]): Promise<UploadItem[]> {\n const formData = new FormData()\n files.forEach((file) => {\n formData.append('files', file)\n })\n\n const res = await request<ApiResponse<UploadItem[]>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'POST',\n body: formData,\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n\n return res.data\n }\n\n /** 批量删除文件 */\n public async delete(fileUrls: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'DELETE',\n body: { fileUrls },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EmailTool, FileTool } from '@/tools'\n\nexport class ToolsClient {\n readonly #lumi: LumiClient\n\n public email: EmailTool\n public file: FileTool\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n this.email = new EmailTool(lumi)\n this.file = new FileTool(lumi)\n }\n}\n","import { LumiAuthClient } from '@/core/auth-client'\nimport { EntitiesClient } from '@/core/entities-client'\nimport { ToolsClient } from '@/core/tools-client'\n\nexport interface LumiClientConfig {\n projectId: string\n apiBaseUrl: string\n authOrigin: string\n}\n\nexport class LumiClient {\n public config: LumiClientConfig\n\n public auth: LumiAuthClient\n public entities: EntitiesClient\n public tools: ToolsClient\n\n constructor(config: LumiClientConfig) {\n this.config = config\n this.auth = new LumiAuthClient(this)\n this.entities = new EntitiesClient(this)\n this.tools = new ToolsClient(this)\n }\n}\n\nexport function createClient(config: LumiClientConfig): LumiClient {\n return new LumiClient(config)\n}\n"],"mappings":"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","names":["v4","Base64","Hex","HmacSHA256","SHA256","hash","ofetch","LumiError","code","message","SECRET_KEY","rfc3986Encode","str","c","createSignatureInterceptor","secretKey","context","options","timestamp","nonce","queryParams","__spreadValues","canonicalQueryString","key","headersToSign","canonicalHeaders","payload","hashedPayload","SHA256","Hex","canonicalRequest","signature","Base64","HmacSHA256","headers","value","requestMap","checkRateLimit","uri","_a","__spreadProps","requestHash","hash","now","requestQueue","time","LumiError","request","lumi","isAuthenticated","ofetch","response","getIcon","_a","_b","getTitle","setStorage","key","value","storage","oldValue","newValue","getStorage","_e","_lumi","_popupName","LumiAuthClient","lumi","__privateAdd","v4","__privateSet","getStorage","accessToken","setStorage","user","left","top","popup","__privateGet","cleanup","resolve","reject","timer","handleGlobalClick","event","handleMessage","data","origin","source","getIcon","getTitle","__async","res","request","callback","handleStorageChange","_lumi","EntityClient","lumi","entityName","__privateAdd","__privateSet","__async","filter","sort","limit","skip","res","request","__privateGet","id","data","ids","suffix","_lumi","EntitiesClient","lumi","__privateAdd","__privateSet","target","p","EntityClient","__privateGet","_lumi","EmailTool","lumi","__privateAdd","__privateSet","_0","__async","to","subject","fromName","html","text","replyTo","scheduledAt","res","request","__privateGet","LumiError","_lumi","FileTool","lumi","__privateAdd","__privateSet","files","__async","formData","file","res","request","__privateGet","LumiError","fileUrls","_lumi","ToolsClient","lumi","__privateAdd","__privateSet","EmailTool","FileTool","LumiClient","config","LumiAuthClient","EntitiesClient","ToolsClient","createClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/auth-client.ts","../src/lib/request.ts","../src/lib/error.ts","../src/utils/common.ts","../src/utils/storage.ts","../src/core/entity-client.ts","../src/core/entities-client.ts","../src/core/functions-client.ts","../src/tools/email-tool.ts","../src/tools/file-tool.ts","../src/core/tools-client.ts","../src/core/lumi-client.ts"],"sourcesContent":["import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { v4 } from 'uuid'\nimport { MessageType, StorageKey } from '@/constants'\nimport { request } from '@/lib/request'\nimport { getIcon, getTitle, isServer } from '@/utils/common'\nimport { getStorage, setStorage } from '@/utils/storage'\n\nexport interface User {\n userId: string\n email: string\n userName: string\n userRole: 'ADMIN' | 'USER'\n createdTime: string\n}\n\nexport interface MessageSignInData {\n projectId: string\n accessToken: string\n user: User\n}\n\nexport type MessageDataReceive = {\n type: MessageType.READY\n} | {\n type: MessageType.SIGN_IN\n data: MessageSignInData\n}\n\nexport interface MessageInitData {\n projectId: string\n icon: string | null\n title: string | null\n}\n\nexport interface MessageDataSend {\n type: MessageType.INIT\n data: MessageInitData\n}\n\nexport class LumiAuthClient {\n readonly #lumi: LumiClient\n readonly #popupName: string = `lumi-auth-${v4()}`\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n Promise.resolve().then(() => {\n if (!isServer && this.isAuthenticated)\n void this.refreshUser()\n })\n }\n\n /** 访问令牌 */\n public get accessToken(): string | null {\n if (isServer) {\n const authorization = this.#lumi.config.authorization\n return authorization ? authorization.replace('Bearer ', '') : null\n }\n return getStorage<string>(StorageKey.ACCESS_TOKEN)\n }\n\n public set accessToken(accessToken: string | null) {\n if (isServer) {\n this.#lumi.config.authorization = accessToken ? `Bearer ${accessToken}` : undefined\n return\n }\n setStorage(StorageKey.ACCESS_TOKEN, accessToken)\n }\n\n #user: User | null = null\n\n /** 用户 */\n public get user(): User | null {\n if (isServer)\n return this.#user\n return getStorage<User>(StorageKey.USER)\n }\n\n public set user(user: User | null) {\n if (isServer) {\n this.#user = user\n return\n }\n setStorage(StorageKey.USER, user)\n }\n\n public get isAuthenticated(): boolean {\n return !!this.accessToken\n }\n\n /** 登录 */\n public signIn(): Promise<MessageSignInData> {\n if (isServer)\n throw new Error('auth.signIn() can only be called on the client side')\n\n const width = 800\n const height = 600\n const left = (window.screen.width - width) / 2\n const top = (window.screen.height - height) / 2\n const popup = window.open(this.#lumi.config.authOrigin, this.#popupName, `width=${width},height=${height},left=${left},top=${top}`)\n\n let cleanup: () => void\n return new Promise<MessageSignInData>((resolve, reject) => {\n if (!popup)\n return reject(new Error('Open auth window failed'))\n\n const timer = setInterval(() => {\n if (popup.closed)\n reject(new Error('Auth window closed'))\n }, 1000)\n\n // 全局点击事件处理函数 - 重新聚焦popup并阻止事件传播\n const handleGlobalClick = (event: MouseEvent): void => {\n if (!popup.closed) {\n popup.focus()\n event.stopPropagation()\n event.preventDefault()\n }\n }\n\n const handleMessage = ({ data, origin, source }: MessageEvent<MessageDataReceive | null>): void => {\n if (origin !== this.#lumi.config.authOrigin || source !== popup)\n return\n\n switch (data?.type) {\n case MessageType.READY: {\n popup.postMessage({\n type: MessageType.INIT,\n data: {\n projectId: this.#lumi.config.projectId,\n icon: getIcon(),\n title: getTitle(),\n },\n } satisfies MessageDataSend, this.#lumi.config.authOrigin)\n break\n }\n case MessageType.SIGN_IN: {\n if (data.data.projectId !== this.#lumi.config.projectId)\n break\n popup.close()\n window.focus()\n this.accessToken = data.data.accessToken\n this.user = data.data.user\n resolve(data.data)\n break\n }\n }\n }\n\n window.addEventListener('message', handleMessage)\n // 添加全局点击事件监听器,使用捕获阶段确保优先处理\n document.addEventListener('click', handleGlobalClick, true)\n\n cleanup = () => {\n clearInterval(timer)\n window.removeEventListener('message', handleMessage)\n document.removeEventListener('click', handleGlobalClick, true)\n }\n }).finally(() => cleanup?.())\n }\n\n /** 退出登录 */\n public signOut(): void {\n if (isServer)\n throw new Error('auth.signOut() can only be called on the client side')\n\n this.accessToken = null\n this.user = null\n }\n\n /** 获取当前用户 */\n public async refreshUser(): Promise<User> {\n const res = await request<ApiResponse<User>>(this.#lumi, '/lm/user/info', {\n method: 'POST',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n this.user = res.data\n return res.data\n }\n\n /** 监听登录状态变化 */\n public onAuthChange(callback: (args: {\n isAuthenticated: boolean\n user: User | null\n }) => void): () => void {\n if (isServer)\n throw new Error('auth.onAuthChange() can only be called on the client side')\n\n const handleStorageChange = (event: StorageEvent): void => {\n if (event.key === StorageKey.ACCESS_TOKEN || event.key === StorageKey.USER || event.key === null) {\n callback({\n isAuthenticated: this.isAuthenticated,\n user: this.user,\n })\n }\n }\n\n window.addEventListener('storage', handleStorageChange)\n\n return () => {\n window.removeEventListener('storage', handleStorageChange)\n }\n }\n}\n","import type { FetchContext, FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport Base64 from 'crypto-js/enc-base64'\nimport Hex from 'crypto-js/enc-hex'\nimport HmacSHA256 from 'crypto-js/hmac-sha256'\nimport SHA256 from 'crypto-js/sha256'\nimport hash from 'object-hash'\nimport { ofetch } from 'ofetch'\nimport { LumiError } from '@/lib/error'\nimport { isServer } from '@/utils/common'\n\nconst SECRET_KEY = '6QrJZ7pFCmBZAeIJF7IArvkCz+EtzA0RVcpHkiQIsQyhs7QtCS9P+CueZdHfB2OtJcgX3BbqY9pfpWeAVTqCwQ=='\n\n/** RFC 3986 compliant URI encoding */\nfunction rfc3986Encode(str: string): string {\n return encodeURIComponent(str).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n}\n\n/** 创建签名拦截器函数 */\nexport function createSignatureInterceptor(secretKey: string) {\n return (context: FetchContext) => {\n const { options } = context\n // 生成签名\n const timestamp = Math.floor(Date.now() / 1000).toString()\n const nonce = Math.random().toString(36).substring(2, 15)\n\n // 构建查询字符串\n const queryParams: Record<string, string> = { ...options.query }\n const canonicalQueryString = Object.keys(queryParams).sort().map(key => `${rfc3986Encode(key)}=${rfc3986Encode(String(queryParams[key]))}`).join('&')\n\n // 构建签名头\n const headersToSign: Record<string, string> = {\n 'x-timestamp': timestamp,\n 'x-nonce': nonce,\n }\n const canonicalHeaders = Object.keys(headersToSign).sort().map(key => `${key}:${headersToSign[key]}`).join('\\n')\n\n // 构建载荷哈希\n const payload = (options.body && !(options.body instanceof FormData)) ? JSON.stringify(options.body) : ''\n const hashedPayload = SHA256(payload).toString(Hex)\n\n // 构建规范请求\n const canonicalRequest = [canonicalQueryString, canonicalHeaders, hashedPayload].join('\\n')\n\n // 生成签名\n const signature = Base64.stringify(HmacSHA256(canonicalRequest, secretKey))\n\n // 添加签名头到请求\n const headers = new Headers(options.headers)\n Object.entries(headersToSign).forEach(([key, value]) => {\n headers.set(key, value)\n })\n headers.set('X-Sign', signature)\n options.headers = headers\n }\n}\n\nexport interface ApiResponse<T> {\n code: number\n message: string\n data: T\n}\n\nexport interface PaginationData<T> {\n total: number\n list: T[]\n}\n\nconst requestMap = new Map<string, number[]>()\n\n/** 限制请求频率,相同参数的请求每秒只能发送4次 */\nexport function checkRateLimit(uri: string, options: FetchOptions<'json'>): void {\n if (options.body instanceof FormData) {\n options = {\n ...options,\n body: Array.from(options.body.entries()),\n }\n }\n const requestHash = hash([uri, options])\n const now = Date.now()\n const requestQueue = requestMap.get(requestHash)?.filter(time => now - time < 1000) || []\n if (requestQueue.length >= 4)\n throw new LumiError(429, 'Too many requests')\n requestQueue.push(now)\n requestMap.set(requestHash, requestQueue)\n}\n\nexport function request<T>(lumi: LumiClient, uri: string, options: FetchOptions<'json'> = {}): Promise<T> {\n // 添加认证头(如果存在)\n if (lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n // 限制请求频率\n checkRateLimit(uri, options)\n\n const isAuthenticated = lumi.auth.isAuthenticated\n\n return ofetch<T>(uri, {\n baseURL: lumi.config.apiBaseUrl,\n ...options,\n onRequest: createSignatureInterceptor(SECRET_KEY),\n onResponse: ({ response }) => {\n // 若 Token 失效则退出登录\n if (!isServer && isAuthenticated && (response._data as ApiResponse<any>)?.code === 2100)\n lumi.auth.signOut()\n },\n })\n}\n","export class LumiError extends Error {\n name: string = 'LumiError'\n code: number\n\n constructor(code: number, message: string) {\n super(message)\n this.code = code\n }\n}\n","export function getIcon(): string | null {\n return document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]')?.href ?? null\n}\n\nexport function getTitle(): string | null {\n return document.title ?? null\n}\n\nexport const isServer = typeof window === 'undefined'\n","import type { StorageKey } from '@/constants'\n\nexport function setStorage<T>(key: StorageKey, value: T, storage: Storage = localStorage): void {\n const oldValue = storage.getItem(key)\n const newValue = value ? JSON.stringify(value) : null\n if (newValue)\n storage.setItem(key, newValue)\n else\n storage.removeItem(key)\n\n window.dispatchEvent(new StorageEvent('storage', {\n key,\n oldValue,\n newValue,\n storageArea: storage,\n }))\n}\n\nexport function getStorage<T>(key: StorageKey, storage: Storage = localStorage): T | null {\n const value = storage.getItem(key)\n try {\n return value ? JSON.parse(value) : null\n }\n catch (_e) {\n return null\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse, PaginationData } from '@/lib/request'\nimport { request } from '@/lib/request'\n\nexport interface Entity extends Record<string, any> {\n id: string\n}\n\nexport class EntityClient {\n readonly #lumi: LumiClient\n public readonly entityName: string\n\n constructor(lumi: LumiClient, entityName: string) {\n this.#lumi = lumi\n this.entityName = entityName\n }\n\n /** 查询文档列表 */\n public async list({ filter, sort, limit, skip }: {\n filter?: any\n sort?: Record<string, 1 | -1>\n limit?: number\n skip?: number\n } = {}): Promise<PaginationData<Entity>> {\n if (!limit) {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/list'), {\n method: 'POST',\n body: { filter, sort },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return {\n total: res.data.length,\n list: res.data,\n }\n }\n else {\n const res = await request<ApiResponse<PaginationData<Entity>>>(this.#lumi, this.uri('/find'), {\n method: 'POST',\n body: { filter, sort, limit, skip },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n }\n\n /** 获取单个文档 */\n public async get(id: string): Promise<Entity | null> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(`/${id}`), {\n method: 'GET',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 创建文档 */\n public async create(data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 批量创建文档 */\n public async createMany(data: Record<string, any>[]): Promise<Entity[]> {\n const res = await request<ApiResponse<Entity[]>>(this.#lumi, this.uri('/batch'), {\n method: 'POST',\n body: data,\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 更新文档 */\n public async update(id: string, data: Record<string, any>): Promise<Entity> {\n const res = await request<ApiResponse<Entity>>(this.#lumi, this.uri(), {\n method: 'PUT',\n body: { filter: { _id: id }, update: data },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n return res.data\n }\n\n /** 删除文档 */\n public async delete(id: string): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri(`/${id}`), {\n method: 'DELETE',\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n /** 批量删除文档 */\n public async deleteMany(ids: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, this.uri('/batch-by-ids'), {\n method: 'DELETE',\n params: { ids },\n })\n if (res.code !== 200)\n throw new Error(res.message)\n }\n\n private uri(suffix = ''): string {\n return `/lm/${this.#lumi.config.projectId}/${this.entityName}/documents${suffix}`\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EntityClient } from '@/core/entity-client'\n\nexport class EntitiesClient {\n readonly #lumi: LumiClient\n [key: string]: EntityClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n return new Proxy(this, {\n get(target: EntitiesClient, p: string) {\n if (!(p in target))\n target[p] = new EntityClient(target.#lumi, p)\n return target[p]\n },\n }) as this\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { LumiClient } from '@/core/lumi-client'\nimport { ofetch } from 'ofetch'\nimport { checkRateLimit } from '@/lib/request'\n\nexport class FunctionsClient {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n public invoke(uri: string, options: FetchOptions<'json'> = {}): Promise<any> {\n if (this.#lumi.auth.accessToken) {\n options.headers = {\n Authorization: `Bearer ${this.#lumi.auth.accessToken}`,\n ...options.headers,\n }\n }\n\n checkRateLimit(uri, options)\n\n return ofetch(uri, {\n ...options,\n })\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport class EmailTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 发送邮件 */\n public async send({ to, subject, fromName, html, text = '', replyTo, scheduledAt }: {\n to: string | string[]\n subject: string\n fromName?: string\n html?: string\n text?: string\n replyTo?: string | string[]\n scheduledAt?: string\n }): Promise<void> {\n if (!to || !subject || (!html && !text))\n throw new Error('Failed to send email: Missing required parameters.')\n\n if (typeof to === 'string')\n to = [to]\n if (typeof replyTo === 'string')\n replyTo = [replyTo]\n\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/email/send`, {\n method: 'POST',\n body: { to, subject, fromName, html, text, replyTo, scheduledAt },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport type { ApiResponse } from '@/lib/request'\nimport { LumiError } from '@/lib/error'\nimport { request } from '@/lib/request'\n\nexport interface UploadItem {\n fileName: string\n fileUrl?: string\n uploadError?: string\n}\n\nexport class FileTool {\n readonly #lumi: LumiClient\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n }\n\n /** 上传文件 */\n public async upload(files: File[]): Promise<UploadItem[]> {\n const formData = new FormData()\n files.forEach((file) => {\n formData.append('files', file)\n })\n\n const res = await request<ApiResponse<UploadItem[]>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'POST',\n body: formData,\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n\n return res.data\n }\n\n /** 批量删除文件 */\n public async delete(fileUrls: string[]): Promise<void> {\n const res = await request<ApiResponse<null>>(this.#lumi, `/lm/${this.#lumi.config.projectId}/file/batch`, {\n method: 'DELETE',\n body: { fileUrls },\n })\n\n if (res.code !== 200)\n throw new LumiError(res.code, res.message)\n }\n}\n","import type { LumiClient } from '@/core/lumi-client'\nimport { EmailTool, FileTool } from '@/tools'\n\nexport class ToolsClient {\n readonly #lumi: LumiClient\n\n public email: EmailTool\n public file: FileTool\n\n constructor(lumi: LumiClient) {\n this.#lumi = lumi\n this.email = new EmailTool(lumi)\n this.file = new FileTool(lumi)\n }\n}\n","import { LumiAuthClient } from '@/core/auth-client'\nimport { EntitiesClient } from '@/core/entities-client'\nimport { FunctionsClient } from '@/core/functions-client'\nimport { ToolsClient } from '@/core/tools-client'\n\nexport interface LumiClientConfig {\n projectId: string\n apiBaseUrl: string\n authOrigin: string\n authorization?: string\n}\n\nexport class LumiClient {\n public config: LumiClientConfig\n\n public auth: LumiAuthClient\n public entities: EntitiesClient\n public tools: ToolsClient\n public functions: FunctionsClient\n\n constructor(config: LumiClientConfig) {\n this.config = config\n this.auth = new LumiAuthClient(this)\n this.entities = new EntitiesClient(this)\n this.tools = new ToolsClient(this)\n this.functions = new FunctionsClient(this)\n }\n}\n\nexport function createClient(config: LumiClientConfig): LumiClient {\n return new LumiClient(config)\n}\n"],"mappings":"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","names":["v4","Base64","Hex","HmacSHA256","SHA256","hash","ofetch","LumiError","code","message","getIcon","_a","_b","getTitle","isServer","SECRET_KEY","rfc3986Encode","str","c","createSignatureInterceptor","secretKey","context","options","timestamp","nonce","queryParams","__spreadValues","canonicalQueryString","key","headersToSign","canonicalHeaders","payload","hashedPayload","SHA256","Hex","canonicalRequest","signature","Base64","HmacSHA256","headers","value","requestMap","checkRateLimit","uri","_a","__spreadProps","requestHash","hash","now","requestQueue","time","LumiError","request","lumi","isAuthenticated","ofetch","response","isServer","setStorage","key","value","storage","oldValue","newValue","getStorage","_e","_lumi","_popupName","_user","LumiAuthClient","lumi","__privateAdd","v4","__privateSet","isServer","authorization","__privateGet","getStorage","accessToken","setStorage","user","width","height","left","top","popup","cleanup","resolve","reject","timer","handleGlobalClick","event","handleMessage","data","origin","source","getIcon","getTitle","__async","res","request","callback","handleStorageChange","_lumi","EntityClient","lumi","entityName","__privateAdd","__privateSet","__async","filter","sort","limit","skip","res","request","__privateGet","id","data","ids","suffix","_lumi","EntitiesClient","lumi","__privateAdd","__privateSet","target","p","EntityClient","__privateGet","ofetch","_lumi","FunctionsClient","lumi","__privateAdd","__privateSet","uri","options","__privateGet","__spreadValues","checkRateLimit","ofetch","_lumi","EmailTool","lumi","__privateAdd","__privateSet","_0","__async","to","subject","fromName","html","text","replyTo","scheduledAt","res","request","__privateGet","LumiError","_lumi","FileTool","lumi","__privateAdd","__privateSet","files","__async","formData","file","res","request","__privateGet","LumiError","fileUrls","_lumi","ToolsClient","lumi","__privateAdd","__privateSet","EmailTool","FileTool","LumiClient","config","LumiAuthClient","EntitiesClient","ToolsClient","FunctionsClient","createClient"]}
|