@cancia/astro 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-4PYVIIOO.js +25 -0
- package/dist/{chunk-DIV2FFYX.js → chunk-5R3I5RLT.js} +15 -8
- package/dist/chunk-6GUOGDWO.js +172 -0
- package/dist/chunk-DEI3FBNY.js +65 -0
- package/dist/{chunk-ONKCUTPU.js → chunk-DOFLZ7KG.js} +6 -7
- package/dist/{chunk-GJIX7MWC.js → chunk-ECPYHIAW.js} +9 -1
- package/dist/{chunk-YGJ3JHXF.js → chunk-QQEUCOXQ.js} +11 -0
- package/dist/{chunk-NVXNJ4YC.js → chunk-R7VA3Z5N.js} +53 -11
- package/dist/{chunk-5IPHDIC6.js → chunk-RHFTQW4W.js} +10 -1
- package/dist/{chunk-2NVZWZPE.js → chunk-S5YLB6P3.js} +310 -7
- package/dist/{chunk-LJSSPOSW.js → chunk-VF3EXXEM.js} +139 -16
- package/dist/chunk-XINNLVZP.js +183 -0
- package/dist/chunk-XZCXWILA.js +145 -0
- package/dist/content.js +3 -3
- package/dist/{upload-DwCGjXbz.d.ts → email-BRK4WAO2.d.ts} +9 -1
- package/dist/endpoints/auth-callback.d.ts +1 -0
- package/dist/endpoints/auth-callback.js +9 -0
- package/dist/endpoints/auth-logout.d.ts +1 -0
- package/dist/endpoints/auth-logout.js +9 -0
- package/dist/endpoints/auth-request.d.ts +18 -0
- package/dist/endpoints/auth-request.js +9 -0
- package/dist/endpoints/auth-session.d.ts +1 -0
- package/dist/endpoints/auth-session.js +9 -0
- package/dist/endpoints/auth.js +10 -2
- package/dist/endpoints/content.js +12 -12
- package/dist/endpoints/lists.js +4 -1
- package/dist/endpoints/publish.js +8 -6
- package/dist/endpoints/schemas.js +6 -3
- package/dist/endpoints/upload.js +11 -10
- package/dist/{git-backed-DtiH52EI.d.ts → git-backed-CwTFfUS4.d.ts} +2 -2
- package/dist/{github-client-Db0pIrqE.d.ts → github-client-Db5EPcSL.d.ts} +1 -1
- package/dist/index.d.ts +32 -6
- package/dist/index.js +125 -35
- package/dist/loader/index.d.ts +34 -4
- package/dist/loader/index.js +3 -3
- package/dist/runtime.d.ts +69 -3
- package/dist/runtime.js +6 -4
- package/dist/schema/index.d.ts +14 -1
- package/dist/schema/index.js +1 -1
- package/dist/storage/index.d.ts +4 -4
- package/dist/storage/index.js +5 -5
- package/dist/{types-BMlLS-OS.d.ts → types-CKzfz5iu.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-MXVOJRAM.js +0 -504
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRateLimiter,
|
|
3
|
+
getIp,
|
|
4
|
+
isRateLimited,
|
|
5
|
+
recordFailure
|
|
6
|
+
} from "./chunk-ECPYHIAW.js";
|
|
7
|
+
import {
|
|
8
|
+
SESSION_TTL_MS,
|
|
9
|
+
clearSessionCookie,
|
|
10
|
+
isSecureRequest,
|
|
11
|
+
normaliseEmail,
|
|
12
|
+
readSessionCookie,
|
|
13
|
+
redeemLoginToken,
|
|
14
|
+
requestLoginLink,
|
|
15
|
+
revokeSession,
|
|
16
|
+
serialiseSessionCookie
|
|
17
|
+
} from "./chunk-6GUOGDWO.js";
|
|
18
|
+
|
|
19
|
+
// src/auth/email.ts
|
|
20
|
+
var LOOPS_API_URL = "https://app.loops.so/api/v1/transactional";
|
|
21
|
+
var consoleLoginEmail = async ({ to, url }) => {
|
|
22
|
+
console.log(
|
|
23
|
+
`
|
|
24
|
+
\x1B[36m[cancia]\x1B[0m login link for \x1B[1m${to}\x1B[0m:
|
|
25
|
+
${url}
|
|
26
|
+
`
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
var loopsLoginEmail = async ({ to, url }) => {
|
|
30
|
+
const apiKey = process.env.LOOPS_API_KEY;
|
|
31
|
+
const transactionalId = process.env.CANCIA_LOGIN_TID;
|
|
32
|
+
if (!apiKey || !transactionalId) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"Loops login email needs LOOPS_API_KEY and CANCIA_LOGIN_TID in the server environment."
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const res = await fetch(LOOPS_API_URL, {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: {
|
|
40
|
+
"Content-Type": "application/json",
|
|
41
|
+
Authorization: `Bearer ${apiKey}`
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
email: to,
|
|
45
|
+
transactionalId,
|
|
46
|
+
dataVariables: { loginUrl: url }
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
throw new Error(`Loops login email failed (${res.status})`);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function resolveLoginEmailSender(explicit) {
|
|
54
|
+
if (explicit) return explicit;
|
|
55
|
+
if (process.env.LOOPS_API_KEY && process.env.CANCIA_LOGIN_TID) return loopsLoginEmail;
|
|
56
|
+
return consoleLoginEmail;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/auth/handlers.ts
|
|
60
|
+
var json = (body, status, headers = {}) => new Response(JSON.stringify(body), {
|
|
61
|
+
status,
|
|
62
|
+
headers: { "Content-Type": "application/json", ...headers }
|
|
63
|
+
});
|
|
64
|
+
var NEUTRAL_ACK = { ok: true, message: "If that address can edit this site, a link is on its way." };
|
|
65
|
+
function looksLikeEmail(value) {
|
|
66
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) && value.length <= 254;
|
|
67
|
+
}
|
|
68
|
+
async function handleLoginRequest(request, ctx, origin) {
|
|
69
|
+
const limiter = ctx.limiter ?? createRateLimiter();
|
|
70
|
+
const now = ctx.now ?? Date.now();
|
|
71
|
+
const ip = getIp(request);
|
|
72
|
+
if (isRateLimited(limiter, ip, now)) {
|
|
73
|
+
return json({ error: "Too many attempts. Try again in a minute." }, 429);
|
|
74
|
+
}
|
|
75
|
+
let email;
|
|
76
|
+
try {
|
|
77
|
+
const body = await request.json();
|
|
78
|
+
email = body?.email;
|
|
79
|
+
} catch {
|
|
80
|
+
return json({ error: "Invalid request body" }, 400);
|
|
81
|
+
}
|
|
82
|
+
if (!email || !looksLikeEmail(email.trim())) {
|
|
83
|
+
return json({ error: "Enter a valid email address." }, 400);
|
|
84
|
+
}
|
|
85
|
+
const normalised = normaliseEmail(email);
|
|
86
|
+
if (isRateLimited(limiter, `email:${normalised}`, now)) {
|
|
87
|
+
return json(NEUTRAL_ACK, 200);
|
|
88
|
+
}
|
|
89
|
+
recordFailure(limiter, ip, now);
|
|
90
|
+
recordFailure(limiter, `email:${normalised}`, now);
|
|
91
|
+
const { token } = await requestLoginLink(ctx.store, ctx.site, normalised, now);
|
|
92
|
+
if (token) {
|
|
93
|
+
const url = `${origin}/?cancia_login=${encodeURIComponent(token)}`;
|
|
94
|
+
void ctx.sendEmail({ to: normalised, url, site: ctx.site }).catch((err) => {
|
|
95
|
+
console.error(
|
|
96
|
+
`[cancia] failed to send login email: ${err instanceof Error ? err.message : String(err)}`
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
void ctx.store.purgeExpired(ctx.site, new Date(now).toISOString()).catch(() => {
|
|
101
|
+
});
|
|
102
|
+
return json(NEUTRAL_ACK, 200);
|
|
103
|
+
}
|
|
104
|
+
async function handleLoginCallback(request, ctx) {
|
|
105
|
+
const now = ctx.now ?? Date.now();
|
|
106
|
+
let token;
|
|
107
|
+
try {
|
|
108
|
+
const body = await request.json();
|
|
109
|
+
token = body?.token;
|
|
110
|
+
} catch {
|
|
111
|
+
return json({ error: "Invalid request body" }, 400);
|
|
112
|
+
}
|
|
113
|
+
const result = await redeemLoginToken(ctx.store, ctx.site, token ?? "", now);
|
|
114
|
+
if (!result.sessionToken) {
|
|
115
|
+
return json({ error: "That link is invalid or has expired. Request a new one." }, 401);
|
|
116
|
+
}
|
|
117
|
+
return json(
|
|
118
|
+
{ ok: true, email: result.email },
|
|
119
|
+
200,
|
|
120
|
+
{
|
|
121
|
+
"Set-Cookie": serialiseSessionCookie(result.sessionToken, {
|
|
122
|
+
secure: isSecureRequest(request),
|
|
123
|
+
maxAgeSeconds: Math.floor(SESSION_TTL_MS / 1e3)
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
async function handleLogout(request, ctx) {
|
|
129
|
+
await revokeSession(ctx.store, ctx.site, readSessionCookie(request));
|
|
130
|
+
return json({ ok: true }, 200, {
|
|
131
|
+
"Set-Cookie": clearSessionCookie({ secure: isSecureRequest(request) })
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
async function handleSessionCheck(request, ctx, authorize) {
|
|
135
|
+
const verdict = await authorize();
|
|
136
|
+
return json({ authenticated: verdict.ok, email: verdict.email }, 200);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
resolveLoginEmailSender,
|
|
141
|
+
handleLoginRequest,
|
|
142
|
+
handleLoginCallback,
|
|
143
|
+
handleLogout,
|
|
144
|
+
handleSessionCheck
|
|
145
|
+
};
|
package/dist/content.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./chunk-FOSOWSXV.js";
|
|
2
2
|
import "./chunk-CJDIVWO3.js";
|
|
3
|
+
import "./chunk-XINNLVZP.js";
|
|
4
|
+
import "./chunk-U7V53JX7.js";
|
|
3
5
|
import {
|
|
4
6
|
createSqliteAdapterV2
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-U7V53JX7.js";
|
|
7
|
-
import "./chunk-2NVZWZPE.js";
|
|
7
|
+
} from "./chunk-S5YLB6P3.js";
|
|
8
8
|
import "./chunk-7IA5B5CF.js";
|
|
9
9
|
|
|
10
10
|
// src/content.ts
|
|
@@ -10,4 +10,12 @@ declare function makeLocalUploadHandler(opts: {
|
|
|
10
10
|
maxMB?: number;
|
|
11
11
|
}): UploadHandler;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
interface LoginEmailPayload {
|
|
14
|
+
to: string;
|
|
15
|
+
/** The full, ready-to-click URL. */
|
|
16
|
+
url: string;
|
|
17
|
+
site: string;
|
|
18
|
+
}
|
|
19
|
+
type SendLoginEmail = (payload: LoginEmailPayload) => Promise<void>;
|
|
20
|
+
|
|
21
|
+
export { type SendLoginEmail as S, type UploadHandler as U, makeLocalUploadHandler as m };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { c as POST } from './auth-request.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { l as POST } from './auth-request.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** POST /api/cancia/auth/request — { email } */
|
|
2
|
+
declare function requestLink({ request }: {
|
|
3
|
+
request: Request;
|
|
4
|
+
}): Promise<Response>;
|
|
5
|
+
/** POST /api/cancia/auth/callback — { token } */
|
|
6
|
+
declare function callback({ request }: {
|
|
7
|
+
request: Request;
|
|
8
|
+
}): Promise<Response>;
|
|
9
|
+
/** POST /api/cancia/auth/logout */
|
|
10
|
+
declare function logout({ request }: {
|
|
11
|
+
request: Request;
|
|
12
|
+
}): Promise<Response>;
|
|
13
|
+
/** GET /api/cancia/auth/session — "am I signed in?" */
|
|
14
|
+
declare function session({ request }: {
|
|
15
|
+
request: Request;
|
|
16
|
+
}): Promise<Response>;
|
|
17
|
+
|
|
18
|
+
export { requestLink as POST, callback as c, logout as l, session as s };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { s as GET } from './auth-request.js';
|
package/dist/endpoints/auth.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRateLimiter,
|
|
3
3
|
runAuth
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-ECPYHIAW.js";
|
|
5
5
|
|
|
6
6
|
// src/endpoints/auth.ts
|
|
7
7
|
import { getCanciaRuntime } from "virtual:cancia/runtime";
|
|
8
8
|
var limiter = createRateLimiter();
|
|
9
9
|
async function POST({ request }) {
|
|
10
|
-
const { secret } = getCanciaRuntime();
|
|
10
|
+
const { secret, auth } = getCanciaRuntime();
|
|
11
|
+
if (auth) {
|
|
12
|
+
return new Response(
|
|
13
|
+
JSON.stringify({
|
|
14
|
+
error: "This site uses email login. Open the site and request a link instead."
|
|
15
|
+
}),
|
|
16
|
+
{ status: 403, headers: { "Content-Type": "application/json" } }
|
|
17
|
+
);
|
|
18
|
+
}
|
|
11
19
|
return runAuth({ request, secret, limiter });
|
|
12
20
|
}
|
|
13
21
|
export {
|
|
@@ -2,20 +2,20 @@ import {
|
|
|
2
2
|
extractRoute,
|
|
3
3
|
invalidateOnSave
|
|
4
4
|
} from "../chunk-VGRG5DN7.js";
|
|
5
|
+
import {
|
|
6
|
+
guardRequest
|
|
7
|
+
} from "../chunk-4PYVIIOO.js";
|
|
8
|
+
import "../chunk-6GUOGDWO.js";
|
|
5
9
|
import "../chunk-X6ZFFGIA.js";
|
|
6
10
|
|
|
7
11
|
// src/endpoints/content.ts
|
|
8
12
|
import { getCanciaRuntime } from "virtual:cancia/runtime";
|
|
9
|
-
function checkAuth(req, secret) {
|
|
10
|
-
|
|
11
|
-
const token = req.headers.get("Authorization")?.replace("Bearer ", "").trim();
|
|
12
|
-
if (token !== secret)
|
|
13
|
-
return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
|
|
14
|
-
return null;
|
|
13
|
+
async function checkAuth(req, secret, auth) {
|
|
14
|
+
return (await guardRequest(req, { secret, auth })).deny;
|
|
15
15
|
}
|
|
16
16
|
async function GET({ request }) {
|
|
17
|
-
const { storage, secret } = getCanciaRuntime();
|
|
18
|
-
const deny = checkAuth(request, secret);
|
|
17
|
+
const { storage, secret, auth } = getCanciaRuntime();
|
|
18
|
+
const deny = await checkAuth(request, secret, auth);
|
|
19
19
|
if (deny) return deny;
|
|
20
20
|
const site = new URL(request.url).searchParams.get("site");
|
|
21
21
|
if (!site)
|
|
@@ -27,8 +27,8 @@ async function GET({ request }) {
|
|
|
27
27
|
}
|
|
28
28
|
async function POST(context) {
|
|
29
29
|
const { request } = context;
|
|
30
|
-
const { storage, secret, publishMode } = getCanciaRuntime();
|
|
31
|
-
const deny = checkAuth(request, secret);
|
|
30
|
+
const { storage, secret, publishMode, auth } = getCanciaRuntime();
|
|
31
|
+
const deny = await checkAuth(request, secret, auth);
|
|
32
32
|
if (deny) return deny;
|
|
33
33
|
const body = await request.json().catch(() => null);
|
|
34
34
|
if (!body?.site || !body?.key || !body?.lang || body?.value === void 0)
|
|
@@ -43,8 +43,8 @@ async function POST(context) {
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
async function DELETE({ request }) {
|
|
46
|
-
const { storage, secret } = getCanciaRuntime();
|
|
47
|
-
const deny = checkAuth(request, secret);
|
|
46
|
+
const { storage, secret, auth } = getCanciaRuntime();
|
|
47
|
+
const deny = await checkAuth(request, secret, auth);
|
|
48
48
|
if (deny) return deny;
|
|
49
49
|
const body = await request.json().catch(() => null);
|
|
50
50
|
if (!body?.site || !body?.key || !body?.lang)
|
package/dist/endpoints/lists.js
CHANGED
|
@@ -4,7 +4,9 @@ import {
|
|
|
4
4
|
} from "../chunk-VGRG5DN7.js";
|
|
5
5
|
import {
|
|
6
6
|
makeListsRoutes
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-5R3I5RLT.js";
|
|
8
|
+
import "../chunk-4PYVIIOO.js";
|
|
9
|
+
import "../chunk-6GUOGDWO.js";
|
|
8
10
|
import "../chunk-X6ZFFGIA.js";
|
|
9
11
|
import "../chunk-VL6FO446.js";
|
|
10
12
|
import "../chunk-7IA5B5CF.js";
|
|
@@ -18,6 +20,7 @@ function getRoutes() {
|
|
|
18
20
|
projectRoot: rt.projectRoot,
|
|
19
21
|
schemasPath: rt.schemasPath,
|
|
20
22
|
secret: rt.secret,
|
|
23
|
+
auth: rt.auth,
|
|
21
24
|
defaultLocale: rt.defaultLocale
|
|
22
25
|
});
|
|
23
26
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runPublish
|
|
3
3
|
} from "../chunk-5RCLBWRH.js";
|
|
4
|
+
import {
|
|
5
|
+
guardRequest
|
|
6
|
+
} from "../chunk-4PYVIIOO.js";
|
|
7
|
+
import "../chunk-6GUOGDWO.js";
|
|
4
8
|
import "../chunk-U7V53JX7.js";
|
|
5
9
|
|
|
6
10
|
// src/endpoints/publish.ts
|
|
@@ -14,13 +18,11 @@ async function POST({ request }) {
|
|
|
14
18
|
publishRepo,
|
|
15
19
|
publishGithubToken,
|
|
16
20
|
publishMode,
|
|
17
|
-
secret
|
|
21
|
+
secret,
|
|
22
|
+
auth
|
|
18
23
|
} = getCanciaRuntime();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (token !== secret)
|
|
22
|
-
return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
|
|
23
|
-
}
|
|
24
|
+
const deny = (await guardRequest(request, { secret, auth })).deny;
|
|
25
|
+
if (deny) return deny;
|
|
24
26
|
const hook = deployHook ?? process.env.CANCIA_DEPLOY_HOOK;
|
|
25
27
|
const ghToken = publishGithubToken ?? process.env.CANCIA_GITHUB_TOKEN?.trim();
|
|
26
28
|
return runPublish({
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeSchemasRoute
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-DOFLZ7KG.js";
|
|
4
|
+
import "../chunk-4PYVIIOO.js";
|
|
5
|
+
import "../chunk-6GUOGDWO.js";
|
|
4
6
|
import "../chunk-VL6FO446.js";
|
|
5
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-QQEUCOXQ.js";
|
|
6
8
|
import "../chunk-KHCFVVYV.js";
|
|
7
9
|
|
|
8
10
|
// src/endpoints/schemas.ts
|
|
@@ -12,7 +14,8 @@ async function GET({ request }) {
|
|
|
12
14
|
const route = makeSchemasRoute({
|
|
13
15
|
projectRoot: rt.projectRoot,
|
|
14
16
|
schemasPath: rt.schemasPath,
|
|
15
|
-
secret: rt.secret
|
|
17
|
+
secret: rt.secret,
|
|
18
|
+
auth: rt.auth
|
|
16
19
|
});
|
|
17
20
|
return route(request);
|
|
18
21
|
}
|
package/dist/endpoints/upload.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
detectUploadType,
|
|
3
3
|
isValidSite
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-RHFTQW4W.js";
|
|
5
|
+
import {
|
|
6
|
+
guardRequest
|
|
7
|
+
} from "../chunk-4PYVIIOO.js";
|
|
8
|
+
import "../chunk-6GUOGDWO.js";
|
|
5
9
|
|
|
6
10
|
// src/endpoints/upload.ts
|
|
7
11
|
import { getCanciaRuntime } from "virtual:cancia/runtime";
|
|
8
12
|
async function POST({ request }) {
|
|
9
|
-
const { uploadHandler, secret, maxUploadMB } = getCanciaRuntime();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (token !== secret)
|
|
13
|
-
return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
|
|
14
|
-
}
|
|
13
|
+
const { uploadHandler, secret, maxUploadMB, auth } = getCanciaRuntime();
|
|
14
|
+
const deny = (await guardRequest(request, { secret, auth })).deny;
|
|
15
|
+
if (deny) return deny;
|
|
15
16
|
const form = await request.formData().catch(() => null);
|
|
16
17
|
const file = form?.get("file");
|
|
17
18
|
const site = form?.get("site");
|
|
@@ -28,9 +29,9 @@ async function POST({ request }) {
|
|
|
28
29
|
{ status: 413 }
|
|
29
30
|
);
|
|
30
31
|
const buf = new Uint8Array(await file.arrayBuffer());
|
|
31
|
-
const detected =
|
|
32
|
+
const detected = detectUploadType(buf);
|
|
32
33
|
if (!detected)
|
|
33
|
-
return new Response(JSON.stringify({ error: "
|
|
34
|
+
return new Response(JSON.stringify({ error: "That file type is not supported. Use a JPEG, PNG, GIF, WebP, AVIF or PDF." }), { status: 415 });
|
|
34
35
|
const url = await uploadHandler(file, site, detected);
|
|
35
36
|
return new Response(JSON.stringify({ url }), {
|
|
36
37
|
headers: { "Content-Type": "application/json" }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { d as CanciaStorage, C as CanciaStorageV2 } from './types-CKzfz5iu.js';
|
|
2
|
+
import { b as GitHubCommitter, G as GitHubClient, F as FetchLike } from './github-client-Db5EPcSL.js';
|
|
3
3
|
|
|
4
4
|
declare function createJsonFileAdapter(filePath?: string): CanciaStorage;
|
|
5
5
|
|
|
@@ -54,4 +54,4 @@ interface GitHubClient {
|
|
|
54
54
|
}
|
|
55
55
|
declare function createGitHubClient(opts: GitHubClientOptions): GitHubClient;
|
|
56
56
|
|
|
57
|
-
export { type CommitFile as C, type FetchLike as F, type
|
|
57
|
+
export { type CommitFile as C, type FetchLike as F, type GitHubClient as G, type GitHubClientOptions as a, type GitHubCommitter as b, createGitHubClient as c };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AstroIntegration } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
4
|
-
import { U as UploadHandler } from './
|
|
5
|
-
export { m as makeLocalUploadHandler } from './
|
|
6
|
-
import {
|
|
2
|
+
import { d as CanciaStorage, C as CanciaStorageV2 } from './types-CKzfz5iu.js';
|
|
3
|
+
export { a as CanciaKVStore, b as CanciaListStore, c as CanciaPageStore, L as ListEntry, P as PageMeta, e as PageRecord, f as PageSEO, R as Rev, g as RevConflictError } from './types-CKzfz5iu.js';
|
|
4
|
+
import { U as UploadHandler, S as SendLoginEmail } from './email-BRK4WAO2.js';
|
|
5
|
+
export { m as makeLocalUploadHandler } from './email-BRK4WAO2.js';
|
|
6
|
+
import { b as GitHubCommitter } from './github-client-Db5EPcSL.js';
|
|
7
7
|
export { CanciaLoaderOptions, canciaLoader } from './loader/index.js';
|
|
8
8
|
export { FieldDescription, FieldMeta, FieldMetaBase, FieldWidget, ListDescription, ListSchema, SchemasModule, defineField, defineList, describeList } from './schema/index.js';
|
|
9
|
-
export { G as GitBackedContentPaths, a as GitBackedControls, b as GitBackedOptions, c as GitBackedStorage, S as SqliteV2Options, d as closeSqliteAdapterV2, e as createGitBackedAdapter, f as createJsonFileAdapter, g as createJsonFileAdapterV2, h as createSQLiteAdapter, i as createSqliteAdapterV2 } from './git-backed-
|
|
9
|
+
export { G as GitBackedContentPaths, a as GitBackedControls, b as GitBackedOptions, c as GitBackedStorage, S as SqliteV2Options, d as closeSqliteAdapterV2, e as createGitBackedAdapter, f as createJsonFileAdapter, g as createJsonFileAdapterV2, h as createSQLiteAdapter, i as createSqliteAdapterV2 } from './git-backed-CwTFfUS4.js';
|
|
10
10
|
export { z } from 'zod';
|
|
11
11
|
import 'astro/loaders';
|
|
12
12
|
import './portable-text-D74aIuHn.js';
|
|
@@ -139,6 +139,32 @@ interface CanciaIntegrationOptions {
|
|
|
139
139
|
* Use for public demos only — anyone can edit if this is enabled.
|
|
140
140
|
*/
|
|
141
141
|
public?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Email addresses allowed to sign in (042).
|
|
144
|
+
*
|
|
145
|
+
* Setting this switches the site to magic-link login: the client asks for a
|
|
146
|
+
* link, proves they own the address, and gets a session cookie. It also
|
|
147
|
+
* TURNS OFF the legacy `?cancia=<token>` URL login for humans — that token
|
|
148
|
+
* is a permanent password in a URL, and once a real login exists there is no
|
|
149
|
+
* reason to keep accepting it from a person. `CANCIA_TOKEN` stays valid as a
|
|
150
|
+
* machine credential for the build-time content fetch.
|
|
151
|
+
*
|
|
152
|
+
* Leaving it unset preserves the pre-042 behaviour exactly, so upgrading the
|
|
153
|
+
* package never changes how an existing deployment authenticates.
|
|
154
|
+
*
|
|
155
|
+
* cancia({ editors: ["client@theirsite.com"] })
|
|
156
|
+
*
|
|
157
|
+
* Adding someone is a config change plus a redeploy — the right friction for
|
|
158
|
+
* granting write access to a live site.
|
|
159
|
+
*/
|
|
160
|
+
editors?: string[];
|
|
161
|
+
/**
|
|
162
|
+
* Send the login email. Defaults to Loops when LOOPS_API_KEY and
|
|
163
|
+
* CANCIA_LOGIN_TID are set, and otherwise logs the link to the server
|
|
164
|
+
* console (which is also the dev behaviour — no email vendor is needed to
|
|
165
|
+
* work on the CMS locally).
|
|
166
|
+
*/
|
|
167
|
+
sendLoginEmail?: SendLoginEmail;
|
|
142
168
|
/**
|
|
143
169
|
* v2 storage adapter (KV + pages + lists). When omitted, Cancia builds a
|
|
144
170
|
* JSON-file v2 adapter automatically at <projectRoot>/.cancia/. List/page
|