veryfront 0.1.993 → 0.1.995
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/deno.js +1 -1
- package/esm/src/embedding/index.d.ts +1 -1
- package/esm/src/embedding/index.d.ts.map +1 -1
- package/esm/src/embedding/rag-store.d.ts.map +1 -1
- package/esm/src/embedding/rag-store.js +37 -0
- package/esm/src/embedding/types.d.ts +7 -0
- package/esm/src/embedding/types.d.ts.map +1 -1
- package/esm/src/embedding/upload-loader.d.ts +5 -4
- package/esm/src/embedding/upload-loader.d.ts.map +1 -1
- package/esm/src/embedding/upload-loader.js +5 -4
- package/esm/src/embedding/veryfront-cloud/rag-store.d.ts.map +1 -1
- package/esm/src/embedding/veryfront-cloud/rag-store.js +45 -5
- package/esm/src/html/html-injection.d.ts +7 -0
- package/esm/src/html/html-injection.d.ts.map +1 -1
- package/esm/src/html/html-injection.js +7 -1
- package/esm/src/html/hydration-script-builder/templates/renderer.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/templates/renderer.js +6 -2
- package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/templates/router.js +49 -8
- package/esm/src/rendering/layouts/layout-applicator.d.ts.map +1 -1
- package/esm/src/rendering/layouts/layout-applicator.js +2 -5
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +1 -0
- package/esm/src/rendering/page-rendering.d.ts.map +1 -1
- package/esm/src/rendering/page-rendering.js +2 -5
- package/esm/src/rendering/script-page-handling.d.ts.map +1 -1
- package/esm/src/rendering/script-page-handling.js +2 -5
- package/esm/src/routing/api/context-builder.d.ts +4 -0
- package/esm/src/routing/api/context-builder.d.ts.map +1 -1
- package/esm/src/routing/api/context-builder.js +6 -5
- package/esm/src/routing/flatten-route-params.d.ts +11 -0
- package/esm/src/routing/flatten-route-params.d.ts.map +1 -0
- package/esm/src/routing/flatten-route-params.js +20 -0
- package/esm/src/routing/index.d.ts +1 -0
- package/esm/src/routing/index.d.ts.map +1 -1
- package/esm/src/routing/index.js +1 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
package/esm/deno.js
CHANGED
|
@@ -24,6 +24,6 @@ export { loadUpload } from "./upload-loader.js";
|
|
|
24
24
|
export { useUploads } from "./react/use-uploads.js";
|
|
25
25
|
export type { UseUploadsOptions, UseUploadsResult } from "./react/use-uploads.js";
|
|
26
26
|
export { clearEmbeddingProviders, registerEmbeddingProvider, resolveEmbeddingModel, } from "./resolve.js";
|
|
27
|
-
export type { ChunkOptions, Embedding, EmbeddingConfig, RagChunk, RagDocumentMeta, RagSearchOptions, RagSearchResult, RagStore, RagStoreBackend, RagStoreConfig, RagStoreData, SearchOptions, SearchResult, VectorStore, VectorStoreConfig, } from "./types.js";
|
|
27
|
+
export type { ChunkOptions, Embedding, EmbeddingConfig, RagChunk, RagDocumentMeta, RagRefreshOptions, RagSearchOptions, RagSearchResult, RagStore, RagStoreBackend, RagStoreConfig, RagStoreData, SearchOptions, SearchResult, VectorStore, VectorStoreConfig, } from "./types.js";
|
|
28
28
|
export type { UploadAuthorizationResult, UploadAuthorize, UploadHandlerAuthConfig, UploadHandlerConfig, } from "./upload-handler.js";
|
|
29
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/rag-store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/rag-store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAMV,QAAQ,EAER,cAAc,EAEf,MAAM,YAAY,CAAC;AA2HpB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAyCzD"}
|
|
@@ -126,6 +126,13 @@ export function ragStore(config) {
|
|
|
126
126
|
ingest(title, text, meta) {
|
|
127
127
|
return getStore().ingest(title, text, meta);
|
|
128
128
|
},
|
|
129
|
+
refreshDocument(id, text, meta) {
|
|
130
|
+
const store = getStore();
|
|
131
|
+
if (!store.refreshDocument) {
|
|
132
|
+
throw INVALID_ARGUMENT.create({ detail: "RAG store does not support document refresh" });
|
|
133
|
+
}
|
|
134
|
+
return store.refreshDocument(id, text, meta);
|
|
135
|
+
},
|
|
129
136
|
search(query, options) {
|
|
130
137
|
return getStore().search(query, options);
|
|
131
138
|
},
|
|
@@ -404,6 +411,36 @@ function createLocalJsonRagStore(config) {
|
|
|
404
411
|
return documentId;
|
|
405
412
|
});
|
|
406
413
|
},
|
|
414
|
+
async refreshDocument(id, text, meta) {
|
|
415
|
+
return withLock(async () => {
|
|
416
|
+
const data = await load();
|
|
417
|
+
const document = data.documents.find((doc) => doc.id === id);
|
|
418
|
+
if (!document) {
|
|
419
|
+
throw INVALID_ARGUMENT.create({ detail: `RAG document not found: ${id}` });
|
|
420
|
+
}
|
|
421
|
+
if (text.length > MAX_TEXT_LENGTH) {
|
|
422
|
+
throw INVALID_ARGUMENT.create({
|
|
423
|
+
detail: `Upload text exceeds ${MAX_TEXT_LENGTH / 1024 / 1024} MB limit`,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
const chunks = await chunk(text, chunkOptions);
|
|
427
|
+
if (chunks.length === 0) {
|
|
428
|
+
throw INVALID_ARGUMENT.create({ detail: "Upload contains no extractable text" });
|
|
429
|
+
}
|
|
430
|
+
document.title = meta?.title ?? document.title;
|
|
431
|
+
document.source = meta?.source ?? document.source;
|
|
432
|
+
document.type = meta?.type ?? document.type;
|
|
433
|
+
data.chunks = data.chunks.filter((chunk) => chunk.documentId !== id);
|
|
434
|
+
data.chunks.push(...chunks.map((chunkText, index) => ({
|
|
435
|
+
id: dntShim.crypto.randomUUID(),
|
|
436
|
+
documentId: id,
|
|
437
|
+
text: chunkText,
|
|
438
|
+
embedding: [],
|
|
439
|
+
index,
|
|
440
|
+
})));
|
|
441
|
+
await save(data);
|
|
442
|
+
});
|
|
443
|
+
},
|
|
407
444
|
async search(query, options) {
|
|
408
445
|
if (!query.trim())
|
|
409
446
|
return [];
|
|
@@ -102,12 +102,19 @@ export interface RagSearchOptions {
|
|
|
102
102
|
topK?: number;
|
|
103
103
|
threshold?: number;
|
|
104
104
|
}
|
|
105
|
+
/** Options accepted when refreshing an existing rag document. */
|
|
106
|
+
export interface RagRefreshOptions {
|
|
107
|
+
title?: string;
|
|
108
|
+
source?: string;
|
|
109
|
+
type?: string;
|
|
110
|
+
}
|
|
105
111
|
/** Public API contract for rag store. */
|
|
106
112
|
export interface RagStore {
|
|
107
113
|
ingest(title: string, text: string, meta?: {
|
|
108
114
|
source?: string;
|
|
109
115
|
type?: string;
|
|
110
116
|
}): Promise<string>;
|
|
117
|
+
refreshDocument?(id: string, text: string, meta?: RagRefreshOptions): Promise<void>;
|
|
111
118
|
search(query: string, options?: RagSearchOptions): Promise<RagSearchResult[]>;
|
|
112
119
|
listDocuments(): Promise<RagDocumentMeta[]>;
|
|
113
120
|
removeDocument(id: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Extracts
|
|
2
|
+
* Extracts embedding-ready text or Markdown from upload formats.
|
|
3
3
|
*
|
|
4
4
|
* Text and CSV are handled inline (CSV uses a RAG-optimized format that
|
|
5
5
|
* denormalizes headers into every row). All other formats (PDF, DOCX, XLSX,
|
|
6
|
-
* PPTX, HTML, RTF, EPUB, etc.) are delegated to the `DocumentExtractor`
|
|
7
|
-
* contract, which owns kreuzberg and
|
|
6
|
+
* PPTX, HTML, RTF, EPUB, etc.) are delegated to the `DocumentExtractor`
|
|
7
|
+
* extension contract, which owns kreuzberg, Markdown extraction, and Worker
|
|
8
|
+
* isolation on Deno.
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
10
11
|
* ```ts
|
|
11
|
-
* const
|
|
12
|
+
* const markdown = await loadUpload(buffer, "application/pdf");
|
|
12
13
|
* ```
|
|
13
14
|
*/
|
|
14
15
|
export declare function loadUpload(buffer: ArrayBuffer, mimeType: string): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-loader.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/upload-loader.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"upload-loader.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/upload-loader.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BvF"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { tryResolve } from "../extensions/contracts.js";
|
|
2
2
|
/**
|
|
3
|
-
* Extracts
|
|
3
|
+
* Extracts embedding-ready text or Markdown from upload formats.
|
|
4
4
|
*
|
|
5
5
|
* Text and CSV are handled inline (CSV uses a RAG-optimized format that
|
|
6
6
|
* denormalizes headers into every row). All other formats (PDF, DOCX, XLSX,
|
|
7
|
-
* PPTX, HTML, RTF, EPUB, etc.) are delegated to the `DocumentExtractor`
|
|
8
|
-
* contract, which owns kreuzberg and
|
|
7
|
+
* PPTX, HTML, RTF, EPUB, etc.) are delegated to the `DocumentExtractor`
|
|
8
|
+
* extension contract, which owns kreuzberg, Markdown extraction, and Worker
|
|
9
|
+
* isolation on Deno.
|
|
9
10
|
*
|
|
10
11
|
* @example
|
|
11
12
|
* ```ts
|
|
12
|
-
* const
|
|
13
|
+
* const markdown = await loadUpload(buffer, "application/pdf");
|
|
13
14
|
* ```
|
|
14
15
|
*/
|
|
15
16
|
export async function loadUpload(buffer, mimeType) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../../src/src/embedding/veryfront-cloud/rag-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../../src/src/embedding/veryfront-cloud/rag-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAKV,QAAQ,EACR,cAAc,EACf,MAAM,aAAa,CAAC;AA4ErB,KAAK,2BAA2B,GAAG,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA8kBtE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,2BAA2B,GAAG,QAAQ,CAuI1F"}
|
|
@@ -56,12 +56,26 @@ function buildDocumentFilePath(documentId, type) {
|
|
|
56
56
|
const extension = type?.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
57
57
|
return `${DOCUMENTS_DIR}/${documentId}.${extension || "txt"}`;
|
|
58
58
|
}
|
|
59
|
+
function buildRefreshDocumentFilePath(documentId, type) {
|
|
60
|
+
const extension = type?.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
61
|
+
return `${DOCUMENTS_DIR}/${documentId}.refresh-${dntShim.crypto.randomUUID()}.${extension || "txt"}`;
|
|
62
|
+
}
|
|
59
63
|
function isRecord(value) {
|
|
60
64
|
return typeof value === "object" && value !== null;
|
|
61
65
|
}
|
|
62
66
|
function toStringValue(value, fallback = "") {
|
|
63
67
|
return typeof value === "string" ? value : fallback;
|
|
64
68
|
}
|
|
69
|
+
function toPublicRagDocumentMeta(document) {
|
|
70
|
+
return {
|
|
71
|
+
id: document.id,
|
|
72
|
+
title: document.title,
|
|
73
|
+
source: document.source,
|
|
74
|
+
type: document.type,
|
|
75
|
+
createdAt: document.createdAt,
|
|
76
|
+
url: document.url,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
65
79
|
function buildDocumentChunks(sourceText, chunkTexts, metadata) {
|
|
66
80
|
let searchStart = 0;
|
|
67
81
|
return chunkTexts.map((content, index) => {
|
|
@@ -176,6 +190,7 @@ async function listRagDocuments(context) {
|
|
|
176
190
|
source: doc.source,
|
|
177
191
|
type: doc.type,
|
|
178
192
|
createdAt: new Date(doc.created_at).getTime(),
|
|
193
|
+
filePath: typeof doc.metadata?.filePath === "string" ? doc.metadata.filePath : undefined,
|
|
179
194
|
}));
|
|
180
195
|
}
|
|
181
196
|
async function upsertRagDocument(context, document) {
|
|
@@ -197,6 +212,28 @@ async function deleteRagDocument(context, documentId) {
|
|
|
197
212
|
// Document ingestion (chunks + embeddings + server-side record)
|
|
198
213
|
// ---------------------------------------------------------------------------
|
|
199
214
|
async function ingestDocument(context, config, title, text, meta) {
|
|
215
|
+
const documentId = dntShim.crypto.randomUUID();
|
|
216
|
+
await writeDocumentContent(context, config, documentId, title, text, meta);
|
|
217
|
+
return documentId;
|
|
218
|
+
}
|
|
219
|
+
async function refreshCloudDocument(context, config, documentId, text, meta) {
|
|
220
|
+
const documents = await listRagDocuments(context);
|
|
221
|
+
const existing = documents.find((doc) => doc.id === documentId);
|
|
222
|
+
if (!existing) {
|
|
223
|
+
throw INVALID_ARGUMENT.create({ detail: `RAG document not found: ${documentId}` });
|
|
224
|
+
}
|
|
225
|
+
const type = meta?.type ?? existing.type;
|
|
226
|
+
const previousFilePath = existing.filePath ?? buildDocumentFilePath(documentId, existing.type);
|
|
227
|
+
const filePath = buildRefreshDocumentFilePath(documentId, type);
|
|
228
|
+
await writeDocumentContent(context, config, documentId, meta?.title ?? existing.title, text, {
|
|
229
|
+
source: meta?.source ?? existing.source,
|
|
230
|
+
type,
|
|
231
|
+
}, { filePath });
|
|
232
|
+
if (previousFilePath !== filePath) {
|
|
233
|
+
await deleteFileChunks(context, previousFilePath);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async function writeDocumentContent(context, config, documentId, title, text, meta, options) {
|
|
200
237
|
if (text.length > MAX_TEXT_LENGTH) {
|
|
201
238
|
throw INVALID_ARGUMENT.create({
|
|
202
239
|
detail: `Upload text exceeds ${MAX_TEXT_LENGTH / 1024 / 1024} MB limit`,
|
|
@@ -206,8 +243,7 @@ async function ingestDocument(context, config, title, text, meta) {
|
|
|
206
243
|
if (chunkTexts.length === 0) {
|
|
207
244
|
throw INVALID_ARGUMENT.create({ detail: "Upload contains no extractable text" });
|
|
208
245
|
}
|
|
209
|
-
const
|
|
210
|
-
const filePath = buildDocumentFilePath(documentId, meta?.type);
|
|
246
|
+
const filePath = options?.filePath ?? buildDocumentFilePath(documentId, meta?.type);
|
|
211
247
|
const embedder = createEmbedder(config);
|
|
212
248
|
const vectors = await embedder.embedMany(chunkTexts);
|
|
213
249
|
const dimension = toSupportedDimension(vectors[0]?.length ?? 0);
|
|
@@ -243,7 +279,6 @@ async function ingestDocument(context, config, title, text, meta) {
|
|
|
243
279
|
type: meta?.type ?? "",
|
|
244
280
|
metadata: { filePath },
|
|
245
281
|
});
|
|
246
|
-
return documentId;
|
|
247
282
|
}
|
|
248
283
|
function createEmbedder(config) {
|
|
249
284
|
return embedding({
|
|
@@ -340,6 +375,10 @@ export function createVeryfrontCloudRagStore(config) {
|
|
|
340
375
|
const context = getCloudStoreContext(config);
|
|
341
376
|
return ingestDocument(context, config, title, text, meta);
|
|
342
377
|
},
|
|
378
|
+
async refreshDocument(id, text, meta) {
|
|
379
|
+
const context = getCloudStoreContext(config);
|
|
380
|
+
await refreshCloudDocument(context, config, id, text, meta);
|
|
381
|
+
},
|
|
343
382
|
async search(query, options) {
|
|
344
383
|
if (!query.trim())
|
|
345
384
|
return [];
|
|
@@ -376,7 +415,8 @@ export function createVeryfrontCloudRagStore(config) {
|
|
|
376
415
|
},
|
|
377
416
|
async listDocuments() {
|
|
378
417
|
const context = getCloudStoreContext(config);
|
|
379
|
-
|
|
418
|
+
const documents = await listRagDocuments(context);
|
|
419
|
+
return documents.map(toPublicRagDocumentMeta);
|
|
380
420
|
},
|
|
381
421
|
async removeDocument(id) {
|
|
382
422
|
const context = getCloudStoreContext(config);
|
|
@@ -387,7 +427,7 @@ export function createVeryfrontCloudRagStore(config) {
|
|
|
387
427
|
await deleteRagDocument(context, id);
|
|
388
428
|
// Best-effort cleanup of file chunks
|
|
389
429
|
if (target) {
|
|
390
|
-
const filePath = buildDocumentFilePath(id, target.type);
|
|
430
|
+
const filePath = target.filePath ?? buildDocumentFilePath(id, target.type);
|
|
391
431
|
try {
|
|
392
432
|
await deleteFileChunks(context, filePath);
|
|
393
433
|
}
|
|
@@ -9,6 +9,13 @@ export interface InjectHTMLContentOptions {
|
|
|
9
9
|
projectDir?: string;
|
|
10
10
|
/** Whether the page has 'use client' directive */
|
|
11
11
|
isClientPage?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Route params from the initial match, seeded into the 'use client' hydration
|
|
14
|
+
* payload so full-HTML-document client pages hydrate with their params
|
|
15
|
+
* instead of an empty object (issue #2741). Catch-all arrays are preserved;
|
|
16
|
+
* the client runtime joins them (issue #2742).
|
|
17
|
+
*/
|
|
18
|
+
params?: Record<string, string | string[]>;
|
|
12
19
|
/** Whether page is embedded in Studio iframe */
|
|
13
20
|
studioEmbed?: boolean;
|
|
14
21
|
/** Project ID for Studio communication */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-injection.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-injection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"html-injection.d.ts","sourceRoot":"","sources":["../../../src/src/html/html-injection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAmB/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACvC,+DAA+D;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAgBD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,wBAAwB,GAChC,MAAM,CA6GR"}
|
|
@@ -2,6 +2,7 @@ import { resolveRelativePath } from "../modules/react-loader/path-resolver.js";
|
|
|
2
2
|
import { determineClientModuleStrategy } from "../rendering/rsc/client-module-strategy.js";
|
|
3
3
|
import { generateLinkTags, generateMetaTags, generateScriptTags, generateStyleTags, } from "./tag-generators.js";
|
|
4
4
|
import { buildNonceAttribute } from "./html-escape.js";
|
|
5
|
+
import { jsonForInlineScript } from "../security/client/html-sanitizer.js";
|
|
5
6
|
import { getDevScripts, getDevStyles, getPreviewStylesheetLink, getProdScripts, getStudioScripts, } from "./dev-scripts.js";
|
|
6
7
|
function toProjectRelativePath(absolutePath, projectDir) {
|
|
7
8
|
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
@@ -49,10 +50,15 @@ export function injectHTMLContent(template, content, metadata, options) {
|
|
|
49
50
|
const hasBodyClose = /<\/body>/i.test(html);
|
|
50
51
|
// Inject hydration data for 'use client' pages (before scripts, so client.js can find it)
|
|
51
52
|
if (options.pagePath && options.isClientPage && hasBodyClose) {
|
|
52
|
-
|
|
53
|
+
// Serialize with jsonForInlineScript, not raw JSON.stringify: route params
|
|
54
|
+
// (and slug) are URL-derived and decoded, so a segment like `%3C/script%3E`
|
|
55
|
+
// would otherwise break out of the <script> tag (reflected XSS). This escapes
|
|
56
|
+
// `<`, `>`, `&`, and line separators, matching the main shell hydration path.
|
|
57
|
+
const hydrationData = jsonForInlineScript({
|
|
53
58
|
pagePath: toProjectRelativePath(options.pagePath, options.projectDir),
|
|
54
59
|
slug: options.slug,
|
|
55
60
|
isClientPage: true,
|
|
61
|
+
params: options.params ?? {},
|
|
56
62
|
clientModuleStrategy: determineClientModuleStrategy({
|
|
57
63
|
isLocalProject: options.isLocalProject ?? options.mode === "development",
|
|
58
64
|
environment: options.environment,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../../../src/src/html/hydration-script-builder/templates/renderer.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../../../src/src/html/hydration-script-builder/templates/renderer.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,cA4N7B,CAAC"}
|
|
@@ -112,7 +112,11 @@ export const getRendererScript = () => `
|
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
// Normalize catch-all params (arrays -> joined strings) so the hydrated
|
|
116
|
+
// props and page context match the server render. normalizeRouteParams
|
|
117
|
+
// is defined in router.ts, which loads first (issue #2742).
|
|
118
|
+
const normalizedParams = normalizeRouteParams(data.params);
|
|
119
|
+
const pageProps = { ...(data.props || {}), params: normalizedParams };
|
|
116
120
|
let tree = React.createElement(PageComponent, pageProps);
|
|
117
121
|
|
|
118
122
|
const layouts = data.layouts;
|
|
@@ -143,7 +147,7 @@ export const getRendererScript = () => `
|
|
|
143
147
|
const pageContext = {
|
|
144
148
|
slug: data.slug || '',
|
|
145
149
|
path: data.pagePath || resolvedPathname,
|
|
146
|
-
params:
|
|
150
|
+
params: normalizedParams,
|
|
147
151
|
query: Object.fromEntries(new URLSearchParams(window.location.search)),
|
|
148
152
|
frontmatter: data.frontmatter || {},
|
|
149
153
|
headings,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../../../src/src/html/hydration-script-builder/templates/router.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../../../src/src/html/hydration-script-builder/templates/router.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,cA2nC3B,CAAC"}
|
|
@@ -604,13 +604,18 @@ export const getRouterScript = () => `
|
|
|
604
604
|
window.history.pushState({ pageData, scrollY: 0 }, '', href);
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
607
|
+
// Update the shared router snapshot BEFORE rendering. RouterProvider
|
|
608
|
+
// reads router.params during render, so mutating after renderPageFromData
|
|
609
|
+
// would leave the new page's first render with the previous route's
|
|
610
|
+
// params (issue #2741). pathname/query move up for the same reason.
|
|
611
611
|
currentPath = targetPath;
|
|
612
612
|
window.__veryfrontRouter.pathname = targetPath;
|
|
613
613
|
window.__veryfrontRouter.query = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
614
|
+
window.__veryfrontRouter.params = normalizeRouteParams(pageData.params);
|
|
615
|
+
|
|
616
|
+
perfStart('nav:render:' + href);
|
|
617
|
+
await renderPageFromData(pageData, targetPath);
|
|
618
|
+
perfEnd('nav:render:' + href);
|
|
614
619
|
|
|
615
620
|
if (restoreScroll) {
|
|
616
621
|
restoreScrollPosition(targetPath);
|
|
@@ -708,9 +713,15 @@ export const getRouterScript = () => `
|
|
|
708
713
|
}
|
|
709
714
|
}
|
|
710
715
|
|
|
716
|
+
// Normalize catch-all params (arrays -> joined strings) so page props and
|
|
717
|
+
// page context match the server render exactly. SSR emits joined strings
|
|
718
|
+
// via flattenRouteParams; without this the client would hand raw arrays to
|
|
719
|
+
// props and usePageContext() after navigation (issue #2742).
|
|
720
|
+
const normalizedParams = normalizeRouteParams(pageData.params);
|
|
721
|
+
|
|
711
722
|
let tree = React.createElement(PageComponent, {
|
|
712
723
|
...pageData.props,
|
|
713
|
-
params:
|
|
724
|
+
params: normalizedParams
|
|
714
725
|
});
|
|
715
726
|
|
|
716
727
|
if (pageData.layouts?.length) {
|
|
@@ -733,7 +744,7 @@ export const getRouterScript = () => `
|
|
|
733
744
|
const pageContext = {
|
|
734
745
|
slug: pageData.slug || '',
|
|
735
746
|
path: pageData.pagePath || targetPath,
|
|
736
|
-
params:
|
|
747
|
+
params: normalizedParams,
|
|
737
748
|
query: Object.fromEntries(new URLSearchParams(window.location.search)),
|
|
738
749
|
frontmatter: pageData.frontmatter || {},
|
|
739
750
|
headings: headingsArray,
|
|
@@ -951,6 +962,22 @@ export const getRouterScript = () => `
|
|
|
951
962
|
}, IDLE_PREFETCH_DELAY_MS);
|
|
952
963
|
}
|
|
953
964
|
|
|
965
|
+
// ============================================
|
|
966
|
+
// Route params normalization
|
|
967
|
+
// ============================================
|
|
968
|
+
// Catch-all segments arrive as arrays and are joined so no path info is
|
|
969
|
+
// lost, matching the server flattenRouteParams + RSC hydration normalizer.
|
|
970
|
+
function normalizeRouteParams(raw) {
|
|
971
|
+
const out = {};
|
|
972
|
+
if (!raw) return out;
|
|
973
|
+
for (const key in raw) {
|
|
974
|
+
const value = raw[key];
|
|
975
|
+
if (value === undefined) continue;
|
|
976
|
+
out[key] = Array.isArray(value) ? value.join('/') : value;
|
|
977
|
+
}
|
|
978
|
+
return out;
|
|
979
|
+
}
|
|
980
|
+
|
|
954
981
|
// ============================================
|
|
955
982
|
// Router object
|
|
956
983
|
// ============================================
|
|
@@ -974,7 +1001,17 @@ export const getRouterScript = () => `
|
|
|
974
1001
|
},
|
|
975
1002
|
pathname: window.location.pathname,
|
|
976
1003
|
query: Object.fromEntries(new URLSearchParams(window.location.search)),
|
|
977
|
-
params
|
|
1004
|
+
// Seed route params from the hydration data (issue #2741). Catch-all
|
|
1005
|
+
// segments arrive as arrays and are joined so no path info is lost.
|
|
1006
|
+
params: (function () {
|
|
1007
|
+
try {
|
|
1008
|
+
const el = document.getElementById('veryfront-hydration-data');
|
|
1009
|
+
const raw = (JSON.parse(el && el.textContent ? el.textContent : '{}') || {}).params || {};
|
|
1010
|
+
return normalizeRouteParams(raw);
|
|
1011
|
+
} catch (_) {
|
|
1012
|
+
return {};
|
|
1013
|
+
}
|
|
1014
|
+
})(),
|
|
978
1015
|
isPreview: false,
|
|
979
1016
|
isMounted: true,
|
|
980
1017
|
navigate: (path) => navigateSPA(path, true),
|
|
@@ -999,10 +1036,14 @@ export const getRouterScript = () => `
|
|
|
999
1036
|
|
|
1000
1037
|
showNavigationProgress();
|
|
1001
1038
|
try {
|
|
1002
|
-
|
|
1039
|
+
// Update the router snapshot before rendering so RouterProvider reads
|
|
1040
|
+
// this route's params, not the previous route's (issue #2741).
|
|
1003
1041
|
currentPath = path;
|
|
1004
1042
|
window.__veryfrontRouter.pathname = path;
|
|
1005
1043
|
window.__veryfrontRouter.query = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
1044
|
+
window.__veryfrontRouter.params = normalizeRouteParams(e.state.pageData.params);
|
|
1045
|
+
|
|
1046
|
+
await renderPageFromData(e.state.pageData, path);
|
|
1006
1047
|
|
|
1007
1048
|
restoreScrollPosition(path);
|
|
1008
1049
|
hideNavigationProgress();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-applicator.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/layouts/layout-applicator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layout-applicator.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/layouts/layout-applicator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAKzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAiBxE,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,oBAAoB,CAAC;IAClC,gBAAgB,EAAE,aAAa,CAAC;IAChC,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,MAAM,CAAC,CAAoC;IACnD,OAAO,CAAC,WAAW,CAAC,CAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAC,CAAqD;IACtE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,kBAAkB,CAAC,CAAyB;IACpD,OAAO,CAAC,+BAA+B,CAAC,CAGrC;gBAES,OAAO,EAAE,wBAAwB;IAiBvC,YAAY,CAChB,WAAW,EAAE,YAAY,CAAC,YAAY,EACtC,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,SAAS,GAAG,SAAS,EACnC,aAAa,EAAE,UAAU,EAAE,EAC3B,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACnD,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC;YAyFvB,gBAAgB;YAuDhB,sBAAsB;YAWtB,8BAA8B;YA4D9B,oBAAoB;YAqDpB,mBAAmB;YAuCnB,0BAA0B;CAgEzC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { dirname, join } from "../../platform/compat/path/index.js";
|
|
2
2
|
import { rendererLogger } from "../../utils/index.js";
|
|
3
|
+
import { flattenRouteParams } from "../../routing/index.js";
|
|
3
4
|
import { withSpan } from "../../observability/tracing/otlp-setup.js";
|
|
4
5
|
import { SpanNames } from "../../observability/tracing/span-names.js";
|
|
5
6
|
import { resolve as resolveContract } from "../../extensions/contracts.js";
|
|
@@ -66,11 +67,7 @@ export class LayoutApplicator {
|
|
|
66
67
|
}
|
|
67
68
|
const React = await getProjectReact();
|
|
68
69
|
const headingsArray = this.headings ?? [];
|
|
69
|
-
const flatParams = this.params
|
|
70
|
-
? Object.fromEntries(Object.entries(this.params)
|
|
71
|
-
.map(([key, value]) => [key, Array.isArray(value) ? value[0] : value])
|
|
72
|
-
.filter((entry) => entry[1] !== undefined))
|
|
73
|
-
: {};
|
|
70
|
+
const flatParams = flattenRouteParams(this.params);
|
|
74
71
|
const query = this.requestUrl ? Object.fromEntries(this.requestUrl.searchParams) : {};
|
|
75
72
|
const pageContext = {
|
|
76
73
|
slug: pageInfo.entity.slug || "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAClF,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA+FlF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAIjC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BjE,kBAAkB,CACtB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,cAAc,CAAC;YAqEZ,sBAAsB;
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAClF,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA+FlF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAIjC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BjE,kBAAkB,CACtB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,cAAc,CAAC;YAqEZ,sBAAsB;YAwDtB,4BAA4B;YAiB5B,wBAAwB;YAmBxB,gBAAgB;YAyBhB,kBAAkB;IAwDhC,OAAO,CAAC,cAAc;YAQR,eAAe;YAaf,gBAAgB;IAoF9B;;;;OAIG;YACW,gBAAgB;CAc/B"}
|
|
@@ -163,6 +163,7 @@ export class HTMLGenerator {
|
|
|
163
163
|
pagePath,
|
|
164
164
|
projectDir: this.config.projectDir,
|
|
165
165
|
isClientPage,
|
|
166
|
+
params: context.options?.params,
|
|
166
167
|
environment: context.options?.environment,
|
|
167
168
|
isLocalProject: this.config.mode === "development",
|
|
168
169
|
nonce: context.options?.nonce,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-rendering.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/page-rendering.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"page-rendering.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/page-rendering.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,mBAAmB,CAAC;AASrG,UAAU,aAAa;IACrB,WAAW,EAAE,YAAY,CAAC,YAAY,CAAC;IACvC,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,UAAU,sBAAsB;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,0BAA0B;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAInE;AAED,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,UAAU,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IACR,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC,sBAAsB,CAAC,CA4CjC;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,aAAa,EAC/B,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,SAAS,CAAC,EACvB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,aAAa,CAAC,CAmHxB"}
|
|
@@ -3,6 +3,7 @@ import { RENDER_ERROR } from "../errors/error-registry.js";
|
|
|
3
3
|
import { mdxRenderer } from "../transforms/mdx/index.js";
|
|
4
4
|
import { clearMdxEsmCacheNamespace } from "../transforms/mdx/esm-module-loader/index.js";
|
|
5
5
|
import { getProjectReact } from "../react/index.js";
|
|
6
|
+
import { flattenRouteParams } from "../routing/index.js";
|
|
6
7
|
import { compileContent } from "../transforms/mdx/compiler/index.js";
|
|
7
8
|
import { ensureError, getErrorMessage } from "../errors/veryfront-error.js";
|
|
8
9
|
import { withSpan } from "../observability/tracing/otlp-setup.js";
|
|
@@ -77,11 +78,7 @@ export function handleMDXPage(pageInfo, slug, projectDir, mergedComponents, _com
|
|
|
77
78
|
}
|
|
78
79
|
if (typeof mod.generateMetadata === "function") {
|
|
79
80
|
try {
|
|
80
|
-
const params = options?.params
|
|
81
|
-
? Object.fromEntries(Object.entries(options.params)
|
|
82
|
-
.map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])
|
|
83
|
-
.filter((entry) => entry[1] !== undefined))
|
|
84
|
-
: {};
|
|
81
|
+
const params = flattenRouteParams(options?.params);
|
|
85
82
|
const query = options?.url ? Object.fromEntries(options.url.searchParams) : {};
|
|
86
83
|
const gen = await mod.generateMetadata({
|
|
87
84
|
params,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-page-handling.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/script-page-handling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"script-page-handling.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/script-page-handling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EAGV,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAenE,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+GD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,YAAY,CAAC,CAiDvB"}
|
|
@@ -9,6 +9,7 @@ import { rewriteNpmImports } from "../transforms/npm-import-rewrites.js";
|
|
|
9
9
|
import { dirname, join } from "../platform/compat/path/index.js";
|
|
10
10
|
import { cwd } from "../platform/compat/process.js";
|
|
11
11
|
import { RENDER_ERROR } from "../errors/error-registry.js";
|
|
12
|
+
import { flattenRouteParams } from "../routing/index.js";
|
|
12
13
|
import { createError, toError } from "../errors/veryfront-error.js";
|
|
13
14
|
import { computeHash } from "./utils/index.js";
|
|
14
15
|
import { wrapInHTMLShell } from "../html/index.js";
|
|
@@ -75,11 +76,7 @@ function extractHtmlAndMetadata(output) {
|
|
|
75
76
|
}));
|
|
76
77
|
}
|
|
77
78
|
function buildPageContext(pageInfo, slug, params, url) {
|
|
78
|
-
const flatParams = params
|
|
79
|
-
? Object.fromEntries(Object.entries(params)
|
|
80
|
-
.map(([k, v]) => [k, Array.isArray(v) ? v[0] : v])
|
|
81
|
-
.filter((entry) => entry[1] !== undefined))
|
|
82
|
-
: {};
|
|
79
|
+
const flatParams = flattenRouteParams(params);
|
|
83
80
|
return {
|
|
84
81
|
params: flatParams,
|
|
85
82
|
query: url ? Object.fromEntries(url.searchParams) : {},
|
|
@@ -16,5 +16,9 @@ export interface APIContext {
|
|
|
16
16
|
fs: FileSystemAdapter;
|
|
17
17
|
}
|
|
18
18
|
export declare function createContext(request: Request, match: RouteMatch, fs: FileSystemAdapter): APIContext;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Use {@link flattenRouteParams} directly. Kept as a thin alias so
|
|
21
|
+
* the routing barrel exposes a single flattener implementation (issue #2742).
|
|
22
|
+
*/
|
|
19
23
|
export declare function normalizeParams(params: Record<string, string | string[]>): Record<string, string>;
|
|
20
24
|
//# sourceMappingURL=context-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/src/routing/api/context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/src/routing/api/context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,QAAQ,CAAC;IACvD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,KAAK,QAAQ,CAAC;IACtD,EAAE,EAAE,iBAAiB,CAAC;CACvB;AAgBD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,iBAAiB,GACpB,UAAU,CAmBZ;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseCookies } from "../../utils/cookie-utils.js";
|
|
2
|
+
import { flattenRouteParams } from "../flatten-route-params.js";
|
|
2
3
|
export { parseCookies };
|
|
3
4
|
function createResponse(body, contentType, init) {
|
|
4
5
|
return new Response(body, {
|
|
@@ -26,10 +27,10 @@ export function createContext(request, match, fs) {
|
|
|
26
27
|
fs,
|
|
27
28
|
};
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use {@link flattenRouteParams} directly. Kept as a thin alias so
|
|
32
|
+
* the routing barrel exposes a single flattener implementation (issue #2742).
|
|
33
|
+
*/
|
|
29
34
|
export function normalizeParams(params) {
|
|
30
|
-
|
|
31
|
-
for (const [key, value] of Object.entries(params)) {
|
|
32
|
-
out[key] = Array.isArray(value) ? value.join("/") : value;
|
|
33
|
-
}
|
|
34
|
-
return out;
|
|
35
|
+
return flattenRouteParams(params);
|
|
35
36
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens matched route params (which may be arrays for catch-all `[...slug]`
|
|
3
|
+
* segments) into the `Record<string, string>` shape the router value exposes.
|
|
4
|
+
*
|
|
5
|
+
* Catch-all segments are **joined with `/`** so no path information is lost —
|
|
6
|
+
* `/docs/guides/intro` -> `{ slug: "guides/intro" }`, not `{ slug: "guides" }`.
|
|
7
|
+
* This matches the client SPA normalizer and the RSC hydration normalizer, so
|
|
8
|
+
* server and client agree.
|
|
9
|
+
*/
|
|
10
|
+
export declare function flattenRouteParams(params?: Record<string, string | string[]>): Record<string, string>;
|
|
11
|
+
//# sourceMappingURL=flatten-route-params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-route-params.d.ts","sourceRoot":"","sources":["../../../src/src/routing/flatten-route-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flattens matched route params (which may be arrays for catch-all `[...slug]`
|
|
3
|
+
* segments) into the `Record<string, string>` shape the router value exposes.
|
|
4
|
+
*
|
|
5
|
+
* Catch-all segments are **joined with `/`** so no path information is lost —
|
|
6
|
+
* `/docs/guides/intro` -> `{ slug: "guides/intro" }`, not `{ slug: "guides" }`.
|
|
7
|
+
* This matches the client SPA normalizer and the RSC hydration normalizer, so
|
|
8
|
+
* server and client agree.
|
|
9
|
+
*/
|
|
10
|
+
export function flattenRouteParams(params) {
|
|
11
|
+
if (!params)
|
|
12
|
+
return {};
|
|
13
|
+
const flat = {};
|
|
14
|
+
for (const [key, value] of Object.entries(params)) {
|
|
15
|
+
if (value === undefined)
|
|
16
|
+
continue;
|
|
17
|
+
flat[key] = Array.isArray(value) ? value.join("/") : value;
|
|
18
|
+
}
|
|
19
|
+
return flat;
|
|
20
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @module routing
|
|
6
6
|
*/
|
|
7
7
|
export type { Route, RouteMatch } from "./matchers/index.js";
|
|
8
|
+
export { flattenRouteParams } from "./flatten-route-params.js";
|
|
8
9
|
export { getSpecificityScore, matchRoute, normalizePath, PageRouteMatcher, parseRoute, } from "./matchers/index.js";
|
|
9
10
|
export type { PathCandidates, RouteParams } from "./slug-mapper/index.js";
|
|
10
11
|
export { extractParams, getPathCandidates, getSlugFromPath, getSupportedExtensions, isDynamicRoute, matchesPattern, normalizeSlug, pathToSlug, slugToPath, } from "./slug-mapper/index.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,GACX,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,aAAa,EACb,UAAU,EACV,UAAU,GACX,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/routing/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,UAAU,GACX,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,aAAa,EACb,UAAU,EACV,UAAU,GACX,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC"}
|
package/esm/src/routing/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module routing
|
|
6
6
|
*/
|
|
7
|
+
export { flattenRouteParams } from "./flatten-route-params.js";
|
|
7
8
|
export { getSpecificityScore, matchRoute, normalizePath, PageRouteMatcher, parseRoute, } from "./matchers/index.js";
|
|
8
9
|
export { extractParams, getPathCandidates, getSlugFromPath, getSupportedExtensions, isDynamicRoute, matchesPattern, normalizeSlug, pathToSlug, slugToPath, } from "./slug-mapper/index.js";
|
|
9
10
|
export { extractPageDataFromScript, NavigationHandlers, PageLoader, PageTransition, ViewportPrefetch, } from "./client/index.js";
|