@appwarden/middleware 3.2.1 → 3.4.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/vercel.js CHANGED
@@ -4,22 +4,27 @@ import {
4
4
  } from "./chunk-QEFORWCW.js";
5
5
  import {
6
6
  validateConfig
7
- } from "./chunk-COV6SHCD.js";
7
+ } from "./chunk-U3T4R5KZ.js";
8
8
  import {
9
- LockValue,
10
9
  MemoryCache,
11
10
  TEMPORARY_REDIRECT_STATUS,
12
11
  buildLockPageUrl,
12
+ debug,
13
13
  isOnLockPage
14
- } from "./chunk-ZX5QO4Y2.js";
14
+ } from "./chunk-QVRWMYGL.js";
15
15
  import {
16
16
  APPWARDEN_CACHE_KEY,
17
- debug,
17
+ CSPDirectivesSchema,
18
+ CSPModeSchema,
18
19
  errors,
19
20
  globalErrors,
20
- isHTMLRequest,
21
+ isHTMLRequest
22
+ } from "./chunk-HCGLR3Z3.js";
23
+ import {
24
+ LockValue,
25
+ makeCSPHeader,
21
26
  printMessage
22
- } from "./chunk-L5EQIJZB.js";
27
+ } from "./chunk-G4RRFNHY.js";
23
28
 
24
29
  // src/runners/appwarden-on-vercel.ts
25
30
  import { waitUntil } from "@vercel/functions";
@@ -101,7 +106,7 @@ var APIError = class extends Error {
101
106
  }
102
107
  };
103
108
  var syncEdgeValue = async (context) => {
104
- debug(`syncing with api`);
109
+ context.debug("syncing with api");
105
110
  try {
106
111
  const response = await fetch(new URL("/v1/status/check", "https://api.appwarden.io"), {
107
112
  method: "POST",
@@ -134,11 +139,43 @@ var syncEdgeValue = async (context) => {
134
139
  };
135
140
 
136
141
  // src/schemas/vercel.ts
142
+ var VercelCSPSchema = z.object({
143
+ mode: CSPModeSchema,
144
+ directives: z.lazy(() => CSPDirectivesSchema).optional().refine(
145
+ (val) => {
146
+ try {
147
+ if (typeof val === "string") {
148
+ JSON.parse(val);
149
+ }
150
+ return true;
151
+ } catch {
152
+ return false;
153
+ }
154
+ },
155
+ { message: "DirectivesBadParse" /* DirectivesBadParse */ }
156
+ ).refine(
157
+ (val) => {
158
+ if (!val) return true;
159
+ const serialized = typeof val === "string" ? val : JSON.stringify(val);
160
+ return !serialized.includes("{{nonce}}");
161
+ },
162
+ {
163
+ message: "Nonce-based CSP is not supported in Vercel Edge Middleware. Remove '{{nonce}}' placeholders from your CSP directives, as Vercel does not support nonce injection."
164
+ }
165
+ ).transform(
166
+ (val) => typeof val === "string" ? JSON.parse(val) : val
167
+ )
168
+ }).refine(
169
+ (values) => ["report-only", "enforced"].includes(values.mode) ? !!values.directives : true,
170
+ { path: ["directives"], message: "DirectivesRequired" /* DirectivesRequired */ }
171
+ );
137
172
  var BaseNextJsConfigSchema = z.object({
138
173
  cacheUrl: z.string(),
139
174
  appwardenApiToken: z.string(),
140
175
  vercelApiToken: z.string().optional(),
141
- lockPageSlug: z.string().default("").transform((val) => val.replace(/^\/?/, "/"))
176
+ debug: z.boolean().optional(),
177
+ lockPageSlug: z.string().default("").transform((val) => val.replace(/^\/?/, "/")),
178
+ contentSecurityPolicy: VercelCSPSchema.optional()
142
179
  });
143
180
  var AppwardenConfigSchema = BaseNextJsConfigSchema.refine(
144
181
  (data) => {
@@ -188,7 +225,6 @@ var AppwardenConfigSchema = BaseNextJsConfigSchema.refine(
188
225
  });
189
226
 
190
227
  // src/runners/appwarden-on-vercel.ts
191
- debug("Instantiating isolate");
192
228
  var memoryCache = new MemoryCache({ maxSize: 1 });
193
229
  function safeWaitUntil(promise) {
194
230
  try {
@@ -203,29 +239,54 @@ function createAppwardenMiddleware(config) {
203
239
  return NextResponse.next();
204
240
  }
205
241
  const parsedConfig = AppwardenConfigSchema.parse(config);
242
+ const debugFn = debug(parsedConfig.debug ?? false);
243
+ const applyCspHeaders = (response) => {
244
+ const cspConfig = parsedConfig.contentSecurityPolicy;
245
+ if (cspConfig && ["enforced", "report-only"].includes(cspConfig.mode)) {
246
+ const [headerName, headerValue] = makeCSPHeader(
247
+ "",
248
+ cspConfig.directives,
249
+ cspConfig.mode
250
+ );
251
+ response.headers.set(headerName, headerValue);
252
+ }
253
+ return response;
254
+ };
206
255
  try {
207
256
  const requestUrl = new URL(request.url);
208
257
  const isHTML = isHTMLRequest(request);
209
- debug({ isHTMLRequest: isHTML, url: requestUrl.pathname });
258
+ debugFn(
259
+ `Appwarden middleware invoked for ${requestUrl.pathname}`,
260
+ `isHTML: ${isHTML}`
261
+ );
210
262
  if (!isHTML) {
263
+ debugFn("Non-HTML request detected - passing through");
211
264
  return NextResponse.next();
212
265
  }
213
266
  if (!parsedConfig.lockPageSlug) {
267
+ debugFn("No lockPageSlug configured - passing through");
214
268
  return NextResponse.next();
215
269
  }
216
270
  if (isOnLockPage(parsedConfig.lockPageSlug, request.url)) {
271
+ debugFn("Already on lock page - passing through");
217
272
  return NextResponse.next();
218
273
  }
219
274
  const provider = isCacheUrl.edgeConfig(parsedConfig.cacheUrl) ? "edge-config" : "upstash";
275
+ debugFn(`Using provider: ${provider}`);
220
276
  const cacheValue = memoryCache.get(APPWARDEN_CACHE_KEY);
221
277
  const shouldRecheck = MemoryCache.isExpired(cacheValue);
222
278
  if (!cacheValue || shouldRecheck) {
279
+ debugFn(
280
+ "Memory cache miss or expired - syncing edge value in background",
281
+ `shouldRecheck=${shouldRecheck}`
282
+ );
223
283
  safeWaitUntil(
224
284
  syncEdgeValue({
225
285
  requestUrl,
226
286
  cacheUrl: parsedConfig.cacheUrl,
227
287
  appwardenApiToken: parsedConfig.appwardenApiToken,
228
- vercelApiToken: parsedConfig.vercelApiToken
288
+ vercelApiToken: parsedConfig.vercelApiToken,
289
+ debug: debugFn
229
290
  })
230
291
  );
231
292
  }
@@ -235,17 +296,25 @@ function createAppwardenMiddleware(config) {
235
296
  provider
236
297
  })).lockValue;
237
298
  if (lockValue?.isLocked) {
299
+ debugFn("Site is locked - redirecting to lock page");
238
300
  const lockPageUrl = buildLockPageUrl(
239
301
  parsedConfig.lockPageSlug,
240
302
  request.url
241
303
  );
242
- return Response.redirect(
304
+ const redirectResponse = Response.redirect(
243
305
  lockPageUrl.toString(),
244
306
  TEMPORARY_REDIRECT_STATUS
245
307
  );
308
+ return applyCspHeaders(redirectResponse);
246
309
  }
247
- return NextResponse.next();
310
+ const response = NextResponse.next();
311
+ debugFn("Site is not locked - passing through");
312
+ return applyCspHeaders(response);
248
313
  } catch (e) {
314
+ debugFn(
315
+ "Error in Appwarden Vercel middleware",
316
+ e instanceof Error ? e.message : String(e)
317
+ );
249
318
  const message = "Appwarden encountered an unknown error. Please contact Appwarden support at https://appwarden.io/join-community.";
250
319
  if (e instanceof Error) {
251
320
  if (!globalErrors.includes(e.message)) {
package/chunk-A5XGYLYS.js DELETED
@@ -1,196 +0,0 @@
1
- import {
2
- debug,
3
- isHTMLResponse,
4
- printMessage
5
- } from "./chunk-L5EQIJZB.js";
6
-
7
- // src/schemas/use-content-security-policy.ts
8
- import { z as z2 } from "zod";
9
-
10
- // src/types/csp.ts
11
- import { z } from "zod";
12
- var stringySchema = z.union([z.array(z.string()), z.string(), z.boolean()]);
13
- var ContentSecurityPolicySchema = z.object({
14
- "default-src": stringySchema.optional(),
15
- "script-src": stringySchema.optional(),
16
- "style-src": stringySchema.optional(),
17
- "img-src": stringySchema.optional(),
18
- "connect-src": stringySchema.optional(),
19
- "font-src": stringySchema.optional(),
20
- "object-src": stringySchema.optional(),
21
- "media-src": stringySchema.optional(),
22
- "frame-src": stringySchema.optional(),
23
- sandbox: stringySchema.optional(),
24
- "report-uri": stringySchema.optional(),
25
- "child-src": stringySchema.optional(),
26
- "form-action": stringySchema.optional(),
27
- "frame-ancestors": stringySchema.optional(),
28
- "plugin-types": stringySchema.optional(),
29
- "base-uri": stringySchema.optional(),
30
- "report-to": stringySchema.optional(),
31
- "worker-src": stringySchema.optional(),
32
- "manifest-src": stringySchema.optional(),
33
- "prefetch-src": stringySchema.optional(),
34
- "navigate-to": stringySchema.optional(),
35
- "require-sri-for": stringySchema.optional(),
36
- "block-all-mixed-content": stringySchema.optional(),
37
- "upgrade-insecure-requests": stringySchema.optional(),
38
- "trusted-types": stringySchema.optional(),
39
- "require-trusted-types-for": stringySchema.optional()
40
- });
41
-
42
- // src/schemas/use-content-security-policy.ts
43
- var CSPDirectivesSchema = z2.union([
44
- z2.string(),
45
- ContentSecurityPolicySchema
46
- ]);
47
- var CSPModeSchema = z2.union([
48
- z2.literal("disabled"),
49
- z2.literal("report-only"),
50
- z2.literal("enforced")
51
- ]).optional().default("disabled");
52
- var UseCSPInputSchema = z2.object({
53
- hostname: z2.string().optional(),
54
- mode: CSPModeSchema,
55
- directives: CSPDirectivesSchema.optional().refine(
56
- (val) => {
57
- try {
58
- if (typeof val === "string") {
59
- JSON.parse(val);
60
- }
61
- return true;
62
- } catch (error) {
63
- return false;
64
- }
65
- },
66
- { message: "DirectivesBadParse" /* DirectivesBadParse */ }
67
- ).transform(
68
- (val) => typeof val === "string" ? JSON.parse(val) : val
69
- )
70
- }).refine(
71
- (values) => (
72
- // validate that directives are provided when the mode is "report-only" or "enforced"
73
- ["report-only", "enforced"].includes(values.mode) ? !!values.directives : true
74
- ),
75
- { path: ["directives"], message: "DirectivesRequired" /* DirectivesRequired */ }
76
- );
77
-
78
- // src/utils/cloudflare/csp-keywords.ts
79
- var CSP_KEYWORDS = [
80
- "self",
81
- "none",
82
- "unsafe-inline",
83
- "unsafe-eval",
84
- "unsafe-hashes",
85
- "strict-dynamic",
86
- "report-sample",
87
- "unsafe-allow-redirects",
88
- "wasm-unsafe-eval",
89
- "trusted-types-eval",
90
- "report-sha256",
91
- "report-sha384",
92
- "report-sha512",
93
- "unsafe-webtransport-hashes"
94
- ];
95
- var CSP_KEYWORDS_SET = new Set(CSP_KEYWORDS);
96
- var isCSPKeyword = (value) => {
97
- return CSP_KEYWORDS_SET.has(value.toLowerCase());
98
- };
99
- var isQuoted = (value) => {
100
- return value.startsWith("'") && value.endsWith("'");
101
- };
102
- var autoQuoteCSPKeyword = (value) => {
103
- const trimmed = value.trim();
104
- if (isQuoted(trimmed)) {
105
- return trimmed;
106
- }
107
- if (isCSPKeyword(trimmed)) {
108
- return `'${trimmed}'`;
109
- }
110
- return trimmed;
111
- };
112
- var autoQuoteCSPDirectiveValue = (value) => {
113
- return value.trim().split(/\s+/).filter(Boolean).map(autoQuoteCSPKeyword).join(" ");
114
- };
115
- var autoQuoteCSPDirectiveArray = (values) => {
116
- return values.map(autoQuoteCSPKeyword);
117
- };
118
-
119
- // src/utils/cloudflare/make-csp-header.ts
120
- var addNonce = (value, cspNonce) => value.replace("{{nonce}}", `'nonce-${cspNonce}'`);
121
- var makeCSPHeader = (cspNonce, directives, mode) => {
122
- const namesSeen = /* @__PURE__ */ new Set(), result = [];
123
- Object.entries(directives ?? {}).forEach(([originalName, value]) => {
124
- const name = originalName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
125
- if (namesSeen.has(name)) {
126
- throw new Error(`${originalName} is specified more than once`);
127
- }
128
- namesSeen.add(name);
129
- let directiveValue;
130
- if (Array.isArray(value)) {
131
- directiveValue = autoQuoteCSPDirectiveArray(value).join(" ");
132
- } else if (value === true) {
133
- directiveValue = "";
134
- } else if (typeof value === "string") {
135
- directiveValue = autoQuoteCSPDirectiveValue(value);
136
- } else {
137
- return;
138
- }
139
- if (directiveValue) {
140
- result.push(`${name} ${addNonce(directiveValue, cspNonce)}`);
141
- } else {
142
- result.push(name);
143
- }
144
- });
145
- return [
146
- mode === "enforced" ? "Content-Security-Policy" : "Content-Security-Policy-Report-Only",
147
- result.join("; ")
148
- ];
149
- };
150
-
151
- // src/middlewares/use-content-security-policy.ts
152
- var AppendAttribute = (attribute, nonce) => ({
153
- element: function(element) {
154
- element.setAttribute(attribute, nonce);
155
- }
156
- });
157
- var useContentSecurityPolicy = (input) => {
158
- const parsedInput = UseCSPInputSchema.safeParse(input);
159
- if (!parsedInput.success) {
160
- throw parsedInput.error;
161
- }
162
- const config = parsedInput.data;
163
- return async (context, next) => {
164
- await next();
165
- if (config.hostname && context.hostname !== config.hostname) {
166
- return;
167
- }
168
- const { response } = context;
169
- if (
170
- // if the csp is disabled
171
- !["enforced", "report-only"].includes(config.mode)
172
- ) {
173
- debug(printMessage("csp is disabled"));
174
- return;
175
- }
176
- if (response.headers.has("Content-Type") && !isHTMLResponse(response)) {
177
- return;
178
- }
179
- const cspNonce = crypto.randomUUID();
180
- const [cspHeaderName, cspHeaderValue] = makeCSPHeader(
181
- cspNonce,
182
- config.directives,
183
- config.mode
184
- );
185
- const nextResponse = new Response(response.body, response);
186
- nextResponse.headers.set(cspHeaderName, cspHeaderValue);
187
- nextResponse.headers.set("content-type", "text/html; charset=utf-8");
188
- context.response = new HTMLRewriter().on("style", AppendAttribute("nonce", cspNonce)).on("script", AppendAttribute("nonce", cspNonce)).transform(nextResponse);
189
- };
190
- };
191
-
192
- export {
193
- CSPDirectivesSchema,
194
- CSPModeSchema,
195
- useContentSecurityPolicy
196
- };
package/chunk-L5EQIJZB.js DELETED
@@ -1,54 +0,0 @@
1
- // src/constants.ts
2
- var LOCKDOWN_TEST_EXPIRY_MS = 5 * 60 * 1e3;
3
- var errors = { badCacheConnection: "BAD_CACHE_CONNECTION" };
4
- var globalErrors = [errors.badCacheConnection];
5
- var APPWARDEN_TEST_ROUTE = "/_appwarden/test";
6
- var APPWARDEN_CACHE_KEY = "appwarden-lock";
7
-
8
- // src/utils/debug.ts
9
- var debug = (...msg) => {
10
- if (true) {
11
- const formatted = msg.map((m) => {
12
- if (typeof m === "object" && m !== null) {
13
- if (m instanceof Error) {
14
- return m.stack ?? m.message;
15
- }
16
- try {
17
- return JSON.stringify(m);
18
- } catch {
19
- try {
20
- return String(m);
21
- } catch {
22
- return "[Unserializable value]";
23
- }
24
- }
25
- }
26
- return m;
27
- });
28
- console.log(...formatted);
29
- }
30
- };
31
-
32
- // src/utils/print-message.ts
33
- var addSlashes = (str) => str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/"/g, '\\"').replace(/'/g, "\\'").replace(/\u0000/g, "\\0").replace(/<\/script>/gi, "<\\/script>");
34
- var printMessage = (message) => `[@appwarden/middleware] ${addSlashes(message)}`;
35
-
36
- // src/utils/request-checks.ts
37
- function isHTMLResponse(response) {
38
- return response.headers.get("Content-Type")?.includes("text/html") ?? false;
39
- }
40
- function isHTMLRequest(request) {
41
- return request.headers.get("accept")?.includes("text/html") ?? false;
42
- }
43
-
44
- export {
45
- LOCKDOWN_TEST_EXPIRY_MS,
46
- errors,
47
- globalErrors,
48
- APPWARDEN_TEST_ROUTE,
49
- APPWARDEN_CACHE_KEY,
50
- debug,
51
- printMessage,
52
- isHTMLResponse,
53
- isHTMLRequest
54
- };
package/chunk-MDODCAA3.js DELETED
@@ -1,232 +0,0 @@
1
- import {
2
- LockValue,
3
- MemoryCache
4
- } from "./chunk-ZX5QO4Y2.js";
5
- import {
6
- APPWARDEN_CACHE_KEY,
7
- APPWARDEN_TEST_ROUTE,
8
- debug,
9
- printMessage
10
- } from "./chunk-L5EQIJZB.js";
11
-
12
- // src/utils/cloudflare/cloudflare-cache.ts
13
- var store = {
14
- json: (context, cacheKey, options) => {
15
- const cacheKeyUrl = new URL(cacheKey, context.serviceOrigin);
16
- return {
17
- getValue: () => getCacheValue(context, cacheKeyUrl),
18
- updateValue: (json) => updateCacheValue(context, cacheKeyUrl, json, options?.ttl),
19
- deleteValue: () => clearCache(context, cacheKeyUrl)
20
- };
21
- }
22
- };
23
- var getCacheValue = async (context, cacheKey) => {
24
- const match = await context.cache.match(cacheKey);
25
- if (!match) {
26
- debug(`[${cacheKey.pathname}] Cache MISS!`);
27
- return void 0;
28
- }
29
- debug(`[${cacheKey.pathname}] Cache MATCH!`);
30
- return match;
31
- };
32
- var updateCacheValue = async (context, cacheKey, value, ttl) => {
33
- debug(
34
- "updating cache...",
35
- cacheKey.href,
36
- value,
37
- ttl ? `expires in ${ttl}s` : ""
38
- );
39
- await context.cache.put(
40
- cacheKey,
41
- new Response(JSON.stringify(value), {
42
- headers: {
43
- "content-type": "application/json",
44
- ...ttl && {
45
- "cache-control": `max-age=${ttl}`
46
- }
47
- }
48
- })
49
- );
50
- };
51
- var clearCache = (context, cacheKey) => context.cache.delete(cacheKey);
52
-
53
- // src/utils/cloudflare/delete-edge-value.ts
54
- var deleteEdgeValue = async (context) => {
55
- try {
56
- switch (context.provider) {
57
- case "cloudflare-cache": {
58
- const success = await context.edgeCache.deleteValue();
59
- if (!success) {
60
- throw new Error();
61
- }
62
- break;
63
- }
64
- default:
65
- throw new Error(`Unsupported provider: ${context.provider}`);
66
- }
67
- } catch (e) {
68
- const message = "Failed to delete edge value";
69
- console.error(
70
- printMessage(e instanceof Error ? `${message} - ${e.message}` : message)
71
- );
72
- }
73
- };
74
-
75
- // src/utils/cloudflare/get-lock-value.ts
76
- var getLockValue = async (context) => {
77
- try {
78
- let shouldDeleteEdgeValue = false;
79
- let cacheResponse, lockValue = {
80
- isLocked: 0,
81
- isLockedTest: 0,
82
- lastCheck: Date.now(),
83
- code: ""
84
- };
85
- switch (context.provider) {
86
- case "cloudflare-cache": {
87
- cacheResponse = await context.edgeCache.getValue();
88
- break;
89
- }
90
- default:
91
- throw new Error(`Unsupported provider: ${context.provider}`);
92
- }
93
- if (!cacheResponse) {
94
- return { lockValue: void 0 };
95
- }
96
- try {
97
- const clonedResponse = cacheResponse?.clone();
98
- lockValue = LockValue.parse(
99
- clonedResponse ? await clonedResponse.json() : void 0
100
- );
101
- } catch (error) {
102
- console.error(
103
- printMessage(
104
- `Failed to parse ${context.keyName} from edge cache - ${error}`
105
- )
106
- );
107
- shouldDeleteEdgeValue = true;
108
- }
109
- return { lockValue, shouldDeleteEdgeValue };
110
- } catch (e) {
111
- const message = "Failed to retrieve edge value";
112
- console.error(
113
- printMessage(e instanceof Error ? `${message} - ${e.message}` : message)
114
- );
115
- return { lockValue: void 0 };
116
- }
117
- };
118
-
119
- // src/utils/cloudflare/sync-edge-value.ts
120
- var APIError = class extends Error {
121
- constructor(message) {
122
- super(message);
123
- this.name = "APIError";
124
- }
125
- };
126
- var DEFAULT_API_HOSTNAME = "https://api.appwarden.io";
127
- var syncEdgeValue = async (context) => {
128
- debug(`syncing with api`);
129
- try {
130
- const apiHostname = context.appwardenApiHostname ?? DEFAULT_API_HOSTNAME;
131
- const response = await fetch(new URL("/v1/status/check", apiHostname), {
132
- method: "POST",
133
- headers: { "content-type": "application/json" },
134
- body: JSON.stringify({
135
- service: "cloudflare",
136
- provider: context.provider,
137
- fqdn: context.requestUrl.hostname,
138
- appwardenApiToken: context.appwardenApiToken
139
- })
140
- });
141
- if (response.status !== 200) {
142
- throw new Error(`${response.status} ${response.statusText}`);
143
- }
144
- if (response.headers.get("content-type")?.includes("application/json")) {
145
- const result = await response.json();
146
- if (result.error) {
147
- throw new APIError(result.error.message);
148
- }
149
- if (!result.content) {
150
- throw new APIError("no content from api");
151
- }
152
- try {
153
- const parsedValue = LockValue.omit({ lastCheck: true }).parse(
154
- result.content
155
- );
156
- debug(`syncing with api...DONE ${JSON.stringify(parsedValue, null, 2)}`);
157
- await context.edgeCache.updateValue({
158
- ...parsedValue,
159
- lastCheck: Date.now()
160
- });
161
- } catch (error) {
162
- throw new APIError(`Failed to parse check endpoint result - ${error}`);
163
- }
164
- }
165
- } catch (e) {
166
- const message = "Failed to fetch from check endpoint";
167
- console.error(
168
- printMessage(
169
- e instanceof APIError ? e.message : e instanceof Error ? `${message} - ${e.message}` : message
170
- )
171
- );
172
- }
173
- };
174
-
175
- // src/core/check-lock-status.ts
176
- var createContext = async (config) => {
177
- const requestUrl = new URL(config.request.url);
178
- const keyName = APPWARDEN_CACHE_KEY;
179
- const provider = "cloudflare-cache";
180
- const edgeCache = store.json(
181
- {
182
- serviceOrigin: requestUrl.origin,
183
- cache: await caches.open("appwarden:lock")
184
- },
185
- keyName
186
- );
187
- return {
188
- keyName,
189
- request: config.request,
190
- edgeCache,
191
- requestUrl,
192
- provider,
193
- debug: config.debug ?? false,
194
- lockPageSlug: config.lockPageSlug,
195
- appwardenApiToken: config.appwardenApiToken,
196
- appwardenApiHostname: config.appwardenApiHostname,
197
- waitUntil: config.waitUntil
198
- };
199
- };
200
- var resolveLockStatus = async (context) => {
201
- const { lockValue, shouldDeleteEdgeValue } = await getLockValue(context);
202
- if (shouldDeleteEdgeValue) {
203
- await deleteEdgeValue(context);
204
- }
205
- const isTestRoute = context.requestUrl.pathname === APPWARDEN_TEST_ROUTE;
206
- const isTestLock = isTestRoute && !MemoryCache.isTestExpired(lockValue) && !!lockValue;
207
- return {
208
- isLocked: !!lockValue?.isLocked || isTestLock,
209
- isTestLock,
210
- lockValue,
211
- wasDeleted: shouldDeleteEdgeValue ?? false
212
- };
213
- };
214
- var checkLockStatus = async (config) => {
215
- const context = await createContext(config);
216
- let { isLocked, isTestLock, lockValue, wasDeleted } = await resolveLockStatus(context);
217
- if (MemoryCache.isExpired(lockValue) || wasDeleted) {
218
- if (!lockValue || wasDeleted || lockValue.isLocked) {
219
- await syncEdgeValue(context);
220
- ({ isLocked, isTestLock } = await resolveLockStatus(context));
221
- } else {
222
- config.waitUntil(syncEdgeValue(context));
223
- }
224
- }
225
- return { isLocked, isTestLock };
226
- };
227
-
228
- export {
229
- store,
230
- getLockValue,
231
- checkLockStatus
232
- };