octocms 0.4.12 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/actions/entries.js +46 -45
- package/dist/admin/actions/entries.js.map +1 -1
- package/dist/admin/actions/files.d.ts +5 -0
- package/dist/admin/actions/files.d.ts.map +1 -1
- package/dist/admin/actions/files.js +48 -9
- package/dist/admin/actions/files.js.map +1 -1
- package/dist/admin/actions/search.js +2 -2
- package/dist/admin/actions/search.js.map +1 -1
- package/dist/agent/embedder.js +1 -1
- package/dist/agent/embedder.js.map +1 -1
- package/dist/agent/index.cjs +118 -41
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/tools/index.js +1 -1
- package/dist/agent/tools/index.js.map +1 -1
- package/dist/chunk-NAHOP7TG.js +7 -0
- package/dist/{chunk-L27J3XWV.js.map → chunk-NAHOP7TG.js.map} +1 -1
- package/dist/{chunk-TG624CCO.js → chunk-ZYUK2J5L.js} +4 -43
- package/dist/chunk-ZYUK2J5L.js.map +1 -0
- package/dist/cli/index.js +6 -6
- package/dist/cli/lib/codegen.d.ts +2 -8
- package/dist/cli/lib/codegen.d.ts.map +1 -1
- package/dist/cli/lib/codegen.js +11 -18
- package/dist/cli/lib/codegen.js.map +1 -1
- package/dist/cli/lib/project.js +2 -41
- package/dist/cli/lib/project.js.map +1 -1
- package/dist/components/FormReferenceField.d.ts.map +1 -1
- package/dist/components/FormReferenceField.js +1 -1
- package/dist/components/FormReferenceField.js.map +1 -1
- package/dist/{embeddingsGen-7MXSZQ43.js → embeddingsGen-FXWCPGB7.js} +39 -8
- package/dist/embeddingsGen-FXWCPGB7.js.map +1 -0
- package/dist/index.cjs +88 -68
- package/dist/index.cjs.map +1 -1
- package/dist/{init-N6K464EZ.js → init-KWH66PKY.js} +2 -2
- package/dist/lib/localReader.d.ts +13 -0
- package/dist/lib/localReader.d.ts.map +1 -1
- package/dist/lib/localReader.js +20 -0
- package/dist/lib/localReader.js.map +1 -1
- package/dist/lib/publicSearchIndex.d.ts.map +1 -1
- package/dist/lib/publicSearchIndex.js +2 -2
- package/dist/lib/publicSearchIndex.js.map +1 -1
- package/dist/query.cjs +88 -68
- package/dist/query.cjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/{typesGen-EYRZAA56.js → typesGen-MFAL3B4V.js} +32 -6
- package/dist/typesGen-MFAL3B4V.js.map +1 -0
- package/dist/{validate-6AFW6U2X.js → validate-AAW4IGWD.js} +2 -2
- package/package.json +1 -1
- package/dist/admin/consts.d.ts +0 -3
- package/dist/admin/consts.d.ts.map +0 -1
- package/dist/admin/consts.js +0 -24
- package/dist/admin/consts.js.map +0 -1
- package/dist/chunk-L27J3XWV.js +0 -7
- package/dist/chunk-TG624CCO.js.map +0 -1
- package/dist/embeddingsGen-7MXSZQ43.js.map +0 -1
- package/dist/typesGen-EYRZAA56.js.map +0 -1
- /package/dist/{init-N6K464EZ.js.map → init-KWH66PKY.js.map} +0 -0
- /package/dist/{validate-6AFW6U2X.js.map → validate-AAW4IGWD.js.map} +0 -0
package/dist/agent/index.cjs
CHANGED
|
@@ -270,7 +270,7 @@ var init_embedder = __esm({
|
|
|
270
270
|
const msg = e instanceof Error ? e.message : String(e);
|
|
271
271
|
if (/libonnxruntime|onnxruntime-node|ERR_DLOPEN_FAILED/i.test(msg)) {
|
|
272
272
|
throw new Error(
|
|
273
|
-
`Embeddings unavailable: '@huggingface/transformers' loaded but its native dependency 'onnxruntime-node' could not load (${msg}). On Vercel, add './node_modules/onnxruntime-node/**' to 'outputFileTracingIncludes' for the relevant routes, or rely on offline '
|
|
273
|
+
`Embeddings unavailable: '@huggingface/transformers' loaded but its native dependency 'onnxruntime-node' could not load (${msg}). On Vercel, add './node_modules/onnxruntime-node/**' to 'outputFileTracingIncludes' for the relevant routes, or rely on offline 'npx octocms embeddings:gen'.`
|
|
274
274
|
);
|
|
275
275
|
}
|
|
276
276
|
throw new Error(
|
|
@@ -1626,6 +1626,44 @@ var init_registerConfig = __esm({
|
|
|
1626
1626
|
}
|
|
1627
1627
|
});
|
|
1628
1628
|
|
|
1629
|
+
// lib/localReader.ts
|
|
1630
|
+
async function listLocalFilesRecursive(dirPath, ext) {
|
|
1631
|
+
return listLocalFilesWithExtensions(dirPath, [ext], true);
|
|
1632
|
+
}
|
|
1633
|
+
async function listLocalFilesWithExtensions(dirPath, extensions, recursive = false) {
|
|
1634
|
+
const fullDir = import_path4.default.join(process.cwd(), dirPath);
|
|
1635
|
+
const normalizedExts = extensions.map((e) => e.startsWith(".") ? e : `.${e}`);
|
|
1636
|
+
try {
|
|
1637
|
+
if (recursive) {
|
|
1638
|
+
const names = await import_promises.default.readdir(fullDir, { recursive: true });
|
|
1639
|
+
return names.filter((n) => normalizedExts.some((e) => n.endsWith(e))).map((n) => `${dirPath}/${n}`.replace(/\\/g, "/")).sort();
|
|
1640
|
+
}
|
|
1641
|
+
const entries = await import_promises.default.readdir(fullDir, { withFileTypes: true });
|
|
1642
|
+
return entries.filter((e) => e.isFile() && normalizedExts.some((ext) => e.name.endsWith(ext))).map((e) => `${dirPath}/${e.name}`).sort();
|
|
1643
|
+
} catch (error) {
|
|
1644
|
+
if ((error == null ? void 0 : error.code) === "ENOENT") return [];
|
|
1645
|
+
throw error;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
async function listLocalCollectionFiles(dirPath) {
|
|
1649
|
+
const fullDir = import_path4.default.join(process.cwd(), dirPath);
|
|
1650
|
+
try {
|
|
1651
|
+
const entries = await import_promises.default.readdir(fullDir, { withFileTypes: true });
|
|
1652
|
+
return entries.filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => `${dirPath}/${e.name}`);
|
|
1653
|
+
} catch (error) {
|
|
1654
|
+
if ((error == null ? void 0 : error.code) === "ENOENT") return [];
|
|
1655
|
+
throw error;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
var import_promises, import_path4;
|
|
1659
|
+
var init_localReader = __esm({
|
|
1660
|
+
"lib/localReader.ts"() {
|
|
1661
|
+
"use strict";
|
|
1662
|
+
import_promises = __toESM(require("fs/promises"), 1);
|
|
1663
|
+
import_path4 = __toESM(require("path"), 1);
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
|
|
1629
1667
|
// lib/branchHistory.ts
|
|
1630
1668
|
var import_zod, BRANCH_HISTORY_FILE_PATH, branchWorkspaceSchema, rootSchema, parseBranchHistoryFile, serializeBranchHistoryFile, appendEntryPathToBranch, mergeHistoryContentWithAppendedEntry;
|
|
1631
1669
|
var init_branchHistory = __esm({
|
|
@@ -2758,9 +2796,9 @@ async function getStoredContentFiles(collection, branch) {
|
|
|
2758
2796
|
if (!store) return null;
|
|
2759
2797
|
if (collection === "**") {
|
|
2760
2798
|
const all = [];
|
|
2761
|
-
for (const [
|
|
2762
|
-
if (
|
|
2763
|
-
all.push(
|
|
2799
|
+
for (const [path6] of store.entries) {
|
|
2800
|
+
if (path6.endsWith(".json")) {
|
|
2801
|
+
all.push(path6);
|
|
2764
2802
|
}
|
|
2765
2803
|
}
|
|
2766
2804
|
return all;
|
|
@@ -2898,6 +2936,7 @@ __export(files_exports, {
|
|
|
2898
2936
|
assertFeatureBranchForWritesIfRequired: () => assertFeatureBranchForWritesIfRequired,
|
|
2899
2937
|
getContentFiles: () => getContentFiles,
|
|
2900
2938
|
getFile: () => getFile,
|
|
2939
|
+
getFileJson: () => getFileJson,
|
|
2901
2940
|
getMediaContentFiles: () => getMediaContentFiles,
|
|
2902
2941
|
getMediaFiles: () => getMediaFiles,
|
|
2903
2942
|
newFile: () => newFile,
|
|
@@ -2938,14 +2977,14 @@ async function persistBranchHistoryEntryIfNeeded(activeBranch, entryPath) {
|
|
|
2938
2977
|
return;
|
|
2939
2978
|
}
|
|
2940
2979
|
try {
|
|
2941
|
-
const abs =
|
|
2980
|
+
const abs = import_path5.default.join(
|
|
2942
2981
|
/*turbopackIgnore: true*/
|
|
2943
2982
|
process.cwd(),
|
|
2944
2983
|
BRANCH_HISTORY_FILE_PATH
|
|
2945
2984
|
);
|
|
2946
2985
|
let raw = "";
|
|
2947
2986
|
try {
|
|
2948
|
-
raw = await
|
|
2987
|
+
raw = await import_promises2.default.readFile(abs, { encoding: "utf8" });
|
|
2949
2988
|
} catch (e) {
|
|
2950
2989
|
raw = "";
|
|
2951
2990
|
}
|
|
@@ -2953,8 +2992,8 @@ async function persistBranchHistoryEntryIfNeeded(activeBranch, entryPath) {
|
|
|
2953
2992
|
if (next == null) {
|
|
2954
2993
|
return;
|
|
2955
2994
|
}
|
|
2956
|
-
await
|
|
2957
|
-
await
|
|
2995
|
+
await import_promises2.default.mkdir(import_path5.default.dirname(abs), { recursive: true });
|
|
2996
|
+
await import_promises2.default.writeFile(abs, next, "utf8");
|
|
2958
2997
|
} catch (e) {
|
|
2959
2998
|
}
|
|
2960
2999
|
}
|
|
@@ -3066,7 +3105,7 @@ async function readCompanionMarkdownContent(filePath) {
|
|
|
3066
3105
|
}
|
|
3067
3106
|
}
|
|
3068
3107
|
try {
|
|
3069
|
-
return await
|
|
3108
|
+
return await import_promises2.default.readFile(import_path5.default.join(
|
|
3070
3109
|
/*turbopackIgnore: true*/
|
|
3071
3110
|
process.cwd(),
|
|
3072
3111
|
filePath
|
|
@@ -3077,17 +3116,17 @@ async function readCompanionMarkdownContent(filePath) {
|
|
|
3077
3116
|
return "";
|
|
3078
3117
|
}
|
|
3079
3118
|
}
|
|
3080
|
-
var
|
|
3119
|
+
var import_promises2, import_path5, import_headers, CMS_ACTIVE_BRANCH_COOKIE, MEDIA_UUID_RE, assertFeatureBranchForWritesIfRequired, waitForPublicReadConsistency, getContentFiles, getMediaContentFiles, getMediaFiles, getFileJson, getFile, saveFile, newFile, removeFile;
|
|
3081
3120
|
var init_files = __esm({
|
|
3082
3121
|
"admin/actions/files.ts"() {
|
|
3083
3122
|
"use strict";
|
|
3084
3123
|
"use server";
|
|
3085
3124
|
init_registerConfig();
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
import_glob = require("glob");
|
|
3125
|
+
import_promises2 = __toESM(require("fs/promises"), 1);
|
|
3126
|
+
import_path5 = __toESM(require("path"), 1);
|
|
3089
3127
|
import_headers = require("next/headers");
|
|
3090
3128
|
init_configStore2();
|
|
3129
|
+
init_localReader();
|
|
3091
3130
|
init_configStore();
|
|
3092
3131
|
init_embeddingsHook();
|
|
3093
3132
|
init_branchHistory();
|
|
@@ -3154,8 +3193,10 @@ var init_files = __esm({
|
|
|
3154
3193
|
} catch (e) {
|
|
3155
3194
|
}
|
|
3156
3195
|
}
|
|
3157
|
-
|
|
3158
|
-
|
|
3196
|
+
if (collection === "**") {
|
|
3197
|
+
return await listLocalFilesRecursive(config.contentFolder, ".json");
|
|
3198
|
+
}
|
|
3199
|
+
return await listLocalCollectionFiles(`${config.contentFolder}/${collection}`);
|
|
3159
3200
|
} catch (e) {
|
|
3160
3201
|
return [];
|
|
3161
3202
|
}
|
|
@@ -3171,8 +3212,7 @@ var init_files = __esm({
|
|
|
3171
3212
|
} catch (_e) {
|
|
3172
3213
|
}
|
|
3173
3214
|
}
|
|
3174
|
-
|
|
3175
|
-
return files || [];
|
|
3215
|
+
return await listLocalCollectionFiles(folder);
|
|
3176
3216
|
} catch (_e) {
|
|
3177
3217
|
return [];
|
|
3178
3218
|
}
|
|
@@ -3184,19 +3224,56 @@ var init_files = __esm({
|
|
|
3184
3224
|
if (isProductionMode()) {
|
|
3185
3225
|
const activeBranch = (_a = (await (0, import_headers.cookies)()).get(CMS_ACTIVE_BRANCH_COOKIE)) == null ? void 0 : _a.value;
|
|
3186
3226
|
try {
|
|
3187
|
-
const
|
|
3188
|
-
const allFiles = await listGitHubFilesRecursive(
|
|
3227
|
+
const dir2 = folder === "**" ? config.mediaFolder : `${config.mediaFolder}/${folder}`;
|
|
3228
|
+
const allFiles = await listGitHubFilesRecursive(dir2, void 0, activeBranch);
|
|
3189
3229
|
const extensions = config.mediaAllowedFormats;
|
|
3190
3230
|
return allFiles.filter((f) => extensions.some((ext) => f.endsWith(`.${ext}`)));
|
|
3191
3231
|
} catch (e) {
|
|
3192
3232
|
}
|
|
3193
3233
|
}
|
|
3194
|
-
const
|
|
3195
|
-
return
|
|
3234
|
+
const dir = folder === "**" ? config.mediaFolder : `${config.mediaFolder}/${folder}`;
|
|
3235
|
+
return await listLocalFilesWithExtensions(dir, config.mediaAllowedFormats, folder === "**");
|
|
3196
3236
|
} catch (e) {
|
|
3197
3237
|
return [];
|
|
3198
3238
|
}
|
|
3199
3239
|
};
|
|
3240
|
+
getFileJson = async (fileName) => {
|
|
3241
|
+
var _a;
|
|
3242
|
+
if (isProductionMode()) {
|
|
3243
|
+
let activeBranch;
|
|
3244
|
+
try {
|
|
3245
|
+
activeBranch = (_a = (await (0, import_headers.cookies)()).get(CMS_ACTIVE_BRANCH_COOKIE)) == null ? void 0 : _a.value;
|
|
3246
|
+
} catch (e) {
|
|
3247
|
+
}
|
|
3248
|
+
try {
|
|
3249
|
+
const stored = await getStoredFile(fileName, activeBranch);
|
|
3250
|
+
if (stored) return structuredClone(stored.content);
|
|
3251
|
+
} catch (e) {
|
|
3252
|
+
}
|
|
3253
|
+
try {
|
|
3254
|
+
const result = await getGitHubFile(fileName, activeBranch);
|
|
3255
|
+
if (result) return JSON.parse(result.content);
|
|
3256
|
+
} catch (e) {
|
|
3257
|
+
}
|
|
3258
|
+
try {
|
|
3259
|
+
const raw = await readGitHubFilePublic(fileName, activeBranch);
|
|
3260
|
+
if (raw) return JSON.parse(raw);
|
|
3261
|
+
} catch (e) {
|
|
3262
|
+
}
|
|
3263
|
+
return null;
|
|
3264
|
+
}
|
|
3265
|
+
try {
|
|
3266
|
+
const filePath = import_path5.default.join(
|
|
3267
|
+
/*turbopackIgnore: true*/
|
|
3268
|
+
process.cwd(),
|
|
3269
|
+
fileName
|
|
3270
|
+
);
|
|
3271
|
+
const data = await import_promises2.default.readFile(filePath, { encoding: "utf8" });
|
|
3272
|
+
return JSON.parse(data);
|
|
3273
|
+
} catch (e) {
|
|
3274
|
+
return null;
|
|
3275
|
+
}
|
|
3276
|
+
};
|
|
3200
3277
|
getFile = async (fileName) => {
|
|
3201
3278
|
var _a, _b, _c, _d;
|
|
3202
3279
|
const config = getConfig();
|
|
@@ -3240,12 +3317,12 @@ var init_files = __esm({
|
|
|
3240
3317
|
if (isProductionMode()) {
|
|
3241
3318
|
return {};
|
|
3242
3319
|
}
|
|
3243
|
-
const filePath =
|
|
3320
|
+
const filePath = import_path5.default.join(
|
|
3244
3321
|
/*turbopackIgnore: true*/
|
|
3245
3322
|
process.cwd(),
|
|
3246
3323
|
fileName
|
|
3247
3324
|
);
|
|
3248
|
-
const data = await
|
|
3325
|
+
const data = await import_promises2.default.readFile(filePath, { encoding: "utf8" });
|
|
3249
3326
|
entry = JSON.parse(data);
|
|
3250
3327
|
}
|
|
3251
3328
|
if (!entry) {
|
|
@@ -3372,16 +3449,16 @@ var init_files = __esm({
|
|
|
3372
3449
|
}
|
|
3373
3450
|
const cookieStore = await (0, import_headers.cookies)();
|
|
3374
3451
|
const activeBranchDev = (_l = cookieStore.get(CMS_ACTIVE_BRANCH_COOKIE)) == null ? void 0 : _l.value;
|
|
3375
|
-
const filePath =
|
|
3452
|
+
const filePath = import_path5.default.join(
|
|
3376
3453
|
/*turbopackIgnore: true*/
|
|
3377
3454
|
process.cwd(),
|
|
3378
3455
|
fileName
|
|
3379
3456
|
);
|
|
3380
|
-
await
|
|
3457
|
+
await import_promises2.default.writeFile(filePath, normalizedData, "utf8");
|
|
3381
3458
|
const mdPaths = typeof entryType === "string" ? companionMarkdownPathsForEntry(fileName, entryType, config.collections) : {};
|
|
3382
3459
|
for (const [fieldName, mdPath] of Object.entries(mdPaths)) {
|
|
3383
3460
|
const mdContent = (_m = markdownContents[fieldName]) != null ? _m : "";
|
|
3384
|
-
await
|
|
3461
|
+
await import_promises2.default.writeFile(import_path5.default.join(
|
|
3385
3462
|
/*turbopackIgnore: true*/
|
|
3386
3463
|
process.cwd(),
|
|
3387
3464
|
mdPath
|
|
@@ -3390,7 +3467,7 @@ var init_files = __esm({
|
|
|
3390
3467
|
const rtPathsDev = typeof entryType === "string" ? companionRichTextPathsForEntry(fileName, entryType, config.collections) : {};
|
|
3391
3468
|
for (const [fieldName, rtPath] of Object.entries(rtPathsDev)) {
|
|
3392
3469
|
const rtContent = (_n = markdownContents[fieldName]) != null ? _n : "";
|
|
3393
|
-
await
|
|
3470
|
+
await import_promises2.default.writeFile(import_path5.default.join(
|
|
3394
3471
|
/*turbopackIgnore: true*/
|
|
3395
3472
|
process.cwd(),
|
|
3396
3473
|
rtPath
|
|
@@ -3441,13 +3518,13 @@ var init_files = __esm({
|
|
|
3441
3518
|
}
|
|
3442
3519
|
const cookieStore = await (0, import_headers.cookies)();
|
|
3443
3520
|
const activeBranchDev = (_b = cookieStore.get(CMS_ACTIVE_BRANCH_COOKIE)) == null ? void 0 : _b.value;
|
|
3444
|
-
const filePath =
|
|
3521
|
+
const filePath = import_path5.default.join(
|
|
3445
3522
|
/*turbopackIgnore: true*/
|
|
3446
3523
|
process.cwd(),
|
|
3447
3524
|
file
|
|
3448
3525
|
);
|
|
3449
|
-
await
|
|
3450
|
-
await
|
|
3526
|
+
await import_promises2.default.mkdir(import_path5.default.dirname(filePath), { recursive: true });
|
|
3527
|
+
await import_promises2.default.writeFile(filePath, normalizedData, "utf8");
|
|
3451
3528
|
await persistBranchHistoryEntryIfNeeded(activeBranchDev, file);
|
|
3452
3529
|
await syncEmbeddingsForUpsertIfEnabled(file, values, {}, activeBranchDev, false);
|
|
3453
3530
|
const built = await buildJsons(file);
|
|
@@ -3487,15 +3564,15 @@ var init_files = __esm({
|
|
|
3487
3564
|
const built2 = await buildJsons(fileName);
|
|
3488
3565
|
return built2.success ? actionOk() : built2;
|
|
3489
3566
|
}
|
|
3490
|
-
const filePath =
|
|
3567
|
+
const filePath = import_path5.default.join(
|
|
3491
3568
|
/*turbopackIgnore: true*/
|
|
3492
3569
|
process.cwd(),
|
|
3493
3570
|
fileName
|
|
3494
3571
|
);
|
|
3495
|
-
await
|
|
3572
|
+
await import_promises2.default.unlink(filePath);
|
|
3496
3573
|
for (const mdPath of companionPaths) {
|
|
3497
3574
|
try {
|
|
3498
|
-
await
|
|
3575
|
+
await import_promises2.default.unlink(import_path5.default.join(
|
|
3499
3576
|
/*turbopackIgnore: true*/
|
|
3500
3577
|
process.cwd(),
|
|
3501
3578
|
mdPath
|
|
@@ -4289,7 +4366,7 @@ var searchContentTool = {
|
|
|
4289
4366
|
if (hits.length === 0) {
|
|
4290
4367
|
return JSON.stringify({
|
|
4291
4368
|
results: [],
|
|
4292
|
-
note: "No results \u2014 verify the query, or try a broader phrasing. If embeddings.json is missing, run `
|
|
4369
|
+
note: "No results \u2014 verify the query, or try a broader phrasing. If embeddings.json is missing, run `npx octocms embeddings:gen` on your dev machine."
|
|
4293
4370
|
});
|
|
4294
4371
|
}
|
|
4295
4372
|
return JSON.stringify({
|
|
@@ -4622,17 +4699,17 @@ var findEntryForDocumentTool = {
|
|
|
4622
4699
|
}
|
|
4623
4700
|
};
|
|
4624
4701
|
function matchRouteTemplate(template, url) {
|
|
4625
|
-
let
|
|
4626
|
-
const protoIdx =
|
|
4702
|
+
let path6 = url;
|
|
4703
|
+
const protoIdx = path6.indexOf("://");
|
|
4627
4704
|
if (protoIdx !== -1) {
|
|
4628
|
-
const slash =
|
|
4629
|
-
|
|
4705
|
+
const slash = path6.indexOf("/", protoIdx + 3);
|
|
4706
|
+
path6 = slash === -1 ? "/" : path6.slice(slash);
|
|
4630
4707
|
}
|
|
4631
|
-
const queryIdx =
|
|
4632
|
-
if (queryIdx !== -1)
|
|
4708
|
+
const queryIdx = path6.indexOf("?");
|
|
4709
|
+
if (queryIdx !== -1) path6 = path6.slice(0, queryIdx);
|
|
4633
4710
|
const norm = (s) => s.replace(/\/+$/, "") || "/";
|
|
4634
4711
|
const tplParts = norm(template).split("/");
|
|
4635
|
-
const urlParts = norm(
|
|
4712
|
+
const urlParts = norm(path6).split("/");
|
|
4636
4713
|
if (tplParts.length !== urlParts.length) return null;
|
|
4637
4714
|
const out = {};
|
|
4638
4715
|
for (let i = 0; i < tplParts.length; i++) {
|