deesse 0.2.7 → 0.2.9
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/dist/cache.d.ts +16 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +59 -0
- package/dist/cache.js.map +1 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +24 -0
- package/dist/client.js.map +1 -0
- package/dist/config/define.d.ts +16 -1
- package/dist/config/define.d.ts.map +1 -1
- package/dist/config/define.js +10 -1
- package/dist/config/define.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/page.d.ts +2 -0
- package/dist/config/page.d.ts.map +1 -1
- package/dist/config/page.js +1 -0
- package/dist/config/page.js.map +1 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/admin.d.ts +24 -0
- package/dist/lib/admin.d.ts.map +1 -0
- package/dist/lib/admin.js +50 -0
- package/dist/lib/admin.js.map +1 -0
- package/dist/lib/validation.d.ts +32 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +80 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +17 -0
- package/dist/server.js.map +1 -0
- package/package.json +3 -1
- package/src/cache.ts +81 -0
- package/src/client.ts +39 -0
- package/src/config/define.ts +28 -2
- package/src/config/index.ts +1 -1
- package/src/config/page.ts +3 -0
- package/src/index.ts +137 -1
- package/src/lib/admin.ts +68 -0
- package/src/lib/validation.ts +89 -0
- package/src/server.ts +31 -0
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-type-check.log +0 -4
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CacheState<T> = {
|
|
2
|
+
instances: Map<string, T>;
|
|
3
|
+
promises: Map<string, Promise<T>>;
|
|
4
|
+
};
|
|
5
|
+
export declare const emptyCache: <T>() => CacheState<T>;
|
|
6
|
+
export declare const setCacheInstance: <T>(state: CacheState<T>, key: string, instance: T) => CacheState<T>;
|
|
7
|
+
export declare const setCachePromise: <T>(state: CacheState<T>, key: string, promise: Promise<T>) => CacheState<T>;
|
|
8
|
+
export declare const getCacheEntry: <T>(state: CacheState<T>, key: string) => T | Promise<T> | undefined;
|
|
9
|
+
export declare const removeCachePromise: <T>(state: CacheState<T>, key: string) => CacheState<T>;
|
|
10
|
+
export type CreateCache = <T, Options>(createInstance: (options: Options) => Promise<T>) => {
|
|
11
|
+
get(key: string, options: Options): Promise<T>;
|
|
12
|
+
getState(): Readonly<CacheState<T>>;
|
|
13
|
+
clear(): void;
|
|
14
|
+
};
|
|
15
|
+
export declare const createCache: CreateCache;
|
|
16
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,CAAC,OAAK,UAAU,CAAC,CAAC,CAG3C,CAAC;AAEH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,UAAU,CAAC,KAAG,UAAU,CAAC,CAAC,CAO/F,CAAC;AAEH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC,KAAG,UAAU,CAAC,CAAC,CAGtG,CAAC;AAEH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,KAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAIrF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,KAAG,UAAU,CAAC,CAAC,CAOpF,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,EAAE,OAAO,EACnC,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,KAC7C;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/C,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,WA+BzB,CAAC"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Generic cache utility with immutable state
|
|
2
|
+
export const emptyCache = () => ({
|
|
3
|
+
instances: new Map(),
|
|
4
|
+
promises: new Map(),
|
|
5
|
+
});
|
|
6
|
+
export const setCacheInstance = (state, key, instance) => ({
|
|
7
|
+
instances: new Map(state.instances).set(key, instance),
|
|
8
|
+
promises: (() => {
|
|
9
|
+
const m = new Map(state.promises);
|
|
10
|
+
m.delete(key);
|
|
11
|
+
return m;
|
|
12
|
+
})(),
|
|
13
|
+
});
|
|
14
|
+
export const setCachePromise = (state, key, promise) => ({
|
|
15
|
+
instances: state.instances,
|
|
16
|
+
promises: new Map(state.promises).set(key, promise),
|
|
17
|
+
});
|
|
18
|
+
export const getCacheEntry = (state, key) => {
|
|
19
|
+
const instance = state.instances.get(key);
|
|
20
|
+
if (instance !== undefined)
|
|
21
|
+
return instance;
|
|
22
|
+
return state.promises.get(key);
|
|
23
|
+
};
|
|
24
|
+
export const removeCachePromise = (state, key) => ({
|
|
25
|
+
instances: state.instances,
|
|
26
|
+
promises: (() => {
|
|
27
|
+
const m = new Map(state.promises);
|
|
28
|
+
m.delete(key);
|
|
29
|
+
return m;
|
|
30
|
+
})(),
|
|
31
|
+
});
|
|
32
|
+
export const createCache = (createInstance) => {
|
|
33
|
+
let state = emptyCache();
|
|
34
|
+
return {
|
|
35
|
+
async get(key, options) {
|
|
36
|
+
const cached = getCacheEntry(state, key);
|
|
37
|
+
if (cached !== undefined)
|
|
38
|
+
return cached;
|
|
39
|
+
const promise = createInstance(options);
|
|
40
|
+
state = setCachePromise(state, key, promise);
|
|
41
|
+
try {
|
|
42
|
+
const instance = await promise;
|
|
43
|
+
state = setCacheInstance(state, key, instance);
|
|
44
|
+
return instance;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
state = removeCachePromise(state, key);
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
getState() {
|
|
52
|
+
return state;
|
|
53
|
+
},
|
|
54
|
+
clear() {
|
|
55
|
+
state = emptyCache();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAO7C,MAAM,CAAC,MAAM,UAAU,GAAG,GAAqB,EAAE,CAAC,CAAC;IACjD,SAAS,EAAE,IAAI,GAAG,EAAE;IACpB,QAAQ,EAAE,IAAI,GAAG,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAI,KAAoB,EAAE,GAAW,EAAE,QAAW,EAAiB,EAAE,CAAC,CAAC;IACrG,SAAS,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC;IACtD,QAAQ,EAAE,CAAC,GAAG,EAAE;QACd,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,EAAE;CACL,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,KAAoB,EAAE,GAAW,EAAE,OAAmB,EAAiB,EAAE,CAAC,CAAC;IAC5G,SAAS,EAAE,KAAK,CAAC,SAAS;IAC1B,QAAQ,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;CACpD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAI,KAAoB,EAAE,GAAW,EAA8B,EAAE;IAChG,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAI,KAAoB,EAAE,GAAW,EAAiB,EAAE,CAAC,CAAC;IAC1F,SAAS,EAAE,KAAK,CAAC,SAAS;IAC1B,QAAQ,EAAE,CAAC,GAAG,EAAE;QACd,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,EAAE;CACL,CAAC,CAAC;AAUH,MAAM,CAAC,MAAM,WAAW,GAAgB,CACtC,cAAgD,EAChD,EAAE;IACF,IAAI,KAAK,GAAkB,UAAU,EAAK,CAAC;IAE3C,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,OAAgB;YACrC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAW,CAAC;YAE7C,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;YACxC,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAE7C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;gBAC/B,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC/C,OAAO,QAAQ,CAAC;YAClB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACvC,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,QAAQ;YACN,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK;YACH,KAAK,GAAG,UAAU,EAAK,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AuthClient, BetterAuthClientOptions } from "better-auth/client";
|
|
2
|
+
export interface DeesseClientOptions {
|
|
3
|
+
auth: BetterAuthClientOptions;
|
|
4
|
+
}
|
|
5
|
+
export interface DeesseClient {
|
|
6
|
+
auth: AuthClient<BetterAuthClientOptions>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a type-safe authentication client.
|
|
10
|
+
* Wraps better-auth's createAuthClient with a simpler API.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { createClient } from "deesse";
|
|
15
|
+
*
|
|
16
|
+
* export const client = createClient({
|
|
17
|
+
* auth: {
|
|
18
|
+
* baseURL: "/api/auth",
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // In a component:
|
|
23
|
+
* const { data, isPending } = client.auth.useSession();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function createClient(options: DeesseClientOptions): DeesseClient;
|
|
27
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,uBAAuB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC,uBAAuB,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,mBAAmB,GAC3B,YAAY,CAId"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createAuthClient } from "better-auth/react";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a type-safe authentication client.
|
|
4
|
+
* Wraps better-auth's createAuthClient with a simpler API.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createClient } from "deesse";
|
|
9
|
+
*
|
|
10
|
+
* export const client = createClient({
|
|
11
|
+
* auth: {
|
|
12
|
+
* baseURL: "/api/auth",
|
|
13
|
+
* },
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // In a component:
|
|
17
|
+
* const { data, isPending } = client.auth.useSession();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function createClient(options) {
|
|
21
|
+
const auth = createAuthClient(options.auth);
|
|
22
|
+
return { auth };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAcrD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA4B;IAE5B,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAmD,CAAC;IAE9F,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC"}
|
package/dist/config/define.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
|
2
|
+
import type { BetterAuthPlugin } from 'better-auth';
|
|
2
3
|
import type { Plugin } from './plugin';
|
|
3
4
|
import type { PageTree } from './page';
|
|
4
5
|
export type Config = {
|
|
6
|
+
name?: string;
|
|
5
7
|
database: PostgresJsDatabase;
|
|
6
8
|
plugins?: Plugin[];
|
|
7
9
|
pages?: PageTree[];
|
|
10
|
+
secret: string;
|
|
11
|
+
auth: {
|
|
12
|
+
baseURL: string;
|
|
13
|
+
};
|
|
8
14
|
};
|
|
9
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Internal config type used at runtime - includes admin plugin
|
|
17
|
+
*/
|
|
18
|
+
export type InternalConfig = Config & {
|
|
19
|
+
auth: {
|
|
20
|
+
baseURL: string;
|
|
21
|
+
plugins: BetterAuthPlugin[];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export declare function defineConfig(config: Config): InternalConfig;
|
|
10
25
|
//# sourceMappingURL=define.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/config/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/config/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGvC,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IACpC,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,gBAAgB,EAAE,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAW3D"}
|
package/dist/config/define.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import { admin } from 'better-auth/plugins';
|
|
1
2
|
export function defineConfig(config) {
|
|
2
|
-
|
|
3
|
+
// Always include admin plugin - user cannot remove it
|
|
4
|
+
const authPlugins = [admin()];
|
|
5
|
+
return {
|
|
6
|
+
...config,
|
|
7
|
+
auth: {
|
|
8
|
+
...config.auth,
|
|
9
|
+
plugins: authPlugins,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
3
12
|
}
|
|
4
13
|
//# sourceMappingURL=define.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/config/define.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/config/define.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAuB5C,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,sDAAsD;IACtD,MAAM,WAAW,GAAuB,CAAC,KAAK,EAAE,CAAC,CAAC;IAElD,OAAO;QACL,GAAG,MAAM;QACT,IAAI,EAAE;YACJ,GAAG,MAAM,CAAC,IAAI;YACd,OAAO,EAAE,WAAW;SACrB;KACgB,CAAC;AACtB,CAAC"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACvC,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/config/page.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type Section = {
|
|
|
11
11
|
type: "section";
|
|
12
12
|
name: string;
|
|
13
13
|
slug: string;
|
|
14
|
+
bottom?: boolean;
|
|
14
15
|
children: PageTree[];
|
|
15
16
|
};
|
|
16
17
|
export type PageTree = Page | Section;
|
|
@@ -23,6 +24,7 @@ export declare function page(config: {
|
|
|
23
24
|
export declare function section(config: {
|
|
24
25
|
name: string;
|
|
25
26
|
slug?: string;
|
|
27
|
+
bottom?: boolean;
|
|
26
28
|
children: PageTree[];
|
|
27
29
|
}): Section;
|
|
28
30
|
//# sourceMappingURL=page.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/config/page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC;AAMtC,wBAAgB,IAAI,CAAC,MAAM,EAAE;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;CAC3B,GAAG,IAAI,CAQP;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/config/page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC;AAMtC,wBAAgB,IAAI,CAAC,MAAM,EAAE;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;CAC3B,GAAG,IAAI,CAQP;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB,GAAG,OAAO,CAQV"}
|
package/dist/config/page.js
CHANGED
package/dist/config/page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/config/page.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/config/page.ts"],"names":[],"mappings":"AAqBA,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,MAKpB;IACC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACxC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAKvB;IACC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
+
import type { InternalConfig } from "./config/define";
|
|
2
|
+
import { type Deesse } from "./server";
|
|
1
3
|
export { defineConfig } from "./config";
|
|
2
|
-
export type { Config } from "./config";
|
|
4
|
+
export type { Config, InternalConfig } from "./config";
|
|
3
5
|
export { plugin } from "./config";
|
|
4
6
|
export type { Plugin } from "./config";
|
|
5
7
|
export { page, section } from "./config";
|
|
6
8
|
export type { Page, Section, PageTree } from "./config";
|
|
7
9
|
export { z } from "zod";
|
|
8
10
|
export type { ZodSchema } from "zod";
|
|
11
|
+
export type { Deesse } from "./server";
|
|
12
|
+
export { createClient } from "./client";
|
|
13
|
+
export type { DeesseClient, DeesseClientOptions } from "./client";
|
|
14
|
+
export { isDatabaseEmpty, requireDatabaseNotEmpty, validateAdminEmail } from "./lib/admin";
|
|
15
|
+
export type { EmailValidationOptions } from "./lib/admin";
|
|
16
|
+
export { isPublicEmailDomain, isAllowedAdminEmail, getAllowedDomains, validateAdminEmailDomain, PUBLIC_EMAIL_DOMAINS } from "./lib/validation";
|
|
17
|
+
/**
|
|
18
|
+
* Get the Deesse singleton instance.
|
|
19
|
+
* Cached on global to persist across HMR.
|
|
20
|
+
*/
|
|
21
|
+
export declare const getDeesse: (config: InternalConfig) => Promise<Deesse>;
|
|
22
|
+
/**
|
|
23
|
+
* Clear the Deesse singleton cache.
|
|
24
|
+
* Primarily useful for testing.
|
|
25
|
+
*/
|
|
26
|
+
export declare const clearDeesseCache: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Graceful shutdown - call this on process exit.
|
|
29
|
+
* Ensures all database connections are properly closed.
|
|
30
|
+
*/
|
|
31
|
+
export declare const shutdownDeesse: () => Promise<void>;
|
|
9
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAExD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,YAAY,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAErC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC3F,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AA+C/I;;;GAGG;AACH,eAAO,MAAM,SAAS,GACpB,QAAQ,cAAc,KACrB,OAAO,CAAC,MAAM,CA4BhB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,IAKnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,IAAI,CAcnD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,110 @@
|
|
|
1
1
|
// @deessejs/deesse core package
|
|
2
|
+
import { createDeesse } from "./server";
|
|
2
3
|
export { defineConfig } from "./config";
|
|
3
4
|
export { plugin } from "./config";
|
|
4
5
|
export { page, section } from "./config";
|
|
5
6
|
export { z } from "zod";
|
|
7
|
+
export { createClient } from "./client";
|
|
8
|
+
export { isDatabaseEmpty, requireDatabaseNotEmpty, validateAdminEmail } from "./lib/admin";
|
|
9
|
+
export { isPublicEmailDomain, isAllowedAdminEmail, getAllowedDomains, validateAdminEmailDomain, PUBLIC_EMAIL_DOMAINS } from "./lib/validation";
|
|
10
|
+
/**
|
|
11
|
+
* Symbol-based global storage for Deesse instance.
|
|
12
|
+
* Using Symbol.for ensures uniqueness across the process.
|
|
13
|
+
*/
|
|
14
|
+
const DEESSE_GLOBAL_KEY = Symbol.for("@deessejs/core.instance");
|
|
15
|
+
function getGlobalCache() {
|
|
16
|
+
const g = global;
|
|
17
|
+
if (!g[DEESSE_GLOBAL_KEY]) {
|
|
18
|
+
g[DEESSE_GLOBAL_KEY] = {
|
|
19
|
+
instance: undefined,
|
|
20
|
+
config: undefined,
|
|
21
|
+
pool: undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return g[DEESSE_GLOBAL_KEY];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deep equality check for config comparison.
|
|
28
|
+
* Required because config objects are recreated on HMR.
|
|
29
|
+
*/
|
|
30
|
+
function isConfigEqual(a, b) {
|
|
31
|
+
if (a.secret !== b.secret)
|
|
32
|
+
return false;
|
|
33
|
+
if (a.name !== b.name)
|
|
34
|
+
return false;
|
|
35
|
+
if (a.auth.baseURL !== b.auth.baseURL)
|
|
36
|
+
return false;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extract pool reference from database.
|
|
41
|
+
* For pg Pool passed to drizzle-orm/node-postgres, the pool is stored in $client.
|
|
42
|
+
*/
|
|
43
|
+
function extractPool(db) {
|
|
44
|
+
return db.$client;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the Deesse singleton instance.
|
|
48
|
+
* Cached on global to persist across HMR.
|
|
49
|
+
*/
|
|
50
|
+
export const getDeesse = async (config) => {
|
|
51
|
+
const cache = getGlobalCache();
|
|
52
|
+
// Case 1: Instance exists and config is semantically equal
|
|
53
|
+
if (cache.instance && cache.config && isConfigEqual(cache.config, config)) {
|
|
54
|
+
return cache.instance;
|
|
55
|
+
}
|
|
56
|
+
// Case 2: Instance exists but config changed - hot reload
|
|
57
|
+
// IMPORTANT: Don't close the pool! cache.instance still uses the old pool.
|
|
58
|
+
// The new config's pool will be garbage collected when the HMR module reference is dropped.
|
|
59
|
+
if (cache.instance &&
|
|
60
|
+
cache.config &&
|
|
61
|
+
!isConfigEqual(cache.config, config)) {
|
|
62
|
+
console.info("[deesse] Config changed, performing hot reload...");
|
|
63
|
+
cache.config = config;
|
|
64
|
+
return cache.instance;
|
|
65
|
+
}
|
|
66
|
+
// Case 3: No instance exists - create one
|
|
67
|
+
const instance = createDeesse(config);
|
|
68
|
+
cache.pool = extractPool(instance.database);
|
|
69
|
+
cache.instance = instance;
|
|
70
|
+
cache.config = config;
|
|
71
|
+
return instance;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Clear the Deesse singleton cache.
|
|
75
|
+
* Primarily useful for testing.
|
|
76
|
+
*/
|
|
77
|
+
export const clearDeesseCache = () => {
|
|
78
|
+
const cache = getGlobalCache();
|
|
79
|
+
cache.instance = undefined;
|
|
80
|
+
cache.config = undefined;
|
|
81
|
+
cache.pool = undefined;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Graceful shutdown - call this on process exit.
|
|
85
|
+
* Ensures all database connections are properly closed.
|
|
86
|
+
*/
|
|
87
|
+
export const shutdownDeesse = async () => {
|
|
88
|
+
const cache = getGlobalCache();
|
|
89
|
+
if (cache.pool) {
|
|
90
|
+
console.info("[deesse] Closing database pool...");
|
|
91
|
+
const pool = cache.pool;
|
|
92
|
+
if (pool && typeof pool.end === "function") {
|
|
93
|
+
await pool.end();
|
|
94
|
+
}
|
|
95
|
+
cache.pool = undefined;
|
|
96
|
+
}
|
|
97
|
+
cache.instance = undefined;
|
|
98
|
+
cache.config = undefined;
|
|
99
|
+
};
|
|
100
|
+
// Register graceful shutdown hooks
|
|
101
|
+
if (process.env["NODE_ENV"] !== "test") {
|
|
102
|
+
const shutdown = () => {
|
|
103
|
+
shutdownDeesse()
|
|
104
|
+
.catch(console.error)
|
|
105
|
+
.finally(() => process.exit(0));
|
|
106
|
+
};
|
|
107
|
+
process.on("SIGINT", shutdown);
|
|
108
|
+
process.on("SIGTERM", shutdown);
|
|
109
|
+
}
|
|
6
110
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Auth } from "better-auth";
|
|
2
|
+
/**
|
|
3
|
+
* Check if the database has any users.
|
|
4
|
+
* Returns true if the database is empty (no users).
|
|
5
|
+
*/
|
|
6
|
+
export declare function isDatabaseEmpty(auth: Auth): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Require that the database is NOT empty.
|
|
9
|
+
* Throws if no users exist.
|
|
10
|
+
*/
|
|
11
|
+
export declare function requireDatabaseNotEmpty(auth: Auth): Promise<void>;
|
|
12
|
+
export interface EmailValidationOptions {
|
|
13
|
+
allowedDomains?: string[];
|
|
14
|
+
blockedDomains?: string[];
|
|
15
|
+
requireOrganization?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validate an admin email against configured rules.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateAdminEmail(email: string, options?: EmailValidationOptions): {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
error?: string;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/lib/admin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,sBAA2B,GACnC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BpC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if the database has any users.
|
|
3
|
+
* Returns true if the database is empty (no users).
|
|
4
|
+
*/
|
|
5
|
+
export async function isDatabaseEmpty(auth) {
|
|
6
|
+
try {
|
|
7
|
+
const result = await auth.api.listUsers({ limit: 1 });
|
|
8
|
+
return !result?.users || result.users.length === 0;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// If listUsers fails, assume not empty (safer default)
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Require that the database is NOT empty.
|
|
17
|
+
* Throws if no users exist.
|
|
18
|
+
*/
|
|
19
|
+
export async function requireDatabaseNotEmpty(auth) {
|
|
20
|
+
if (await isDatabaseEmpty(auth)) {
|
|
21
|
+
throw new Error("Database is empty. Cannot proceed with this operation. " +
|
|
22
|
+
"Use the First Admin Setup page to create the initial admin account.");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validate an admin email against configured rules.
|
|
27
|
+
*/
|
|
28
|
+
export function validateAdminEmail(email, options = {}) {
|
|
29
|
+
const domain = email.split('@')[1]?.toLowerCase();
|
|
30
|
+
if (!domain) {
|
|
31
|
+
return { valid: false, error: "Invalid email format" };
|
|
32
|
+
}
|
|
33
|
+
// Check blocked domains
|
|
34
|
+
if (options.blockedDomains?.includes(domain)) {
|
|
35
|
+
return { valid: false, error: `Email domain ${domain} is blocked` };
|
|
36
|
+
}
|
|
37
|
+
// Check allowed domains (if specified)
|
|
38
|
+
if (options.allowedDomains?.length && !options.allowedDomains.includes(domain)) {
|
|
39
|
+
return { valid: false, error: `Email must be from: ${options.allowedDomains.join(', ')}` };
|
|
40
|
+
}
|
|
41
|
+
// Require organization (no public email domains)
|
|
42
|
+
if (options.requireOrganization) {
|
|
43
|
+
const PUBLIC_DOMAINS = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'icloud.com'];
|
|
44
|
+
if (PUBLIC_DOMAINS.includes(domain)) {
|
|
45
|
+
return { valid: false, error: "Personal email domains are not allowed. Use an organizational email." };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { valid: true };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/lib/admin.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAU;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,GAAW,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAU;IACtD,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,yDAAyD;YACzD,qEAAqE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAQD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,UAAkC,EAAE;IAEpC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAElD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IACzD,CAAC;IAED,wBAAwB;IACxB,IAAI,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,MAAM,aAAa,EAAE,CAAC;IACtE,CAAC;IAED,uCAAuC;IACvC,IAAI,OAAO,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC7F,CAAC;IAED,iDAAiD;IACjD,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;QAC9F,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,sEAAsE,EAAE,CAAC;QACzG,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email validation utilities for admin email enforcement
|
|
3
|
+
*/
|
|
4
|
+
export declare const PUBLIC_EMAIL_DOMAINS: readonly ["gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "icloud.com", "mail.com", "aol.com", "protonmail.com", "zoho.com", "yandex.com", "gmx.com"];
|
|
5
|
+
export type PublicEmailDomain = (typeof PUBLIC_EMAIL_DOMAINS)[number];
|
|
6
|
+
/**
|
|
7
|
+
* Check if an email uses a public email domain
|
|
8
|
+
*/
|
|
9
|
+
export declare function isPublicEmailDomain(email: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Get allowed domains from ADMIN_ALLOWED_DOMAINS environment variable.
|
|
12
|
+
* Returns empty array if not configured (no restrictions).
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAllowedDomains(): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Check if an email is from an allowed domain.
|
|
17
|
+
* If no allowed domains are configured, all domains are allowed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isAllowedAdminEmail(email: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Validate admin email against organizational requirements.
|
|
22
|
+
* Returns an error message if validation fails.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateAdminEmailDomain(email: string): {
|
|
25
|
+
valid: true;
|
|
26
|
+
} | {
|
|
27
|
+
valid: false;
|
|
28
|
+
code: string;
|
|
29
|
+
message: string;
|
|
30
|
+
suggestion?: string;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,oBAAoB,+JAYvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAO5C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK1D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CA8BxF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email validation utilities for admin email enforcement
|
|
3
|
+
*/
|
|
4
|
+
export const PUBLIC_EMAIL_DOMAINS = [
|
|
5
|
+
'gmail.com',
|
|
6
|
+
'yahoo.com',
|
|
7
|
+
'hotmail.com',
|
|
8
|
+
'outlook.com',
|
|
9
|
+
'icloud.com',
|
|
10
|
+
'mail.com',
|
|
11
|
+
'aol.com',
|
|
12
|
+
'protonmail.com',
|
|
13
|
+
'zoho.com',
|
|
14
|
+
'yandex.com',
|
|
15
|
+
'gmx.com',
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Check if an email uses a public email domain
|
|
19
|
+
*/
|
|
20
|
+
export function isPublicEmailDomain(email) {
|
|
21
|
+
const domain = email.split('@')[1]?.toLowerCase();
|
|
22
|
+
return PUBLIC_EMAIL_DOMAINS.includes(domain);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get allowed domains from ADMIN_ALLOWED_DOMAINS environment variable.
|
|
26
|
+
* Returns empty array if not configured (no restrictions).
|
|
27
|
+
*/
|
|
28
|
+
export function getAllowedDomains() {
|
|
29
|
+
const envValue = process.env['ADMIN_ALLOWED_DOMAINS'];
|
|
30
|
+
if (!envValue)
|
|
31
|
+
return [];
|
|
32
|
+
return envValue
|
|
33
|
+
.split(',')
|
|
34
|
+
.map((d) => d.trim().toLowerCase())
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if an email is from an allowed domain.
|
|
39
|
+
* If no allowed domains are configured, all domains are allowed.
|
|
40
|
+
*/
|
|
41
|
+
export function isAllowedAdminEmail(email) {
|
|
42
|
+
const allowed = getAllowedDomains();
|
|
43
|
+
if (!allowed.length)
|
|
44
|
+
return true; // No restriction configured
|
|
45
|
+
const domain = email.split('@')[1]?.toLowerCase();
|
|
46
|
+
return allowed.includes(domain);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate admin email against organizational requirements.
|
|
50
|
+
* Returns an error message if validation fails.
|
|
51
|
+
*/
|
|
52
|
+
export function validateAdminEmailDomain(email) {
|
|
53
|
+
// Check if email is from a public domain (warning level, not blocking)
|
|
54
|
+
const isPublic = isPublicEmailDomain(email);
|
|
55
|
+
const allowed = getAllowedDomains();
|
|
56
|
+
// If allowed domains are configured, enforce them strictly
|
|
57
|
+
if (allowed.length > 0) {
|
|
58
|
+
const domain = email.split('@')[1]?.toLowerCase();
|
|
59
|
+
if (!allowed.includes(domain)) {
|
|
60
|
+
return {
|
|
61
|
+
valid: false,
|
|
62
|
+
code: 'INVALID_EMAIL_DOMAIN',
|
|
63
|
+
message: `Admin email must be from an allowed domain. Allowed: ${allowed.join(', ')}`,
|
|
64
|
+
suggestion: 'Set ADMIN_ALLOWED_DOMAINS environment variable to configure allowed email domains',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// If email is from a public domain, return warning info (but allow through)
|
|
69
|
+
if (isPublic && allowed.length === 0) {
|
|
70
|
+
const domain = email.split('@')[1]?.toLowerCase();
|
|
71
|
+
return {
|
|
72
|
+
valid: false,
|
|
73
|
+
code: 'PUBLIC_EMAIL_DOMAIN',
|
|
74
|
+
message: `${email} is a public email domain. Admin accounts should use organizational email addresses.`,
|
|
75
|
+
suggestion: `Set ADMIN_ALLOWED_DOMAINS environment variable to restrict to organizational domains only (e.g., ADMIN_ALLOWED_DOMAINS=${domain})`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return { valid: true };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,WAAW;IACX,WAAW;IACX,aAAa;IACb,aAAa;IACb,YAAY;IACZ,UAAU;IACV,SAAS;IACT,gBAAgB;IAChB,UAAU;IACV,YAAY;IACZ,SAAS;CACD,CAAC;AAIX;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAClD,OAAO,oBAAoB,CAAC,QAAQ,CAAC,MAA2B,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,OAAO,QAAQ;SACZ,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClC,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,CAAC,4BAA4B;IAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAClD,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAa;IAEb,uEAAuE;IACvE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,2DAA2D;IAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QAClD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,wDAAwD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACrF,UAAU,EAAE,mFAAmF;aAChG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QAClD,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,GAAG,KAAK,sFAAsF;YACvG,UAAU,EAAE,0HAA0H,MAAM,GAAG;SAChJ,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import type { BetterAuthPlugin } from "better-auth";
|
|
3
|
+
import type { InternalConfig } from "./config/define";
|
|
4
|
+
import { betterAuth } from "better-auth";
|
|
5
|
+
import { drizzleAdapter } from "@better-auth/drizzle-adapter";
|
|
6
|
+
export type Deesse = {
|
|
7
|
+
auth: Awaited<ReturnType<typeof betterAuth<{
|
|
8
|
+
database: ReturnType<typeof drizzleAdapter>;
|
|
9
|
+
baseURL: string;
|
|
10
|
+
secret: string;
|
|
11
|
+
plugins: BetterAuthPlugin[];
|
|
12
|
+
}>>>;
|
|
13
|
+
database: PostgresJsDatabase;
|
|
14
|
+
};
|
|
15
|
+
export declare function createDeesse(config: InternalConfig): Deesse;
|
|
16
|
+
//# sourceMappingURL=server.d.ts.map
|