@coursebuilder/server 0.1.0-canary.0.0c9beb2ae
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/dist/actions/checkout.d.ts +6 -0
- package/dist/actions/checkout.js +9 -0
- package/dist/actions/checkout.js.map +1 -0
- package/dist/actions/claimed.d.ts +6 -0
- package/dist/actions/claimed.js +8 -0
- package/dist/actions/claimed.js.map +1 -0
- package/dist/actions/create-magic-link.d.ts +6 -0
- package/dist/actions/create-magic-link.js +9 -0
- package/dist/actions/create-magic-link.js.map +1 -0
- package/dist/actions/index.d.ts +11 -0
- package/dist/actions/index.js +18 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/prices-coupon-for-code.d.ts +6 -0
- package/dist/actions/prices-coupon-for-code.js +63 -0
- package/dist/actions/prices-coupon-for-code.js.map +1 -0
- package/dist/actions/prices-formatted.d.ts +6 -0
- package/dist/actions/prices-formatted.js +8 -0
- package/dist/actions/prices-formatted.js.map +1 -0
- package/dist/actions/process-refund.d.ts +1 -0
- package/dist/actions/process-refund.js +8 -0
- package/dist/actions/process-refund.js.map +1 -0
- package/dist/actions/redeem.d.ts +1 -0
- package/dist/actions/redeem.js +8 -0
- package/dist/actions/redeem.js.map +1 -0
- package/dist/actions/transfer-purchase.d.ts +1 -0
- package/dist/actions/transfer-purchase.js +8 -0
- package/dist/actions/transfer-purchase.js.map +1 -0
- package/dist/actions/user-lookup.d.ts +6 -0
- package/dist/actions/user-lookup.js +9 -0
- package/dist/actions/user-lookup.js.map +1 -0
- package/dist/adapter-BtDS6LDw.d.ts +9 -0
- package/dist/chunk-22AMOZYZ.js +67 -0
- package/dist/chunk-22AMOZYZ.js.map +1 -0
- package/dist/chunk-4EQQSW57.js +32 -0
- package/dist/chunk-4EQQSW57.js.map +1 -0
- package/dist/chunk-4LZZLN6T.js +52 -0
- package/dist/chunk-4LZZLN6T.js.map +1 -0
- package/dist/chunk-4QQA3TC2.js +29 -0
- package/dist/chunk-4QQA3TC2.js.map +1 -0
- package/dist/chunk-4TSEPUSC.js +160 -0
- package/dist/chunk-4TSEPUSC.js.map +1 -0
- package/dist/chunk-5O4UO4IR.js +93 -0
- package/dist/chunk-5O4UO4IR.js.map +1 -0
- package/dist/chunk-7FCQOLKL.js +26 -0
- package/dist/chunk-7FCQOLKL.js.map +1 -0
- package/dist/chunk-AZLUMIIF.js +8 -0
- package/dist/chunk-AZLUMIIF.js.map +1 -0
- package/dist/chunk-E6HV6TNI.js +38 -0
- package/dist/chunk-E6HV6TNI.js.map +1 -0
- package/dist/chunk-ECNJPNPU.js +54 -0
- package/dist/chunk-ECNJPNPU.js.map +1 -0
- package/dist/chunk-F3KUYN5I.js +111 -0
- package/dist/chunk-F3KUYN5I.js.map +1 -0
- package/dist/chunk-G63YAJF2.js +107 -0
- package/dist/chunk-G63YAJF2.js.map +1 -0
- package/dist/chunk-JFR7XO72.js +7 -0
- package/dist/chunk-JFR7XO72.js.map +1 -0
- package/dist/chunk-KNC7QVGZ.js +26 -0
- package/dist/chunk-KNC7QVGZ.js.map +1 -0
- package/dist/chunk-ODSSRMD2.js +270 -0
- package/dist/chunk-ODSSRMD2.js.map +1 -0
- package/dist/chunk-VEKYIR7I.js +26 -0
- package/dist/chunk-VEKYIR7I.js.map +1 -0
- package/dist/chunk-W7YAT4NR.js +12 -0
- package/dist/chunk-W7YAT4NR.js.map +1 -0
- package/dist/chunk-WGAPYIUP.js +56 -0
- package/dist/chunk-WGAPYIUP.js.map +1 -0
- package/dist/chunk-WYNH2AWD.js +7 -0
- package/dist/chunk-WYNH2AWD.js.map +1 -0
- package/dist/chunk-Y5X5J55Z.js +384 -0
- package/dist/chunk-Y5X5J55Z.js.map +1 -0
- package/dist/chunk-YFLGJIMA.js +216 -0
- package/dist/chunk-YFLGJIMA.js.map +1 -0
- package/dist/chunk-ZFZNN4E5.js +7 -0
- package/dist/chunk-ZFZNN4E5.js.map +1 -0
- package/dist/create-inngest-middleware.d.ts +635 -0
- package/dist/create-inngest-middleware.js +12 -0
- package/dist/create-inngest-middleware.js.map +1 -0
- package/dist/http-router.d.ts +20 -0
- package/dist/http-router.js +24 -0
- package/dist/http-router.js.map +1 -0
- package/dist/http.d.ts +38 -0
- package/dist/http.js +32 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +365 -0
- package/dist/index.js.map +1 -0
- package/dist/magic-string.es-ENO43NON.js +1389 -0
- package/dist/magic-string.es-ENO43NON.js.map +1 -0
- package/dist/runtime/actions.d.ts +5 -0
- package/dist/runtime/actions.js +8 -0
- package/dist/runtime/actions.js.map +1 -0
- package/dist/runtime/assert.d.ts +15 -0
- package/dist/runtime/assert.js +8 -0
- package/dist/runtime/assert.js.map +1 -0
- package/dist/runtime/cookie.d.ts +8 -0
- package/dist/runtime/cookie.js +8 -0
- package/dist/runtime/cookie.js.map +1 -0
- package/dist/runtime/env.d.ts +9 -0
- package/dist/runtime/env.js +11 -0
- package/dist/runtime/env.js.map +1 -0
- package/dist/runtime/env.test.d.ts +2 -0
- package/dist/runtime/env.test.js +14956 -0
- package/dist/runtime/env.test.js.map +1 -0
- package/dist/runtime/init.d.ts +26 -0
- package/dist/runtime/init.js +14 -0
- package/dist/runtime/init.js.map +1 -0
- package/dist/runtime/logger.d.ts +4 -0
- package/dist/runtime/logger.js +10 -0
- package/dist/runtime/logger.js.map +1 -0
- package/dist/runtime/merge.d.ts +4 -0
- package/dist/runtime/merge.js +8 -0
- package/dist/runtime/merge.js.map +1 -0
- package/dist/runtime/providers.d.ts +21 -0
- package/dist/runtime/providers.js +9 -0
- package/dist/runtime/providers.js.map +1 -0
- package/dist/runtime/web.d.ts +29 -0
- package/dist/runtime/web.js +16 -0
- package/dist/runtime/web.js.map +1 -0
- package/package.json +65 -0
- package/src/actions/actions.test.ts +232 -0
- package/src/actions/checkout.ts +160 -0
- package/src/actions/claimed.ts +40 -0
- package/src/actions/create-magic-link.ts +78 -0
- package/src/actions/index.ts +401 -0
- package/src/actions/prices-coupon-for-code.ts +91 -0
- package/src/actions/prices-formatted.ts +313 -0
- package/src/actions/process-refund.ts +2 -0
- package/src/actions/redeem.ts +2 -0
- package/src/actions/transfer-purchase.ts +2 -0
- package/src/actions/user-lookup.ts +37 -0
- package/src/adapter.ts +28 -0
- package/src/create-inngest-middleware.ts +157 -0
- package/src/http-actions.ts +29 -0
- package/src/http-router.ts +79 -0
- package/src/http.test.ts +46 -0
- package/src/http.ts +83 -0
- package/src/index.test.ts +21 -0
- package/src/index.ts +44 -0
- package/src/mock-adapter.ts +398 -0
- package/src/mock-payment-provider.ts +56 -0
- package/src/resource-chat.ts +371 -0
- package/src/runtime/actions.ts +25 -0
- package/src/runtime/assert.ts +55 -0
- package/src/runtime/cookie.ts +12 -0
- package/src/runtime/env.test.ts +49 -0
- package/src/runtime/env.ts +63 -0
- package/src/runtime/init.ts +112 -0
- package/src/runtime/logger.ts +6 -0
- package/src/runtime/merge.ts +25 -0
- package/src/runtime/providers.ts +38 -0
- package/src/runtime/web.ts +199 -0
- package/src/streaming-chat-prompt-executor.ts +43 -0
- package/src/type-contracts.test.ts +167 -0
- package/src/web-body-parse.test.ts +55 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isCourseBuilderAction
|
|
3
|
+
} from "./chunk-VEKYIR7I.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-AZLUMIIF.js";
|
|
7
|
+
|
|
8
|
+
// src/runtime/web.ts
|
|
9
|
+
import { parse as parseCookie, serialize } from "cookie";
|
|
10
|
+
import { CourseBuilderError } from "@coursebuilder/core/errors";
|
|
11
|
+
async function getBody(req, config) {
|
|
12
|
+
const headers = Object.fromEntries(req.headers);
|
|
13
|
+
const isStripeWebhook = ["stripe-signature"].every((prop) => {
|
|
14
|
+
return prop in headers;
|
|
15
|
+
});
|
|
16
|
+
if (isStripeWebhook) {
|
|
17
|
+
let parsedBody;
|
|
18
|
+
const stripeProvider = config.providers.find((p) => p.id === "stripe");
|
|
19
|
+
parsedBody = await req.text();
|
|
20
|
+
stripeProvider?.options?.paymentsAdapter.verifyWebhookSignature(
|
|
21
|
+
parsedBody,
|
|
22
|
+
headers["stripe-signature"]
|
|
23
|
+
);
|
|
24
|
+
parsedBody = JSON.parse(parsedBody);
|
|
25
|
+
return parsedBody;
|
|
26
|
+
}
|
|
27
|
+
if (!("body" in req) || !req.body || req.method !== "POST")
|
|
28
|
+
return;
|
|
29
|
+
const contentType = req.headers.get("content-type");
|
|
30
|
+
if (contentType?.includes("application/json")) {
|
|
31
|
+
const rawBody = await req.text();
|
|
32
|
+
if (rawBody.trim().length === 0)
|
|
33
|
+
return void 0;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(rawBody);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
logger.error(e instanceof Error ? e : new Error(String(e)), {
|
|
38
|
+
context: "web.body-parse",
|
|
39
|
+
method: req.method,
|
|
40
|
+
contentType
|
|
41
|
+
});
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
} else if (contentType?.includes("application/x-www-form-urlencoded")) {
|
|
45
|
+
const params = new URLSearchParams(await req.text());
|
|
46
|
+
return Object.fromEntries(params);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function toInternalRequest(req, config) {
|
|
50
|
+
try {
|
|
51
|
+
config.basePath ?? (config.basePath = "/coursebuilder");
|
|
52
|
+
const url = new URL(req.url);
|
|
53
|
+
const { action, providerId } = parseActionAndProviderId(
|
|
54
|
+
url.pathname,
|
|
55
|
+
config.basePath
|
|
56
|
+
);
|
|
57
|
+
logger.debug("web.action-parsed", {
|
|
58
|
+
pathname: url.pathname,
|
|
59
|
+
action,
|
|
60
|
+
providerId: providerId ?? null,
|
|
61
|
+
searchParamCount: url.searchParams.size
|
|
62
|
+
});
|
|
63
|
+
const parsedCookies = parseCookie(req.headers.get("cookie") ?? "") ?? {};
|
|
64
|
+
logger.debug("web.request-parsed", {
|
|
65
|
+
action,
|
|
66
|
+
method: req.method,
|
|
67
|
+
providerId: providerId ?? null,
|
|
68
|
+
hasCookieHeader: Boolean(req.headers.get("cookie")),
|
|
69
|
+
parsedCookieCount: Object.keys(parsedCookies).length,
|
|
70
|
+
hasSl_ref: "sl_ref" in parsedCookies
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
url,
|
|
74
|
+
action,
|
|
75
|
+
providerId,
|
|
76
|
+
method: req.method,
|
|
77
|
+
headers: Object.fromEntries(req.headers),
|
|
78
|
+
body: req.body ? await getBody(req, config) : void 0,
|
|
79
|
+
cookies: parsedCookies,
|
|
80
|
+
error: url.searchParams.get("error") ?? void 0,
|
|
81
|
+
query: Object.fromEntries(url.searchParams)
|
|
82
|
+
};
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logger.error(e instanceof Error ? e : new Error(String(e)), {
|
|
85
|
+
context: "web.to-internal-request",
|
|
86
|
+
method: req.method,
|
|
87
|
+
url: req.url,
|
|
88
|
+
basePath: config.basePath
|
|
89
|
+
});
|
|
90
|
+
logger.debug("web.request-context", {
|
|
91
|
+
method: req.method,
|
|
92
|
+
url: req.url,
|
|
93
|
+
hasBody: Boolean(req.body),
|
|
94
|
+
hasCookieHeader: Boolean(req.headers.get("cookie"))
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function parseActionAndProviderId(pathname, base) {
|
|
99
|
+
const a = pathname.match(new RegExp(`^${base}(.+)`));
|
|
100
|
+
if (a === null)
|
|
101
|
+
throw new UnknownAction(`Cannot parse action at ${pathname}`);
|
|
102
|
+
const [_, actionAndProviderId] = a;
|
|
103
|
+
const b = actionAndProviderId.replace(/^\//, "").split("/");
|
|
104
|
+
if (b.length !== 1 && b.length !== 2)
|
|
105
|
+
throw new UnknownAction(`**Cannot parse action at ${pathname}`);
|
|
106
|
+
const [action, providerId] = b;
|
|
107
|
+
if (!isCourseBuilderAction(action))
|
|
108
|
+
throw new UnknownAction(`***Cannot parse action at ${pathname}`);
|
|
109
|
+
if (providerId && ![
|
|
110
|
+
"webhook",
|
|
111
|
+
"srt",
|
|
112
|
+
"session",
|
|
113
|
+
"subscribe-to-list",
|
|
114
|
+
"checkout",
|
|
115
|
+
"redeem",
|
|
116
|
+
"subscriber",
|
|
117
|
+
"lookup",
|
|
118
|
+
"claimed",
|
|
119
|
+
"nameUpdate",
|
|
120
|
+
"transfer",
|
|
121
|
+
"refund",
|
|
122
|
+
"create-magic-link"
|
|
123
|
+
].includes(action))
|
|
124
|
+
throw new UnknownAction(
|
|
125
|
+
`**** Cannot parse action at ${pathname}. add it to the list in web.ts?`
|
|
126
|
+
);
|
|
127
|
+
return { action, providerId };
|
|
128
|
+
}
|
|
129
|
+
var UnknownAction = class extends CourseBuilderError {
|
|
130
|
+
};
|
|
131
|
+
UnknownAction.type = "UnknownAction";
|
|
132
|
+
function toResponse(res) {
|
|
133
|
+
const headers = new Headers(res.headers);
|
|
134
|
+
res.cookies?.forEach((cookie) => {
|
|
135
|
+
const { name, value, options } = cookie;
|
|
136
|
+
const cookieHeader = serialize(name, value, options);
|
|
137
|
+
if (headers.has("Set-Cookie"))
|
|
138
|
+
headers.append("Set-Cookie", cookieHeader);
|
|
139
|
+
else
|
|
140
|
+
headers.set("Set-Cookie", cookieHeader);
|
|
141
|
+
});
|
|
142
|
+
let body = res.body;
|
|
143
|
+
if (headers.get("content-type") === "application/json")
|
|
144
|
+
body = JSON.stringify(res.body);
|
|
145
|
+
else if (headers.get("content-type") === "application/x-www-form-urlencoded")
|
|
146
|
+
body = new URLSearchParams(res.body).toString();
|
|
147
|
+
const status = res.redirect ? 302 : res.status ?? 200;
|
|
148
|
+
const response = new Response(body, { headers, status });
|
|
149
|
+
if (res.redirect)
|
|
150
|
+
response.headers.set("Location", res.redirect);
|
|
151
|
+
return response;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
toInternalRequest,
|
|
156
|
+
parseActionAndProviderId,
|
|
157
|
+
UnknownAction,
|
|
158
|
+
toResponse
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=chunk-4TSEPUSC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/web.ts"],"sourcesContent":["import { parse as parseCookie, serialize } from 'cookie'\n\nimport { CourseBuilderError } from '@coursebuilder/core/errors'\nimport {\n\tCourseBuilderAction,\n\tRequestInternal,\n\tResponseInternal,\n} from '@coursebuilder/core/types'\n\nimport { CourseBuilderConfig } from '../http'\nimport { isCourseBuilderAction } from './actions'\nimport { logger } from './logger'\n\nasync function getBody(\n\treq: Request,\n\tconfig: CourseBuilderConfig,\n): Promise<Record<string, any> | undefined> {\n\tconst headers = Object.fromEntries(req.headers)\n\tconst isStripeWebhook = ['stripe-signature'].every((prop: string) => {\n\t\treturn prop in headers\n\t})\n\n\tif (isStripeWebhook) {\n\t\tlet parsedBody\n\t\tconst stripeProvider = config.providers.find((p: any) => p.id === 'stripe')\n\t\tparsedBody = await req.text()\n\t\tstripeProvider?.options?.paymentsAdapter.verifyWebhookSignature(\n\t\t\tparsedBody,\n\t\t\theaders['stripe-signature'],\n\t\t)\n\t\tparsedBody = JSON.parse(parsedBody)\n\t\treturn parsedBody\n\t}\n\n\tif (!('body' in req) || !req.body || req.method !== 'POST') return\n\n\tconst contentType = req.headers.get('content-type')\n\tif (contentType?.includes('application/json')) {\n\t\tconst rawBody = await req.text()\n\t\tif (rawBody.trim().length === 0) return undefined\n\n\t\ttry {\n\t\t\treturn JSON.parse(rawBody)\n\t\t} catch (e) {\n\t\t\tlogger.error(e instanceof Error ? e : new Error(String(e)), {\n\t\t\t\tcontext: 'web.body-parse',\n\t\t\t\tmethod: req.method,\n\t\t\t\tcontentType,\n\t\t\t})\n\t\t\treturn undefined\n\t\t}\n\t} else if (contentType?.includes('application/x-www-form-urlencoded')) {\n\t\tconst params = new URLSearchParams(await req.text())\n\t\treturn Object.fromEntries(params)\n\t}\n}\n\n/**\n * takes a `Request` object and converts it into an internal request object\n * that we use throughout the system\n * @param req\n * @param config\n * @returns\n */\nexport async function toInternalRequest(\n\treq: Request,\n\tconfig: CourseBuilderConfig,\n): Promise<RequestInternal | undefined> {\n\ttry {\n\t\tconfig.basePath ??= '/coursebuilder'\n\n\t\tconst url = new URL(req.url)\n\n\t\tconst { action, providerId } = parseActionAndProviderId(\n\t\t\turl.pathname,\n\t\t\tconfig.basePath,\n\t\t)\n\n\t\tlogger.debug('web.action-parsed', {\n\t\t\tpathname: url.pathname,\n\t\t\taction,\n\t\t\tproviderId: providerId ?? null,\n\t\t\tsearchParamCount: url.searchParams.size,\n\t\t})\n\n\t\tconst parsedCookies = parseCookie(req.headers.get('cookie') ?? '') ?? {}\n\n\t\tlogger.debug('web.request-parsed', {\n\t\t\taction,\n\t\t\tmethod: req.method,\n\t\t\tproviderId: providerId ?? null,\n\t\t\thasCookieHeader: Boolean(req.headers.get('cookie')),\n\t\t\tparsedCookieCount: Object.keys(parsedCookies).length,\n\t\t\thasSl_ref: 'sl_ref' in parsedCookies,\n\t\t})\n\n\t\treturn {\n\t\t\turl,\n\t\t\taction,\n\t\t\tproviderId,\n\t\t\tmethod: req.method as 'POST' | 'GET',\n\t\t\theaders: Object.fromEntries(req.headers),\n\t\t\tbody: req.body ? await getBody(req, config) : undefined,\n\t\t\tcookies: parsedCookies,\n\t\t\terror: url.searchParams.get('error') ?? undefined,\n\t\t\tquery: Object.fromEntries(url.searchParams),\n\t\t}\n\t} catch (e) {\n\t\tlogger.error(e instanceof Error ? e : new Error(String(e)), {\n\t\t\tcontext: 'web.to-internal-request',\n\t\t\tmethod: req.method,\n\t\t\turl: req.url,\n\t\t\tbasePath: config.basePath,\n\t\t})\n\t\tlogger.debug('web.request-context', {\n\t\t\tmethod: req.method,\n\t\t\turl: req.url,\n\t\t\thasBody: Boolean(req.body),\n\t\t\thasCookieHeader: Boolean(req.headers.get('cookie')),\n\t\t})\n\t}\n}\n\nexport function parseActionAndProviderId(\n\tpathname: string,\n\tbase: string,\n): {\n\taction: CourseBuilderAction\n\tproviderId?: string\n} {\n\tconst a = pathname.match(new RegExp(`^${base}(.+)`))\n\n\tif (a === null) throw new UnknownAction(`Cannot parse action at ${pathname}`)\n\n\tconst [_, actionAndProviderId] = a\n\n\tconst b = actionAndProviderId.replace(/^\\//, '').split('/')\n\n\tif (b.length !== 1 && b.length !== 2)\n\t\tthrow new UnknownAction(`**Cannot parse action at ${pathname}`)\n\n\tconst [action, providerId] = b\n\n\tif (!isCourseBuilderAction(action))\n\t\tthrow new UnknownAction(`***Cannot parse action at ${pathname}`)\n\n\tif (\n\t\tproviderId &&\n\t\t![\n\t\t\t'webhook',\n\t\t\t'srt',\n\t\t\t'session',\n\t\t\t'subscribe-to-list',\n\t\t\t'checkout',\n\t\t\t'redeem',\n\t\t\t'subscriber',\n\t\t\t'lookup',\n\t\t\t'claimed',\n\t\t\t'nameUpdate',\n\t\t\t'transfer',\n\t\t\t'refund',\n\t\t\t'create-magic-link',\n\t\t].includes(action)\n\t)\n\t\tthrow new UnknownAction(\n\t\t\t`**** Cannot parse action at ${pathname}. add it to the list in web.ts?`,\n\t\t)\n\n\treturn { action, providerId }\n}\n\nexport class UnknownAction extends CourseBuilderError {\n\tstatic type = 'UnknownAction'\n}\n\nexport function toResponse(res: ResponseInternal): Response {\n\tconst headers = new Headers(res.headers)\n\n\tres.cookies?.forEach((cookie) => {\n\t\tconst { name, value, options } = cookie\n\t\tconst cookieHeader = serialize(name, value, options)\n\t\tif (headers.has('Set-Cookie')) headers.append('Set-Cookie', cookieHeader)\n\t\telse headers.set('Set-Cookie', cookieHeader)\n\t})\n\n\tlet body = res.body\n\n\tif (headers.get('content-type') === 'application/json')\n\t\tbody = JSON.stringify(res.body)\n\telse if (headers.get('content-type') === 'application/x-www-form-urlencoded')\n\t\tbody = new URLSearchParams(res.body).toString()\n\n\tconst status = res.redirect ? 302 : (res.status ?? 200)\n\tconst response = new Response(body, { headers, status })\n\n\tif (res.redirect) response.headers.set('Location', res.redirect)\n\n\treturn response\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultCookies
|
|
3
|
+
} from "./chunk-W7YAT4NR.js";
|
|
4
|
+
import {
|
|
5
|
+
parseProviders
|
|
6
|
+
} from "./chunk-4QQA3TC2.js";
|
|
7
|
+
import {
|
|
8
|
+
merge
|
|
9
|
+
} from "./chunk-KNC7QVGZ.js";
|
|
10
|
+
import {
|
|
11
|
+
logger
|
|
12
|
+
} from "./chunk-AZLUMIIF.js";
|
|
13
|
+
|
|
14
|
+
// src/runtime/init.ts
|
|
15
|
+
import { AdapterError } from "@coursebuilder/core/errors";
|
|
16
|
+
async function init({
|
|
17
|
+
url,
|
|
18
|
+
courseBuilderOptions,
|
|
19
|
+
providerId,
|
|
20
|
+
action,
|
|
21
|
+
isPost,
|
|
22
|
+
cookies: reqCookies
|
|
23
|
+
}) {
|
|
24
|
+
const { providers, provider } = parseProviders({
|
|
25
|
+
providers: courseBuilderOptions.providers,
|
|
26
|
+
url,
|
|
27
|
+
providerId,
|
|
28
|
+
options: courseBuilderOptions
|
|
29
|
+
});
|
|
30
|
+
const maxAge = 30 * 24 * 60 * 60;
|
|
31
|
+
const options = {
|
|
32
|
+
debug: false,
|
|
33
|
+
pages: {},
|
|
34
|
+
...courseBuilderOptions,
|
|
35
|
+
url,
|
|
36
|
+
action,
|
|
37
|
+
// @ts-expect-errors
|
|
38
|
+
provider,
|
|
39
|
+
cookies: merge(
|
|
40
|
+
{},
|
|
41
|
+
defaultCookies(
|
|
42
|
+
courseBuilderOptions.useSecureCookies ?? url.protocol === "https:"
|
|
43
|
+
),
|
|
44
|
+
courseBuilderOptions.cookies || {},
|
|
45
|
+
reqCookies
|
|
46
|
+
),
|
|
47
|
+
providers,
|
|
48
|
+
adapter: adapterErrorHandler(courseBuilderOptions.adapter, logger),
|
|
49
|
+
callbacks: { ...defaultCallbacks, ...courseBuilderOptions.callbacks },
|
|
50
|
+
logger,
|
|
51
|
+
getCurrentUser: courseBuilderOptions.getCurrentUser
|
|
52
|
+
};
|
|
53
|
+
const cookies = Object.entries(reqCookies || {}).filter((entry) => typeof entry[1] === "string").map(([name, value]) => ({
|
|
54
|
+
name,
|
|
55
|
+
value,
|
|
56
|
+
options: {}
|
|
57
|
+
}));
|
|
58
|
+
logger.debug("init.request-cookies", {
|
|
59
|
+
rawCookieKeys: Object.keys(reqCookies || {}),
|
|
60
|
+
convertedCount: cookies.length,
|
|
61
|
+
hasSl_ref: cookies.some((c) => c.name === "sl_ref")
|
|
62
|
+
});
|
|
63
|
+
return { options, cookies };
|
|
64
|
+
}
|
|
65
|
+
var defaultCallbacks = {
|
|
66
|
+
session(payload) {
|
|
67
|
+
return payload;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
function adapterErrorHandler(adapter, logger2) {
|
|
71
|
+
if (!adapter)
|
|
72
|
+
return;
|
|
73
|
+
return Object.keys(adapter).reduce((acc, name) => {
|
|
74
|
+
acc[name] = async (...args) => {
|
|
75
|
+
try {
|
|
76
|
+
logger2.debug(`adapter_${name}`, { args });
|
|
77
|
+
const method = adapter[name];
|
|
78
|
+
return await method(...args);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
const error = new AdapterError(e);
|
|
81
|
+
logger2.error(error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return acc;
|
|
86
|
+
}, {});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
init,
|
|
91
|
+
defaultCallbacks
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=chunk-5O4UO4IR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/init.ts"],"sourcesContent":["import { AdapterError } from '@coursebuilder/core/errors'\nimport {\n\tCallbacksOptions,\n\tInternalOptions,\n\tRequestInternal,\n} from '@coursebuilder/core/types'\n\nimport { CourseBuilderConfig } from '../http'\nimport * as cookie from './cookie.js'\nimport { logger, LoggerInstance } from './logger'\nimport { merge } from './merge'\nimport parseProviders from './providers'\n\ninterface InitParams {\n\turl: URL\n\tcourseBuilderOptions: CourseBuilderConfig\n\tproviderId?: string\n\taction: InternalOptions['action']\n\tisPost: boolean\n\tcookies: RequestInternal['cookies']\n}\n\nexport async function init({\n\turl,\n\tcourseBuilderOptions,\n\tproviderId,\n\taction,\n\tisPost,\n\tcookies: reqCookies,\n}: InitParams): Promise<{\n\toptions: InternalOptions\n\tcookies: cookie.Cookie[]\n}> {\n\tconst { providers, provider } = parseProviders({\n\t\tproviders: courseBuilderOptions.providers,\n\t\turl,\n\t\tproviderId,\n\t\toptions: courseBuilderOptions,\n\t})\n\n\tconst maxAge = 30 * 24 * 60 * 60\n\n\tconst options: InternalOptions = {\n\t\tdebug: false,\n\t\tpages: {},\n\t\t...courseBuilderOptions,\n\t\turl,\n\t\taction,\n\t\t// @ts-expect-errors\n\t\tprovider,\n\t\tcookies: merge(\n\t\t\t{},\n\t\t\tcookie.defaultCookies(\n\t\t\t\tcourseBuilderOptions.useSecureCookies ?? url.protocol === 'https:',\n\t\t\t),\n\t\t\tcourseBuilderOptions.cookies || {},\n\t\t\treqCookies,\n\t\t),\n\t\tproviders,\n\t\tadapter: adapterErrorHandler(courseBuilderOptions.adapter, logger),\n\t\tcallbacks: { ...defaultCallbacks, ...courseBuilderOptions.callbacks },\n\t\tlogger,\n\t\tgetCurrentUser: courseBuilderOptions.getCurrentUser,\n\t}\n\n\t// Convert request cookies to Cookie[] format for actions\n\tconst cookies: cookie.Cookie[] = Object.entries(reqCookies || {})\n\t\t.filter((entry): entry is [string, string] => typeof entry[1] === 'string')\n\t\t.map(([name, value]) => ({\n\t\t\tname,\n\t\t\tvalue,\n\t\t\toptions: {},\n\t\t}))\n\n\tlogger.debug('init.request-cookies', {\n\t\trawCookieKeys: Object.keys(reqCookies || {}),\n\t\tconvertedCount: cookies.length,\n\t\thasSl_ref: cookies.some((c) => c.name === 'sl_ref'),\n\t})\n\n\treturn { options, cookies }\n}\n\ntype Method = (...args: any[]) => Promise<any>\n\nexport const defaultCallbacks: CallbacksOptions = {\n\tsession(payload) {\n\t\treturn payload\n\t},\n}\n\nfunction adapterErrorHandler(\n\tadapter: CourseBuilderConfig['adapter'],\n\tlogger: LoggerInstance,\n) {\n\tif (!adapter) return\n\n\treturn Object.keys(adapter).reduce<any>((acc, name) => {\n\t\tacc[name] = async (...args: any[]) => {\n\t\t\ttry {\n\t\t\t\tlogger.debug(`adapter_${name}`, { args })\n\t\t\t\tconst method: Method = adapter[name as keyof Method]\n\t\t\t\treturn await method(...args)\n\t\t\t} catch (e) {\n\t\t\t\tconst error = new AdapterError(e as Error)\n\t\t\t\tlogger.error(error)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t\treturn acc\n\t}, {})\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAsB7B,eAAsB,KAAK;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AACV,GAGG;AACF,QAAM,EAAE,WAAW,SAAS,IAAI,eAAe;AAAA,IAC9C,WAAW,qBAAqB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EACV,CAAC;AAED,QAAM,SAAS,KAAK,KAAK,KAAK;AAE9B,QAAM,UAA2B;AAAA,IAChC,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,IACR,GAAG;AAAA,IACH;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA,SAAS;AAAA,MACR,CAAC;AAAA,MACM;AAAA,QACN,qBAAqB,oBAAoB,IAAI,aAAa;AAAA,MAC3D;AAAA,MACA,qBAAqB,WAAW,CAAC;AAAA,MACjC;AAAA,IACD;AAAA,IACA;AAAA,IACA,SAAS,oBAAoB,qBAAqB,SAAS,MAAM;AAAA,IACjE,WAAW,EAAE,GAAG,kBAAkB,GAAG,qBAAqB,UAAU;AAAA,IACpE;AAAA,IACA,gBAAgB,qBAAqB;AAAA,EACtC;AAGA,QAAM,UAA2B,OAAO,QAAQ,cAAc,CAAC,CAAC,EAC9D,OAAO,CAAC,UAAqC,OAAO,MAAM,CAAC,MAAM,QAAQ,EACzE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,IACxB;AAAA,IACA;AAAA,IACA,SAAS,CAAC;AAAA,EACX,EAAE;AAEH,SAAO,MAAM,wBAAwB;AAAA,IACpC,eAAe,OAAO,KAAK,cAAc,CAAC,CAAC;AAAA,IAC3C,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAAA,EACnD,CAAC;AAED,SAAO,EAAE,SAAS,QAAQ;AAC3B;AAIO,IAAM,mBAAqC;AAAA,EACjD,QAAQ,SAAS;AAChB,WAAO;AAAA,EACR;AACD;AAEA,SAAS,oBACR,SACAA,SACC;AACD,MAAI,CAAC;AAAS;AAEd,SAAO,OAAO,KAAK,OAAO,EAAE,OAAY,CAAC,KAAK,SAAS;AACtD,QAAI,IAAI,IAAI,UAAU,SAAgB;AACrC,UAAI;AACH,QAAAA,QAAO,MAAM,WAAW,IAAI,IAAI,EAAE,KAAK,CAAC;AACxC,cAAM,SAAiB,QAAQ,IAAoB;AACnD,eAAO,MAAM,OAAO,GAAG,IAAI;AAAA,MAC5B,SAAS,GAAG;AACX,cAAM,QAAQ,IAAI,aAAa,CAAU;AACzC,QAAAA,QAAO,MAAM,KAAK;AAClB,cAAM;AAAA,MACP;AAAA,IACD;AACA,WAAO;AAAA,EACR,GAAG,CAAC,CAAC;AACN;","names":["logger"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/actions/claimed.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
async function claimed(request, cookies, options) {
|
|
4
|
+
if (!options.adapter)
|
|
5
|
+
throw new Error("Adapter not found");
|
|
6
|
+
const bulkCouponId = z.string().optional().parse(request.query?.bulkCouponId || request.body?.bulkCouponId);
|
|
7
|
+
if (!bulkCouponId)
|
|
8
|
+
throw new Error("Bulk coupon ID is required");
|
|
9
|
+
const purchases = await options.adapter.getPurchasesForBulkCouponId(bulkCouponId);
|
|
10
|
+
const users = purchases.map((purchase) => {
|
|
11
|
+
return {
|
|
12
|
+
name: purchase.user.name,
|
|
13
|
+
email: purchase.user.email
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
body: users,
|
|
18
|
+
headers: { "Content-Type": "application/json" },
|
|
19
|
+
cookies
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
claimed
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=chunk-7FCQOLKL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/actions/claimed.ts"],"sourcesContent":["import { z } from 'zod'\n\nimport type {\n\tInternalOptions,\n\tRequestInternal,\n\tResponseInternal,\n} from '@coursebuilder/core/types'\n\nimport type { Cookie } from '../runtime/cookie'\n\nexport async function claimed(\n\trequest: RequestInternal,\n\tcookies: Cookie[],\n\toptions: InternalOptions,\n): Promise<ResponseInternal> {\n\tif (!options.adapter) throw new Error('Adapter not found')\n\n\tconst bulkCouponId = z\n\t\t.string()\n\t\t.optional()\n\t\t.parse(request.query?.bulkCouponId || request.body?.bulkCouponId)\n\n\tif (!bulkCouponId) throw new Error('Bulk coupon ID is required')\n\n\tconst purchases =\n\t\tawait options.adapter.getPurchasesForBulkCouponId(bulkCouponId)\n\n\tconst users = purchases.map((purchase) => {\n\t\treturn {\n\t\t\tname: purchase.user.name,\n\t\t\temail: purchase.user.email,\n\t\t}\n\t})\n\n\treturn {\n\t\tbody: users,\n\t\theaders: { 'Content-Type': 'application/json' },\n\t\tcookies,\n\t}\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAUlB,eAAsB,QACrB,SACA,SACA,SAC4B;AAC5B,MAAI,CAAC,QAAQ;AAAS,UAAM,IAAI,MAAM,mBAAmB;AAEzD,QAAM,eAAe,EACnB,OAAO,EACP,SAAS,EACT,MAAM,QAAQ,OAAO,gBAAgB,QAAQ,MAAM,YAAY;AAEjE,MAAI,CAAC;AAAc,UAAM,IAAI,MAAM,4BAA4B;AAE/D,QAAM,YACL,MAAM,QAAQ,QAAQ,4BAA4B,YAAY;AAE/D,QAAM,QAAQ,UAAU,IAAI,CAAC,aAAa;AACzC,WAAO;AAAA,MACN,MAAM,SAAS,KAAK;AAAA,MACpB,OAAO,SAAS,KAAK;AAAA,IACtB;AAAA,EACD,CAAC;AAED,SAAO;AAAA,IACN,MAAM;AAAA,IACN,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C;AAAA,EACD;AACD;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/logger.ts"],"sourcesContent":["export { logger, setLogger } from '@coursebuilder/utils/logger'\nexport type {\n\tLogAttributes,\n\tLoggerInstance,\n\tWarningCode,\n} from '@coursebuilder/utils/logger'\n"],"mappings":";AAAA,SAAS,QAAQ,iBAAiB;","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/runtime/assert.ts
|
|
2
|
+
import {
|
|
3
|
+
MissingAdapterMethods
|
|
4
|
+
} from "@coursebuilder/core/errors";
|
|
5
|
+
var hasTranscript = false;
|
|
6
|
+
var warned = false;
|
|
7
|
+
function assertConfig(request, options) {
|
|
8
|
+
const { url } = request;
|
|
9
|
+
const warnings = [];
|
|
10
|
+
if (!warned && options.debug)
|
|
11
|
+
warnings.push("debug-enabled");
|
|
12
|
+
for (const p of options.providers) {
|
|
13
|
+
const provider = typeof p === "function" ? p() : p;
|
|
14
|
+
if (provider.type === "transcription") {
|
|
15
|
+
hasTranscript = true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const { adapter } = options;
|
|
19
|
+
let requiredMethods = [];
|
|
20
|
+
if (hasTranscript) {
|
|
21
|
+
}
|
|
22
|
+
if (adapter) {
|
|
23
|
+
const missing = requiredMethods.filter((m) => !(m in adapter));
|
|
24
|
+
if (missing.length) {
|
|
25
|
+
return new MissingAdapterMethods(
|
|
26
|
+
`Required adapter methods were missing: ${missing.join(", ")}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!warned)
|
|
31
|
+
warned = true;
|
|
32
|
+
return warnings;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
assertConfig
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-E6HV6TNI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/assert.ts"],"sourcesContent":["import type { ServerAdapter } from '../adapter'\nimport {\n\tMissingAdapter,\n\tMissingAdapterMethods,\n\tUnsupportedStrategy,\n} from '@coursebuilder/core/errors'\nimport { RequestInternal } from '@coursebuilder/core/types'\n\nimport { CourseBuilderConfig } from '../http'\nimport { WarningCode } from './logger'\n\ntype ConfigError = MissingAdapter | MissingAdapterMethods | UnsupportedStrategy\n\nlet hasTranscript = false\nlet warned = false\n\nexport function assertConfig(\n\trequest: RequestInternal,\n\toptions: CourseBuilderConfig,\n): ConfigError | WarningCode[] {\n\tconst { url } = request\n\tconst warnings: WarningCode[] = []\n\n\tif (!warned && options.debug) warnings.push('debug-enabled')\n\n\t// Keep track of webauthn providers that use conditional UI\n\n\tfor (const p of options.providers) {\n\t\tconst provider = typeof p === 'function' ? p() : p\n\t\tif (provider.type === 'transcription') {\n\t\t\thasTranscript = true\n\t\t}\n\t}\n\n\tconst { adapter } = options\n\n\tlet requiredMethods: (keyof ServerAdapter)[] = []\n\n\tif (hasTranscript) {\n\t}\n\n\tif (adapter) {\n\t\tconst missing = requiredMethods.filter((m) => !(m in adapter))\n\n\t\tif (missing.length) {\n\t\t\treturn new MissingAdapterMethods(\n\t\t\t\t`Required adapter methods were missing: ${missing.join(', ')}`,\n\t\t\t)\n\t\t}\n\t}\n\n\tif (!warned) warned = true\n\n\treturn warnings\n}\n"],"mappings":";AACA;AAAA,EAEC;AAAA,OAEM;AAQP,IAAI,gBAAgB;AACpB,IAAI,SAAS;AAEN,SAAS,aACf,SACA,SAC8B;AAC9B,QAAM,EAAE,IAAI,IAAI;AAChB,QAAM,WAA0B,CAAC;AAEjC,MAAI,CAAC,UAAU,QAAQ;AAAO,aAAS,KAAK,eAAe;AAI3D,aAAW,KAAK,QAAQ,WAAW;AAClC,UAAM,WAAW,OAAO,MAAM,aAAa,EAAE,IAAI;AACjD,QAAI,SAAS,SAAS,iBAAiB;AACtC,sBAAgB;AAAA,IACjB;AAAA,EACD;AAEA,QAAM,EAAE,QAAQ,IAAI;AAEpB,MAAI,kBAA2C,CAAC;AAEhD,MAAI,eAAe;AAAA,EACnB;AAEA,MAAI,SAAS;AACZ,UAAM,UAAU,gBAAgB,OAAO,CAAC,MAAM,EAAE,KAAK,QAAQ;AAE7D,QAAI,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACV,0CAA0C,QAAQ,KAAK,IAAI,CAAC;AAAA,MAC7D;AAAA,IACD;AAAA,EACD;AAEA,MAAI,CAAC;AAAQ,aAAS;AAEtB,SAAO;AACR;","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertConfig
|
|
3
|
+
} from "./chunk-E6HV6TNI.js";
|
|
4
|
+
import {
|
|
5
|
+
CourseBuilderInternal
|
|
6
|
+
} from "./chunk-G63YAJF2.js";
|
|
7
|
+
import {
|
|
8
|
+
toInternalRequest,
|
|
9
|
+
toResponse
|
|
10
|
+
} from "./chunk-4TSEPUSC.js";
|
|
11
|
+
import {
|
|
12
|
+
logger,
|
|
13
|
+
setLogger
|
|
14
|
+
} from "./chunk-AZLUMIIF.js";
|
|
15
|
+
|
|
16
|
+
// src/http.ts
|
|
17
|
+
async function CourseBuilder(request, config) {
|
|
18
|
+
setLogger(config.logger, config.debug);
|
|
19
|
+
const internalRequest = await toInternalRequest(request, config);
|
|
20
|
+
if (!internalRequest) {
|
|
21
|
+
return Response.json("Bad request", { status: 400 });
|
|
22
|
+
}
|
|
23
|
+
const warningsOrError = assertConfig(internalRequest, config);
|
|
24
|
+
if (Array.isArray(warningsOrError)) {
|
|
25
|
+
warningsOrError.forEach((code) => logger.warn(code));
|
|
26
|
+
} else if (warningsOrError) {
|
|
27
|
+
logger.error(warningsOrError);
|
|
28
|
+
return Response.json("Internal Server Error", { status: 500 });
|
|
29
|
+
}
|
|
30
|
+
const isRedirect = request.headers?.has("X-Course-Builder-Return-Redirect");
|
|
31
|
+
try {
|
|
32
|
+
const internalResponse = await CourseBuilderInternal(
|
|
33
|
+
internalRequest,
|
|
34
|
+
config
|
|
35
|
+
);
|
|
36
|
+
const response = toResponse(internalResponse);
|
|
37
|
+
const url = response.headers.get("Location");
|
|
38
|
+
if (!isRedirect || !url)
|
|
39
|
+
return response;
|
|
40
|
+
return Response.json({ url }, { headers: response.headers });
|
|
41
|
+
} catch (e) {
|
|
42
|
+
logger.error(e);
|
|
43
|
+
if (request.method === "POST" && internalRequest.action === "session")
|
|
44
|
+
return Response.json(null, { status: 400 });
|
|
45
|
+
return Response.json(`something broke: ${e.message}`, {
|
|
46
|
+
status: 400
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
CourseBuilder
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=chunk-ECNJPNPU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/http.ts"],"sourcesContent":["import type { Inngest } from 'inngest'\n\nimport type { ServerAdapter } from './adapter'\nimport type { CourseBuilderAuthConfig } from '@coursebuilder/core/auth'\nimport type { Provider } from '@coursebuilder/core/providers'\nimport type { User } from '@coursebuilder/core/schemas'\nimport type {\n\tCallbacksOptions,\n\tCookiesOptions,\n} from '@coursebuilder/core/types'\n\nimport { CourseBuilderInternal } from './http-router'\nimport { assertConfig } from './runtime/assert'\nimport { createActionURL, setEnvDefaults } from './runtime/env.js'\nimport { logger, setLogger, type LoggerInstance } from './runtime/logger'\nimport { toInternalRequest, toResponse } from './runtime/web'\n\nexport { createActionURL, setEnvDefaults }\n\n/**\n * Handle a Course Builder HTTP request.\n *\n * @param request - Web-standard request to route.\n * @param config - Course Builder server runtime configuration.\n * @returns The web-standard response produced by the selected action.\n */\nexport async function CourseBuilder(\n\trequest: Request,\n\tconfig: CourseBuilderConfig,\n): Promise<Response> {\n\tsetLogger(config.logger, config.debug)\n\n\tconst internalRequest = await toInternalRequest(request, config)\n\tif (!internalRequest) {\n\t\treturn Response.json('Bad request', { status: 400 })\n\t}\n\n\tconst warningsOrError = assertConfig(internalRequest, config)\n\n\tif (Array.isArray(warningsOrError)) {\n\t\twarningsOrError.forEach((code) => logger.warn(code))\n\t} else if (warningsOrError) {\n\t\tlogger.error(warningsOrError)\n\t\treturn Response.json('Internal Server Error', { status: 500 })\n\t}\n\tconst isRedirect = request.headers?.has('X-Course-Builder-Return-Redirect')\n\n\ttry {\n\t\tconst internalResponse = await CourseBuilderInternal(\n\t\t\tinternalRequest,\n\t\t\tconfig,\n\t\t)\n\n\t\tconst response = toResponse(internalResponse)\n\t\tconst url = response.headers.get('Location')\n\t\tif (!isRedirect || !url) return response\n\n\t\treturn Response.json({ url }, { headers: response.headers })\n\t} catch (e) {\n\t\tlogger.error(e as Error)\n\t\tif (request.method === 'POST' && internalRequest.action === 'session')\n\t\t\treturn Response.json(null, { status: 400 })\n\t\treturn Response.json(`something broke: ${(e as Error).message}`, {\n\t\t\tstatus: 400,\n\t\t})\n\t}\n}\n\n/** Runtime configuration consumed by the server-owned HTTP entry point. */\nexport interface CourseBuilderConfig {\n\tcallbacks?: Partial<CallbacksOptions>\n\tadapter?: ServerAdapter\n\tproviders: Provider[]\n\tdebug?: boolean\n\tbasePath?: string\n\tlogger?: LoggerInstance\n\tcookies?: Partial<CookiesOptions>\n\tuseSecureCookies?: boolean\n\tinngest?: Inngest\n\tgetCurrentUser?: () => Promise<User | null>\n\tauthConfig: CourseBuilderAuthConfig\n\tbaseUrl: string\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA0BA,eAAsB,cACrB,SACA,QACoB;AACpB,YAAU,OAAO,QAAQ,OAAO,KAAK;AAErC,QAAM,kBAAkB,MAAM,kBAAkB,SAAS,MAAM;AAC/D,MAAI,CAAC,iBAAiB;AACrB,WAAO,SAAS,KAAK,eAAe,EAAE,QAAQ,IAAI,CAAC;AAAA,EACpD;AAEA,QAAM,kBAAkB,aAAa,iBAAiB,MAAM;AAE5D,MAAI,MAAM,QAAQ,eAAe,GAAG;AACnC,oBAAgB,QAAQ,CAAC,SAAS,OAAO,KAAK,IAAI,CAAC;AAAA,EACpD,WAAW,iBAAiB;AAC3B,WAAO,MAAM,eAAe;AAC5B,WAAO,SAAS,KAAK,yBAAyB,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACA,QAAM,aAAa,QAAQ,SAAS,IAAI,kCAAkC;AAE1E,MAAI;AACH,UAAM,mBAAmB,MAAM;AAAA,MAC9B;AAAA,MACA;AAAA,IACD;AAEA,UAAM,WAAW,WAAW,gBAAgB;AAC5C,UAAM,MAAM,SAAS,QAAQ,IAAI,UAAU;AAC3C,QAAI,CAAC,cAAc,CAAC;AAAK,aAAO;AAEhC,WAAO,SAAS,KAAK,EAAE,IAAI,GAAG,EAAE,SAAS,SAAS,QAAQ,CAAC;AAAA,EAC5D,SAAS,GAAG;AACX,WAAO,MAAM,CAAU;AACvB,QAAI,QAAQ,WAAW,UAAU,gBAAgB,WAAW;AAC3D,aAAO,SAAS,KAAK,MAAM,EAAE,QAAQ,IAAI,CAAC;AAC3C,WAAO,SAAS,KAAK,oBAAqB,EAAY,OAAO,IAAI;AAAA,MAChE,QAAQ;AAAA,IACT,CAAC;AAAA,EACF;AACD;","names":[]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-AZLUMIIF.js";
|
|
4
|
+
|
|
5
|
+
// src/actions/checkout.ts
|
|
6
|
+
import { buildCheckoutAttribution } from "@coursebuilder/commerce/checkout-attribution";
|
|
7
|
+
import { CheckoutParamsSchema } from "@coursebuilder/commerce/stripe-checkout";
|
|
8
|
+
var searchParamsWithoutNil = (params) => {
|
|
9
|
+
return new URLSearchParams(
|
|
10
|
+
Object.entries(params).flatMap(([key, value]) => {
|
|
11
|
+
if (value === void 0 || value === null)
|
|
12
|
+
return [];
|
|
13
|
+
return [[key, String(value)]];
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
async function checkout(request, cookies, options) {
|
|
18
|
+
const response = {
|
|
19
|
+
body: null,
|
|
20
|
+
headers: { "Content-Type": "application/json" },
|
|
21
|
+
cookies
|
|
22
|
+
};
|
|
23
|
+
const shortlinkRefCookie = cookies.find((c) => c.name === "sl_ref");
|
|
24
|
+
const shortlinkRef = shortlinkRefCookie?.value;
|
|
25
|
+
const ftAttrCookie = cookies.find((c) => c.name === "ft_attr");
|
|
26
|
+
let firstTouch = {};
|
|
27
|
+
try {
|
|
28
|
+
if (ftAttrCookie?.value) {
|
|
29
|
+
firstTouch = JSON.parse(decodeURIComponent(ftAttrCookie.value));
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
const ltAttrCookie = cookies.find((c) => c.name === "lt_attr");
|
|
34
|
+
let lastTouch = {};
|
|
35
|
+
try {
|
|
36
|
+
if (ltAttrCookie?.value) {
|
|
37
|
+
lastTouch = JSON.parse(decodeURIComponent(ltAttrCookie.value));
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
const selfReportedSource = typeof request.query?.selfReportedSource === "string" ? request.query.selfReportedSource.slice(0, 500) : void 0;
|
|
42
|
+
const checkoutAttribution = buildCheckoutAttribution({
|
|
43
|
+
firstTouch,
|
|
44
|
+
lastTouch,
|
|
45
|
+
shortlinkRef,
|
|
46
|
+
selfReportedSource
|
|
47
|
+
});
|
|
48
|
+
logger.debug("checkout.cookies-received", {
|
|
49
|
+
cookieCount: cookies.length,
|
|
50
|
+
cookieNames: cookies.map((c) => c.name),
|
|
51
|
+
hasShortlinkRef: Boolean(shortlinkRef),
|
|
52
|
+
hasAttributionSnapshot: Boolean(checkoutAttribution.attributionSnapshot)
|
|
53
|
+
});
|
|
54
|
+
const checkoutParamsParsed = CheckoutParamsSchema.safeParse({
|
|
55
|
+
...request.query,
|
|
56
|
+
country: request.query?.country || request.headers?.["x-vercel-ip-country"] || process.env.DEFAULT_COUNTRY || "US",
|
|
57
|
+
ip_address: request.query?.ip_address || request.headers?.["x-forwarded-for"] || "0.0.0.0",
|
|
58
|
+
organizationId: request.query?.organizationId,
|
|
59
|
+
...selfReportedSource && { selfReportedSource },
|
|
60
|
+
...checkoutAttribution
|
|
61
|
+
});
|
|
62
|
+
if (!checkoutParamsParsed.success) {
|
|
63
|
+
const parseError = new Error("Error parsing checkout params");
|
|
64
|
+
logger.error(parseError, {
|
|
65
|
+
context: "checkout.params-parse",
|
|
66
|
+
issueCount: checkoutParamsParsed.error.issues.length,
|
|
67
|
+
issuePaths: checkoutParamsParsed.error.issues.map(
|
|
68
|
+
(issue) => issue.path.join(".")
|
|
69
|
+
),
|
|
70
|
+
productId: typeof request.query?.productId === "string" ? request.query.productId : void 0,
|
|
71
|
+
organizationId: typeof request.query?.organizationId === "string" ? request.query.organizationId : void 0
|
|
72
|
+
});
|
|
73
|
+
throw new Error("Error parsing checkout params");
|
|
74
|
+
}
|
|
75
|
+
const checkoutParams = checkoutParamsParsed.data;
|
|
76
|
+
try {
|
|
77
|
+
const stripe = await options.provider.createCheckoutSession(
|
|
78
|
+
checkoutParams,
|
|
79
|
+
options.adapter
|
|
80
|
+
);
|
|
81
|
+
const product = await options.adapter?.getProduct(checkoutParams.productId);
|
|
82
|
+
if (product?.type && ["membership", "cohort", "cohort-archive", "live"].includes(product.type)) {
|
|
83
|
+
return Response.redirect(
|
|
84
|
+
`${options.baseUrl}/subscribe/verify-login?${searchParamsWithoutNil({
|
|
85
|
+
...request.query,
|
|
86
|
+
country: request.query?.country || request.headers?.["x-vercel-ip-country"] || process.env.DEFAULT_COUNTRY || "US",
|
|
87
|
+
ip_address: request.query?.ip_address || request.headers?.["x-forwarded-for"] || "0.0.0.0",
|
|
88
|
+
organizationId: request.query?.organizationId,
|
|
89
|
+
productId: checkoutParams.productId,
|
|
90
|
+
checkoutUrl: stripe.redirect,
|
|
91
|
+
cancelUrl: checkoutParams.cancelUrl,
|
|
92
|
+
selfReportedSource
|
|
93
|
+
})}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return Response.redirect(stripe.redirect);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
logger.error(e instanceof Error ? e : new Error(String(e)), {
|
|
99
|
+
context: "checkout.create-session",
|
|
100
|
+
productId: checkoutParams.productId,
|
|
101
|
+
organizationId: checkoutParams.organizationId,
|
|
102
|
+
country: checkoutParams.country
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return response;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
checkout
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=chunk-F3KUYN5I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/actions/checkout.ts"],"sourcesContent":["import { buildCheckoutAttribution } from '@coursebuilder/commerce/checkout-attribution'\nimport { CheckoutParamsSchema } from '@coursebuilder/commerce/stripe-checkout'\nimport type {\n\tInternalOptions,\n\tRequestInternal,\n\tResponseInternal,\n} from '@coursebuilder/core/types'\n\nimport type { Cookie } from '../runtime/cookie'\nimport { logger } from '../runtime/logger'\n\nconst searchParamsWithoutNil = (params: Record<string, unknown>) => {\n\treturn new URLSearchParams(\n\t\tObject.entries(params).flatMap(([key, value]) => {\n\t\t\tif (value === undefined || value === null) return []\n\t\t\treturn [[key, String(value)]]\n\t\t}),\n\t)\n}\n\nexport async function checkout(\n\trequest: RequestInternal,\n\tcookies: Cookie[],\n\toptions: InternalOptions<'payment'>,\n): Promise<ResponseInternal> {\n\tconst response: ResponseInternal<any | null> = {\n\t\tbody: null,\n\t\theaders: { 'Content-Type': 'application/json' },\n\t\tcookies,\n\t}\n\n\t// Extract shortlink reference from cookie\n\tconst shortlinkRefCookie = cookies.find((c) => c.name === 'sl_ref')\n\tconst shortlinkRef = shortlinkRefCookie?.value\n\n\t// Extract first-touch attribution from cookie\n\tconst ftAttrCookie = cookies.find((c) => c.name === 'ft_attr')\n\tlet firstTouch: Record<string, unknown> = {}\n\ttry {\n\t\tif (ftAttrCookie?.value) {\n\t\t\tfirstTouch = JSON.parse(decodeURIComponent(ftAttrCookie.value))\n\t\t}\n\t} catch {\n\t\t// Malformed cookie, ignore\n\t}\n\n\t// Extract last-touch attribution from cookie\n\tconst ltAttrCookie = cookies.find((c) => c.name === 'lt_attr')\n\tlet lastTouch: Record<string, string> = {}\n\ttry {\n\t\tif (ltAttrCookie?.value) {\n\t\t\tlastTouch = JSON.parse(decodeURIComponent(ltAttrCookie.value))\n\t\t}\n\t} catch {\n\t\t// Malformed cookie, ignore\n\t}\n\n\tconst selfReportedSource =\n\t\ttypeof request.query?.selfReportedSource === 'string'\n\t\t\t? request.query.selfReportedSource.slice(0, 500)\n\t\t\t: undefined\n\tconst checkoutAttribution = buildCheckoutAttribution({\n\t\tfirstTouch,\n\t\tlastTouch,\n\t\tshortlinkRef,\n\t\tselfReportedSource,\n\t})\n\n\tlogger.debug('checkout.cookies-received', {\n\t\tcookieCount: cookies.length,\n\t\tcookieNames: cookies.map((c) => c.name),\n\t\thasShortlinkRef: Boolean(shortlinkRef),\n\t\thasAttributionSnapshot: Boolean(checkoutAttribution.attributionSnapshot),\n\t})\n\n\tconst checkoutParamsParsed = CheckoutParamsSchema.safeParse({\n\t\t...request.query,\n\t\tcountry:\n\t\t\trequest.query?.country ||\n\t\t\trequest.headers?.['x-vercel-ip-country'] ||\n\t\t\tprocess.env.DEFAULT_COUNTRY ||\n\t\t\t'US',\n\t\tip_address:\n\t\t\trequest.query?.ip_address ||\n\t\t\trequest.headers?.['x-forwarded-for'] ||\n\t\t\t'0.0.0.0',\n\t\torganizationId: request.query?.organizationId,\n\t\t...(selfReportedSource && { selfReportedSource }),\n\t\t...checkoutAttribution,\n\t})\n\n\tif (!checkoutParamsParsed.success) {\n\t\tconst parseError = new Error('Error parsing checkout params')\n\t\tlogger.error(parseError, {\n\t\t\tcontext: 'checkout.params-parse',\n\t\t\tissueCount: checkoutParamsParsed.error.issues.length,\n\t\t\tissuePaths: checkoutParamsParsed.error.issues.map((issue) =>\n\t\t\t\tissue.path.join('.'),\n\t\t\t),\n\t\t\tproductId:\n\t\t\t\ttypeof request.query?.productId === 'string'\n\t\t\t\t\t? request.query.productId\n\t\t\t\t\t: undefined,\n\t\t\torganizationId:\n\t\t\t\ttypeof request.query?.organizationId === 'string'\n\t\t\t\t\t? request.query.organizationId\n\t\t\t\t\t: undefined,\n\t\t})\n\t\tthrow new Error('Error parsing checkout params')\n\t}\n\n\tconst checkoutParams = checkoutParamsParsed.data\n\n\ttry {\n\t\tconst stripe = await options.provider.createCheckoutSession(\n\t\t\tcheckoutParams,\n\t\t\toptions.adapter,\n\t\t)\n\n\t\tconst product = await options.adapter?.getProduct(checkoutParams.productId)\n\n\t\t// if the product is a membership or cohort, we need to redirect to the login page\n\t\t// if the user isn't logged in. we want to ensure an org id is set.\n\t\tif (\n\t\t\tproduct?.type &&\n\t\t\t['membership', 'cohort', 'cohort-archive', 'live'].includes(product.type)\n\t\t) {\n\t\t\treturn Response.redirect(\n\t\t\t\t`${options.baseUrl}/subscribe/verify-login?${searchParamsWithoutNil({\n\t\t\t\t\t...request.query,\n\t\t\t\t\tcountry:\n\t\t\t\t\t\trequest.query?.country ||\n\t\t\t\t\t\trequest.headers?.['x-vercel-ip-country'] ||\n\t\t\t\t\t\tprocess.env.DEFAULT_COUNTRY ||\n\t\t\t\t\t\t'US',\n\t\t\t\t\tip_address:\n\t\t\t\t\t\trequest.query?.ip_address ||\n\t\t\t\t\t\trequest.headers?.['x-forwarded-for'] ||\n\t\t\t\t\t\t'0.0.0.0',\n\t\t\t\t\torganizationId: request.query?.organizationId,\n\t\t\t\t\tproductId: checkoutParams.productId,\n\t\t\t\t\tcheckoutUrl: stripe.redirect,\n\t\t\t\t\tcancelUrl: checkoutParams.cancelUrl,\n\t\t\t\t\tselfReportedSource,\n\t\t\t\t})}`,\n\t\t\t)\n\t\t}\n\n\t\treturn Response.redirect(stripe.redirect)\n\t} catch (e) {\n\t\tlogger.error(e instanceof Error ? e : new Error(String(e)), {\n\t\t\tcontext: 'checkout.create-session',\n\t\t\tproductId: checkoutParams.productId,\n\t\t\torganizationId: checkoutParams.organizationId,\n\t\t\tcountry: checkoutParams.country,\n\t\t})\n\t}\n\n\treturn response\n}\n"],"mappings":"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","names":[]}
|