opacacms 0.1.7 → 0.1.8
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/admin/index.js +255 -20
- package/dist/admin/webcomponent.js +291 -46
- package/dist/cli/index.js +3638 -30
- package/dist/client.js +126 -5
- package/dist/db/bun-sqlite.js +790 -21
- package/dist/db/d1.js +788 -19
- package/dist/db/index.js +53 -4
- package/dist/db/postgres.js +792 -23
- package/dist/db/sqlite.js +788 -19
- package/dist/index.js +456 -8
- package/dist/runtimes/bun.js +1909 -8
- package/dist/runtimes/cloudflare-workers.js +1910 -9
- package/dist/runtimes/next.js +1908 -7
- package/dist/runtimes/node.js +1909 -8
- package/dist/schema/collection.d.ts +3 -7
- package/dist/schema/fields/index.d.ts +24 -25
- package/dist/schema/global.d.ts +9 -9
- package/dist/schema/index.d.ts +30 -4
- package/dist/schema/index.js +546 -1
- package/dist/server.js +2246 -17
- package/dist/storage/index.js +40 -1
- package/package.json +1 -1
- package/dist/chunk-16vgcf3k.js +0 -88
- package/dist/chunk-2yz1nsxs.js +0 -126
- package/dist/chunk-5gvbp2qa.js +0 -167
- package/dist/chunk-62ev8gnc.js +0 -41
- package/dist/chunk-6ew02s0c.js +0 -472
- package/dist/chunk-7a9kn0np.js +0 -116
- package/dist/chunk-8sqjbsgt.js +0 -42
- package/dist/chunk-9kxpbcb1.js +0 -85
- package/dist/chunk-cvdd4eqh.js +0 -110
- package/dist/chunk-d3ffeqp9.js +0 -87
- package/dist/chunk-fa5mg0hr.js +0 -96
- package/dist/chunk-j4d50hrx.js +0 -20
- package/dist/chunk-jwjk85ze.js +0 -15
- package/dist/chunk-m09hahe2.js +0 -250
- package/dist/chunk-s8mqwnm1.js +0 -14
- package/dist/chunk-srsac177.js +0 -85
- package/dist/chunk-v521d72w.js +0 -10
- package/dist/chunk-vtvqfhgy.js +0 -2442
- package/dist/chunk-xa7rjsn2.js +0 -20
- package/dist/chunk-xg35h5a3.js +0 -15
- package/dist/chunk-y8hc6nm4.js +0 -17
- package/dist/chunk-ybbbqj63.js +0 -130
- package/dist/chunk-yr32cp7h.js +0 -1603
- package/dist/chunk-zvwb67nd.js +0 -332
package/dist/admin/index.js
CHANGED
|
@@ -1,25 +1,260 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
function __accessProp(key) {
|
|
7
|
+
return this[key];
|
|
8
|
+
}
|
|
9
|
+
var __toCommonJS = (from) => {
|
|
10
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
11
|
+
if (entry)
|
|
12
|
+
return entry;
|
|
13
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (var key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(entry, key))
|
|
17
|
+
__defProp(entry, key, {
|
|
18
|
+
get: __accessProp.bind(from, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
__moduleCache.set(from, entry);
|
|
23
|
+
return entry;
|
|
24
|
+
};
|
|
25
|
+
var __moduleCache;
|
|
26
|
+
var __returnValue = (v) => v;
|
|
27
|
+
function __exportSetter(name, newValue) {
|
|
28
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
29
|
+
}
|
|
30
|
+
var __export = (target, all) => {
|
|
31
|
+
for (var name in all)
|
|
32
|
+
__defProp(target, name, {
|
|
33
|
+
get: all[name],
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
set: __exportSetter.bind(all, name)
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
40
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
|
+
|
|
42
|
+
// src/admin/auth-client.ts
|
|
43
|
+
import { createAuthClient } from "better-auth/client";
|
|
44
|
+
import { adminClient } from "better-auth/client/plugins";
|
|
45
|
+
var client = null, currentURL = null, configureAuth = (serverUrl) => {
|
|
46
|
+
if (!serverUrl || !serverUrl.startsWith("http"))
|
|
47
|
+
return;
|
|
48
|
+
const url = serverUrl;
|
|
49
|
+
const baseURL = url.replace(/\/$/, "") + "/api/auth";
|
|
50
|
+
if (client && currentURL === baseURL)
|
|
51
|
+
return;
|
|
52
|
+
currentURL = baseURL;
|
|
53
|
+
client = createAuthClient({
|
|
54
|
+
baseURL,
|
|
55
|
+
autoRefresh: true,
|
|
56
|
+
fetchOptions: {
|
|
57
|
+
credentials: "include"
|
|
58
|
+
},
|
|
59
|
+
plugins: [adminClient()]
|
|
60
|
+
});
|
|
61
|
+
}, authClient;
|
|
62
|
+
var init_auth_client = __esm(() => {
|
|
63
|
+
authClient = new Proxy({}, {
|
|
64
|
+
get(_, prop) {
|
|
65
|
+
if (!client) {
|
|
66
|
+
throw new Error("Auth client not configured. Did you provide a valid serverUrl?");
|
|
67
|
+
}
|
|
68
|
+
return client[prop];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// src/admin/stores/ui.ts
|
|
74
|
+
var exports_ui = {};
|
|
75
|
+
__export(exports_ui, {
|
|
76
|
+
toggleSidebar: () => toggleSidebar,
|
|
77
|
+
notify: () => notify,
|
|
78
|
+
clearToast: () => clearToast,
|
|
79
|
+
$toasts: () => $toasts,
|
|
80
|
+
$isSidebarCollapsed: () => $isSidebarCollapsed
|
|
81
|
+
});
|
|
82
|
+
import { persistentAtom } from "@nanostores/persistent";
|
|
83
|
+
import { atom as atom2 } from "nanostores";
|
|
84
|
+
function toggleSidebar() {
|
|
85
|
+
$isSidebarCollapsed.set(!$isSidebarCollapsed.get());
|
|
86
|
+
}
|
|
87
|
+
function notify(message, type = "success") {
|
|
88
|
+
const id = Math.random().toString(36).substring(2, 9);
|
|
89
|
+
$toasts.set([...$toasts.get(), { id, message, type }]);
|
|
90
|
+
}
|
|
91
|
+
function clearToast(id) {
|
|
92
|
+
$toasts.set($toasts.get().filter((t) => t.id !== id));
|
|
93
|
+
}
|
|
94
|
+
var $toasts, $isSidebarCollapsed;
|
|
95
|
+
var init_ui = __esm(() => {
|
|
96
|
+
$toasts = atom2([]);
|
|
97
|
+
$isSidebarCollapsed = persistentAtom("opaca-sidebar-collapsed", false, {
|
|
98
|
+
encode: JSON.stringify,
|
|
99
|
+
decode: JSON.parse
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// src/admin/stores/auth.ts
|
|
104
|
+
var exports_auth = {};
|
|
105
|
+
__export(exports_auth, {
|
|
106
|
+
syncSession: () => syncSession,
|
|
107
|
+
logout: () => logout,
|
|
108
|
+
login: () => login,
|
|
109
|
+
$user: () => $user,
|
|
110
|
+
$session: () => $session,
|
|
111
|
+
$isAuthenticated: () => $isAuthenticated,
|
|
112
|
+
$isAuthPending: () => $isAuthPending
|
|
113
|
+
});
|
|
114
|
+
import { atom as atom3, computed } from "nanostores";
|
|
115
|
+
async function syncSession() {
|
|
116
|
+
$isAuthPending.set(true);
|
|
117
|
+
try {
|
|
118
|
+
const res = await authClient.getSession();
|
|
119
|
+
$session.set(res.data);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error("[OpacaCMS] Failed to sync session:", err);
|
|
122
|
+
} finally {
|
|
123
|
+
$isAuthPending.set(false);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function login(data) {
|
|
127
|
+
$isAuthPending.set(true);
|
|
128
|
+
try {
|
|
129
|
+
const res = await authClient.signIn.email({
|
|
130
|
+
email: data.email,
|
|
131
|
+
password: data.password
|
|
132
|
+
});
|
|
133
|
+
if (res.error) {
|
|
134
|
+
throw new Error(res.error.message || "Invalid credentials");
|
|
135
|
+
}
|
|
136
|
+
await syncSession();
|
|
137
|
+
notify("Logged in successfully", "success");
|
|
138
|
+
return res;
|
|
139
|
+
} catch (error) {
|
|
140
|
+
notify(error instanceof Error ? error.message : "Login failed", "error");
|
|
141
|
+
throw error;
|
|
142
|
+
} finally {
|
|
143
|
+
$isAuthPending.set(false);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function logout() {
|
|
147
|
+
$isAuthPending.set(true);
|
|
148
|
+
try {
|
|
149
|
+
await authClient.signOut();
|
|
150
|
+
$session.set(null);
|
|
151
|
+
notify("Logged out successfully");
|
|
152
|
+
} catch {
|
|
153
|
+
notify("Logout failed", "error");
|
|
154
|
+
} finally {
|
|
155
|
+
$isAuthPending.set(false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
var $session, $isAuthPending, $user, $isAuthenticated;
|
|
159
|
+
var init_auth = __esm(() => {
|
|
160
|
+
init_auth_client();
|
|
161
|
+
init_ui();
|
|
162
|
+
$session = atom3(null);
|
|
163
|
+
$isAuthPending = atom3(true);
|
|
164
|
+
$user = computed($session, (session) => session?.user ?? null);
|
|
165
|
+
$isAuthenticated = computed($session, (session) => !!session);
|
|
166
|
+
});
|
|
167
|
+
// src/admin/router.ts
|
|
168
|
+
import { createRouter } from "@nanostores/router";
|
|
169
|
+
var $router = createRouter({
|
|
170
|
+
dashboard: "/admin",
|
|
171
|
+
collections: "/admin/collections/:slug",
|
|
172
|
+
document: "/admin/collections/:slug/:id",
|
|
173
|
+
globals: "/admin/globals/:slug",
|
|
174
|
+
settings: "/admin/settings"
|
|
175
|
+
});
|
|
176
|
+
// src/admin/stores/config.ts
|
|
177
|
+
import { atom } from "nanostores";
|
|
178
|
+
var $config = atom(null);
|
|
179
|
+
var $needsInit = atom(false);
|
|
180
|
+
var $isFetchingConfig = atom(false);
|
|
181
|
+
var $hasMetadataError = atom(false);
|
|
182
|
+
function setConfig(config) {
|
|
183
|
+
$config.set(config);
|
|
184
|
+
}
|
|
185
|
+
function setNeedsInit(needs) {
|
|
186
|
+
$needsInit.set(needs);
|
|
187
|
+
}
|
|
188
|
+
// src/admin/stores/query.ts
|
|
189
|
+
import { nanoquery } from "@nanostores/query";
|
|
190
|
+
|
|
191
|
+
// src/admin/api-client.ts
|
|
192
|
+
import ky from "ky";
|
|
193
|
+
var client2 = null;
|
|
194
|
+
var currentBaseURL = null;
|
|
195
|
+
var configureAPI = (serverUrl) => {
|
|
196
|
+
if (!serverUrl || !serverUrl.startsWith("http"))
|
|
197
|
+
return;
|
|
198
|
+
const url = serverUrl;
|
|
199
|
+
const baseURL = url.replace(/\/$/, "");
|
|
200
|
+
if (client2 && currentBaseURL === baseURL)
|
|
201
|
+
return;
|
|
202
|
+
currentBaseURL = baseURL;
|
|
203
|
+
client2 = ky.create({
|
|
204
|
+
prefixUrl: baseURL,
|
|
205
|
+
credentials: "include",
|
|
206
|
+
retry: 0,
|
|
207
|
+
hooks: {
|
|
208
|
+
afterResponse: [
|
|
209
|
+
async (_request, _options, response) => {
|
|
210
|
+
if (response.status === 401 || response.status === 403) {
|
|
211
|
+
try {
|
|
212
|
+
const { $session: $session2 } = await Promise.resolve().then(() => (init_auth(), exports_auth));
|
|
213
|
+
const { notify: notify2 } = await Promise.resolve().then(() => (init_ui(), exports_ui));
|
|
214
|
+
$session2.set(null);
|
|
215
|
+
notify2("Session expired. Please log in again.", "error");
|
|
216
|
+
} catch (e) {}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
var getCurrentBaseURL = () => {
|
|
224
|
+
if (!currentBaseURL) {
|
|
225
|
+
throw new Error("API client not configured. Did you provide a valid serverUrl?");
|
|
226
|
+
}
|
|
227
|
+
return currentBaseURL;
|
|
228
|
+
};
|
|
229
|
+
var api = new Proxy({}, {
|
|
230
|
+
get(_, prop) {
|
|
231
|
+
if (!client2) {
|
|
232
|
+
throw new Error("API client not configured. Did you provide a valid serverUrl?");
|
|
233
|
+
}
|
|
234
|
+
if (!client2)
|
|
235
|
+
throw new Error("API client not configured");
|
|
236
|
+
const c = client2;
|
|
237
|
+
if (c) {
|
|
238
|
+
return c[prop];
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// src/admin/stores/query.ts
|
|
245
|
+
var [
|
|
7
246
|
createFetcherStore,
|
|
8
247
|
createMutatorStore,
|
|
9
|
-
invalidateKeys,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
notify,
|
|
20
|
-
toggleSidebar
|
|
21
|
-
} from "../chunk-j4d50hrx.js";
|
|
22
|
-
import"../chunk-8sqjbsgt.js";
|
|
248
|
+
{ invalidateKeys, revalidateKeys, mutateCache }
|
|
249
|
+
] = nanoquery({
|
|
250
|
+
fetcher: (...keys) => {
|
|
251
|
+
const url = keys.join("");
|
|
252
|
+
return api.get(url).json();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// src/admin/index.ts
|
|
257
|
+
init_ui();
|
|
23
258
|
export {
|
|
24
259
|
toggleSidebar,
|
|
25
260
|
setNeedsInit,
|
|
@@ -1,32 +1,169 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
function __accessProp(key) {
|
|
7
|
+
return this[key];
|
|
8
|
+
}
|
|
9
|
+
var __toCommonJS = (from) => {
|
|
10
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
11
|
+
if (entry)
|
|
12
|
+
return entry;
|
|
13
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (var key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(entry, key))
|
|
17
|
+
__defProp(entry, key, {
|
|
18
|
+
get: __accessProp.bind(from, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
__moduleCache.set(from, entry);
|
|
23
|
+
return entry;
|
|
24
|
+
};
|
|
25
|
+
var __moduleCache;
|
|
26
|
+
var __returnValue = (v) => v;
|
|
27
|
+
function __exportSetter(name, newValue) {
|
|
28
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
29
|
+
}
|
|
30
|
+
var __export = (target, all) => {
|
|
31
|
+
for (var name in all)
|
|
32
|
+
__defProp(target, name, {
|
|
33
|
+
get: all[name],
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
set: __exportSetter.bind(all, name)
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
40
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
|
+
|
|
42
|
+
// src/admin/auth-client.ts
|
|
43
|
+
import { createAuthClient } from "better-auth/client";
|
|
44
|
+
import { adminClient } from "better-auth/client/plugins";
|
|
45
|
+
var client = null, currentURL = null, configureAuth = (serverUrl) => {
|
|
46
|
+
if (!serverUrl || !serverUrl.startsWith("http"))
|
|
47
|
+
return;
|
|
48
|
+
const url = serverUrl;
|
|
49
|
+
const baseURL = url.replace(/\/$/, "") + "/api/auth";
|
|
50
|
+
if (client && currentURL === baseURL)
|
|
51
|
+
return;
|
|
52
|
+
currentURL = baseURL;
|
|
53
|
+
client = createAuthClient({
|
|
54
|
+
baseURL,
|
|
55
|
+
autoRefresh: true,
|
|
56
|
+
fetchOptions: {
|
|
57
|
+
credentials: "include"
|
|
58
|
+
},
|
|
59
|
+
plugins: [adminClient()]
|
|
60
|
+
});
|
|
61
|
+
}, authClient;
|
|
62
|
+
var init_auth_client = __esm(() => {
|
|
63
|
+
authClient = new Proxy({}, {
|
|
64
|
+
get(_, prop) {
|
|
65
|
+
if (!client) {
|
|
66
|
+
throw new Error("Auth client not configured. Did you provide a valid serverUrl?");
|
|
67
|
+
}
|
|
68
|
+
return client[prop];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// src/admin/stores/ui.ts
|
|
74
|
+
var exports_ui = {};
|
|
75
|
+
__export(exports_ui, {
|
|
76
|
+
toggleSidebar: () => toggleSidebar,
|
|
77
|
+
notify: () => notify,
|
|
78
|
+
clearToast: () => clearToast,
|
|
79
|
+
$toasts: () => $toasts,
|
|
80
|
+
$isSidebarCollapsed: () => $isSidebarCollapsed
|
|
81
|
+
});
|
|
82
|
+
import { persistentAtom } from "@nanostores/persistent";
|
|
83
|
+
import { atom } from "nanostores";
|
|
84
|
+
function toggleSidebar() {
|
|
85
|
+
$isSidebarCollapsed.set(!$isSidebarCollapsed.get());
|
|
86
|
+
}
|
|
87
|
+
function notify(message, type = "success") {
|
|
88
|
+
const id = Math.random().toString(36).substring(2, 9);
|
|
89
|
+
$toasts.set([...$toasts.get(), { id, message, type }]);
|
|
90
|
+
}
|
|
91
|
+
function clearToast(id) {
|
|
92
|
+
$toasts.set($toasts.get().filter((t) => t.id !== id));
|
|
93
|
+
}
|
|
94
|
+
var $toasts, $isSidebarCollapsed;
|
|
95
|
+
var init_ui = __esm(() => {
|
|
96
|
+
$toasts = atom([]);
|
|
97
|
+
$isSidebarCollapsed = persistentAtom("opaca-sidebar-collapsed", false, {
|
|
98
|
+
encode: JSON.stringify,
|
|
99
|
+
decode: JSON.parse
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// src/admin/stores/auth.ts
|
|
104
|
+
var exports_auth = {};
|
|
105
|
+
__export(exports_auth, {
|
|
106
|
+
syncSession: () => syncSession,
|
|
107
|
+
logout: () => logout,
|
|
108
|
+
login: () => login,
|
|
109
|
+
$user: () => $user,
|
|
110
|
+
$session: () => $session,
|
|
111
|
+
$isAuthenticated: () => $isAuthenticated,
|
|
112
|
+
$isAuthPending: () => $isAuthPending
|
|
113
|
+
});
|
|
114
|
+
import { atom as atom2, computed } from "nanostores";
|
|
115
|
+
async function syncSession() {
|
|
116
|
+
$isAuthPending.set(true);
|
|
117
|
+
try {
|
|
118
|
+
const res = await authClient.getSession();
|
|
119
|
+
$session.set(res.data);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error("[OpacaCMS] Failed to sync session:", err);
|
|
122
|
+
} finally {
|
|
123
|
+
$isAuthPending.set(false);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function login(data) {
|
|
127
|
+
$isAuthPending.set(true);
|
|
128
|
+
try {
|
|
129
|
+
const res = await authClient.signIn.email({
|
|
130
|
+
email: data.email,
|
|
131
|
+
password: data.password
|
|
132
|
+
});
|
|
133
|
+
if (res.error) {
|
|
134
|
+
throw new Error(res.error.message || "Invalid credentials");
|
|
135
|
+
}
|
|
136
|
+
await syncSession();
|
|
137
|
+
notify("Logged in successfully", "success");
|
|
138
|
+
return res;
|
|
139
|
+
} catch (error) {
|
|
140
|
+
notify(error instanceof Error ? error.message : "Login failed", "error");
|
|
141
|
+
throw error;
|
|
142
|
+
} finally {
|
|
143
|
+
$isAuthPending.set(false);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function logout() {
|
|
147
|
+
$isAuthPending.set(true);
|
|
148
|
+
try {
|
|
149
|
+
await authClient.signOut();
|
|
150
|
+
$session.set(null);
|
|
151
|
+
notify("Logged out successfully");
|
|
152
|
+
} catch {
|
|
153
|
+
notify("Logout failed", "error");
|
|
154
|
+
} finally {
|
|
155
|
+
$isAuthPending.set(false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
var $session, $isAuthPending, $user, $isAuthenticated;
|
|
159
|
+
var init_auth = __esm(() => {
|
|
160
|
+
init_auth_client();
|
|
161
|
+
init_ui();
|
|
162
|
+
$session = atom2(null);
|
|
163
|
+
$isAuthPending = atom2(true);
|
|
164
|
+
$user = computed($session, (session) => session?.user ?? null);
|
|
165
|
+
$isAuthenticated = computed($session, (session) => !!session);
|
|
166
|
+
});
|
|
30
167
|
|
|
31
168
|
// src/admin/webcomponent.tsx
|
|
32
169
|
import r2wc from "@r2wc/react-to-web-component";
|
|
@@ -36,6 +173,91 @@ import { useStore as useStore10 } from "@nanostores/react";
|
|
|
36
173
|
import { Loader2 as Loader211 } from "lucide-react";
|
|
37
174
|
import { useCallback as useCallback10, useEffect as useEffect19, useState as useState26 } from "react";
|
|
38
175
|
|
|
176
|
+
// src/admin/api-client.ts
|
|
177
|
+
import ky from "ky";
|
|
178
|
+
var client2 = null;
|
|
179
|
+
var currentBaseURL = null;
|
|
180
|
+
var configureAPI = (serverUrl) => {
|
|
181
|
+
if (!serverUrl || !serverUrl.startsWith("http"))
|
|
182
|
+
return;
|
|
183
|
+
const url = serverUrl;
|
|
184
|
+
const baseURL = url.replace(/\/$/, "");
|
|
185
|
+
if (client2 && currentBaseURL === baseURL)
|
|
186
|
+
return;
|
|
187
|
+
currentBaseURL = baseURL;
|
|
188
|
+
client2 = ky.create({
|
|
189
|
+
prefixUrl: baseURL,
|
|
190
|
+
credentials: "include",
|
|
191
|
+
retry: 0,
|
|
192
|
+
hooks: {
|
|
193
|
+
afterResponse: [
|
|
194
|
+
async (_request, _options, response) => {
|
|
195
|
+
if (response.status === 401 || response.status === 403) {
|
|
196
|
+
try {
|
|
197
|
+
const { $session: $session2 } = await Promise.resolve().then(() => (init_auth(), exports_auth));
|
|
198
|
+
const { notify: notify2 } = await Promise.resolve().then(() => (init_ui(), exports_ui));
|
|
199
|
+
$session2.set(null);
|
|
200
|
+
notify2("Session expired. Please log in again.", "error");
|
|
201
|
+
} catch (e) {}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
var getCurrentBaseURL = () => {
|
|
209
|
+
if (!currentBaseURL) {
|
|
210
|
+
throw new Error("API client not configured. Did you provide a valid serverUrl?");
|
|
211
|
+
}
|
|
212
|
+
return currentBaseURL;
|
|
213
|
+
};
|
|
214
|
+
var api = new Proxy({}, {
|
|
215
|
+
get(_, prop) {
|
|
216
|
+
if (!client2) {
|
|
217
|
+
throw new Error("API client not configured. Did you provide a valid serverUrl?");
|
|
218
|
+
}
|
|
219
|
+
if (!client2)
|
|
220
|
+
throw new Error("API client not configured");
|
|
221
|
+
const c = client2;
|
|
222
|
+
if (c) {
|
|
223
|
+
return c[prop];
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// src/admin/ui/admin-client.tsx
|
|
230
|
+
init_auth_client();
|
|
231
|
+
|
|
232
|
+
// src/admin/router.ts
|
|
233
|
+
import { createRouter } from "@nanostores/router";
|
|
234
|
+
var $router = createRouter({
|
|
235
|
+
dashboard: "/admin",
|
|
236
|
+
collections: "/admin/collections/:slug",
|
|
237
|
+
document: "/admin/collections/:slug/:id",
|
|
238
|
+
globals: "/admin/globals/:slug",
|
|
239
|
+
settings: "/admin/settings"
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// src/admin/ui/admin-client.tsx
|
|
243
|
+
init_auth();
|
|
244
|
+
|
|
245
|
+
// src/admin/stores/config.ts
|
|
246
|
+
import { atom as atom3 } from "nanostores";
|
|
247
|
+
var $config = atom3(null);
|
|
248
|
+
var $needsInit = atom3(false);
|
|
249
|
+
var $isFetchingConfig = atom3(false);
|
|
250
|
+
var $hasMetadataError = atom3(false);
|
|
251
|
+
function setConfig(config) {
|
|
252
|
+
$config.set(config);
|
|
253
|
+
}
|
|
254
|
+
function setNeedsInit(needs) {
|
|
255
|
+
$needsInit.set(needs);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/admin/ui/admin-client.tsx
|
|
259
|
+
init_ui();
|
|
260
|
+
|
|
39
261
|
// src/admin/ui/admin-layout.tsx
|
|
40
262
|
import { useStore } from "@nanostores/react";
|
|
41
263
|
import * as LucideIcons from "lucide-react";
|
|
@@ -49,6 +271,7 @@ import {
|
|
|
49
271
|
LogOut,
|
|
50
272
|
Settings
|
|
51
273
|
} from "lucide-react";
|
|
274
|
+
init_ui();
|
|
52
275
|
|
|
53
276
|
// src/admin/ui/components/link.tsx
|
|
54
277
|
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
@@ -1313,9 +1536,24 @@ function traverseNodes(children) {
|
|
|
1313
1536
|
}
|
|
1314
1537
|
|
|
1315
1538
|
// src/admin/stores/admin-queries.ts
|
|
1316
|
-
import { atom, computed } from "nanostores";
|
|
1317
|
-
|
|
1318
|
-
|
|
1539
|
+
import { atom as atom4, computed as computed2 } from "nanostores";
|
|
1540
|
+
|
|
1541
|
+
// src/admin/stores/query.ts
|
|
1542
|
+
import { nanoquery } from "@nanostores/query";
|
|
1543
|
+
var [
|
|
1544
|
+
createFetcherStore,
|
|
1545
|
+
createMutatorStore,
|
|
1546
|
+
{ invalidateKeys, revalidateKeys, mutateCache }
|
|
1547
|
+
] = nanoquery({
|
|
1548
|
+
fetcher: (...keys) => {
|
|
1549
|
+
const url = keys.join("");
|
|
1550
|
+
return api.get(url).json();
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
|
|
1554
|
+
// src/admin/stores/admin-queries.ts
|
|
1555
|
+
var $collectionQuery = atom4(null);
|
|
1556
|
+
var $collectionUrl = computed2($collectionQuery, (params) => {
|
|
1319
1557
|
if (!params)
|
|
1320
1558
|
return null;
|
|
1321
1559
|
const searchParams = new URLSearchParams;
|
|
@@ -1350,8 +1588,8 @@ var $collectionUrl = computed($collectionQuery, (params) => {
|
|
|
1350
1588
|
var $collectionData = createFetcherStore([
|
|
1351
1589
|
$collectionUrl
|
|
1352
1590
|
]);
|
|
1353
|
-
var $documentQuery =
|
|
1354
|
-
var $documentUrl =
|
|
1591
|
+
var $documentQuery = atom4(null);
|
|
1592
|
+
var $documentUrl = computed2($documentQuery, (params) => {
|
|
1355
1593
|
if (!params)
|
|
1356
1594
|
return null;
|
|
1357
1595
|
return `api/${params.slug}/${params.id}`;
|
|
@@ -1366,8 +1604,8 @@ var $saveDocument = createMutatorStore(async ({ data, revalidate }) => {
|
|
|
1366
1604
|
revalidate(`api/${slug}/${id}`);
|
|
1367
1605
|
return res;
|
|
1368
1606
|
});
|
|
1369
|
-
var $globalQuery =
|
|
1370
|
-
var $globalUrl =
|
|
1607
|
+
var $globalQuery = atom4(null);
|
|
1608
|
+
var $globalUrl = computed2($globalQuery, (slug) => {
|
|
1371
1609
|
if (!slug)
|
|
1372
1610
|
return null;
|
|
1373
1611
|
return `api/globals/${slug}`;
|
|
@@ -1381,8 +1619,8 @@ var $saveGlobal = createMutatorStore(async ({ data, revalidate }) => {
|
|
|
1381
1619
|
});
|
|
1382
1620
|
|
|
1383
1621
|
// src/admin/stores/column-visibility.ts
|
|
1384
|
-
import { persistentAtom } from "@nanostores/persistent";
|
|
1385
|
-
var $columnVisibility =
|
|
1622
|
+
import { persistentAtom as persistentAtom2 } from "@nanostores/persistent";
|
|
1623
|
+
var $columnVisibility = persistentAtom2("opaca-column-visibility", {}, {
|
|
1386
1624
|
encode: JSON.stringify,
|
|
1387
1625
|
decode: JSON.parse
|
|
1388
1626
|
});
|
|
@@ -1406,6 +1644,9 @@ function initColumnVisibility(slug, fields, defaultColumns) {
|
|
|
1406
1644
|
});
|
|
1407
1645
|
}
|
|
1408
1646
|
|
|
1647
|
+
// src/admin/ui/views/collection-list-view.tsx
|
|
1648
|
+
init_ui();
|
|
1649
|
+
|
|
1409
1650
|
// src/admin/ui/components/ColumnVisibilityToggle.tsx
|
|
1410
1651
|
import { useStore as useStore2 } from "@nanostores/react";
|
|
1411
1652
|
import { Check, ChevronDown as ChevronDown2, Settings2 } from "lucide-react";
|
|
@@ -1795,17 +2036,17 @@ import {
|
|
|
1795
2036
|
import React14, { useMemo as useMemo4, useRef as useRef4, useState as useState8 } from "react";
|
|
1796
2037
|
|
|
1797
2038
|
// src/admin/stores/media.ts
|
|
1798
|
-
import { persistentAtom as
|
|
1799
|
-
import { atom as
|
|
1800
|
-
var $mediaViewMode =
|
|
1801
|
-
var $mediaSelectedBucket =
|
|
1802
|
-
var $bucketColors =
|
|
2039
|
+
import { persistentAtom as persistentAtom3 } from "@nanostores/persistent";
|
|
2040
|
+
import { atom as atom5 } from "nanostores";
|
|
2041
|
+
var $mediaViewMode = persistentAtom3("opaca-media-view-mode", "grid");
|
|
2042
|
+
var $mediaSelectedBucket = persistentAtom3("opaca-media-selected-bucket", "all");
|
|
2043
|
+
var $bucketColors = persistentAtom3("opaca-bucket-colors", {}, {
|
|
1803
2044
|
encode: JSON.stringify,
|
|
1804
2045
|
decode: JSON.parse
|
|
1805
2046
|
});
|
|
1806
|
-
var $mediaCurrentFolder =
|
|
1807
|
-
var $mediaSearch =
|
|
1808
|
-
var $mediaPage =
|
|
2047
|
+
var $mediaCurrentFolder = atom5("");
|
|
2048
|
+
var $mediaSearch = atom5("");
|
|
2049
|
+
var $mediaPage = atom5(1);
|
|
1809
2050
|
var $assets = createFetcherStore(["api/__system/assets", $mediaSelectedBucket, $mediaCurrentFolder, $mediaSearch, $mediaPage], {
|
|
1810
2051
|
fetcher: (base, bucket, folder, search, page) => {
|
|
1811
2052
|
const params = new URLSearchParams({
|
|
@@ -4258,6 +4499,7 @@ import { useStore as useStore7 } from "@nanostores/react";
|
|
|
4258
4499
|
import { useForm } from "@tanstack/react-form";
|
|
4259
4500
|
import { AlertCircle as AlertCircle2, ArrowLeft, Loader2 as Loader25, Save as Save2, Trash2 as Trash24 } from "lucide-react";
|
|
4260
4501
|
import { useEffect as useEffect16, useMemo as useMemo8, useState as useState20 } from "react";
|
|
4502
|
+
init_ui();
|
|
4261
4503
|
|
|
4262
4504
|
// src/admin/ui/components/fields/index.tsx
|
|
4263
4505
|
import React17, { useEffect as useEffect15, useRef as useRef7 } from "react";
|
|
@@ -6608,6 +6850,7 @@ function DocumentEditView({ collection, id, onBack }) {
|
|
|
6608
6850
|
import { useStore as useStore8 } from "@nanostores/react";
|
|
6609
6851
|
import { AlertCircle as AlertCircle3, Loader2 as Loader26, Save as Save3 } from "lucide-react";
|
|
6610
6852
|
import { useEffect as useEffect17, useState as useState21 } from "react";
|
|
6853
|
+
init_ui();
|
|
6611
6854
|
import { jsxDEV as jsxDEV55 } from "react/jsx-dev-runtime";
|
|
6612
6855
|
function GlobalEditView({ global }) {
|
|
6613
6856
|
const [formData, setFormData] = useState21({});
|
|
@@ -6808,6 +7051,7 @@ function GlobalEditView({ global }) {
|
|
|
6808
7051
|
}
|
|
6809
7052
|
|
|
6810
7053
|
// src/admin/ui/views/init-view.tsx
|
|
7054
|
+
init_auth_client();
|
|
6811
7055
|
import { AlertCircle as AlertCircle4, Loader2 as Loader27, Lock, ShieldCheck, User } from "lucide-react";
|
|
6812
7056
|
import { useState as useState22 } from "react";
|
|
6813
7057
|
import { jsxDEV as jsxDEV56, Fragment as Fragment10 } from "react/jsx-dev-runtime";
|
|
@@ -7193,6 +7437,7 @@ import {
|
|
|
7193
7437
|
} from "lucide-react";
|
|
7194
7438
|
import { useMemo as useMemo9, useRef as useRef8, useState as useState24 } from "react";
|
|
7195
7439
|
import { createPortal as createPortal6 } from "react-dom";
|
|
7440
|
+
init_ui();
|
|
7196
7441
|
import { jsxDEV as jsxDEV58 } from "react/jsx-dev-runtime";
|
|
7197
7442
|
var formatMediaDate = (date) => {
|
|
7198
7443
|
if (!date)
|