@ampless/admin 0.2.0-alpha.2 → 0.2.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +73 -0
- package/README.md +3 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/chunk-2ITWLRYF.js +38 -0
- package/dist/chunk-5JKOPRCO.js +41 -0
- package/dist/chunk-5Q6KVRZ2.js +250 -0
- package/dist/chunk-7IR4F7GA.js +6 -0
- package/dist/chunk-A3SWBQA6.js +71 -0
- package/dist/chunk-BC4B6DLO.js +21 -0
- package/dist/chunk-BWFCQNPU.js +1264 -0
- package/dist/chunk-CQY55RDG.js +48 -0
- package/dist/chunk-CVJCMTYB.js +1197 -0
- package/dist/chunk-JOASK4AM.js +360 -0
- package/dist/{chunk-TJR3ALRJ.js → chunk-OSUTPPAU.js} +171 -68
- package/dist/chunk-QXJIIBUQ.js +21 -0
- package/dist/chunk-S66L5CDS.js +335 -0
- package/dist/chunk-SRNH2IVA.js +149 -0
- package/dist/chunk-TZWSXAHD.js +32 -0
- package/dist/chunk-VXEVLHGL.js +10 -0
- package/dist/chunk-W6BXESPW.js +198 -0
- package/dist/chunk-XY4JWSMS.js +33 -0
- package/dist/components/admin-dashboard.d.ts +10 -0
- package/dist/components/admin-dashboard.js +9 -0
- package/dist/components/edit-post-view.d.ts +9 -0
- package/dist/components/edit-post-view.js +14 -0
- package/dist/components/index.d.ts +40 -21
- package/dist/components/index.js +32 -15
- package/dist/components/login-view.d.ts +5 -0
- package/dist/components/login-view.js +9 -0
- package/dist/components/mcp-tokens-view.d.ts +22 -0
- package/dist/components/mcp-tokens-view.js +9 -0
- package/dist/components/media-view.d.ts +5 -0
- package/dist/components/media-view.js +12 -0
- package/dist/components/new-post-view.d.ts +5 -0
- package/dist/components/new-post-view.js +14 -0
- package/dist/components/posts-list-view.d.ts +5 -0
- package/dist/components/posts-list-view.js +11 -0
- package/dist/components/users-list-view.d.ts +7 -0
- package/dist/components/users-list-view.js +9 -0
- package/dist/{i18n-ByHM_Bho.d.ts → i18n-MWvAMHzn.d.ts} +253 -2
- package/dist/index.d.ts +14 -9
- package/dist/index.js +18 -10
- package/dist/lib/theme-actions.d.ts +17 -0
- package/dist/lib/theme-actions.js +7 -0
- package/dist/metafile-esm.json +1 -1
- package/dist/pages/index.d.ts +67 -15
- package/dist/pages/index.js +147 -659
- package/package.json +12 -9
- package/dist/chunk-T2RSMFOI.js +0 -2074
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
useT
|
|
4
|
+
} from "./chunk-XY4JWSMS.js";
|
|
5
|
+
|
|
6
|
+
// src/components/mcp-tokens-view.tsx
|
|
7
|
+
import { useEffect, useState } from "react";
|
|
8
|
+
import {
|
|
9
|
+
Button,
|
|
10
|
+
Table,
|
|
11
|
+
TableBody,
|
|
12
|
+
TableCell,
|
|
13
|
+
TableHead,
|
|
14
|
+
TableHeader,
|
|
15
|
+
TableRow
|
|
16
|
+
} from "@ampless/runtime/ui";
|
|
17
|
+
|
|
18
|
+
// src/lib/mcp-token-format.ts
|
|
19
|
+
import { randomBytes, createHash } from "crypto";
|
|
20
|
+
function generateToken() {
|
|
21
|
+
const random = toBase64Url(randomBytes(32));
|
|
22
|
+
const plain = `amk_${random}`;
|
|
23
|
+
return {
|
|
24
|
+
plain,
|
|
25
|
+
hash: hashToken(plain),
|
|
26
|
+
prefix: plain.slice(0, 8)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function hashToken(plain) {
|
|
30
|
+
return createHash("sha256").update(plain).digest("hex");
|
|
31
|
+
}
|
|
32
|
+
function toBase64Url(bytes) {
|
|
33
|
+
return bytes.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/lib/mcp-token-storage.ts
|
|
37
|
+
import { getKvStore } from "ampless";
|
|
38
|
+
var TOKENS_PK = "mcp-tokens";
|
|
39
|
+
async function listTokens() {
|
|
40
|
+
const items = await getKvStore().query(TOKENS_PK);
|
|
41
|
+
return items.map((item) => item.value);
|
|
42
|
+
}
|
|
43
|
+
async function findByHash(hash) {
|
|
44
|
+
return await getKvStore().get(TOKENS_PK, hash);
|
|
45
|
+
}
|
|
46
|
+
async function createToken(meta) {
|
|
47
|
+
const full = {
|
|
48
|
+
...meta,
|
|
49
|
+
lastUsedAt: null,
|
|
50
|
+
revokedAt: null
|
|
51
|
+
};
|
|
52
|
+
await getKvStore().put(TOKENS_PK, meta.hash, full);
|
|
53
|
+
return full;
|
|
54
|
+
}
|
|
55
|
+
async function revokeToken(hash) {
|
|
56
|
+
const existing = await findByHash(hash);
|
|
57
|
+
if (!existing) return;
|
|
58
|
+
if (existing.revokedAt) return;
|
|
59
|
+
await getKvStore().put(TOKENS_PK, hash, {
|
|
60
|
+
...existing,
|
|
61
|
+
revokedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/components/mcp-tokens-view.tsx
|
|
66
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
67
|
+
function tokenStatus(tok) {
|
|
68
|
+
if (tok.revokedAt) return "revoked";
|
|
69
|
+
if (tok.expiresAt && new Date(tok.expiresAt) < /* @__PURE__ */ new Date()) return "expired";
|
|
70
|
+
return "active";
|
|
71
|
+
}
|
|
72
|
+
function relativeTime(iso) {
|
|
73
|
+
if (!iso) return "";
|
|
74
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
75
|
+
const s = Math.floor(ms / 1e3);
|
|
76
|
+
if (s < 60) return `${s}s ago`;
|
|
77
|
+
const m = Math.floor(s / 60);
|
|
78
|
+
if (m < 60) return `${m}m ago`;
|
|
79
|
+
const h = Math.floor(m / 60);
|
|
80
|
+
if (h < 24) return `${h}h ago`;
|
|
81
|
+
const d = Math.floor(h / 24);
|
|
82
|
+
return `${d}d ago`;
|
|
83
|
+
}
|
|
84
|
+
function McpTokensView({ currentUserId, currentUserEmail, sites, mcpEndpoint }) {
|
|
85
|
+
const t = useT();
|
|
86
|
+
const [endpointCopied, setEndpointCopied] = useState(false);
|
|
87
|
+
async function copyEndpoint() {
|
|
88
|
+
if (!mcpEndpoint) return;
|
|
89
|
+
try {
|
|
90
|
+
await navigator.clipboard.writeText(mcpEndpoint);
|
|
91
|
+
setEndpointCopied(true);
|
|
92
|
+
setTimeout(() => setEndpointCopied(false), 2e3);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.error("[mcp-tokens-view] copy endpoint failed", err);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const [tokens, setTokens] = useState(null);
|
|
98
|
+
const [loading, setLoading] = useState(true);
|
|
99
|
+
const [loadError, setLoadError] = useState(null);
|
|
100
|
+
const [showCreateModal, setShowCreateModal] = useState(false);
|
|
101
|
+
const [scopeSiteId, setScopeSiteId] = useState(null);
|
|
102
|
+
const [expPreset, setExpPreset] = useState("never");
|
|
103
|
+
const [customDate, setCustomDate] = useState("");
|
|
104
|
+
const [creating, setCreating] = useState(false);
|
|
105
|
+
const [createError, setCreateError] = useState(null);
|
|
106
|
+
const [revealedPlain, setRevealedPlain] = useState(null);
|
|
107
|
+
const [copied, setCopied] = useState(false);
|
|
108
|
+
async function loadTokens() {
|
|
109
|
+
setLoading(true);
|
|
110
|
+
setLoadError(null);
|
|
111
|
+
try {
|
|
112
|
+
const list = await listTokens();
|
|
113
|
+
setTokens(list);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.error("[mcp-tokens-view] listTokens failed", err);
|
|
116
|
+
setLoadError(err instanceof Error ? err.message : String(err));
|
|
117
|
+
} finally {
|
|
118
|
+
setLoading(false);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
void loadTokens();
|
|
123
|
+
}, []);
|
|
124
|
+
function openCreateModal() {
|
|
125
|
+
setScopeSiteId(null);
|
|
126
|
+
setExpPreset("never");
|
|
127
|
+
setCustomDate("");
|
|
128
|
+
setCreateError(null);
|
|
129
|
+
setShowCreateModal(true);
|
|
130
|
+
}
|
|
131
|
+
function expiresAtFromPreset() {
|
|
132
|
+
if (expPreset === "never") return null;
|
|
133
|
+
if (expPreset === "30days") {
|
|
134
|
+
const d = /* @__PURE__ */ new Date();
|
|
135
|
+
d.setDate(d.getDate() + 30);
|
|
136
|
+
return d.toISOString();
|
|
137
|
+
}
|
|
138
|
+
if (expPreset === "90days") {
|
|
139
|
+
const d = /* @__PURE__ */ new Date();
|
|
140
|
+
d.setDate(d.getDate() + 90);
|
|
141
|
+
return d.toISOString();
|
|
142
|
+
}
|
|
143
|
+
if (expPreset === "custom" && customDate) {
|
|
144
|
+
return new Date(customDate).toISOString();
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
async function handleIssue() {
|
|
149
|
+
setCreating(true);
|
|
150
|
+
setCreateError(null);
|
|
151
|
+
try {
|
|
152
|
+
const { plain, hash, prefix } = generateToken();
|
|
153
|
+
const meta = await createToken({
|
|
154
|
+
hash,
|
|
155
|
+
prefix,
|
|
156
|
+
scope: { siteId: scopeSiteId },
|
|
157
|
+
createdBy: currentUserId,
|
|
158
|
+
createdByEmail: currentUserEmail,
|
|
159
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
160
|
+
expiresAt: expiresAtFromPreset()
|
|
161
|
+
});
|
|
162
|
+
void meta;
|
|
163
|
+
setShowCreateModal(false);
|
|
164
|
+
setRevealedPlain(plain);
|
|
165
|
+
void loadTokens();
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error("[mcp-tokens-view] createToken failed", err);
|
|
168
|
+
setCreateError(err instanceof Error ? err.message : String(err));
|
|
169
|
+
} finally {
|
|
170
|
+
setCreating(false);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function handleRevoke(hash) {
|
|
174
|
+
if (!confirm(t("mcpTokens.revokeConfirm"))) return;
|
|
175
|
+
try {
|
|
176
|
+
await revokeToken(hash);
|
|
177
|
+
void loadTokens();
|
|
178
|
+
} catch (err) {
|
|
179
|
+
console.error("[mcp-tokens-view] revokeToken failed", err);
|
|
180
|
+
alert(err instanceof Error ? err.message : String(err));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function copyToClipboard() {
|
|
184
|
+
if (!revealedPlain) return;
|
|
185
|
+
try {
|
|
186
|
+
await navigator.clipboard.writeText(revealedPlain);
|
|
187
|
+
setCopied(true);
|
|
188
|
+
setTimeout(() => setCopied(false), 1500);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
console.warn("[mcp-tokens-view] clipboard write failed", err);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function scopeLabel(siteId) {
|
|
194
|
+
if (!siteId) return t("mcpTokens.scopeAll");
|
|
195
|
+
const site = sites.find((s) => s.id === siteId);
|
|
196
|
+
return site?.name ?? siteId;
|
|
197
|
+
}
|
|
198
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl space-y-8 p-4 md:p-8", children: [
|
|
199
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
200
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
201
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold md:text-3xl", children: t("mcpTokens.title") }),
|
|
202
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t("mcpTokens.description") })
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsx(Button, { type: "button", onClick: openCreateModal, children: t("mcpTokens.createButton") })
|
|
205
|
+
] }),
|
|
206
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-card px-4 py-3 text-sm", children: [
|
|
207
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: t("mcpTokens.endpointTitle") }),
|
|
208
|
+
mcpEndpoint ? /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
|
|
209
|
+
/* @__PURE__ */ jsx("code", { className: "flex-1 overflow-x-auto rounded border bg-muted px-2 py-1 font-mono text-xs", children: mcpEndpoint }),
|
|
210
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: copyEndpoint, children: endpointCopied ? t("mcpTokens.endpointCopied") : t("mcpTokens.endpointCopy") })
|
|
211
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "mt-1 text-muted-foreground", children: t("mcpTokens.endpointMissing") })
|
|
212
|
+
] }),
|
|
213
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-md border border-yellow-300 bg-yellow-50 px-4 py-3 text-sm text-yellow-800 dark:border-yellow-700 dark:bg-yellow-950 dark:text-yellow-200", children: t("mcpTokens.inertBanner") }),
|
|
214
|
+
/* @__PURE__ */ jsx("section", { className: "space-y-3", children: loading ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("mcpTokens.loading") }) : loadError ? /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
215
|
+
t("mcpTokens.error"),
|
|
216
|
+
": ",
|
|
217
|
+
loadError
|
|
218
|
+
] }) : !tokens || tokens.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t("mcpTokens.listEmpty") }) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
219
|
+
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
220
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("mcpTokens.columnPrefix") }),
|
|
221
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("mcpTokens.columnScope") }),
|
|
222
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("mcpTokens.columnCreated") }),
|
|
223
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("mcpTokens.columnLastUsed") }),
|
|
224
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("mcpTokens.columnStatus") }),
|
|
225
|
+
/* @__PURE__ */ jsx(TableHead, { children: t("common.actions") })
|
|
226
|
+
] }) }),
|
|
227
|
+
/* @__PURE__ */ jsx(TableBody, { children: tokens.map((tok) => {
|
|
228
|
+
const status = tokenStatus(tok);
|
|
229
|
+
return /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
230
|
+
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-xs", children: tok.prefix }),
|
|
231
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-sm", children: scopeLabel(tok.scope.siteId) }),
|
|
232
|
+
/* @__PURE__ */ jsxs(TableCell, { className: "text-xs text-muted-foreground", children: [
|
|
233
|
+
/* @__PURE__ */ jsx("span", { title: tok.createdAt, children: relativeTime(tok.createdAt) }),
|
|
234
|
+
tok.createdByEmail && /* @__PURE__ */ jsxs("span", { className: "ml-1 text-muted-foreground/70", children: [
|
|
235
|
+
"by ",
|
|
236
|
+
tok.createdByEmail
|
|
237
|
+
] })
|
|
238
|
+
] }),
|
|
239
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-xs text-muted-foreground", children: tok.lastUsedAt ? /* @__PURE__ */ jsx("span", { title: tok.lastUsedAt, children: relativeTime(tok.lastUsedAt) }) : t("mcpTokens.lastUsedNever") }),
|
|
240
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(
|
|
241
|
+
"span",
|
|
242
|
+
{
|
|
243
|
+
className: status === "active" ? "text-sm font-medium text-green-700 dark:text-green-400" : "text-sm text-muted-foreground",
|
|
244
|
+
children: status === "active" ? t("mcpTokens.statusActive") : status === "revoked" ? t("mcpTokens.statusRevoked") : t("mcpTokens.statusExpired")
|
|
245
|
+
}
|
|
246
|
+
) }),
|
|
247
|
+
/* @__PURE__ */ jsx(TableCell, { children: status === "active" && /* @__PURE__ */ jsx(
|
|
248
|
+
Button,
|
|
249
|
+
{
|
|
250
|
+
type: "button",
|
|
251
|
+
variant: "outline",
|
|
252
|
+
size: "sm",
|
|
253
|
+
onClick: () => handleRevoke(tok.hash),
|
|
254
|
+
children: t("mcpTokens.revoke")
|
|
255
|
+
}
|
|
256
|
+
) })
|
|
257
|
+
] }, tok.hash);
|
|
258
|
+
}) })
|
|
259
|
+
] }) }) }),
|
|
260
|
+
showCreateModal && /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md rounded-md border bg-card p-6 shadow-lg", children: [
|
|
261
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("mcpTokens.createModalTitle") }),
|
|
262
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-4", children: [
|
|
263
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
264
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", htmlFor: "mcp-scope", children: t("mcpTokens.scopeLabel") }),
|
|
265
|
+
/* @__PURE__ */ jsxs(
|
|
266
|
+
"select",
|
|
267
|
+
{
|
|
268
|
+
id: "mcp-scope",
|
|
269
|
+
className: "w-full rounded-md border bg-background px-2 py-1.5 text-sm",
|
|
270
|
+
value: scopeSiteId ?? "",
|
|
271
|
+
onChange: (e) => setScopeSiteId(e.target.value === "" ? null : e.target.value),
|
|
272
|
+
children: [
|
|
273
|
+
/* @__PURE__ */ jsx("option", { value: "", children: t("mcpTokens.scopeAll") }),
|
|
274
|
+
sites.map((s) => /* @__PURE__ */ jsx("option", { value: s.id, children: s.name }, s.id))
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
)
|
|
278
|
+
] }),
|
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
280
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: t("mcpTokens.expirationLabel") }),
|
|
281
|
+
["never", "30days", "90days", "custom"].map((preset) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
|
|
282
|
+
/* @__PURE__ */ jsx(
|
|
283
|
+
"input",
|
|
284
|
+
{
|
|
285
|
+
type: "radio",
|
|
286
|
+
name: "mcp-expiration",
|
|
287
|
+
value: preset,
|
|
288
|
+
checked: expPreset === preset,
|
|
289
|
+
onChange: () => setExpPreset(preset)
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
t(`mcpTokens.expiration${preset.charAt(0).toUpperCase() + preset.slice(1)}`)
|
|
293
|
+
] }, preset)),
|
|
294
|
+
expPreset === "custom" && /* @__PURE__ */ jsx(
|
|
295
|
+
"input",
|
|
296
|
+
{
|
|
297
|
+
type: "date",
|
|
298
|
+
className: "mt-1 block rounded-md border bg-background px-2 py-1 text-sm",
|
|
299
|
+
value: customDate,
|
|
300
|
+
min: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
301
|
+
onChange: (e) => setCustomDate(e.target.value)
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
] }),
|
|
305
|
+
createError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: createError })
|
|
306
|
+
] }),
|
|
307
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-6 flex justify-end gap-2", children: [
|
|
308
|
+
/* @__PURE__ */ jsx(
|
|
309
|
+
Button,
|
|
310
|
+
{
|
|
311
|
+
type: "button",
|
|
312
|
+
variant: "outline",
|
|
313
|
+
onClick: () => setShowCreateModal(false),
|
|
314
|
+
children: t("common.cancel")
|
|
315
|
+
}
|
|
316
|
+
),
|
|
317
|
+
/* @__PURE__ */ jsx(
|
|
318
|
+
Button,
|
|
319
|
+
{
|
|
320
|
+
type: "button",
|
|
321
|
+
disabled: creating || expPreset === "custom" && !customDate,
|
|
322
|
+
onClick: () => void handleIssue(),
|
|
323
|
+
children: creating ? t("mcpTokens.issuing") : t("mcpTokens.issueButton")
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
] })
|
|
327
|
+
] }) }),
|
|
328
|
+
revealedPlain && /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-2xl rounded-md border bg-card p-6 shadow-lg", children: [
|
|
329
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("mcpTokens.revealTitle") }),
|
|
330
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: t("mcpTokens.revealHint") }),
|
|
331
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 rounded-md border bg-muted/50 p-3", children: /* @__PURE__ */ jsx("code", { className: "block select-all break-all font-mono text-xs", children: revealedPlain }) }),
|
|
332
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [
|
|
333
|
+
/* @__PURE__ */ jsx(
|
|
334
|
+
Button,
|
|
335
|
+
{
|
|
336
|
+
type: "button",
|
|
337
|
+
variant: "outline",
|
|
338
|
+
onClick: () => void copyToClipboard(),
|
|
339
|
+
children: copied ? t("mcpTokens.copied") : t("mcpTokens.copy")
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
/* @__PURE__ */ jsx(
|
|
343
|
+
Button,
|
|
344
|
+
{
|
|
345
|
+
type: "button",
|
|
346
|
+
onClick: () => {
|
|
347
|
+
setRevealedPlain(null);
|
|
348
|
+
setCopied(false);
|
|
349
|
+
},
|
|
350
|
+
children: t("mcpTokens.done")
|
|
351
|
+
}
|
|
352
|
+
)
|
|
353
|
+
] })
|
|
354
|
+
] }) })
|
|
355
|
+
] });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export {
|
|
359
|
+
McpTokensView
|
|
360
|
+
};
|
|
@@ -34,9 +34,13 @@ var en_default = {
|
|
|
34
34
|
posts: "Posts",
|
|
35
35
|
media: "Media",
|
|
36
36
|
sites: "Sites",
|
|
37
|
+
users: "Users",
|
|
38
|
+
mcpTokens: "MCP tokens",
|
|
37
39
|
viewSite: "View site",
|
|
38
40
|
signOut: "Sign out",
|
|
39
|
-
site: "Site"
|
|
41
|
+
site: "Site",
|
|
42
|
+
openMenu: "Open menu",
|
|
43
|
+
closeMenu: "Close menu"
|
|
40
44
|
},
|
|
41
45
|
dashboard: {
|
|
42
46
|
title: "Dashboard",
|
|
@@ -76,6 +80,20 @@ var en_default = {
|
|
|
76
80
|
tagsPlaceholder: "comma, separated, tags",
|
|
77
81
|
tagsHint: "Used to group posts on tag pages (e.g. /tag/tech).",
|
|
78
82
|
status: "Status",
|
|
83
|
+
noLayout: "No layout",
|
|
84
|
+
noLayoutHint: "Serve this post as bare HTML \u2014 no theme header, footer, or root layout. The body is returned as the entire response. Best paired with format: HTML when the body contains a full <!DOCTYPE html>\u2026</html> document.",
|
|
85
|
+
formatStaticLabel: "Static (zip / file bundle)",
|
|
86
|
+
static: {
|
|
87
|
+
pick: "Pick a .zip or one or more files",
|
|
88
|
+
pickHint: "Bundle assets must reference each other with relative paths only (no leading /). The zip's contents are extracted into a directory under your post slug and served verbatim \u2014 no theme chrome.",
|
|
89
|
+
currentBundle: "Current bundle: {count} files (entry: {entrypoint})",
|
|
90
|
+
pendingBundle: "Pending upload: {count} files, {size}",
|
|
91
|
+
issuesTitle: "{count} validation issue(s)",
|
|
92
|
+
issuesHint: "Fix the listed paths and re-upload. Absolute (/foo) and protocol-relative (//cdn.example/foo) references break under the bundle's URL prefix.",
|
|
93
|
+
emptyBundle: "No usable files found in the selection.",
|
|
94
|
+
noBundle: "Pick a bundle before saving.",
|
|
95
|
+
previewHint: "Static bundles render as the served HTML at /<slug>/. Preview by saving and visiting the public URL."
|
|
96
|
+
},
|
|
79
97
|
saveChanges: "Save changes",
|
|
80
98
|
createPost: "Create post",
|
|
81
99
|
delete: "Delete",
|
|
@@ -147,6 +165,25 @@ var en_default = {
|
|
|
147
165
|
label: "Site"
|
|
148
166
|
}
|
|
149
167
|
},
|
|
168
|
+
users: {
|
|
169
|
+
list: {
|
|
170
|
+
title: "Users",
|
|
171
|
+
description: "Promote signed-up users to admin or editor. Sign-ups always start with no role and must be granted access here.",
|
|
172
|
+
columnEmail: "Email",
|
|
173
|
+
columnRole: "Role",
|
|
174
|
+
columnActions: "Actions",
|
|
175
|
+
save: "Save",
|
|
176
|
+
saving: "Saving...",
|
|
177
|
+
saved: "Saved.",
|
|
178
|
+
cannotEditSelf: "You cannot change your own role.",
|
|
179
|
+
empty: "No users yet.",
|
|
180
|
+
loading: "Loading users...",
|
|
181
|
+
error: "Failed to load users",
|
|
182
|
+
roleAdmin: "Admin",
|
|
183
|
+
roleEditor: "Editor",
|
|
184
|
+
roleNone: "None"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
150
187
|
theme: {
|
|
151
188
|
title: "Theme",
|
|
152
189
|
activeLabel: "Active theme",
|
|
@@ -164,7 +201,14 @@ var en_default = {
|
|
|
164
201
|
customizationHeading: "{theme} customization",
|
|
165
202
|
customizationHint: "Empty input resets to the manifest default.",
|
|
166
203
|
lengthHelp: "CSS length, e.g. 0.5rem, 4px.",
|
|
167
|
-
imagePlaceholder: "https://\u2026 or /media/\u2026"
|
|
204
|
+
imagePlaceholder: "https://\u2026 or /media/\u2026",
|
|
205
|
+
colorScheme: {
|
|
206
|
+
label: "Color scheme",
|
|
207
|
+
hint: "How the public site picks between the theme's light and dark token palettes.",
|
|
208
|
+
auto: "Auto (follow visitor's system)",
|
|
209
|
+
light: "Light only",
|
|
210
|
+
dark: "Dark only"
|
|
211
|
+
}
|
|
168
212
|
},
|
|
169
213
|
editor: {
|
|
170
214
|
linkPrompt: "URL",
|
|
@@ -225,6 +269,45 @@ var en_default = {
|
|
|
225
269
|
userExists: "An account with this email already exists."
|
|
226
270
|
}
|
|
227
271
|
},
|
|
272
|
+
mcpTokens: {
|
|
273
|
+
title: "MCP tokens",
|
|
274
|
+
description: "Access tokens for the HTTP MCP endpoint. Use them in Claude Desktop / Cursor / any MCP-aware client to read and write this CMS over the wire.",
|
|
275
|
+
endpointTitle: "MCP endpoint",
|
|
276
|
+
endpointCopy: "Copy",
|
|
277
|
+
endpointCopied: "Copied",
|
|
278
|
+
endpointMissing: "Not deployed yet. Run `npm run sandbox` or push to Amplify Hosting to provision the endpoint URL.",
|
|
279
|
+
inertBanner: "Heads up: the endpoint validates tokens, but tool dispatch (list_posts / create_post / etc.) lands in v0.2 Phase 4. Valid tokens currently get a stub 200 response.",
|
|
280
|
+
createButton: "Create token",
|
|
281
|
+
createModalTitle: "Create token",
|
|
282
|
+
scopeLabel: "Scope",
|
|
283
|
+
scopeAll: "All sites",
|
|
284
|
+
expirationLabel: "Expiration",
|
|
285
|
+
expirationNever: "Never",
|
|
286
|
+
expiration30days: "30 days",
|
|
287
|
+
expiration90days: "90 days",
|
|
288
|
+
expirationCustom: "Custom date",
|
|
289
|
+
issueButton: "Issue token",
|
|
290
|
+
issuing: "Issuing...",
|
|
291
|
+
revealTitle: "Token issued",
|
|
292
|
+
revealHint: "This is the only time you will see this token. Copy it now \u2014 closing this dialog discards it permanently.",
|
|
293
|
+
copy: "Copy",
|
|
294
|
+
copied: "Copied!",
|
|
295
|
+
done: "Done",
|
|
296
|
+
loading: "Loading tokens...",
|
|
297
|
+
error: "Failed to load tokens",
|
|
298
|
+
listEmpty: "No tokens yet. Click 'Create token' to issue your first one.",
|
|
299
|
+
columnPrefix: "Prefix",
|
|
300
|
+
columnScope: "Scope",
|
|
301
|
+
columnCreated: "Created",
|
|
302
|
+
columnLastUsed: "Last used",
|
|
303
|
+
columnStatus: "Status",
|
|
304
|
+
lastUsedNever: "Never used",
|
|
305
|
+
statusActive: "Active",
|
|
306
|
+
statusRevoked: "Revoked",
|
|
307
|
+
statusExpired: "Expired",
|
|
308
|
+
revoke: "Revoke",
|
|
309
|
+
revokeConfirm: "Revoke this token? This cannot be undone."
|
|
310
|
+
},
|
|
228
311
|
public: {
|
|
229
312
|
back: "\u2190 Back",
|
|
230
313
|
home: "\u2190 Home",
|
|
@@ -269,9 +352,13 @@ var ja_default = {
|
|
|
269
352
|
posts: "\u8A18\u4E8B",
|
|
270
353
|
media: "\u30E1\u30C7\u30A3\u30A2",
|
|
271
354
|
sites: "\u30B5\u30A4\u30C8",
|
|
355
|
+
users: "\u30E6\u30FC\u30B6\u30FC",
|
|
356
|
+
mcpTokens: "MCP \u30C8\u30FC\u30AF\u30F3",
|
|
272
357
|
viewSite: "\u30B5\u30A4\u30C8\u3092\u8868\u793A",
|
|
273
358
|
signOut: "\u30B5\u30A4\u30F3\u30A2\u30A6\u30C8",
|
|
274
|
-
site: "\u30B5\u30A4\u30C8"
|
|
359
|
+
site: "\u30B5\u30A4\u30C8",
|
|
360
|
+
openMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u958B\u304F",
|
|
361
|
+
closeMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B"
|
|
275
362
|
},
|
|
276
363
|
dashboard: {
|
|
277
364
|
title: "\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9",
|
|
@@ -311,6 +398,20 @@ var ja_default = {
|
|
|
311
398
|
tagsPlaceholder: "\u30AB\u30F3\u30DE, \u533A\u5207\u308A, \u30BF\u30B0",
|
|
312
399
|
tagsHint: "\u30BF\u30B0\u30DA\u30FC\u30B8\u3067\u8A18\u4E8B\u3092\u30B0\u30EB\u30FC\u30D4\u30F3\u30B0 (\u4F8B: /tag/tech)\u3002",
|
|
313
400
|
status: "\u30B9\u30C6\u30FC\u30BF\u30B9",
|
|
401
|
+
noLayout: "\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u4F7F\u308F\u306A\u3044",
|
|
402
|
+
noLayoutHint: "\u30C6\u30FC\u30DE\u306E\u30D8\u30C3\u30C0\u30FC / \u30D5\u30C3\u30BF\u30FC / root layout \u3092\u4ECB\u3055\u305A\u3001\u672C\u6587\u3092 HTTP \u30EC\u30B9\u30DD\u30F3\u30B9\u672C\u4F53\u3068\u3057\u3066\u305D\u306E\u307E\u307E\u8FD4\u3057\u307E\u3059\u3002\u672C\u6587\u306B <!DOCTYPE html>\u2026</html> \u304C\u542B\u307E\u308C\u308B\u5834\u5408\u306F\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8: HTML \u3068\u306E\u7D44\u307F\u5408\u308F\u305B\u304C\u6700\u9069\u3067\u3059\u3002",
|
|
403
|
+
formatStaticLabel: "Static (zip / \u30D5\u30A1\u30A4\u30EB\u4E00\u62EC)",
|
|
404
|
+
static: {
|
|
405
|
+
pick: ".zip \u307E\u305F\u306F\u8907\u6570\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E",
|
|
406
|
+
pickHint: "\u30D0\u30F3\u30C9\u30EB\u5185\u306E\u30D5\u30A1\u30A4\u30EB\u9593\u53C2\u7167\u306F\u76F8\u5BFE\u30D1\u30B9\u306E\u307F (\u5148\u982D / \u306A\u3057)\u3002zip \u306E\u4E2D\u8EAB\u306F\u8A18\u4E8B slug \u306E\u914D\u4E0B\u306B\u5C55\u958B\u3055\u308C\u3001\u30C6\u30FC\u30DE\u88C5\u98FE\u3092\u4ECB\u3055\u305A\u305D\u306E\u307E\u307E\u914D\u4FE1\u3055\u308C\u307E\u3059\u3002",
|
|
407
|
+
currentBundle: "\u73FE\u5728\u306E\u30D0\u30F3\u30C9\u30EB: {count} \u30D5\u30A1\u30A4\u30EB (entry: {entrypoint})",
|
|
408
|
+
pendingBundle: "\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5F85\u3061: {count} \u30D5\u30A1\u30A4\u30EB, {size}",
|
|
409
|
+
issuesTitle: "{count} \u4EF6\u306E\u691C\u8A3C\u30A8\u30E9\u30FC",
|
|
410
|
+
issuesHint: "\u8A72\u5F53\u30D1\u30B9\u3092\u4FEE\u6B63\u3057\u3066\u518D\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7D76\u5BFE\u30D1\u30B9 (/foo) \u3084\u30D7\u30ED\u30C8\u30B3\u30EB\u7701\u7565 (//cdn.example/foo) \u306F\u30D0\u30F3\u30C9\u30EB\u306E URL prefix \u4E0B\u3067\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
411
|
+
emptyBundle: "\u9078\u629E\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u53D6\u308A\u51FA\u305B\u308B\u4E2D\u8EAB\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002",
|
|
412
|
+
noBundle: "\u4FDD\u5B58\u524D\u306B\u30D0\u30F3\u30C9\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
413
|
+
previewHint: "Static \u30D0\u30F3\u30C9\u30EB\u306F /<slug>/ \u304B\u3089\u5B9F HTML \u3068\u3057\u3066\u914D\u4FE1\u3055\u308C\u307E\u3059\u3002\u4FDD\u5B58\u5F8C\u306B\u516C\u958B URL \u3092\u958B\u3044\u3066\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
414
|
+
},
|
|
314
415
|
saveChanges: "\u5909\u66F4\u3092\u4FDD\u5B58",
|
|
315
416
|
createPost: "\u8A18\u4E8B\u3092\u4F5C\u6210",
|
|
316
417
|
delete: "\u524A\u9664",
|
|
@@ -382,6 +483,25 @@ var ja_default = {
|
|
|
382
483
|
label: "\u30B5\u30A4\u30C8"
|
|
383
484
|
}
|
|
384
485
|
},
|
|
486
|
+
users: {
|
|
487
|
+
list: {
|
|
488
|
+
title: "\u30E6\u30FC\u30B6\u30FC",
|
|
489
|
+
description: "\u30B5\u30A4\u30F3\u30A2\u30C3\u30D7\u6E08\u307F\u30E6\u30FC\u30B6\u30FC\u3092\u7BA1\u7406\u8005\u307E\u305F\u306F\u7DE8\u96C6\u8005\u306B\u6607\u683C\u3057\u307E\u3059\u3002\u30B5\u30A4\u30F3\u30A2\u30C3\u30D7\u76F4\u5F8C\u306F\u30ED\u30FC\u30EB\u7121\u3057\u306E\u305F\u3081\u3001\u3053\u3053\u3067\u30A2\u30AF\u30BB\u30B9\u3092\u4ED8\u4E0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
490
|
+
columnEmail: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9",
|
|
491
|
+
columnRole: "\u30ED\u30FC\u30EB",
|
|
492
|
+
columnActions: "\u64CD\u4F5C",
|
|
493
|
+
save: "\u4FDD\u5B58",
|
|
494
|
+
saving: "\u4FDD\u5B58\u4E2D...",
|
|
495
|
+
saved: "\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
|
|
496
|
+
cannotEditSelf: "\u81EA\u5206\u81EA\u8EAB\u306E\u30ED\u30FC\u30EB\u306F\u5909\u66F4\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
497
|
+
empty: "\u30E6\u30FC\u30B6\u30FC\u304C\u3044\u307E\u305B\u3093\u3002",
|
|
498
|
+
loading: "\u30E6\u30FC\u30B6\u30FC\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...",
|
|
499
|
+
error: "\u30E6\u30FC\u30B6\u30FC\u4E00\u89A7\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
500
|
+
roleAdmin: "\u7BA1\u7406\u8005",
|
|
501
|
+
roleEditor: "\u7DE8\u96C6\u8005",
|
|
502
|
+
roleNone: "\u306A\u3057"
|
|
503
|
+
}
|
|
504
|
+
},
|
|
385
505
|
theme: {
|
|
386
506
|
title: "\u30C6\u30FC\u30DE",
|
|
387
507
|
activeLabel: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30C6\u30FC\u30DE",
|
|
@@ -399,7 +519,14 @@ var ja_default = {
|
|
|
399
519
|
customizationHeading: "{theme}\u306E\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA",
|
|
400
520
|
customizationHint: "\u7A7A\u6B04\u306B\u3059\u308B\u3068\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306B\u623B\u308A\u307E\u3059\u3002",
|
|
401
521
|
lengthHelp: "CSS\u306E\u9577\u3055\u3002\u4F8B: 0.5rem, 4px\u3002",
|
|
402
|
-
imagePlaceholder: "https://\u2026 \u307E\u305F\u306F /media/\u2026"
|
|
522
|
+
imagePlaceholder: "https://\u2026 \u307E\u305F\u306F /media/\u2026",
|
|
523
|
+
colorScheme: {
|
|
524
|
+
label: "\u30AB\u30E9\u30FC\u30B9\u30AD\u30FC\u30E0",
|
|
525
|
+
hint: "\u516C\u958B\u30B5\u30A4\u30C8\u3067\u30C6\u30FC\u30DE\u306E\u30E9\u30A4\u30C8/\u30C0\u30FC\u30AF\u4E21\u30D1\u30EC\u30C3\u30C8\u306E\u3069\u3061\u3089\u3092\u4F7F\u3046\u304B\u306E\u9078\u629E\u3002",
|
|
526
|
+
auto: "\u81EA\u52D5 (\u95B2\u89A7\u8005\u306EOS\u8A2D\u5B9A\u306B\u8FFD\u5F93)",
|
|
527
|
+
light: "\u30E9\u30A4\u30C8\u56FA\u5B9A",
|
|
528
|
+
dark: "\u30C0\u30FC\u30AF\u56FA\u5B9A"
|
|
529
|
+
}
|
|
403
530
|
},
|
|
404
531
|
editor: {
|
|
405
532
|
linkPrompt: "URL",
|
|
@@ -460,6 +587,45 @@ var ja_default = {
|
|
|
460
587
|
userExists: "\u3053\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002"
|
|
461
588
|
}
|
|
462
589
|
},
|
|
590
|
+
mcpTokens: {
|
|
591
|
+
title: "MCP \u30C8\u30FC\u30AF\u30F3",
|
|
592
|
+
description: "HTTP MCP \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u7528\u306E\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u3002Claude Desktop / Cursor \u306A\u3069\u306E MCP \u5BFE\u5FDC\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304B\u3089\u3001\u3053\u306E CMS \u306E\u8AAD\u307F\u66F8\u304D\u306B\u4F7F\u3048\u307E\u3059\u3002",
|
|
593
|
+
endpointTitle: "MCP \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8",
|
|
594
|
+
endpointCopy: "\u30B3\u30D4\u30FC",
|
|
595
|
+
endpointCopied: "\u30B3\u30D4\u30FC\u6E08\u307F",
|
|
596
|
+
endpointMissing: "\u307E\u3060\u30C7\u30D7\u30ED\u30A4\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002`npm run sandbox` \u3092\u5B9F\u884C\u3059\u308B\u304B Amplify Hosting \u306B push \u3057\u3066\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u3092\u30D7\u30ED\u30D3\u30B8\u30E7\u30CB\u30F3\u30B0\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
597
|
+
inertBanner: "\u6CE8\u610F: \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306F\u30C8\u30FC\u30AF\u30F3\u691C\u8A3C\u3092\u884C\u3044\u307E\u3059\u304C\u3001\u30C4\u30FC\u30EB\u30C7\u30A3\u30B9\u30D1\u30C3\u30C1 (list_posts / create_post \u306A\u3069) \u306F v0.2 Phase 4 \u3067\u5B9F\u88C5\u3055\u308C\u307E\u3059\u3002\u73FE\u5728\u306F\u6709\u52B9\u306A\u30C8\u30FC\u30AF\u30F3\u306B\u5BFE\u3057\u3066 stub \u306E 200 \u30EC\u30B9\u30DD\u30F3\u30B9\u3092\u8FD4\u3057\u307E\u3059\u3002",
|
|
598
|
+
createButton: "\u30C8\u30FC\u30AF\u30F3\u3092\u4F5C\u6210",
|
|
599
|
+
createModalTitle: "\u30C8\u30FC\u30AF\u30F3\u3092\u4F5C\u6210",
|
|
600
|
+
scopeLabel: "\u30B9\u30B3\u30FC\u30D7",
|
|
601
|
+
scopeAll: "\u3059\u3079\u3066\u306E\u30B5\u30A4\u30C8",
|
|
602
|
+
expirationLabel: "\u6709\u52B9\u671F\u9650",
|
|
603
|
+
expirationNever: "\u7121\u671F\u9650",
|
|
604
|
+
expiration30days: "30\u65E5",
|
|
605
|
+
expiration90days: "90\u65E5",
|
|
606
|
+
expirationCustom: "\u65E5\u4ED8\u3092\u6307\u5B9A",
|
|
607
|
+
issueButton: "\u30C8\u30FC\u30AF\u30F3\u3092\u767A\u884C",
|
|
608
|
+
issuing: "\u767A\u884C\u4E2D...",
|
|
609
|
+
revealTitle: "\u30C8\u30FC\u30AF\u30F3\u3092\u767A\u884C\u3057\u307E\u3057\u305F",
|
|
610
|
+
revealHint: "\u3053\u306E\u30C8\u30FC\u30AF\u30F3\u304C\u8868\u793A\u3055\u308C\u308B\u306E\u306F\u4ECA\u56DE\u9650\u308A\u3067\u3059\u3002\u4ECA\u3059\u3050\u30B3\u30D4\u30FC\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 \u30C0\u30A4\u30A2\u30ED\u30B0\u3092\u9589\u3058\u308B\u3068\u6C38\u4E45\u306B\u5931\u308F\u308C\u307E\u3059\u3002",
|
|
611
|
+
copy: "\u30B3\u30D4\u30FC",
|
|
612
|
+
copied: "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F",
|
|
613
|
+
done: "\u9589\u3058\u308B",
|
|
614
|
+
loading: "\u30C8\u30FC\u30AF\u30F3\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...",
|
|
615
|
+
error: "\u30C8\u30FC\u30AF\u30F3\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
616
|
+
listEmpty: "\u30C8\u30FC\u30AF\u30F3\u304C\u307E\u3060\u3042\u308A\u307E\u305B\u3093\u3002\u300C\u30C8\u30FC\u30AF\u30F3\u3092\u4F5C\u6210\u300D\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u6700\u521D\u306E\u30C8\u30FC\u30AF\u30F3\u3092\u767A\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
617
|
+
columnPrefix: "\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9",
|
|
618
|
+
columnScope: "\u30B9\u30B3\u30FC\u30D7",
|
|
619
|
+
columnCreated: "\u4F5C\u6210\u65E5\u6642",
|
|
620
|
+
columnLastUsed: "\u6700\u7D42\u4F7F\u7528",
|
|
621
|
+
columnStatus: "\u30B9\u30C6\u30FC\u30BF\u30B9",
|
|
622
|
+
lastUsedNever: "\u672A\u4F7F\u7528",
|
|
623
|
+
statusActive: "\u6709\u52B9",
|
|
624
|
+
statusRevoked: "\u5931\u52B9",
|
|
625
|
+
statusExpired: "\u671F\u9650\u5207\u308C",
|
|
626
|
+
revoke: "\u5931\u52B9",
|
|
627
|
+
revokeConfirm: "\u3053\u306E\u30C8\u30FC\u30AF\u30F3\u3092\u5931\u52B9\u3055\u305B\u307E\u3059\u304B\uFF1F\u3053\u306E\u64CD\u4F5C\u306F\u5143\u306B\u623B\u305B\u307E\u305B\u3093\u3002"
|
|
628
|
+
},
|
|
463
629
|
public: {
|
|
464
630
|
back: "\u2190 \u623B\u308B",
|
|
465
631
|
home: "\u2190 \u30DB\u30FC\u30E0",
|
|
@@ -505,71 +671,8 @@ function translate(dict, key, vars) {
|
|
|
505
671
|
});
|
|
506
672
|
}
|
|
507
673
|
|
|
508
|
-
// src/lib/media.ts
|
|
509
|
-
var state = { outputs: null, cmsConfig: null };
|
|
510
|
-
function setAdminMediaContext(outputs, cmsConfig2) {
|
|
511
|
-
state.outputs = outputs;
|
|
512
|
-
state.cmsConfig = cmsConfig2;
|
|
513
|
-
}
|
|
514
|
-
function publicMediaUrl(input) {
|
|
515
|
-
if (/^https?:\/\//.test(input)) return input;
|
|
516
|
-
let path = input.replace(/^\/+/, "");
|
|
517
|
-
if (path.startsWith("public/")) path = path.slice("public/".length);
|
|
518
|
-
const { outputs, cmsConfig: cmsConfig2 } = state;
|
|
519
|
-
const delivery = cmsConfig2?.media?.delivery ?? "nextjs";
|
|
520
|
-
if (delivery !== "s3-direct") return `/api/media/${path}`;
|
|
521
|
-
const storage = outputs?.storage;
|
|
522
|
-
if (!storage) return `/api/media/${path}`;
|
|
523
|
-
return `https://${storage.bucket_name}.s3.${storage.aws_region}.amazonaws.com/public/${path}`;
|
|
524
|
-
}
|
|
525
|
-
function createMedia(outputs, cmsConfig2) {
|
|
526
|
-
const storage = outputs.storage;
|
|
527
|
-
function s3DirectUrl(path) {
|
|
528
|
-
if (!storage) return `/api/media/${path}`;
|
|
529
|
-
return `https://${storage.bucket_name}.s3.${storage.aws_region}.amazonaws.com/public/${path}`;
|
|
530
|
-
}
|
|
531
|
-
function urlFor(input) {
|
|
532
|
-
if (/^https?:\/\//.test(input)) return input;
|
|
533
|
-
let path = input.replace(/^\/+/, "");
|
|
534
|
-
if (path.startsWith("public/")) path = path.slice("public/".length);
|
|
535
|
-
const delivery = cmsConfig2.media?.delivery ?? "nextjs";
|
|
536
|
-
return delivery === "s3-direct" ? s3DirectUrl(path) : `/api/media/${path}`;
|
|
537
|
-
}
|
|
538
|
-
return { publicMediaUrl: urlFor };
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// src/lib/admin-site-client.ts
|
|
542
|
-
import { DEFAULT_SITE_ID, isMultiSite } from "ampless";
|
|
543
|
-
var ADMIN_SITE_COOKIE = "admin-site-id";
|
|
544
|
-
var cmsConfig = null;
|
|
545
|
-
function setAdminCmsConfig(config) {
|
|
546
|
-
cmsConfig = config;
|
|
547
|
-
}
|
|
548
|
-
function readAdminSiteIdFromCookie() {
|
|
549
|
-
if (!cmsConfig) return DEFAULT_SITE_ID;
|
|
550
|
-
if (!isMultiSite(cmsConfig)) return DEFAULT_SITE_ID;
|
|
551
|
-
const sites = cmsConfig.sites ?? {};
|
|
552
|
-
if (typeof document !== "undefined") {
|
|
553
|
-
const match = document.cookie.match(
|
|
554
|
-
new RegExp(`(?:^|;\\s*)${ADMIN_SITE_COOKIE}=([^;]+)`)
|
|
555
|
-
);
|
|
556
|
-
if (match) {
|
|
557
|
-
const v = decodeURIComponent(match[1]);
|
|
558
|
-
if (sites[v]) return v;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
const first = Object.keys(sites)[0];
|
|
562
|
-
return first ?? DEFAULT_SITE_ID;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
674
|
export {
|
|
566
675
|
resolveLocale,
|
|
567
676
|
getDictionary,
|
|
568
|
-
translate
|
|
569
|
-
setAdminMediaContext,
|
|
570
|
-
publicMediaUrl,
|
|
571
|
-
createMedia,
|
|
572
|
-
ADMIN_SITE_COOKIE,
|
|
573
|
-
setAdminCmsConfig,
|
|
574
|
-
readAdminSiteIdFromCookie
|
|
677
|
+
translate
|
|
575
678
|
};
|