opacacms 0.3.12 → 0.3.14
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/LICENSE +21 -0
- package/README.md +196 -173
- package/dist/admin/ui/components/ui/button.d.ts +1 -1
- package/dist/{chunk-8hhzvesq.js → chunk-5b9eqr34.js} +3 -2
- package/dist/{chunk-1vtdkx5e.js → chunk-dz5bh1bd.js} +7 -2
- package/dist/{chunk-2fm4kv2q.js → chunk-nv91gc63.js} +32 -14
- package/dist/{chunk-xdmw9vzq.js → chunk-nz6xhtja.js} +7 -2
- package/dist/{chunk-0njhbe4a.js → chunk-qsefknd3.js} +7 -2
- package/dist/{chunk-2ec9fsgr.js → chunk-tsmhn78f.js} +6 -2
- package/dist/client.d.ts +88 -10
- package/dist/client.js +1 -1
- package/dist/config.d.ts +8 -1
- package/dist/db/better-sqlite.js +1 -1
- package/dist/db/bun-sqlite.js +1 -1
- package/dist/db/d1.js +1 -1
- package/dist/db/index.js +5 -5
- package/dist/db/postgres.js +1 -1
- package/dist/db/sqlite.js +1 -1
- package/dist/index.js +1 -1
- package/dist/schema/collection.d.ts +5 -5
- package/dist/schema/global.d.ts +5 -5
- package/dist/types/access.d.ts +30 -0
- package/dist/types.d.ts +2 -24
- package/dist/validation.d.ts +7 -7
- package/package.json +3 -2
|
@@ -16,9 +16,14 @@ class OpacaError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
function createClient(configOrOptions) {
|
|
19
|
-
const
|
|
19
|
+
const isConfig = configOrOptions.serverURL || configOrOptions.collections;
|
|
20
|
+
const options = isConfig ? {
|
|
21
|
+
baseURL: configOrOptions.serverURL || "http://localhost:3000",
|
|
22
|
+
token: configOrOptions.token,
|
|
23
|
+
api: configOrOptions.api
|
|
24
|
+
} : configOrOptions;
|
|
20
25
|
const baseURL = options.baseURL.replace(/\/$/, "");
|
|
21
|
-
let engineConfig = null;
|
|
26
|
+
let engineConfig = options.api || null;
|
|
22
27
|
let metadataCache = null;
|
|
23
28
|
const getHeaders = () => {
|
|
24
29
|
const headers = {
|
|
@@ -45,18 +50,20 @@ function createClient(configOrOptions) {
|
|
|
45
50
|
return res.json();
|
|
46
51
|
};
|
|
47
52
|
const initConfig = async () => {
|
|
48
|
-
if (engineConfig && metadataCache)
|
|
53
|
+
if (engineConfig && engineConfig.graphql && metadataCache)
|
|
49
54
|
return;
|
|
50
55
|
try {
|
|
51
56
|
const [setupRes, metadataRes] = await Promise.all([
|
|
52
57
|
fetcher("/api/__admin/setup"),
|
|
53
58
|
fetcher("/api/__admin/collections")
|
|
54
59
|
]);
|
|
55
|
-
engineConfig = setupRes.api || { rest: true, graphql: { enabled: false, path: "/graphql" } };
|
|
60
|
+
engineConfig = setupRes.api || engineConfig || { rest: true, graphql: { enabled: false, path: "/graphql" } };
|
|
56
61
|
metadataCache = metadataRes;
|
|
57
62
|
} catch (e) {
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
const localCols = configOrOptions.collections || [];
|
|
64
|
+
const localGlobals = configOrOptions.globals || [];
|
|
65
|
+
engineConfig = engineConfig || { rest: true, graphql: { enabled: false, path: "/graphql" } };
|
|
66
|
+
metadataCache = { collections: localCols, globals: localGlobals };
|
|
60
67
|
}
|
|
61
68
|
};
|
|
62
69
|
const buildSelectionSet = (fields) => {
|
|
@@ -86,7 +93,11 @@ function createClient(configOrOptions) {
|
|
|
86
93
|
if (!engineConfig?.graphql?.enabled) {
|
|
87
94
|
throw new OpacaError("GraphQL is not enabled on this server.", 400);
|
|
88
95
|
}
|
|
89
|
-
|
|
96
|
+
let gqlPath = engineConfig.graphql.path || "/graphql";
|
|
97
|
+
if (!gqlPath.startsWith("/api") && !gqlPath.startsWith("http")) {
|
|
98
|
+
gqlPath = `/api${gqlPath.startsWith("/") ? "" : "/"}${gqlPath}`;
|
|
99
|
+
}
|
|
100
|
+
return fetcher(gqlPath, {
|
|
90
101
|
method: "POST",
|
|
91
102
|
body: JSON.stringify({ query, variables })
|
|
92
103
|
});
|
|
@@ -96,7 +107,8 @@ function createClient(configOrOptions) {
|
|
|
96
107
|
return {
|
|
97
108
|
find: async (query) => {
|
|
98
109
|
await initConfig();
|
|
99
|
-
|
|
110
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
111
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
100
112
|
const selection = getSelectionSetForCollection(String(collectionSlug));
|
|
101
113
|
const limit = query?.limit ? `limit: ${query.limit}` : "";
|
|
102
114
|
const page = query?.page ? `page: ${query.page}` : "";
|
|
@@ -118,7 +130,8 @@ function createClient(configOrOptions) {
|
|
|
118
130
|
},
|
|
119
131
|
findOne: async (id) => {
|
|
120
132
|
await initConfig();
|
|
121
|
-
|
|
133
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
134
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
122
135
|
const selection = getSelectionSetForCollection(String(collectionSlug));
|
|
123
136
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(collectionSlug)));
|
|
124
137
|
const res = await client.graphql(`query getDoc($id: String!) { get${capitalizedSlug}(id: $id) { ${selection} } }`, { id });
|
|
@@ -131,7 +144,8 @@ function createClient(configOrOptions) {
|
|
|
131
144
|
},
|
|
132
145
|
create: async (data) => {
|
|
133
146
|
await initConfig();
|
|
134
|
-
|
|
147
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
148
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
135
149
|
const selection = getSelectionSetForCollection(String(collectionSlug));
|
|
136
150
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(collectionSlug)));
|
|
137
151
|
const res = await client.graphql(`mutation createDoc($data: JSON!) { create${capitalizedSlug}(data: $data) { ${selection} } }`, { data });
|
|
@@ -144,7 +158,8 @@ function createClient(configOrOptions) {
|
|
|
144
158
|
},
|
|
145
159
|
update: async (id, data) => {
|
|
146
160
|
await initConfig();
|
|
147
|
-
|
|
161
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
162
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
148
163
|
const selection = getSelectionSetForCollection(String(collectionSlug));
|
|
149
164
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(collectionSlug)));
|
|
150
165
|
const res = await client.graphql(`mutation updateDoc($id: String!, $data: JSON!) { update${capitalizedSlug}(id: $id, data: $data) { ${selection} } }`, { id, data });
|
|
@@ -157,7 +172,8 @@ function createClient(configOrOptions) {
|
|
|
157
172
|
},
|
|
158
173
|
delete: async (id) => {
|
|
159
174
|
await initConfig();
|
|
160
|
-
|
|
175
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
176
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
161
177
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(collectionSlug)));
|
|
162
178
|
const res = await client.graphql(`mutation deleteDoc($id: String!) { delete${capitalizedSlug}(id: $id) }`, { id });
|
|
163
179
|
return res.data[`delete${capitalizedSlug}`];
|
|
@@ -174,7 +190,8 @@ function createClient(configOrOptions) {
|
|
|
174
190
|
return {
|
|
175
191
|
get: async () => {
|
|
176
192
|
await initConfig();
|
|
177
|
-
|
|
193
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
194
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
178
195
|
const selection = getSelectionSetForGlobal(String(globalSlug));
|
|
179
196
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(globalSlug)));
|
|
180
197
|
const res = await client.graphql(`query getGlobal { get${capitalizedSlug} { ${selection} } }`);
|
|
@@ -184,7 +201,8 @@ function createClient(configOrOptions) {
|
|
|
184
201
|
},
|
|
185
202
|
update: async (data) => {
|
|
186
203
|
await initConfig();
|
|
187
|
-
|
|
204
|
+
const isRestDisabled = engineConfig?.rest === false || engineConfig?.rest?.enabled === false;
|
|
205
|
+
if (engineConfig?.graphql?.enabled && isRestDisabled) {
|
|
188
206
|
const selection = getSelectionSetForGlobal(String(globalSlug));
|
|
189
207
|
const capitalizedSlug = capitalize(sanitizeGraphQLName(String(globalSlug)));
|
|
190
208
|
const res = await client.graphql(`mutation updateGlobal($data: JSON!) { update${capitalizedSlug}(data: $data) { ${selection} } }`, { data });
|
|
@@ -125,6 +125,10 @@ class SQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
125
125
|
filteredData[col] = flatData[col];
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
+
if (!filteredData.id) {
|
|
129
|
+
filteredData.id = crypto.randomUUID();
|
|
130
|
+
flatData.id = filteredData.id;
|
|
131
|
+
}
|
|
128
132
|
await tx.insertInto(tableName).values(filteredData).execute();
|
|
129
133
|
for (const [key, values] of Object.entries(hasManyData)) {
|
|
130
134
|
const joinTableName = `${tableName}_${toSnakeCase(key)}_relations`.toLowerCase();
|
|
@@ -340,6 +344,7 @@ class SQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
340
344
|
}
|
|
341
345
|
}
|
|
342
346
|
const totalPages = Math.ceil(total / limit);
|
|
347
|
+
const hasNextPage = page * limit < total;
|
|
343
348
|
return {
|
|
344
349
|
docs: docs.filter(Boolean),
|
|
345
350
|
totalDocs: total,
|
|
@@ -347,11 +352,11 @@ class SQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
347
352
|
totalPages,
|
|
348
353
|
page,
|
|
349
354
|
pagingCounter: offset + 1,
|
|
350
|
-
hasNextPage
|
|
355
|
+
hasNextPage,
|
|
351
356
|
hasPrevPage: page > 1 || !!options?.after || !!options?.before,
|
|
352
357
|
prevPage: page > 1 ? page - 1 : null,
|
|
353
358
|
nextPage: page < totalPages ? page + 1 : null,
|
|
354
|
-
nextCursor: docs.length > 0 ? docs[docs.length - 1][cursorColumn] : null,
|
|
359
|
+
nextCursor: hasNextPage && docs.length > 0 ? docs[docs.length - 1][cursorColumn] : null,
|
|
355
360
|
prevCursor: docs.length > 0 && (page > 1 || !!options?.after || !!options?.before) ? docs[0][cursorColumn] : null
|
|
356
361
|
};
|
|
357
362
|
}
|
|
@@ -117,6 +117,10 @@ class BunSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
117
117
|
filteredData[col] = flatData[col];
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
+
if (!filteredData.id) {
|
|
121
|
+
filteredData.id = crypto.randomUUID();
|
|
122
|
+
flatData.id = filteredData.id;
|
|
123
|
+
}
|
|
120
124
|
await this.db.insertInto(tableName).values(filteredData).execute();
|
|
121
125
|
for (const [key, values] of Object.entries(hasManyData)) {
|
|
122
126
|
const joinTableName = `${tableName}_${toSnakeCase(key)}_relations`.toLowerCase();
|
|
@@ -331,6 +335,7 @@ class BunSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
337
|
const totalPages = Math.ceil(total / limit);
|
|
338
|
+
const hasNextPage = page * limit < total;
|
|
334
339
|
return {
|
|
335
340
|
docs: docs.filter(Boolean),
|
|
336
341
|
totalDocs: total,
|
|
@@ -338,11 +343,11 @@ class BunSQLiteAdapter extends BaseDatabaseAdapter {
|
|
|
338
343
|
totalPages,
|
|
339
344
|
page,
|
|
340
345
|
pagingCounter: offset + 1,
|
|
341
|
-
hasNextPage
|
|
346
|
+
hasNextPage,
|
|
342
347
|
hasPrevPage: page > 1 || !!options?.after || !!options?.before,
|
|
343
348
|
prevPage: page > 1 ? page - 1 : null,
|
|
344
349
|
nextPage: page < totalPages ? page + 1 : null,
|
|
345
|
-
nextCursor: docs.length > 0 ? docs[docs.length - 1][cursorColumn] : null,
|
|
350
|
+
nextCursor: hasNextPage && docs.length > 0 ? docs[docs.length - 1][cursorColumn] : null,
|
|
346
351
|
prevCursor: docs.length > 0 && (page > 1 || !!options?.after || !!options?.before) ? docs[0][cursorColumn] : null
|
|
347
352
|
};
|
|
348
353
|
}
|
|
@@ -150,6 +150,9 @@ class PostgresAdapter extends BaseDatabaseAdapter {
|
|
|
150
150
|
delete flatData[key];
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
if (!flatData.id) {
|
|
154
|
+
flatData.id = crypto.randomUUID();
|
|
155
|
+
}
|
|
153
156
|
await tx.insertInto(tableName).values(flatData).execute();
|
|
154
157
|
for (const [key, values] of Object.entries(hasManyData)) {
|
|
155
158
|
const joinTableName = `${tableName}_${toSnakeCase(key)}_relations`.toLowerCase();
|
|
@@ -360,6 +363,7 @@ class PostgresAdapter extends BaseDatabaseAdapter {
|
|
|
360
363
|
}
|
|
361
364
|
}
|
|
362
365
|
const totalPages = Math.ceil(total / limit);
|
|
366
|
+
const hasNextPage = page * limit < total;
|
|
363
367
|
return {
|
|
364
368
|
docs: docs.filter(Boolean),
|
|
365
369
|
totalDocs: total,
|
|
@@ -367,11 +371,11 @@ class PostgresAdapter extends BaseDatabaseAdapter {
|
|
|
367
371
|
totalPages,
|
|
368
372
|
page,
|
|
369
373
|
pagingCounter: offset + 1,
|
|
370
|
-
hasNextPage
|
|
374
|
+
hasNextPage,
|
|
371
375
|
hasPrevPage: page > 1 || !!options?.after || !!options?.before,
|
|
372
376
|
prevPage: page > 1 ? page - 1 : null,
|
|
373
377
|
nextPage: page < totalPages ? page + 1 : null,
|
|
374
|
-
nextCursor: docs.length > 0 ? docs[docs.length - 1][cursorColumn] : null,
|
|
378
|
+
nextCursor: docs.length > 0 && hasNextPage ? docs[docs.length - 1][cursorColumn] : null,
|
|
375
379
|
prevCursor: docs.length > 0 && (page > 1 || !!options?.after || !!options?.before) ? docs[0][cursorColumn] : null
|
|
376
380
|
};
|
|
377
381
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,85 @@
|
|
|
1
|
-
import type { OpacaConfig } from "./types";
|
|
2
1
|
export interface OpacaClientOptions {
|
|
3
2
|
baseURL: string;
|
|
4
3
|
token?: string;
|
|
4
|
+
api?: any;
|
|
5
5
|
}
|
|
6
|
+
export interface OpacaAsset {
|
|
7
|
+
id: string;
|
|
8
|
+
url: string;
|
|
9
|
+
filename: string;
|
|
10
|
+
mime_type: string;
|
|
11
|
+
filesize: number;
|
|
12
|
+
alt_text?: string;
|
|
13
|
+
caption?: string;
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Utility types for automatic type inference from OpacaConfig
|
|
18
|
+
*/
|
|
19
|
+
type MapFieldToType<F> = F extends {
|
|
20
|
+
type: "text" | "textarea" | "richtext" | "slug" | "date" | "select" | "radio";
|
|
21
|
+
} ? string : F extends {
|
|
22
|
+
type: "number";
|
|
23
|
+
} ? number : F extends {
|
|
24
|
+
type: "boolean";
|
|
25
|
+
} ? boolean : F extends {
|
|
26
|
+
type: "json";
|
|
27
|
+
} ? any : F extends {
|
|
28
|
+
type: "file";
|
|
29
|
+
} ? OpacaAsset : F extends {
|
|
30
|
+
type: "relationship";
|
|
31
|
+
} ? F extends {
|
|
32
|
+
hasMany: true;
|
|
33
|
+
} ? any[] : any : F extends {
|
|
34
|
+
type: "array";
|
|
35
|
+
fields: infer Fs;
|
|
36
|
+
} ? Fs extends readonly any[] ? MapFieldsToType<Fs>[] : any[] : F extends {
|
|
37
|
+
type: "group";
|
|
38
|
+
fields: infer Fs;
|
|
39
|
+
} ? Fs extends readonly any[] ? MapFieldsToType<Fs> : any : F extends {
|
|
40
|
+
type: "blocks";
|
|
41
|
+
blocks: infer Bs;
|
|
42
|
+
} ? Bs extends readonly any[] ? MapBlocksToType<Bs>[] : any[] : any;
|
|
43
|
+
type MapBlocksToType<Bs extends readonly any[]> = Bs[number] extends infer B ? B extends {
|
|
44
|
+
slug: infer S;
|
|
45
|
+
fields: infer Fs;
|
|
46
|
+
} ? S extends string ? Fs extends readonly any[] ? MapFieldsToType<Fs> & {
|
|
47
|
+
blockType: S;
|
|
48
|
+
} : never : never : never : never;
|
|
49
|
+
type MapFieldsToType<Fs extends readonly any[]> = {
|
|
50
|
+
[K in Extract<Fs[number], {
|
|
51
|
+
required: true;
|
|
52
|
+
}> as K["name"]]: MapFieldToType<K>;
|
|
53
|
+
} & {
|
|
54
|
+
[K in Fs[number] as K["required"] extends true ? never : K["name"]]?: MapFieldToType<K>;
|
|
55
|
+
};
|
|
56
|
+
type InferCollectionType<C> = C extends {
|
|
57
|
+
__type: infer T;
|
|
58
|
+
} ? T : C extends {
|
|
59
|
+
fields: infer Fs;
|
|
60
|
+
timestamps?: infer T;
|
|
61
|
+
} ? (Fs extends readonly any[] ? MapFieldsToType<Fs> : any) & (T extends true | {
|
|
62
|
+
createdAt?: any;
|
|
63
|
+
updatedAt?: any;
|
|
64
|
+
} ? {
|
|
65
|
+
createdAt: string;
|
|
66
|
+
updatedAt: string;
|
|
67
|
+
} : {}) : any;
|
|
68
|
+
type InferGlobalType<G> = G extends {
|
|
69
|
+
__type: infer T;
|
|
70
|
+
} ? T : G extends {
|
|
71
|
+
fields: infer Fs;
|
|
72
|
+
} ? Fs extends readonly any[] ? MapFieldsToType<Fs> : any : any;
|
|
73
|
+
type InferCollections<T> = T extends {
|
|
74
|
+
collections: infer C;
|
|
75
|
+
} ? C extends readonly any[] ? {
|
|
76
|
+
[K in C[number] as K["slug"]]: InferCollectionType<K>;
|
|
77
|
+
} : Record<string, any> : Record<string, any>;
|
|
78
|
+
type InferGlobals<T> = T extends {
|
|
79
|
+
globals: infer G;
|
|
80
|
+
} ? G extends readonly any[] ? {
|
|
81
|
+
[K in G[number] as K["slug"]]: InferGlobalType<K>;
|
|
82
|
+
} : Record<string, any> : Record<string, any>;
|
|
6
83
|
/**
|
|
7
84
|
* A proxy-based client that provides a typed experience for interacting with the OpacaCMS API.
|
|
8
85
|
*/
|
|
@@ -24,28 +101,29 @@ export declare function createClient<T = any>(configOrOptions: T | OpacaClientOp
|
|
|
24
101
|
getSetupStatus: () => Promise<{
|
|
25
102
|
initialized: boolean;
|
|
26
103
|
}>;
|
|
27
|
-
collections: { [K in
|
|
104
|
+
collections: { [K in (keyof InferCollections<T> extends never ? string : keyof InferCollections<T>) & string]: {
|
|
28
105
|
find: (query?: any) => Promise<{
|
|
29
|
-
docs:
|
|
106
|
+
docs: K extends keyof InferCollections<T> ? InferCollections<T>[K][] : any[];
|
|
30
107
|
totalDocs: number;
|
|
31
108
|
page: number;
|
|
32
109
|
totalPages: number;
|
|
33
110
|
}>;
|
|
34
|
-
findOne: (id: string) => Promise<
|
|
111
|
+
findOne: (id: string) => Promise<K extends keyof InferCollections<T> ? InferCollections<T>[K] : any>;
|
|
35
112
|
list: () => Promise<{
|
|
36
|
-
docs:
|
|
113
|
+
docs: K extends keyof InferCollections<T> ? InferCollections<T>[K][] : any[];
|
|
37
114
|
totalDocs: number;
|
|
38
115
|
page: number;
|
|
39
116
|
totalPages: number;
|
|
40
117
|
}>;
|
|
41
|
-
create: (data: Partial<
|
|
42
|
-
update: (id: string, data: Partial<
|
|
118
|
+
create: (data: Partial<K extends keyof InferCollections<T> ? InferCollections<T>[K] : any>) => Promise<K extends keyof InferCollections<T> ? InferCollections<T>[K] : any>;
|
|
119
|
+
update: (id: string, data: Partial<K extends keyof InferCollections<T> ? InferCollections<T>[K] : any>) => Promise<K extends keyof InferCollections<T> ? InferCollections<T>[K] : any>;
|
|
43
120
|
delete: (id: string) => Promise<{
|
|
44
121
|
success: boolean;
|
|
45
122
|
}>;
|
|
46
123
|
}; };
|
|
47
|
-
globals: { [K in
|
|
48
|
-
get: () => Promise<
|
|
49
|
-
update: (data: Partial<
|
|
124
|
+
globals: { [K in (keyof InferGlobals<T> extends never ? string : keyof InferGlobals<T>) & string]: {
|
|
125
|
+
get: () => Promise<K extends keyof InferGlobals<T> ? InferGlobals<T>[K] : any>;
|
|
126
|
+
update: (data: Partial<K extends keyof InferGlobals<T> ? InferGlobals<T>[K] : any>) => Promise<any>;
|
|
50
127
|
}; };
|
|
51
128
|
};
|
|
129
|
+
export {};
|
package/dist/client.js
CHANGED
package/dist/config.d.ts
CHANGED
|
@@ -23,5 +23,12 @@ export declare function defineConfig<const TCollections extends readonly Buildab
|
|
|
23
23
|
}>[] = [], TResource extends string = ResourceOf<TCollections, TGlobals>>(config: Omit<OpacaConfig<TResource>, "collections" | "globals"> & {
|
|
24
24
|
collections: TCollections;
|
|
25
25
|
globals?: TGlobals;
|
|
26
|
-
}): OpacaConfig<TResource
|
|
26
|
+
}): Omit<OpacaConfig<TResource>, "collections" | "globals"> & {
|
|
27
|
+
collections: {
|
|
28
|
+
[K in keyof TCollections]: BuiltResource<TCollections[K]>;
|
|
29
|
+
};
|
|
30
|
+
globals: {
|
|
31
|
+
[K in keyof TGlobals]: BuiltResource<TGlobals[K]>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
27
34
|
export {};
|
package/dist/db/better-sqlite.js
CHANGED
package/dist/db/bun-sqlite.js
CHANGED
package/dist/db/d1.js
CHANGED
package/dist/db/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
D1Adapter,
|
|
3
3
|
createD1Adapter
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-5b9eqr34.js";
|
|
5
5
|
import {
|
|
6
6
|
PostgresAdapter,
|
|
7
7
|
createPostgresAdapter
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-tsmhn78f.js";
|
|
9
9
|
import {
|
|
10
10
|
SQLiteAdapter,
|
|
11
11
|
createSQLiteAdapter
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-nz6xhtja.js";
|
|
13
13
|
import {
|
|
14
14
|
BunSQLiteAdapter,
|
|
15
15
|
createBunSQLiteAdapter
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-qsefknd3.js";
|
|
17
17
|
import {
|
|
18
18
|
BetterSQLiteAdapter,
|
|
19
19
|
createBetterSQLiteAdapter
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-dz5bh1bd.js";
|
|
21
21
|
import"../chunk-re459gm9.js";
|
|
22
22
|
import {
|
|
23
23
|
BaseDatabaseAdapter
|
package/dist/db/postgres.js
CHANGED
package/dist/db/sqlite.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Faker } from "@faker-js/faker";
|
|
2
2
|
import type { AccessConfig, CollectionHooks, LucideIcons } from "@/types";
|
|
3
3
|
import { type ZodObject, type ZodRawShape, type infer as zInfer } from "./zod";
|
|
4
|
-
export interface CollectionConfig<T = any> {
|
|
5
|
-
slug:
|
|
4
|
+
export interface CollectionConfig<T = any, S extends string = string> {
|
|
5
|
+
slug: S;
|
|
6
6
|
label?: string;
|
|
7
7
|
admin?: {
|
|
8
8
|
useAsTitle?: string;
|
|
@@ -58,19 +58,19 @@ export interface CollectionConfig<T = any> {
|
|
|
58
58
|
*/
|
|
59
59
|
seed?: (faker: Faker) => Partial<T> | Promise<Partial<T>>;
|
|
60
60
|
}
|
|
61
|
-
export interface DefineCollectionArgs<T extends ZodRawShape> extends CollectionConfig<zInfer<ZodObject<T
|
|
61
|
+
export interface DefineCollectionArgs<T extends ZodRawShape, S extends string> extends CollectionConfig<zInfer<ZodObject<T>>, S> {
|
|
62
62
|
schema: ZodObject<T>;
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Replaces the legacy Collection.create() Builder API.
|
|
66
66
|
* Wraps a Zod Schema and attaches collection-level metadata to it.
|
|
67
67
|
*/
|
|
68
|
-
export declare function defineCollection<T extends ZodRawShape>(config: DefineCollectionArgs<T>): {
|
|
68
|
+
export declare function defineCollection<T extends ZodRawShape, S extends string>(config: DefineCollectionArgs<T, S>): {
|
|
69
69
|
schema: ZodObject<T, import("better-auth").$strip>;
|
|
70
70
|
fields: any[];
|
|
71
71
|
seed: ((faker: Faker) => Partial<import("better-auth").$InferObjectOutput<T, {}>> | Promise<Partial<import("better-auth").$InferObjectOutput<T, {}>>>) | undefined;
|
|
72
72
|
__type: zInfer<ZodObject<T, import("better-auth").$strip>>;
|
|
73
|
-
slug:
|
|
73
|
+
slug: S;
|
|
74
74
|
label?: string;
|
|
75
75
|
admin?: {
|
|
76
76
|
useAsTitle?: string;
|
package/dist/schema/global.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Faker } from "@faker-js/faker";
|
|
2
2
|
import { type ZodObject, type ZodRawShape, type infer as zInfer } from "./zod";
|
|
3
|
-
export interface GlobalConfig {
|
|
4
|
-
slug:
|
|
3
|
+
export interface GlobalConfig<S extends string = string> {
|
|
4
|
+
slug: S;
|
|
5
5
|
label?: string;
|
|
6
6
|
admin?: {
|
|
7
7
|
hidden?: boolean;
|
|
@@ -19,18 +19,18 @@ export interface GlobalConfig {
|
|
|
19
19
|
*/
|
|
20
20
|
seed?: (faker: Faker) => any | Promise<any>;
|
|
21
21
|
}
|
|
22
|
-
export interface DefineGlobalArgs<T extends ZodRawShape> extends GlobalConfig {
|
|
22
|
+
export interface DefineGlobalArgs<T extends ZodRawShape, S extends string> extends GlobalConfig<S> {
|
|
23
23
|
schema: ZodObject<T>;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Zod-based replacement for the legacy GlobalBuilder.
|
|
27
27
|
*/
|
|
28
|
-
export declare function defineGlobal<T extends ZodRawShape>(config: DefineGlobalArgs<T>): {
|
|
28
|
+
export declare function defineGlobal<T extends ZodRawShape, S extends string>(config: DefineGlobalArgs<T, S>): {
|
|
29
29
|
schema: ZodObject<T, import("better-auth").$strip>;
|
|
30
30
|
fields: any[];
|
|
31
31
|
seed: ((faker: Faker) => any | Promise<any>) | undefined;
|
|
32
32
|
__type: zInfer<ZodObject<T, import("better-auth").$strip>>;
|
|
33
|
-
slug:
|
|
33
|
+
slug: S;
|
|
34
34
|
label?: string;
|
|
35
35
|
admin?: {
|
|
36
36
|
hidden?: boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
export interface AccessArgs {
|
|
3
|
+
req: Context;
|
|
4
|
+
user: any;
|
|
5
|
+
session: any;
|
|
6
|
+
apiKey: any;
|
|
7
|
+
/** The document being created/updated or the search query */
|
|
8
|
+
data?: any;
|
|
9
|
+
/** The ID of the document being read/updated/deleted */
|
|
10
|
+
id?: string;
|
|
11
|
+
operation: "read" | "create" | "update" | "delete";
|
|
12
|
+
}
|
|
13
|
+
export interface AccessConfig {
|
|
14
|
+
read?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
15
|
+
create?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
16
|
+
update?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
17
|
+
delete?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
18
|
+
requireApiKey?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface FieldAccessArgs extends AccessArgs {
|
|
21
|
+
field: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FieldAccessConfig {
|
|
24
|
+
/** If true, the field is removed from API and UI. */
|
|
25
|
+
hidden?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
26
|
+
/** If true, the data is shown but cannot be edited. */
|
|
27
|
+
readOnly?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
28
|
+
/** If true, the input is visually disabled. */
|
|
29
|
+
disabled?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
30
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { Context } from "hono";
|
|
|
4
4
|
import type { icons } from "lucide-react";
|
|
5
5
|
import type { z } from "zod";
|
|
6
6
|
import type { AdminConfig, FieldType } from "./validation";
|
|
7
|
+
import type { AccessArgs, AccessConfig, FieldAccessArgs, FieldAccessConfig } from "./types/access";
|
|
8
|
+
export type { AccessArgs, AccessConfig, FieldAccessArgs, FieldAccessConfig };
|
|
7
9
|
export type { FieldType };
|
|
8
10
|
export type Session = BetterAuthSession;
|
|
9
11
|
export type User = Prettify<BetterAuthUser & {
|
|
@@ -273,15 +275,6 @@ export interface ApiKey {
|
|
|
273
275
|
permissions?: Record<string, string[]> | null;
|
|
274
276
|
referenceId: string;
|
|
275
277
|
}
|
|
276
|
-
export interface AccessArgs {
|
|
277
|
-
req: Context;
|
|
278
|
-
user: User | null;
|
|
279
|
-
session: Session | null;
|
|
280
|
-
apiKey?: ApiKey | null;
|
|
281
|
-
data?: any;
|
|
282
|
-
id?: string;
|
|
283
|
-
operation: "read" | "create" | "update" | "delete";
|
|
284
|
-
}
|
|
285
278
|
export interface CollectionHookArgs<T = any> {
|
|
286
279
|
req: Context;
|
|
287
280
|
user: User | null;
|
|
@@ -293,21 +286,6 @@ export interface CollectionHookArgs<T = any> {
|
|
|
293
286
|
id?: string;
|
|
294
287
|
operation: "create" | "update" | "delete";
|
|
295
288
|
}
|
|
296
|
-
export interface FieldAccessConfig {
|
|
297
|
-
/** If true, the field is removed from API and UI. */
|
|
298
|
-
hidden?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
299
|
-
/** If true, the data is shown but cannot be edited. */
|
|
300
|
-
readOnly?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
301
|
-
/** If true, the input is visually disabled. */
|
|
302
|
-
disabled?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
303
|
-
}
|
|
304
|
-
export interface AccessConfig {
|
|
305
|
-
read?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
306
|
-
create?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
307
|
-
update?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
308
|
-
delete?: boolean | ((args: AccessArgs) => boolean | Promise<boolean>);
|
|
309
|
-
requireApiKey?: boolean;
|
|
310
|
-
}
|
|
311
289
|
export interface CollectionHooks<T = any> {
|
|
312
290
|
beforeCreate?: (args: CollectionHookArgs<T>) => T | Promise<T> | void;
|
|
313
291
|
afterCreate?: (args: CollectionHookArgs<T>) => void | Promise<void>;
|
package/dist/validation.d.ts
CHANGED
|
@@ -3,22 +3,22 @@ export declare const FieldTypeSchema: z.ZodEnum<{
|
|
|
3
3
|
number: "number";
|
|
4
4
|
boolean: "boolean";
|
|
5
5
|
text: "text";
|
|
6
|
-
json: "json";
|
|
7
|
-
join: "join";
|
|
8
|
-
slug: "slug";
|
|
9
6
|
textarea: "textarea";
|
|
10
7
|
richtext: "richtext";
|
|
11
|
-
|
|
8
|
+
slug: "slug";
|
|
9
|
+
date: "date";
|
|
12
10
|
select: "select";
|
|
13
11
|
radio: "radio";
|
|
14
|
-
|
|
12
|
+
json: "json";
|
|
15
13
|
file: "file";
|
|
16
|
-
|
|
14
|
+
relationship: "relationship";
|
|
15
|
+
array: "array";
|
|
17
16
|
group: "group";
|
|
17
|
+
blocks: "blocks";
|
|
18
|
+
join: "join";
|
|
18
19
|
row: "row";
|
|
19
20
|
collapsible: "collapsible";
|
|
20
21
|
tabs: "tabs";
|
|
21
|
-
array: "array";
|
|
22
22
|
virtual: "virtual";
|
|
23
23
|
ui: "ui";
|
|
24
24
|
}>;
|