@opensaas/stack-auth 0.20.1 → 0.22.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +122 -0
- package/CLAUDE.md +115 -17
- package/INTEGRATION_SUMMARY.md +21 -20
- package/README.md +82 -48
- package/dist/config/adopt-better-auth-tables.d.ts +107 -0
- package/dist/config/adopt-better-auth-tables.d.ts.map +1 -0
- package/dist/config/adopt-better-auth-tables.js +70 -0
- package/dist/config/adopt-better-auth-tables.js.map +1 -0
- package/dist/config/derive-auth-lists.d.ts +50 -0
- package/dist/config/derive-auth-lists.d.ts.map +1 -0
- package/dist/config/derive-auth-lists.js +274 -0
- package/dist/config/derive-auth-lists.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +43 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/plugin.d.ts +1 -1
- package/dist/config/plugin.d.ts.map +1 -1
- package/dist/config/plugin.js +52 -9
- package/dist/config/plugin.js.map +1 -1
- package/dist/config/types.d.ts +130 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/lists/index.d.ts +17 -11
- package/dist/lists/index.d.ts.map +1 -1
- package/dist/lists/index.js +34 -208
- package/dist/lists/index.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +28 -7
- package/dist/server/index.js.map +1 -1
- package/dist/server/schema-converter.d.ts +1 -1
- package/dist/server/schema-converter.js +1 -1
- package/package.json +3 -3
- package/src/config/adopt-better-auth-tables.ts +146 -0
- package/src/config/derive-auth-lists.ts +323 -0
- package/src/config/index.ts +58 -0
- package/src/config/plugin.ts +67 -10
- package/src/config/types.ts +146 -3
- package/src/index.ts +13 -0
- package/src/lists/index.ts +42 -202
- package/src/server/index.ts +33 -10
- package/src/server/schema-converter.ts +1 -1
- package/tests/adopt-better-auth-tables.test.ts +183 -0
- package/tests/derive-auth-lists.test.ts +232 -0
- package/tests/plugin-derived-keys.test.ts +138 -0
- package/tests/plugin-schema-placement.test.ts +121 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Adopt existing better-auth tables" recipe.
|
|
3
|
+
*
|
|
4
|
+
* A migrating project usually already has a working, hand-wired better-auth
|
|
5
|
+
* installation: its tables are `AuthUser`/`AuthSession`/`AuthAccount`/
|
|
6
|
+
* `AuthVerification`, mapped into a separate `auth` Postgres schema, and its
|
|
7
|
+
* application `User` (`public.User`) is a *different* model. Reconstructing the
|
|
8
|
+
* matching {@link AuthConfig} by hand — four `modelName`s plus a `schema` on each
|
|
9
|
+
* model — is repetitive and easy to get wrong.
|
|
10
|
+
*
|
|
11
|
+
* {@link adoptBetterAuthTables} produces that {@link AuthConfig} fragment from a
|
|
12
|
+
* couple of options so the migrator doesn't rebuild it from scratch. It only
|
|
13
|
+
* sets the *adoption* knobs (per-model `modelName` + the plugin-level `schema`);
|
|
14
|
+
* the developer composes it with the rest of their auth config (providers,
|
|
15
|
+
* session fields, `extendUserList`, etc.):
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* authPlugin({
|
|
19
|
+
* ...adoptBetterAuthTables(),
|
|
20
|
+
* emailAndPassword: { enabled: true },
|
|
21
|
+
* sessionFields: ['userId', 'email', 'name'],
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Combined with the keys/field derivation (`deriveAuthLists`) and schema
|
|
26
|
+
* placement, the generated Auth lists reach **Schema parity** with the live
|
|
27
|
+
* tables — they are modelled for runtime/types without producing a destructive
|
|
28
|
+
* auth migration. The recipe never touches the application's own domain `User`:
|
|
29
|
+
* its model names are `Auth`-prefixed by default and the plugin only ever
|
|
30
|
+
* adds/extends its *derived* keys.
|
|
31
|
+
*/
|
|
32
|
+
import type { AuthConfig } from './types.js';
|
|
33
|
+
/**
|
|
34
|
+
* Options for {@link adoptBetterAuthTables}.
|
|
35
|
+
*
|
|
36
|
+
* All options are optional and default to the conventions of a standard
|
|
37
|
+
* separate-schema better-auth install (an `auth` Postgres schema with
|
|
38
|
+
* `Auth`-prefixed model names).
|
|
39
|
+
*/
|
|
40
|
+
export type AdoptBetterAuthTablesOptions = {
|
|
41
|
+
/**
|
|
42
|
+
* The Postgres schema the live better-auth tables live in.
|
|
43
|
+
*
|
|
44
|
+
* Applied as the plugin-level {@link AuthConfig.schema}, placing every Auth
|
|
45
|
+
* list in this schema via `@@schema(...)`. Pass `'public'` (or any single
|
|
46
|
+
* schema) for an install that is not on a separate schema; pass an explicit
|
|
47
|
+
* value to match your layout.
|
|
48
|
+
*
|
|
49
|
+
* @default 'auth'
|
|
50
|
+
*/
|
|
51
|
+
schema?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Prefix applied to each better-auth model name to derive the list key /
|
|
54
|
+
* table name (e.g. prefix `'Auth'` → `AuthUser`/`AuthSession`/...).
|
|
55
|
+
*
|
|
56
|
+
* A live better-auth install with `modelName: 'AuthUser'` etc. is the common
|
|
57
|
+
* case; override this if your tables use a different prefix. Set to `''` to
|
|
58
|
+
* keep the default better-auth names (`User`/`Session`/...) — but note that an
|
|
59
|
+
* unprefixed `User` will share the app's `User` key, so prefer a prefix when
|
|
60
|
+
* your domain `User` is a separate model (see {@link AuthConfig.user}).
|
|
61
|
+
*
|
|
62
|
+
* @default 'Auth'
|
|
63
|
+
*/
|
|
64
|
+
modelNamePrefix?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Per-model better-auth field → column maps, keyed by model.
|
|
67
|
+
*
|
|
68
|
+
* Only needed when your live tables renamed columns away from the better-auth
|
|
69
|
+
* defaults (e.g. `name → full_name`). Merged into the matching model config so
|
|
70
|
+
* the derived field-level `@map`s match your live columns.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* adoptBetterAuthTables({
|
|
75
|
+
* fields: {
|
|
76
|
+
* user: { name: 'full_name' },
|
|
77
|
+
* session: { userId: 'user_id' },
|
|
78
|
+
* },
|
|
79
|
+
* })
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
fields?: {
|
|
83
|
+
user?: Record<string, string>;
|
|
84
|
+
session?: Record<string, string>;
|
|
85
|
+
account?: Record<string, string>;
|
|
86
|
+
verification?: Record<string, string>;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The adoption-relevant slice of {@link AuthConfig}: the plugin-level `schema`
|
|
91
|
+
* and the per-model `modelName`/`fields`. Returned (not the full `AuthConfig`)
|
|
92
|
+
* so it spreads cleanly into the developer's own `authPlugin` config.
|
|
93
|
+
*/
|
|
94
|
+
export type AdoptBetterAuthTablesConfig = Pick<AuthConfig, 'schema' | 'user' | 'session' | 'account' | 'verification'>;
|
|
95
|
+
/**
|
|
96
|
+
* Build the adoption {@link AuthConfig} fragment for a pre-existing better-auth
|
|
97
|
+
* installation.
|
|
98
|
+
*
|
|
99
|
+
* Returns only the model/schema knobs needed to adopt the live tables; spread it
|
|
100
|
+
* into {@link authPlugin} alongside your own auth config.
|
|
101
|
+
*
|
|
102
|
+
* @param options - Adoption conventions (schema, model-name prefix, column maps)
|
|
103
|
+
* @returns An {@link AuthConfig} fragment with `schema` + per-model `modelName`
|
|
104
|
+
* (and any field column maps) set to match the live tables
|
|
105
|
+
*/
|
|
106
|
+
export declare function adoptBetterAuthTables(options?: AdoptBetterAuthTablesOptions): AdoptBetterAuthTablesConfig;
|
|
107
|
+
//# sourceMappingURL=adopt-better-auth-tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-better-auth-tables.d.ts","sourceRoot":"","sources":["../../src/config/adopt-better-auth-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAA;AAE7D;;;;;;GAMG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACtC,CAAA;CACF,CAAA;AAUD;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAC5C,UAAU,EACV,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,CAC3D,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,2BAA2B,CAqB7B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Adopt existing better-auth tables" recipe.
|
|
3
|
+
*
|
|
4
|
+
* A migrating project usually already has a working, hand-wired better-auth
|
|
5
|
+
* installation: its tables are `AuthUser`/`AuthSession`/`AuthAccount`/
|
|
6
|
+
* `AuthVerification`, mapped into a separate `auth` Postgres schema, and its
|
|
7
|
+
* application `User` (`public.User`) is a *different* model. Reconstructing the
|
|
8
|
+
* matching {@link AuthConfig} by hand — four `modelName`s plus a `schema` on each
|
|
9
|
+
* model — is repetitive and easy to get wrong.
|
|
10
|
+
*
|
|
11
|
+
* {@link adoptBetterAuthTables} produces that {@link AuthConfig} fragment from a
|
|
12
|
+
* couple of options so the migrator doesn't rebuild it from scratch. It only
|
|
13
|
+
* sets the *adoption* knobs (per-model `modelName` + the plugin-level `schema`);
|
|
14
|
+
* the developer composes it with the rest of their auth config (providers,
|
|
15
|
+
* session fields, `extendUserList`, etc.):
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* authPlugin({
|
|
19
|
+
* ...adoptBetterAuthTables(),
|
|
20
|
+
* emailAndPassword: { enabled: true },
|
|
21
|
+
* sessionFields: ['userId', 'email', 'name'],
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Combined with the keys/field derivation (`deriveAuthLists`) and schema
|
|
26
|
+
* placement, the generated Auth lists reach **Schema parity** with the live
|
|
27
|
+
* tables — they are modelled for runtime/types without producing a destructive
|
|
28
|
+
* auth migration. The recipe never touches the application's own domain `User`:
|
|
29
|
+
* its model names are `Auth`-prefixed by default and the plugin only ever
|
|
30
|
+
* adds/extends its *derived* keys.
|
|
31
|
+
*/
|
|
32
|
+
/** The four better-auth models and their default (unprefixed) model names. */
|
|
33
|
+
const MODEL_DEFAULT_NAMES = {
|
|
34
|
+
user: 'User',
|
|
35
|
+
session: 'Session',
|
|
36
|
+
account: 'Account',
|
|
37
|
+
verification: 'Verification',
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Build the adoption {@link AuthConfig} fragment for a pre-existing better-auth
|
|
41
|
+
* installation.
|
|
42
|
+
*
|
|
43
|
+
* Returns only the model/schema knobs needed to adopt the live tables; spread it
|
|
44
|
+
* into {@link authPlugin} alongside your own auth config.
|
|
45
|
+
*
|
|
46
|
+
* @param options - Adoption conventions (schema, model-name prefix, column maps)
|
|
47
|
+
* @returns An {@link AuthConfig} fragment with `schema` + per-model `modelName`
|
|
48
|
+
* (and any field column maps) set to match the live tables
|
|
49
|
+
*/
|
|
50
|
+
export function adoptBetterAuthTables(options = {}) {
|
|
51
|
+
const { schema = 'auth', modelNamePrefix = 'Auth', fields = {} } = options;
|
|
52
|
+
const buildModel = (model) => {
|
|
53
|
+
const config = {
|
|
54
|
+
modelName: `${modelNamePrefix}${MODEL_DEFAULT_NAMES[model]}`,
|
|
55
|
+
};
|
|
56
|
+
const fieldMap = fields[model];
|
|
57
|
+
if (fieldMap && Object.keys(fieldMap).length > 0) {
|
|
58
|
+
config.fields = fieldMap;
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
schema,
|
|
64
|
+
user: buildModel('user'),
|
|
65
|
+
session: buildModel('session'),
|
|
66
|
+
account: buildModel('account'),
|
|
67
|
+
verification: buildModel('verification'),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=adopt-better-auth-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-better-auth-tables.js","sourceRoot":"","sources":["../../src/config/adopt-better-auth-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AA+DH,8EAA8E;AAC9E,MAAM,mBAAmB,GAAG;IAC1B,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,cAAc;CACpB,CAAA;AAYV;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAwC,EAAE;IAE1C,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IAE1E,MAAM,UAAU,GAAG,CAAC,KAAuC,EAAmB,EAAE;QAC9E,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,GAAG,eAAe,GAAG,mBAAmB,CAAC,KAAK,CAAC,EAAE;SAC7D,CAAA;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9B,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAA;QAC1B,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,OAAO;QACL,MAAM;QACN,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC;QACxB,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC;QAC9B,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC;QAC9B,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC;KACzC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure `better-auth config → Auth lists` derivation.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally free of side effects and plugin/runtime
|
|
5
|
+
* concerns: given the resolved better-auth model config (per-model `modelName`
|
|
6
|
+
* and `fields` column maps) plus any custom User fields, it produces the four
|
|
7
|
+
* OpenSaaS Auth lists (user/session/account/verification) with:
|
|
8
|
+
*
|
|
9
|
+
* - list keys taken from each model's `modelName`
|
|
10
|
+
* - a table `@@map` (list-level `db.map`) when the key differs from the
|
|
11
|
+
* default better-auth model name
|
|
12
|
+
* - field-level `@map` (`db.map`) for any better-auth field → column override
|
|
13
|
+
* - relationship refs between the auth lists wired to the *derived* keys
|
|
14
|
+
* (e.g. `Session.user → AuthUser.sessions`)
|
|
15
|
+
*
|
|
16
|
+
* When the developer supplies no `modelName`/`fields` overrides, the output is
|
|
17
|
+
* byte-for-byte the historical default set keyed `User`/`Session`/`Account`/
|
|
18
|
+
* `Verification` with the original field shapes — see the unit tests.
|
|
19
|
+
*
|
|
20
|
+
* `getAuthLists`/`convertBetterAuthSchema` (and the runtime user-key
|
|
21
|
+
* resolution) consume this module so derivation lives in exactly one place.
|
|
22
|
+
*/
|
|
23
|
+
import type { ListConfig } from '@opensaas/stack-core';
|
|
24
|
+
import type { ExtendUserListConfig } from '../lists/index.js';
|
|
25
|
+
import type { NormalizedAuthModels } from './types.js';
|
|
26
|
+
/**
|
|
27
|
+
* The derived Auth list set together with the keys each list was placed under.
|
|
28
|
+
* Keys are surfaced separately so callers (plugin add-vs-extend logic, runtime
|
|
29
|
+
* user-key resolution) don't have to re-derive them.
|
|
30
|
+
*/
|
|
31
|
+
export type DerivedAuthLists = {
|
|
32
|
+
/** Derived list keys, one per better-auth model. */
|
|
33
|
+
keys: {
|
|
34
|
+
user: string;
|
|
35
|
+
session: string;
|
|
36
|
+
account: string;
|
|
37
|
+
verification: string;
|
|
38
|
+
};
|
|
39
|
+
/** The derived list configs, keyed by their derived list keys. */
|
|
40
|
+
lists: Record<string, ListConfig<any>>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Derive the OpenSaaS Auth lists from the resolved better-auth model config.
|
|
44
|
+
*
|
|
45
|
+
* @param models - Resolved better-auth per-model config (modelName + field column maps)
|
|
46
|
+
* @param userConfig - Extra User-list fields/access/hooks supplied via `extendUserList`
|
|
47
|
+
* @returns The derived list keys and the four Auth list configs keyed by those keys
|
|
48
|
+
*/
|
|
49
|
+
export declare function deriveAuthLists(models: NormalizedAuthModels, userConfig?: ExtendUserListConfig): DerivedAuthLists;
|
|
50
|
+
//# sourceMappingURL=derive-auth-lists.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive-auth-lists.d.ts","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAA6B,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAajF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oDAAoD;IACpD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,kEAAkE;IAElE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;CACvC,CAAA;AA+OD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,oBAAoB,EAC5B,UAAU,GAAE,oBAAyB,GACpC,gBAAgB,CAiBlB"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure `better-auth config → Auth lists` derivation.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally free of side effects and plugin/runtime
|
|
5
|
+
* concerns: given the resolved better-auth model config (per-model `modelName`
|
|
6
|
+
* and `fields` column maps) plus any custom User fields, it produces the four
|
|
7
|
+
* OpenSaaS Auth lists (user/session/account/verification) with:
|
|
8
|
+
*
|
|
9
|
+
* - list keys taken from each model's `modelName`
|
|
10
|
+
* - a table `@@map` (list-level `db.map`) when the key differs from the
|
|
11
|
+
* default better-auth model name
|
|
12
|
+
* - field-level `@map` (`db.map`) for any better-auth field → column override
|
|
13
|
+
* - relationship refs between the auth lists wired to the *derived* keys
|
|
14
|
+
* (e.g. `Session.user → AuthUser.sessions`)
|
|
15
|
+
*
|
|
16
|
+
* When the developer supplies no `modelName`/`fields` overrides, the output is
|
|
17
|
+
* byte-for-byte the historical default set keyed `User`/`Session`/`Account`/
|
|
18
|
+
* `Verification` with the original field shapes — see the unit tests.
|
|
19
|
+
*
|
|
20
|
+
* `getAuthLists`/`convertBetterAuthSchema` (and the runtime user-key
|
|
21
|
+
* resolution) consume this module so derivation lives in exactly one place.
|
|
22
|
+
*/
|
|
23
|
+
import { list } from '@opensaas/stack-core';
|
|
24
|
+
import { text, timestamp, checkbox, relationship } from '@opensaas/stack-core/fields';
|
|
25
|
+
/**
|
|
26
|
+
* Default better-auth model names — used to decide whether a `@@map` is needed
|
|
27
|
+
* (only when the configured `modelName` differs from the default).
|
|
28
|
+
*/
|
|
29
|
+
const DEFAULT_MODEL_NAMES = {
|
|
30
|
+
user: 'User',
|
|
31
|
+
session: 'Session',
|
|
32
|
+
account: 'Account',
|
|
33
|
+
verification: 'Verification',
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Build the list-level `db` config (`timestamps` + `@@map` + `@@schema`) for a
|
|
37
|
+
* derived list.
|
|
38
|
+
*
|
|
39
|
+
* Always opts the list into auto-timestamps (`timestamps: true`). better-auth's
|
|
40
|
+
* adapter writes `createdAt`/`updatedAt` on every auth row and the schema
|
|
41
|
+
* converter returns `null` for those columns (it assumes the generator injects
|
|
42
|
+
* them). Now that auto-timestamps are OFF by default (ADR-0004), each derived
|
|
43
|
+
* Auth list must opt back in so the generated models keep those columns and
|
|
44
|
+
* better-auth keeps working.
|
|
45
|
+
*
|
|
46
|
+
* When the developer renames the model (e.g. `modelName: 'AuthUser'`), we also
|
|
47
|
+
* pin the physical table name to that model name via `@@map("AuthUser")` so the
|
|
48
|
+
* generated list adopts the developer's live table exactly. When a `schema` is
|
|
49
|
+
* configured (plugin-level or per-model), the list is placed in that Postgres
|
|
50
|
+
* schema via `@@schema(...)`.
|
|
51
|
+
*
|
|
52
|
+
* With no `modelName`/`schema` overrides we emit only `timestamps: true`,
|
|
53
|
+
* leaving the default `User`/`Session`/... table/schema output unchanged.
|
|
54
|
+
*/
|
|
55
|
+
function listDb(model, defaultModelName) {
|
|
56
|
+
const map = model.modelName !== defaultModelName ? model.modelName : undefined;
|
|
57
|
+
const schema = model.schema;
|
|
58
|
+
return {
|
|
59
|
+
timestamps: true,
|
|
60
|
+
...(map !== undefined ? { map } : {}),
|
|
61
|
+
...(schema !== undefined ? { schema } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the `db.map` (`@map` column override) for a better-auth field, or
|
|
66
|
+
* `undefined` when there is no override (so default output is unchanged).
|
|
67
|
+
*
|
|
68
|
+
* The field builders capture `options.db` in a closure when generating Prisma
|
|
69
|
+
* types, so the column map MUST be passed through the builder's `db` option
|
|
70
|
+
* rather than patched onto the returned field object.
|
|
71
|
+
*/
|
|
72
|
+
function fieldDb(fieldName, fields) {
|
|
73
|
+
const column = fields[fieldName];
|
|
74
|
+
return column ? { map: column } : undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build the foreign-key `db` config for a `user` relationship, honouring a
|
|
78
|
+
* `userId` column override from the better-auth `fields` map.
|
|
79
|
+
*/
|
|
80
|
+
function userForeignKeyDb(fields) {
|
|
81
|
+
const column = fields.userId;
|
|
82
|
+
return column ? { foreignKey: { map: column } } : undefined;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create the Auth user list, applying derived field column maps + table map and
|
|
86
|
+
* wiring the session/account relationships to the derived keys.
|
|
87
|
+
*/
|
|
88
|
+
function createUserList(model, keys, userConfig) {
|
|
89
|
+
const f = model.fields;
|
|
90
|
+
return list({
|
|
91
|
+
fields: {
|
|
92
|
+
name: text({ validation: { isRequired: true }, db: fieldDb('name', f) }),
|
|
93
|
+
email: text({
|
|
94
|
+
validation: { isRequired: true },
|
|
95
|
+
isIndexed: 'unique',
|
|
96
|
+
db: fieldDb('email', f),
|
|
97
|
+
}),
|
|
98
|
+
emailVerified: checkbox({ defaultValue: false, db: fieldDb('emailVerified', f) }),
|
|
99
|
+
image: text({ db: fieldDb('image', f) }),
|
|
100
|
+
// Relationships to the other auth lists — refs follow the derived keys.
|
|
101
|
+
sessions: relationship({ ref: `${keys.session}.user`, many: true }),
|
|
102
|
+
accounts: relationship({ ref: `${keys.account}.user`, many: true }),
|
|
103
|
+
// Custom fields from user config
|
|
104
|
+
...(userConfig.fields || {}),
|
|
105
|
+
},
|
|
106
|
+
db: listDb(model, DEFAULT_MODEL_NAMES.user),
|
|
107
|
+
access: userConfig.access || {
|
|
108
|
+
operation: {
|
|
109
|
+
query: () => true,
|
|
110
|
+
create: () => true,
|
|
111
|
+
update: ({ session, item }) => {
|
|
112
|
+
if (!session)
|
|
113
|
+
return false;
|
|
114
|
+
const userId = session.userId;
|
|
115
|
+
const itemId = item?.id;
|
|
116
|
+
return userId === itemId;
|
|
117
|
+
},
|
|
118
|
+
delete: ({ session, item }) => {
|
|
119
|
+
if (!session)
|
|
120
|
+
return false;
|
|
121
|
+
const userId = session.userId;
|
|
122
|
+
const itemId = item?.id;
|
|
123
|
+
return userId === itemId;
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
hooks: userConfig.hooks,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Create the Auth session list.
|
|
132
|
+
*/
|
|
133
|
+
function createSessionList(model, keys) {
|
|
134
|
+
const f = model.fields;
|
|
135
|
+
return list({
|
|
136
|
+
fields: {
|
|
137
|
+
token: text({
|
|
138
|
+
validation: { isRequired: true },
|
|
139
|
+
isIndexed: 'unique',
|
|
140
|
+
db: fieldDb('token', f),
|
|
141
|
+
}),
|
|
142
|
+
expiresAt: timestamp({ db: fieldDb('expiresAt', f) }),
|
|
143
|
+
ipAddress: text({ db: fieldDb('ipAddress', f) }),
|
|
144
|
+
userAgent: text({ db: fieldDb('userAgent', f) }),
|
|
145
|
+
user: relationship({
|
|
146
|
+
ref: `${keys.user}.sessions`,
|
|
147
|
+
db: userForeignKeyDb(f),
|
|
148
|
+
}),
|
|
149
|
+
},
|
|
150
|
+
db: listDb(model, DEFAULT_MODEL_NAMES.session),
|
|
151
|
+
access: {
|
|
152
|
+
operation: {
|
|
153
|
+
query: ({ session }) => {
|
|
154
|
+
if (!session)
|
|
155
|
+
return false;
|
|
156
|
+
const userId = session.userId;
|
|
157
|
+
if (!userId)
|
|
158
|
+
return false;
|
|
159
|
+
return {
|
|
160
|
+
user: { id: { equals: userId } },
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
create: () => true,
|
|
164
|
+
update: () => false,
|
|
165
|
+
delete: ({ session, item }) => {
|
|
166
|
+
if (!session)
|
|
167
|
+
return false;
|
|
168
|
+
const userId = session.userId;
|
|
169
|
+
const itemUserId = item?.user?.id;
|
|
170
|
+
return userId === itemUserId;
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Create the Auth account list.
|
|
178
|
+
*/
|
|
179
|
+
function createAccountList(model, keys) {
|
|
180
|
+
const f = model.fields;
|
|
181
|
+
return list({
|
|
182
|
+
fields: {
|
|
183
|
+
accountId: text({ validation: { isRequired: true }, db: fieldDb('accountId', f) }),
|
|
184
|
+
providerId: text({ validation: { isRequired: true }, db: fieldDb('providerId', f) }),
|
|
185
|
+
user: relationship({
|
|
186
|
+
ref: `${keys.user}.accounts`,
|
|
187
|
+
db: userForeignKeyDb(f),
|
|
188
|
+
}),
|
|
189
|
+
accessToken: text({ db: fieldDb('accessToken', f) }),
|
|
190
|
+
refreshToken: text({ db: fieldDb('refreshToken', f) }),
|
|
191
|
+
accessTokenExpiresAt: timestamp({ db: fieldDb('accessTokenExpiresAt', f) }),
|
|
192
|
+
refreshTokenExpiresAt: timestamp({ db: fieldDb('refreshTokenExpiresAt', f) }),
|
|
193
|
+
scope: text({ db: fieldDb('scope', f) }),
|
|
194
|
+
idToken: text({ db: fieldDb('idToken', f) }),
|
|
195
|
+
password: text({ db: fieldDb('password', f) }),
|
|
196
|
+
},
|
|
197
|
+
db: listDb(model, DEFAULT_MODEL_NAMES.account),
|
|
198
|
+
access: {
|
|
199
|
+
operation: {
|
|
200
|
+
query: ({ session }) => {
|
|
201
|
+
if (!session)
|
|
202
|
+
return false;
|
|
203
|
+
const userId = session.userId;
|
|
204
|
+
if (!userId)
|
|
205
|
+
return false;
|
|
206
|
+
return {
|
|
207
|
+
user: { id: { equals: userId } },
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
create: () => true,
|
|
211
|
+
update: ({ session, item }) => {
|
|
212
|
+
if (!session)
|
|
213
|
+
return false;
|
|
214
|
+
const userId = session.userId;
|
|
215
|
+
const itemUserId = item?.user?.id;
|
|
216
|
+
return userId === itemUserId;
|
|
217
|
+
},
|
|
218
|
+
delete: ({ session, item }) => {
|
|
219
|
+
if (!session)
|
|
220
|
+
return false;
|
|
221
|
+
const userId = session.userId;
|
|
222
|
+
const itemUserId = item?.user?.id;
|
|
223
|
+
return userId === itemUserId;
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create the Auth verification list.
|
|
231
|
+
*/
|
|
232
|
+
function createVerificationList(model) {
|
|
233
|
+
const f = model.fields;
|
|
234
|
+
return list({
|
|
235
|
+
fields: {
|
|
236
|
+
identifier: text({ validation: { isRequired: true }, db: fieldDb('identifier', f) }),
|
|
237
|
+
value: text({ validation: { isRequired: true }, db: fieldDb('value', f) }),
|
|
238
|
+
expiresAt: timestamp({ db: fieldDb('expiresAt', f) }),
|
|
239
|
+
},
|
|
240
|
+
db: listDb(model, DEFAULT_MODEL_NAMES.verification),
|
|
241
|
+
access: {
|
|
242
|
+
operation: {
|
|
243
|
+
query: () => false,
|
|
244
|
+
create: () => true,
|
|
245
|
+
update: () => false,
|
|
246
|
+
delete: () => true,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Derive the OpenSaaS Auth lists from the resolved better-auth model config.
|
|
253
|
+
*
|
|
254
|
+
* @param models - Resolved better-auth per-model config (modelName + field column maps)
|
|
255
|
+
* @param userConfig - Extra User-list fields/access/hooks supplied via `extendUserList`
|
|
256
|
+
* @returns The derived list keys and the four Auth list configs keyed by those keys
|
|
257
|
+
*/
|
|
258
|
+
export function deriveAuthLists(models, userConfig = {}) {
|
|
259
|
+
const keys = {
|
|
260
|
+
user: models.user.modelName,
|
|
261
|
+
session: models.session.modelName,
|
|
262
|
+
account: models.account.modelName,
|
|
263
|
+
verification: models.verification.modelName,
|
|
264
|
+
};
|
|
265
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
|
|
266
|
+
const lists = {
|
|
267
|
+
[keys.user]: createUserList(models.user, keys, userConfig),
|
|
268
|
+
[keys.session]: createSessionList(models.session, keys),
|
|
269
|
+
[keys.account]: createAccountList(models.account, keys),
|
|
270
|
+
[keys.verification]: createVerificationList(models.verification),
|
|
271
|
+
};
|
|
272
|
+
return { keys, lists };
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=derive-auth-lists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive-auth-lists.js","sourceRoot":"","sources":["../../src/config/derive-auth-lists.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,oBAAoB,EAMrB,MAAM,YAAY,CAAA;AAmDnB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,oBAAoB,CA+D5E;AAED,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAA;AAChD,cAAc,YAAY,CAAA"}
|
package/dist/config/index.js
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default better-auth model names. Used when the developer does not override
|
|
3
|
+
* `modelName`, preserving the historical `User`/`Session`/`Account`/`Verification`
|
|
4
|
+
* keys exactly.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_MODEL_NAMES = {
|
|
7
|
+
user: 'User',
|
|
8
|
+
session: 'Session',
|
|
9
|
+
account: 'Account',
|
|
10
|
+
verification: 'Verification',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a single better-auth model config block into its normalized form,
|
|
14
|
+
* falling back to the better-auth default model name and an empty column map.
|
|
15
|
+
* The model's Postgres schema is the per-model `schema` override when present,
|
|
16
|
+
* otherwise the plugin-level `schema` default (or `undefined` for `public`).
|
|
17
|
+
*/
|
|
18
|
+
function normalizeModelConfig(config, defaultModelName, defaultSchema) {
|
|
19
|
+
return {
|
|
20
|
+
modelName: config?.modelName || defaultModelName,
|
|
21
|
+
fields: config?.fields || {},
|
|
22
|
+
schema: config?.schema ?? defaultSchema,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the better-auth model config for all four auth models.
|
|
27
|
+
* `defaultSchema` is the plugin-level `schema` applied to every model unless a
|
|
28
|
+
* per-model `schema` override is given.
|
|
29
|
+
*/
|
|
30
|
+
function normalizeAuthModels(config) {
|
|
31
|
+
const defaultSchema = config.schema;
|
|
32
|
+
return {
|
|
33
|
+
user: normalizeModelConfig(config.user, DEFAULT_MODEL_NAMES.user, defaultSchema),
|
|
34
|
+
session: normalizeModelConfig(config.session, DEFAULT_MODEL_NAMES.session, defaultSchema),
|
|
35
|
+
account: normalizeModelConfig(config.account, DEFAULT_MODEL_NAMES.account, defaultSchema),
|
|
36
|
+
verification: normalizeModelConfig(config.verification, DEFAULT_MODEL_NAMES.verification, defaultSchema),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
1
39
|
/**
|
|
2
40
|
* Normalize auth configuration with defaults
|
|
3
41
|
*/
|
|
@@ -32,12 +70,17 @@ export function normalizeAuthConfig(config) {
|
|
|
32
70
|
};
|
|
33
71
|
// Session fields defaults
|
|
34
72
|
const sessionFields = config.sessionFields || ['userId', 'email', 'name'];
|
|
73
|
+
// Resolve better-auth per-model config (modelName + field column maps).
|
|
74
|
+
// Defaults preserve the historical User/Session/Account/Verification keys.
|
|
75
|
+
const models = normalizeAuthModels(config);
|
|
35
76
|
return {
|
|
36
77
|
emailAndPassword,
|
|
37
78
|
emailVerification,
|
|
38
79
|
passwordReset,
|
|
39
80
|
socialProviders: config.socialProviders || {},
|
|
40
81
|
session,
|
|
82
|
+
models,
|
|
83
|
+
schema: config.schema,
|
|
41
84
|
sessionFields,
|
|
42
85
|
extendUserList: config.extendUserList || {},
|
|
43
86
|
sendEmail: config.sendEmail ||
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,mBAAmB,GAAG;IAC1B,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,cAAc;CACpB,CAAA;AAEV;;;;;GAKG;AACH,SAAS,oBAAoB,CAC3B,MAAmC,EACnC,gBAAwB,EACxB,aAAiC;IAEjC,OAAO;QACL,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,gBAAgB;QAChD,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE;QAC5B,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,aAAa;KACxC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,MAAkB;IAC7C,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAA;IACnC,OAAO;QACL,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,aAAa,CAAC;QAChF,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC;QACzF,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC;QACzF,YAAY,EAAE,oBAAoB,CAChC,MAAM,CAAC,YAAY,EACnB,mBAAmB,CAAC,YAAY,EAChC,aAAa,CACd;KACF,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,8BAA8B;IAC9B,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,EAAE,OAAO;QACvD,CAAC,CAAC;YACE,OAAO,EAAE,IAAa;YACtB,iBAAiB,EAAG,MAAM,CAAC,gBAAwC,CAAC,iBAAiB,IAAI,CAAC;YAC1F,mBAAmB,EAChB,MAAM,CAAC,gBAAwC,CAAC,mBAAmB,IAAI,IAAI;SAC/E;QACH,CAAC,CAAC,EAAE,OAAO,EAAE,KAAc,EAAE,iBAAiB,EAAE,CAAC,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAA;IAEhF,8BAA8B;IAC9B,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,EAAE,OAAO;QACzD,CAAC,CAAC;YACE,OAAO,EAAE,IAAa;YACtB,YAAY,EAAG,MAAM,CAAC,iBAA6C,CAAC,YAAY,IAAI,IAAI;YACxF,eAAe,EACZ,MAAM,CAAC,iBAA6C,CAAC,eAAe,IAAI,KAAK;SACjF;QACH,CAAC,CAAC,EAAE,OAAO,EAAE,KAAc,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAA;IAE3E,0BAA0B;IAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO;QACjD,CAAC,CAAC;YACE,OAAO,EAAE,IAAa;YACtB,eAAe,EAAG,MAAM,CAAC,aAAqC,CAAC,eAAe,IAAI,IAAI;SACvF;QACH,CAAC,CAAC,EAAE,OAAO,EAAE,KAAc,EAAE,eAAe,EAAE,IAAI,EAAE,CAAA;IAEtD,mBAAmB;IACnB,MAAM,OAAO,GAAG;QACd,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,MAAM,EAAE,SAAS;QACzD,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,IAAI;KAC7C,CAAA;IAED,0BAA0B;IAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IAEzE,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAE1C,OAAO;QACL,gBAAgB;QAChB,iBAAiB;QACjB,aAAa;QACb,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;QAC7C,OAAO;QACP,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,aAAa;QACb,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE;QAC3C,SAAS,EACP,MAAM,CAAC,SAAS;YAChB,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC/B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAA;gBAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;gBACxB,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAA;gBAClC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;YAC9B,CAAC,CAAC;QACJ,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,EAAE;QACjD,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAA;AACH,CAAC;AAGD,cAAc,YAAY,CAAA"}
|
package/dist/config/plugin.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,YAAY,CAAA;AAKlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAqJrD"}
|