veryfront 0.1.746 → 0.1.749
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/esm/cli/templates/manifest.js +2 -2
- package/esm/deno.js +1 -1
- package/esm/src/build/production-build/static-generation.d.ts.map +1 -1
- package/esm/src/build/production-build/static-generation.js +2 -0
- package/esm/src/cache/backends/api.d.ts.map +1 -1
- package/esm/src/cache/backends/api.js +9 -5
- package/esm/src/cache/backends/disk.d.ts +1 -1
- package/esm/src/cache/backends/disk.d.ts.map +1 -1
- package/esm/src/cache/backends/disk.js +41 -13
- package/esm/src/cache/backends/glob.d.ts +6 -0
- package/esm/src/cache/backends/glob.d.ts.map +1 -0
- package/esm/src/cache/backends/glob.js +41 -0
- package/esm/src/cache/backends/memory.d.ts +1 -1
- package/esm/src/cache/backends/memory.d.ts.map +1 -1
- package/esm/src/cache/backends/memory.js +14 -12
- package/esm/src/cache/backends/redis.d.ts.map +1 -1
- package/esm/src/cache/backends/redis.js +33 -7
- package/esm/src/cache/dependency-graph.d.ts +1 -0
- package/esm/src/cache/dependency-graph.d.ts.map +1 -1
- package/esm/src/cache/dependency-graph.js +15 -1
- package/esm/src/cache/paths.d.ts.map +1 -1
- package/esm/src/cache/paths.js +5 -0
- package/esm/src/embedding/index.d.ts +4 -1
- package/esm/src/embedding/index.d.ts.map +1 -1
- package/esm/src/embedding/index.js +3 -1
- package/esm/src/embedding/rag-store.d.ts.map +1 -1
- package/esm/src/embedding/rag-store.js +157 -8
- package/esm/src/embedding/react/use-uploads.d.ts +1 -0
- package/esm/src/embedding/react/use-uploads.d.ts.map +1 -1
- package/esm/src/embedding/react/use-uploads.js +4 -1
- package/esm/src/embedding/upload-handler.d.ts +29 -8
- package/esm/src/embedding/upload-handler.d.ts.map +1 -1
- package/esm/src/embedding/upload-handler.js +66 -6
- package/esm/src/html/html-shell-generator.js +5 -5
- package/esm/src/html/nonce-injection.d.ts.map +1 -1
- package/esm/src/html/nonce-injection.js +11 -4
- package/esm/src/html/utils.d.ts +5 -0
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +19 -9
- package/esm/src/middleware/builtin/security/redis-rate-limit.d.ts +2 -0
- package/esm/src/middleware/builtin/security/redis-rate-limit.d.ts.map +1 -1
- package/esm/src/middleware/builtin/security/redis-rate-limit.js +46 -13
- package/esm/src/modules/react-loader/ssr-module-loader/import-rewriter.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/import-rewriter.js +12 -5
- package/esm/src/modules/server/module-batch-handler.d.ts +1 -0
- package/esm/src/modules/server/module-batch-handler.d.ts.map +1 -1
- package/esm/src/modules/server/module-batch-handler.js +52 -26
- package/esm/src/modules/server/module-server.d.ts.map +1 -1
- package/esm/src/modules/server/module-server.js +87 -69
- package/esm/src/modules/server/module-source-resolution-cache.d.ts +16 -0
- package/esm/src/modules/server/module-source-resolution-cache.d.ts.map +1 -0
- package/esm/src/modules/server/module-source-resolution-cache.js +43 -0
- package/esm/src/oauth/providers/base.d.ts +0 -2
- package/esm/src/oauth/providers/base.d.ts.map +1 -1
- package/esm/src/oauth/providers/base.js +35 -10
- package/esm/src/oauth/token-store/memory.d.ts +7 -0
- package/esm/src/oauth/token-store/memory.d.ts.map +1 -1
- package/esm/src/oauth/token-store/memory.js +14 -1
- package/esm/src/observability/auto-instrument/http-instrumentation.d.ts.map +1 -1
- package/esm/src/observability/auto-instrument/http-instrumentation.js +10 -6
- package/esm/src/observability/file-log-subscriber.d.ts +1 -0
- package/esm/src/observability/file-log-subscriber.d.ts.map +1 -1
- package/esm/src/observability/file-log-subscriber.js +2 -1
- package/esm/src/observability/tracing/api-shim.d.ts +1 -0
- package/esm/src/observability/tracing/api-shim.d.ts.map +1 -1
- package/esm/src/observability/tracing/api-shim.js +7 -0
- package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
- package/esm/src/observability/tracing/otlp-setup.js +17 -7
- package/esm/src/proxy/handler.d.ts +5 -2
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +26 -25
- package/esm/src/proxy/main.js +8 -11
- package/esm/src/rendering/renderer.d.ts.map +1 -1
- package/esm/src/rendering/renderer.js +32 -12
- package/esm/src/server/context/cache-invalidation.d.ts.map +1 -1
- package/esm/src/server/context/cache-invalidation.js +2 -0
- package/esm/src/server/handlers/dev/scripts/error-overlay.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/scripts/error-overlay.js +32 -18
- package/esm/src/server/handlers/monitoring/client-log.handler.d.ts +1 -0
- package/esm/src/server/handlers/monitoring/client-log.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/monitoring/client-log.handler.js +39 -5
- package/esm/src/server/handlers/request/module/batch-module-handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/module/batch-module-handler.js +2 -1
- package/esm/src/utils/logger/redact.d.ts +10 -0
- package/esm/src/utils/logger/redact.d.ts.map +1 -1
- package/esm/src/utils/logger/redact.js +60 -1
- package/esm/src/utils/redis-client.d.ts +1 -0
- package/esm/src/utils/redis-client.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { createError, toError } from "../../../errors/veryfront-error.js";
|
|
2
2
|
import { serverLogger } from "../../../utils/index.js";
|
|
3
3
|
const logger = serverLogger.component("redis-ratelimit");
|
|
4
|
+
const INCREMENT_WITH_TTL_SCRIPT = `
|
|
5
|
+
local count = redis.call("INCR", KEYS[1])
|
|
6
|
+
local ttl = redis.call("PTTL", KEYS[1])
|
|
7
|
+
if ttl < 0 then
|
|
8
|
+
redis.call("PEXPIRE", KEYS[1], ARGV[1])
|
|
9
|
+
ttl = tonumber(ARGV[1])
|
|
10
|
+
end
|
|
11
|
+
return { count, ttl }
|
|
12
|
+
`;
|
|
4
13
|
/** Implement redis rate limit store. */
|
|
5
14
|
export class RedisRateLimitStore {
|
|
6
15
|
client = null;
|
|
@@ -17,6 +26,19 @@ export class RedisRateLimitStore {
|
|
|
17
26
|
this.clientPromise ??= this.connectClient();
|
|
18
27
|
return this.clientPromise;
|
|
19
28
|
}
|
|
29
|
+
clearCachedClient() {
|
|
30
|
+
this.client = null;
|
|
31
|
+
this.clientPromise = null;
|
|
32
|
+
}
|
|
33
|
+
attachClientLifecycleHandlers(client) {
|
|
34
|
+
client.on?.("error", (err) => {
|
|
35
|
+
logger.error("client error", err);
|
|
36
|
+
this.clearCachedClient();
|
|
37
|
+
});
|
|
38
|
+
client.on?.("end", () => {
|
|
39
|
+
this.clearCachedClient();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
20
42
|
async connectClient() {
|
|
21
43
|
let createClient;
|
|
22
44
|
try {
|
|
@@ -34,11 +56,10 @@ export class RedisRateLimitStore {
|
|
|
34
56
|
}
|
|
35
57
|
try {
|
|
36
58
|
const client = createClient({ url: this.url });
|
|
37
|
-
|
|
38
|
-
logger.error("client error", err);
|
|
39
|
-
});
|
|
59
|
+
this.attachClientLifecycleHandlers(client);
|
|
40
60
|
await client.connect();
|
|
41
61
|
this.client = client;
|
|
62
|
+
this.clientPromise = null;
|
|
42
63
|
return client;
|
|
43
64
|
}
|
|
44
65
|
catch (error) {
|
|
@@ -52,15 +73,10 @@ export class RedisRateLimitStore {
|
|
|
52
73
|
async increment(key, windowMs) {
|
|
53
74
|
const client = await this.ensureClient();
|
|
54
75
|
const redisKey = this.storageKey(key);
|
|
55
|
-
const count = await client.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
const pttl = await client.pTTL(redisKey);
|
|
60
|
-
if (pttl === -1) {
|
|
61
|
-
await client.pExpire(redisKey, windowMs);
|
|
62
|
-
return { count, resetAt: Date.now() + windowMs };
|
|
63
|
-
}
|
|
76
|
+
const [count, pttl] = parseIncrementResult(await client.eval(INCREMENT_WITH_TTL_SCRIPT, {
|
|
77
|
+
keys: [redisKey],
|
|
78
|
+
arguments: [String(windowMs)],
|
|
79
|
+
}));
|
|
64
80
|
const ttl = pttl > 0 ? pttl : windowMs;
|
|
65
81
|
return { count, resetAt: Date.now() + ttl };
|
|
66
82
|
}
|
|
@@ -72,6 +88,23 @@ export class RedisRateLimitStore {
|
|
|
72
88
|
if (!this.client)
|
|
73
89
|
return;
|
|
74
90
|
await this.client.disconnect();
|
|
75
|
-
this.
|
|
91
|
+
this.clearCachedClient();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function parseIncrementResult(result) {
|
|
95
|
+
if (!Array.isArray(result) || result.length < 2) {
|
|
96
|
+
throw toError(createError({
|
|
97
|
+
type: "config",
|
|
98
|
+
message: "Redis rate limit eval returned an invalid result.",
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
const count = Number(result[0]);
|
|
102
|
+
const ttl = Number(result[1]);
|
|
103
|
+
if (!Number.isFinite(count) || !Number.isFinite(ttl)) {
|
|
104
|
+
throw toError(createError({
|
|
105
|
+
type: "config",
|
|
106
|
+
message: "Redis rate limit eval returned non-numeric values.",
|
|
107
|
+
}));
|
|
76
108
|
}
|
|
109
|
+
return [count, ttl];
|
|
77
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,
|
|
1
|
+
{"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,CA8BR"}
|
|
@@ -34,16 +34,23 @@ export function rewriteLocalImports(transformed, localImportPaths, fromFilePath,
|
|
|
34
34
|
const fromRelativeDir = fromFileDir.startsWith(normalizedProjectDir)
|
|
35
35
|
? fromFileDir.substring(normalizedProjectDir.length + 1)
|
|
36
36
|
: fromFileDir;
|
|
37
|
-
|
|
37
|
+
const replacementByPattern = new Map();
|
|
38
38
|
for (const [specifierOrPath, tempPath] of localImportPaths) {
|
|
39
39
|
const patterns = buildImportPatterns(specifierOrPath, fromRelativeDir, normalizedProjectDir);
|
|
40
40
|
for (const pattern of patterns) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
if (!replacementByPattern.has(pattern)) {
|
|
42
|
+
replacementByPattern.set(pattern, tempPath);
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
if (replacementByPattern.size === 0)
|
|
47
|
+
return transformed;
|
|
48
|
+
const importPattern = Array.from(replacementByPattern.keys()).map(escapeRegExp).join("|");
|
|
49
|
+
const regex = new RegExp(`${IMPORT_FROM_PREFIX}(${importPattern})${IMPORT_FROM_SUFFIX}`, "g");
|
|
50
|
+
return transformed.replace(regex, (match, specifier) => {
|
|
51
|
+
const tempPath = replacementByPattern.get(specifier);
|
|
52
|
+
return tempPath === undefined ? match : `from "file://${tempPath}"`;
|
|
53
|
+
});
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
49
56
|
* Build import patterns for a given specifier to match in transformed code.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-batch-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-batch-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"module-batch-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-batch-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAiGtE,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6K/F;AA0PD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAc1D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKrE"}
|
|
@@ -27,6 +27,7 @@ import { getFrameworkRootFromMeta } from "../../platform/compat/vfs-paths.js";
|
|
|
27
27
|
import { LRUCache } from "../../utils/lru-wrapper.js";
|
|
28
28
|
import { registerLRUCache } from "../../cache/index.js";
|
|
29
29
|
import { sha256Short } from "../../cache/hash.js";
|
|
30
|
+
import { buildSourceMissCacheKey, clearSourceMissCache, hasSourceMiss, rememberSourceMiss, } from "./module-source-resolution-cache.js";
|
|
30
31
|
const logger = serverLogger.component("module-batch");
|
|
31
32
|
/** Slow request threshold in milliseconds */
|
|
32
33
|
const SLOW_REQUEST_THRESHOLD_MS = 500;
|
|
@@ -57,6 +58,30 @@ const FRAMEWORK_EXTENSIONS = [
|
|
|
57
58
|
".jsx",
|
|
58
59
|
".js", // Regular sources for dev mode
|
|
59
60
|
];
|
|
61
|
+
async function findFirstSecureFile(secureFs, paths) {
|
|
62
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
63
|
+
try {
|
|
64
|
+
const stat = await secureFs.stat(path);
|
|
65
|
+
return stat.isFile ? path : null;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
return results.find((path) => path !== null) ?? null;
|
|
72
|
+
}
|
|
73
|
+
async function findFirstPlatformFile(platformFs, paths) {
|
|
74
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
75
|
+
try {
|
|
76
|
+
const stat = await platformFs.stat(path);
|
|
77
|
+
return stat.isFile ? path : null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}));
|
|
83
|
+
return results.find((path) => path !== null) ?? null;
|
|
84
|
+
}
|
|
60
85
|
/**
|
|
61
86
|
* Handle a batch module request
|
|
62
87
|
*/
|
|
@@ -87,7 +112,7 @@ export function handleModuleBatch(req, options) {
|
|
|
87
112
|
headers: { "Content-Type": "text/plain" },
|
|
88
113
|
});
|
|
89
114
|
}
|
|
90
|
-
const { projectDir, adapter, projectSlug, projectId, branch, dev = false, allowedImportDirs, reactVersion, } = options;
|
|
115
|
+
const { projectDir, adapter, projectSlug, projectId, branch, releaseId, dev = false, allowedImportDirs, reactVersion, } = options;
|
|
91
116
|
const projectKey = projectId || projectSlug || "default";
|
|
92
117
|
const userAgent = req.headers.get("user-agent") ?? "";
|
|
93
118
|
const isSSR = url.searchParams.get("ssr") === "true" || userAgent.startsWith("Deno/");
|
|
@@ -124,6 +149,7 @@ export function handleModuleBatch(req, options) {
|
|
|
124
149
|
projectSlug,
|
|
125
150
|
branch,
|
|
126
151
|
projectId,
|
|
152
|
+
releaseId,
|
|
127
153
|
reactVersion,
|
|
128
154
|
});
|
|
129
155
|
const transformDurationMs = performance.now() - moduleStart;
|
|
@@ -196,21 +222,27 @@ export function handleModuleBatch(req, options) {
|
|
|
196
222
|
*/
|
|
197
223
|
async function loadAndTransformModule(modulePath, projectDir, adapter, secureFs, options) {
|
|
198
224
|
const basePath = modulePath.replace(/\.js$/, "");
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
225
|
+
const missCacheKey = buildSourceMissCacheKey({
|
|
226
|
+
resolver: "module-batch",
|
|
227
|
+
projectDir,
|
|
228
|
+
projectId: options.projectId,
|
|
229
|
+
projectSlug: options.projectSlug,
|
|
230
|
+
branch: options.branch,
|
|
231
|
+
releaseId: options.releaseId,
|
|
232
|
+
basePath,
|
|
233
|
+
reactVersion: options.reactVersion,
|
|
234
|
+
});
|
|
235
|
+
if (hasSourceMiss(missCacheKey))
|
|
236
|
+
return null;
|
|
237
|
+
const sourcePath = await findFirstSecureFile(secureFs, EXTENSIONS.map((ext) => join(projectDir, basePath + ext)));
|
|
238
|
+
if (sourcePath) {
|
|
239
|
+
const source = await secureFs.readFile(sourcePath);
|
|
240
|
+
return transformModule(source, sourcePath, modulePath, projectDir, adapter, secureFs, options);
|
|
211
241
|
}
|
|
212
|
-
if (!basePath.startsWith("lib/"))
|
|
242
|
+
if (!basePath.startsWith("lib/")) {
|
|
243
|
+
rememberSourceMiss(missCacheKey);
|
|
213
244
|
return null;
|
|
245
|
+
}
|
|
214
246
|
// Framework lookup directories in priority order
|
|
215
247
|
const frameworkLookupDirs = [
|
|
216
248
|
EMBEDDED_SRC_DIR, // Embedded sources for compiled binaries (.src files)
|
|
@@ -218,20 +250,13 @@ async function loadAndTransformModule(modulePath, projectDir, adapter, secureFs,
|
|
|
218
250
|
];
|
|
219
251
|
const platformFs = createFileSystem();
|
|
220
252
|
for (const lookupDir of frameworkLookupDirs) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (!stat.isFile)
|
|
226
|
-
continue;
|
|
227
|
-
const source = await platformFs.readTextFile(frameworkPath);
|
|
228
|
-
return transformModule(source, frameworkPath, modulePath, projectDir, adapter, secureFs, options);
|
|
229
|
-
}
|
|
230
|
-
catch (_) {
|
|
231
|
-
/* expected: framework file may not exist at this extension */
|
|
232
|
-
}
|
|
253
|
+
const frameworkPath = await findFirstPlatformFile(platformFs, FRAMEWORK_EXTENSIONS.map((ext) => join(lookupDir, basePath + ext)));
|
|
254
|
+
if (frameworkPath) {
|
|
255
|
+
const source = await platformFs.readTextFile(frameworkPath);
|
|
256
|
+
return transformModule(source, frameworkPath, modulePath, projectDir, adapter, secureFs, options);
|
|
233
257
|
}
|
|
234
258
|
}
|
|
259
|
+
rememberSourceMiss(missCacheKey);
|
|
235
260
|
return null;
|
|
236
261
|
}
|
|
237
262
|
async function transformModule(source, sourceFile, modulePath, projectDir, adapter, secureFs, options) {
|
|
@@ -369,6 +394,7 @@ function transformExportsForBundle(code) {
|
|
|
369
394
|
* Clear the transform cache (on deployment or memory pressure)
|
|
370
395
|
*/
|
|
371
396
|
export function clearBatchCache(projectSlug) {
|
|
397
|
+
clearSourceMissCache("module-batch");
|
|
372
398
|
if (!projectSlug) {
|
|
373
399
|
transformCache.clear();
|
|
374
400
|
logger.debug("Cleared all cache");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAkCtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsDrD,CAAC;AAiBF,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkWzF;AAiVD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGrD"}
|
|
@@ -17,6 +17,7 @@ import { FRAMEWORK_ROOT, resolveFrameworkSourcePath, } from "../../platform/comp
|
|
|
17
17
|
import { getReactUrls, REACT_DEFAULT_VERSION } from "../../utils/constants/cdn.js";
|
|
18
18
|
import { readLimitedCrossProjectSource } from "./cross-project-source-limit.js";
|
|
19
19
|
import { sha256Short } from "../../cache/hash.js";
|
|
20
|
+
import { buildSourceMissCacheKey, hasSourceMiss, rememberSourceMiss, } from "./module-source-resolution-cache.js";
|
|
20
21
|
const logger = serverLogger.component("module-server");
|
|
21
22
|
/**
|
|
22
23
|
* Embedded polyfills for compiled Deno binaries.
|
|
@@ -161,6 +162,10 @@ export function serveModule(req, options) {
|
|
|
161
162
|
secureFs,
|
|
162
163
|
projectDir,
|
|
163
164
|
currentModulePath: `_snippets/${hash}.js`,
|
|
165
|
+
projectId: effectiveProjectId,
|
|
166
|
+
projectSlug: snippetProjectSlug,
|
|
167
|
+
branch: snippetBranch,
|
|
168
|
+
releaseId: options.releaseId,
|
|
164
169
|
reactVersion,
|
|
165
170
|
}),
|
|
166
171
|
});
|
|
@@ -229,6 +234,8 @@ export function serveModule(req, options) {
|
|
|
229
234
|
projectDir,
|
|
230
235
|
currentModulePath: crossPath,
|
|
231
236
|
crossProjectRef: projectRef,
|
|
237
|
+
projectId: effectiveProjectId,
|
|
238
|
+
releaseId: options.releaseId,
|
|
232
239
|
reactVersion,
|
|
233
240
|
}),
|
|
234
241
|
});
|
|
@@ -262,7 +269,13 @@ export function serveModule(req, options) {
|
|
|
262
269
|
branch ??= parsedHost.branch;
|
|
263
270
|
}
|
|
264
271
|
try {
|
|
265
|
-
const findResult = await findSourceFile(secureFs, projectDir, filePathWithoutExt,
|
|
272
|
+
const findResult = await findSourceFile(secureFs, projectDir, filePathWithoutExt, {
|
|
273
|
+
projectId: effectiveProjectId,
|
|
274
|
+
projectSlug,
|
|
275
|
+
branch,
|
|
276
|
+
releaseId: options.releaseId,
|
|
277
|
+
reactVersion,
|
|
278
|
+
});
|
|
266
279
|
if (!findResult) {
|
|
267
280
|
logger.warn("Module not found", {
|
|
268
281
|
modulePath,
|
|
@@ -326,6 +339,10 @@ export function serveModule(req, options) {
|
|
|
326
339
|
secureFs,
|
|
327
340
|
projectDir,
|
|
328
341
|
currentModulePath: modulePath,
|
|
342
|
+
projectId: effectiveProjectId,
|
|
343
|
+
projectSlug,
|
|
344
|
+
branch,
|
|
345
|
+
releaseId: options.releaseId,
|
|
329
346
|
reactVersion,
|
|
330
347
|
}),
|
|
331
348
|
});
|
|
@@ -375,7 +392,13 @@ function createSSRTargetCacheBusterResolver(options) {
|
|
|
375
392
|
const source = await fetchCrossProjectSource(options.crossProjectRef, targetPath);
|
|
376
393
|
return source === null ? undefined : await sha256Short(`${targetPath}\0${source}`);
|
|
377
394
|
}
|
|
378
|
-
const findResult = await findSourceFile(options.secureFs, options.projectDir, stripSSRModuleJsExtension(targetPath),
|
|
395
|
+
const findResult = await findSourceFile(options.secureFs, options.projectDir, stripSSRModuleJsExtension(targetPath), {
|
|
396
|
+
projectId: options.projectId,
|
|
397
|
+
projectSlug: options.projectSlug,
|
|
398
|
+
branch: options.branch,
|
|
399
|
+
releaseId: options.releaseId,
|
|
400
|
+
reactVersion: options.reactVersion,
|
|
401
|
+
});
|
|
379
402
|
if (!findResult)
|
|
380
403
|
return undefined;
|
|
381
404
|
const source = await readSourceFileForVersion(options.secureFs, findResult);
|
|
@@ -415,20 +438,34 @@ function createBrowserReactPackageShim(basePathWithoutExt, reactVersion = REACT_
|
|
|
415
438
|
async function findFrameworkPackageAssetFile(fs, basePathWithoutExt, extensions) {
|
|
416
439
|
if (hasUnsafePackageAssetPath(basePathWithoutExt))
|
|
417
440
|
return null;
|
|
418
|
-
|
|
419
|
-
|
|
441
|
+
return await findFirstPlatformFile(fs, extensions.map((ext) => join(FRAMEWORK_ROOT, basePathWithoutExt + ext)));
|
|
442
|
+
}
|
|
443
|
+
async function findFirstPlatformFile(fs, paths) {
|
|
444
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
420
445
|
try {
|
|
421
|
-
const stat = await fs.stat(
|
|
422
|
-
|
|
423
|
-
return candidatePath;
|
|
446
|
+
const stat = await fs.stat(path);
|
|
447
|
+
return stat.isFile ? path : null;
|
|
424
448
|
}
|
|
425
449
|
catch {
|
|
426
|
-
|
|
450
|
+
return null;
|
|
427
451
|
}
|
|
428
|
-
}
|
|
429
|
-
return null;
|
|
452
|
+
}));
|
|
453
|
+
return results.find((path) => path !== null) ?? null;
|
|
430
454
|
}
|
|
431
|
-
async function
|
|
455
|
+
async function findFirstSecureFile(secureFs, paths) {
|
|
456
|
+
const results = await Promise.all(paths.map(async (path) => {
|
|
457
|
+
try {
|
|
458
|
+
const stat = await secureFs.stat(path);
|
|
459
|
+
return stat.isFile ? path : null;
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
}));
|
|
465
|
+
return results.find((path) => path !== null) ?? null;
|
|
466
|
+
}
|
|
467
|
+
async function findSourceFile(secureFs, projectDir, basePath, context) {
|
|
468
|
+
const { reactVersion } = context;
|
|
432
469
|
// Extensions including .src for compiled binary embedded sources
|
|
433
470
|
const extensions = [
|
|
434
471
|
".json",
|
|
@@ -457,6 +494,16 @@ async function findSourceFile(secureFs, projectDir, basePath, reactVersion) {
|
|
|
457
494
|
const isFrameworkPath = basePathWithoutExt.startsWith("_veryfront/");
|
|
458
495
|
const isFrameworkPackageAssetPath = basePathWithoutExt.startsWith("react/") ||
|
|
459
496
|
basePathWithoutExt.startsWith("deps/");
|
|
497
|
+
const missCacheKey = buildSourceMissCacheKey({
|
|
498
|
+
resolver: "module-server",
|
|
499
|
+
projectDir,
|
|
500
|
+
projectId: context.projectId,
|
|
501
|
+
projectSlug: context.projectSlug,
|
|
502
|
+
branch: context.branch,
|
|
503
|
+
releaseId: context.releaseId,
|
|
504
|
+
basePath: basePathWithoutExt,
|
|
505
|
+
reactVersion,
|
|
506
|
+
});
|
|
460
507
|
// Check embedded polyfills first (no filesystem access needed).
|
|
461
508
|
// These cover both compiled-binary polyfills (node:async_hooks etc.)
|
|
462
509
|
// and dnt build artifacts (_dnt.shims, _dnt.polyfills) that don't
|
|
@@ -475,6 +522,8 @@ async function findSourceFile(secureFs, projectDir, basePath, reactVersion) {
|
|
|
475
522
|
embeddedContent,
|
|
476
523
|
};
|
|
477
524
|
}
|
|
525
|
+
if (hasSourceMiss(missCacheKey))
|
|
526
|
+
return null;
|
|
478
527
|
if (isFrameworkPackageAssetPath) {
|
|
479
528
|
const browserReactShim = createBrowserReactPackageShim(basePathWithoutExt, reactVersion);
|
|
480
529
|
if (browserReactShim) {
|
|
@@ -525,78 +574,47 @@ async function findSourceFile(secureFs, projectDir, basePath, reactVersion) {
|
|
|
525
574
|
}
|
|
526
575
|
}
|
|
527
576
|
// Project file lookups (using secureFs which may go through FSAdapter in proxy mode)
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (stat.isFile) {
|
|
533
|
-
logger.debug("Found file", { basePath, resolvedPath: fullPath });
|
|
534
|
-
return { path: fullPath, isFrameworkFile: false };
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
catch (_) {
|
|
538
|
-
/* expected: file may not exist at this extension */
|
|
539
|
-
}
|
|
577
|
+
const projectFilePath = await findFirstSecureFile(secureFs, extensions.map((ext) => join(projectDir, basePathWithoutExt + ext)));
|
|
578
|
+
if (projectFilePath) {
|
|
579
|
+
logger.debug("Found file", { basePath, resolvedPath: projectFilePath });
|
|
580
|
+
return { path: projectFilePath, isFrameworkFile: false };
|
|
540
581
|
}
|
|
541
582
|
const prefixesToStrip = ["components/", "pages/", "lib/", "app/", "src/"];
|
|
542
583
|
for (const prefix of prefixesToStrip) {
|
|
543
584
|
if (!basePathWithoutExt.startsWith(prefix))
|
|
544
585
|
continue;
|
|
545
586
|
const strippedPath = basePathWithoutExt.slice(prefix.length);
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
resolvedPath: fullPath,
|
|
555
|
-
});
|
|
556
|
-
return { path: fullPath, isFrameworkFile: false };
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
catch (_) {
|
|
560
|
-
/* expected: file may not exist after stripping prefix */
|
|
561
|
-
}
|
|
587
|
+
const strippedFilePath = await findFirstSecureFile(secureFs, extensions.map((ext) => join(projectDir, strippedPath + ext)));
|
|
588
|
+
if (strippedFilePath) {
|
|
589
|
+
logger.debug("Found file after stripping prefix", {
|
|
590
|
+
originalPath: basePathWithoutExt,
|
|
591
|
+
strippedPath,
|
|
592
|
+
resolvedPath: strippedFilePath,
|
|
593
|
+
});
|
|
594
|
+
return { path: strippedFilePath, isFrameworkFile: false };
|
|
562
595
|
}
|
|
563
596
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
resolvedPath: fullPath,
|
|
572
|
-
});
|
|
573
|
-
return { path: fullPath, isFrameworkFile: false };
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
catch (_) {
|
|
577
|
-
/* expected: index file may not exist at this extension */
|
|
578
|
-
}
|
|
597
|
+
const indexFilePath = await findFirstSecureFile(secureFs, extensions.map((ext) => join(projectDir, basePathWithoutExt, `index${ext}`)));
|
|
598
|
+
if (indexFilePath) {
|
|
599
|
+
logger.debug("Found index file", {
|
|
600
|
+
basePath: basePathWithoutExt,
|
|
601
|
+
resolvedPath: indexFilePath,
|
|
602
|
+
});
|
|
603
|
+
return { path: indexFilePath, isFrameworkFile: false };
|
|
579
604
|
}
|
|
580
605
|
// Try looking in common project directories
|
|
581
606
|
const commonDirs = ["components", "app", "pages", "lib", "src"];
|
|
582
607
|
for (const dir of commonDirs) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
resolvedPath: fullPath,
|
|
591
|
-
});
|
|
592
|
-
return { path: fullPath, isFrameworkFile: false };
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
catch (_) {
|
|
596
|
-
/* expected: file may not exist in common directory */
|
|
597
|
-
}
|
|
608
|
+
const commonDirFilePath = await findFirstSecureFile(secureFs, extensions.map((ext) => join(projectDir, dir, basePathWithoutExt + ext)));
|
|
609
|
+
if (commonDirFilePath) {
|
|
610
|
+
logger.debug("Found file in common directory", {
|
|
611
|
+
basePath,
|
|
612
|
+
resolvedPath: commonDirFilePath,
|
|
613
|
+
});
|
|
614
|
+
return { path: commonDirFilePath, isFrameworkFile: false };
|
|
598
615
|
}
|
|
599
616
|
}
|
|
617
|
+
rememberSourceMiss(missCacheKey);
|
|
600
618
|
return null;
|
|
601
619
|
}
|
|
602
620
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type ModuleSourceResolver = "module-server" | "module-batch";
|
|
2
|
+
export declare function buildSourceMissCacheKey(options: {
|
|
3
|
+
resolver: ModuleSourceResolver;
|
|
4
|
+
projectDir: string;
|
|
5
|
+
projectId?: string;
|
|
6
|
+
projectSlug?: string | null;
|
|
7
|
+
branch?: string | null;
|
|
8
|
+
releaseId?: string | null;
|
|
9
|
+
basePath: string;
|
|
10
|
+
reactVersion?: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function hasSourceMiss(cacheKey: string): boolean;
|
|
13
|
+
export declare function rememberSourceMiss(cacheKey: string): void;
|
|
14
|
+
export declare function clearSourceMissCache(resolver?: ModuleSourceResolver): void;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=module-source-resolution-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-source-resolution-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-source-resolution-cache.ts"],"names":[],"mappings":"AAGA,KAAK,oBAAoB,GAAG,eAAe,GAAG,cAAc,CAAC;AAgB7D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAWT;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAO1E"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { registerLRUCache } from "../../cache/index.js";
|
|
2
|
+
import { LRUCache } from "../../utils/lru-wrapper.js";
|
|
3
|
+
const SOURCE_MISS_CACHE_MAX_ENTRIES = 5_000;
|
|
4
|
+
const sourceMissCaches = {
|
|
5
|
+
"module-server": new LRUCache({
|
|
6
|
+
maxEntries: SOURCE_MISS_CACHE_MAX_ENTRIES,
|
|
7
|
+
}),
|
|
8
|
+
"module-batch": new LRUCache({
|
|
9
|
+
maxEntries: SOURCE_MISS_CACHE_MAX_ENTRIES,
|
|
10
|
+
}),
|
|
11
|
+
};
|
|
12
|
+
registerLRUCache("module-server-source-miss-cache", sourceMissCaches["module-server"]);
|
|
13
|
+
registerLRUCache("module-batch-source-miss-cache", sourceMissCaches["module-batch"]);
|
|
14
|
+
export function buildSourceMissCacheKey(options) {
|
|
15
|
+
return [
|
|
16
|
+
options.resolver,
|
|
17
|
+
options.projectDir,
|
|
18
|
+
options.projectId ?? "",
|
|
19
|
+
options.projectSlug ?? "",
|
|
20
|
+
options.branch ?? "",
|
|
21
|
+
options.releaseId ?? "",
|
|
22
|
+
options.reactVersion ?? "",
|
|
23
|
+
options.basePath,
|
|
24
|
+
].join("\0");
|
|
25
|
+
}
|
|
26
|
+
export function hasSourceMiss(cacheKey) {
|
|
27
|
+
return sourceMissCaches[getResolverFromCacheKey(cacheKey)].has(cacheKey);
|
|
28
|
+
}
|
|
29
|
+
export function rememberSourceMiss(cacheKey) {
|
|
30
|
+
sourceMissCaches[getResolverFromCacheKey(cacheKey)].set(cacheKey, true);
|
|
31
|
+
}
|
|
32
|
+
export function clearSourceMissCache(resolver) {
|
|
33
|
+
if (resolver) {
|
|
34
|
+
sourceMissCaches[resolver].clear();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
for (const cache of Object.values(sourceMissCaches))
|
|
38
|
+
cache.clear();
|
|
39
|
+
}
|
|
40
|
+
function getResolverFromCacheKey(cacheKey) {
|
|
41
|
+
const resolver = cacheKey.split("\0", 1)[0];
|
|
42
|
+
return resolver === "module-batch" ? "module-batch" : "module-server";
|
|
43
|
+
}
|
|
@@ -36,11 +36,9 @@ export declare class OAuthProvider {
|
|
|
36
36
|
export declare class OAuthService extends OAuthProvider {
|
|
37
37
|
protected serviceConfig: OAuthServiceConfig;
|
|
38
38
|
protected tokenStore?: TokenStore;
|
|
39
|
-
private refreshPromises;
|
|
40
39
|
constructor(config: OAuthServiceConfig, tokenStore?: TokenStore, envReader?: EnvReader);
|
|
41
40
|
get serviceId(): string;
|
|
42
41
|
get apiBaseUrl(): string;
|
|
43
|
-
private refreshKey;
|
|
44
42
|
createAuthorizationUrl(options?: AuthorizationUrlOptions): Promise<{
|
|
45
43
|
url: string;
|
|
46
44
|
state: OAuthState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/providers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EAEV,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,aAAa,CAAC;AAarB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAuB5D,gCAAgC;AAChC,qBAAa,aAAa;IACxB,SAAS,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACtC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC;gBAEnB,MAAM,EAAE,mBAAmB,EAAE,SAAS,GAAE,SAAkB;IAKtE,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,YAAY,IAAI,OAAO;IAIjB,sBAAsB,CAC1B,OAAO,GAAE,uBAAuB,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACnE,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IA0C9C,OAAO,CAAC,iBAAiB;IAazB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;YA0CZ,gBAAgB;IAe9B,OAAO,CAAC,4BAA4B;YAQtB,aAAa;IAyCrB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgCzE,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBjE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiBnD;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/providers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EAEV,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,aAAa,CAAC;AAarB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAuB5D,gCAAgC;AAChC,qBAAa,aAAa;IACxB,SAAS,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACtC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC;gBAEnB,MAAM,EAAE,mBAAmB,EAAE,SAAS,GAAE,SAAkB;IAKtE,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,YAAY,IAAI,OAAO;IAIjB,sBAAsB,CAC1B,OAAO,GAAE,uBAAuB,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACnE,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IA0C9C,OAAO,CAAC,iBAAiB;IAazB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;YA0CZ,gBAAgB;IAe9B,OAAO,CAAC,4BAA4B;YAQtB,aAAa;IAyCrB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgCzE,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBjE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiBnD;AA2CD,+BAA+B;AAC/B,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC;IAC5C,SAAS,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;gBAEtB,MAAM,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS;IAMtF,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAEQ,sBAAsB,CAC7B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IAO9C;;;;;;OAMG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;YA4B9C,0BAA0B;IAcxC;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAuBpB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;CA+BxF"}
|