lula2 0.6.1 → 0.6.2-nightly.1
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/_app/immutable/chunks/D9NS9sy6.js +3 -0
- package/dist/_app/immutable/chunks/{CIUsQQm2.js → DYH881pG.js} +1 -1
- package/dist/_app/immutable/chunks/{C43miErR.js → DsS_Ymqb.js} +1 -1
- package/dist/_app/immutable/entry/{app.DW8m8_kr.js → app.C2_q7ef5.js} +2 -2
- package/dist/_app/immutable/entry/start.CPOuKwpy.js +1 -0
- package/dist/_app/immutable/nodes/{0.DIHiDqse.js → 0.7TiLCc65.js} +1 -1
- package/dist/_app/immutable/nodes/{1.DyuqnWpt.js → 1.qK8_Tc6M.js} +1 -1
- package/dist/_app/immutable/nodes/{2.DCVMr5cE.js → 2.C0l3mgWP.js} +1 -1
- package/dist/_app/immutable/nodes/{3.CRa3NPUY.js → 3.bzLm8zUT.js} +1 -1
- package/dist/_app/immutable/nodes/{4.BIaoIDIb.js → 4.5BLVnpgw.js} +1 -1
- package/dist/_app/version.json +1 -1
- package/dist/cli/commands/crawl.js +151 -90
- package/dist/cli/commands/ui.js +26 -71
- package/dist/cli/server/index.js +26 -71
- package/dist/cli/server/server.js +26 -71
- package/dist/cli/server/spreadsheetRoutes.js +26 -71
- package/dist/cli/server/websocketServer.js +27 -72
- package/dist/index.html +6 -6
- package/dist/index.js +171 -162
- package/package.json +21 -22
- package/dist/_app/immutable/chunks/BaNghdtJ.js +0 -3
- package/dist/_app/immutable/entry/start.BstRoW_s.js +0 -1
package/dist/index.js
CHANGED
|
@@ -2862,7 +2862,7 @@ __export(spreadsheetRoutes_exports, {
|
|
|
2862
2862
|
});
|
|
2863
2863
|
import crypto from "crypto";
|
|
2864
2864
|
import { parse as parseCSVSync } from "csv-parse/sync";
|
|
2865
|
-
import
|
|
2865
|
+
import * as XLSX from "xlsx-republish";
|
|
2866
2866
|
import express from "express";
|
|
2867
2867
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
2868
2868
|
import { glob } from "glob";
|
|
@@ -2957,20 +2957,13 @@ async function parseUploadedFile(file) {
|
|
|
2957
2957
|
const csvContent = file.buffer.toString("utf-8");
|
|
2958
2958
|
rawData = parseCSV(csvContent);
|
|
2959
2959
|
} else {
|
|
2960
|
-
const workbook =
|
|
2961
|
-
const
|
|
2962
|
-
|
|
2963
|
-
const worksheet = workbook.worksheets[0];
|
|
2964
|
-
if (!worksheet) {
|
|
2960
|
+
const workbook = XLSX.read(file.buffer, { type: "buffer" });
|
|
2961
|
+
const worksheetName = workbook.SheetNames[0];
|
|
2962
|
+
if (!worksheetName) {
|
|
2965
2963
|
throw new Error("No worksheet found in file");
|
|
2966
2964
|
}
|
|
2967
|
-
worksheet
|
|
2968
|
-
|
|
2969
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
2970
|
-
rowData[colNumber - 1] = cell.value;
|
|
2971
|
-
});
|
|
2972
|
-
rawData[rowNumber - 1] = rowData;
|
|
2973
|
-
});
|
|
2965
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
2966
|
+
rawData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
2974
2967
|
}
|
|
2975
2968
|
return rawData;
|
|
2976
2969
|
}
|
|
@@ -3541,43 +3534,20 @@ async function exportAsExcelWithMapping(controls, metadata, columnMappings, res)
|
|
|
3541
3534
|
});
|
|
3542
3535
|
return exportControl;
|
|
3543
3536
|
});
|
|
3544
|
-
const wb =
|
|
3545
|
-
const ws =
|
|
3546
|
-
|
|
3547
|
-
ws.columns = headers.map((header) => ({
|
|
3548
|
-
header,
|
|
3549
|
-
key: header,
|
|
3550
|
-
width: Math.min(
|
|
3551
|
-
Math.max(
|
|
3552
|
-
header.length,
|
|
3553
|
-
...worksheetData.map((row) => String(row[header] || "").length)
|
|
3554
|
-
) + 2,
|
|
3555
|
-
50
|
|
3556
|
-
)
|
|
3557
|
-
// Auto-size with max width of 50
|
|
3558
|
-
}));
|
|
3559
|
-
worksheetData.forEach((row) => {
|
|
3560
|
-
ws.addRow(row);
|
|
3561
|
-
});
|
|
3562
|
-
ws.getRow(1).font = { bold: true };
|
|
3563
|
-
ws.getRow(1).fill = {
|
|
3564
|
-
type: "pattern",
|
|
3565
|
-
pattern: "solid",
|
|
3566
|
-
fgColor: { argb: "FFE0E0E0" }
|
|
3567
|
-
};
|
|
3537
|
+
const wb = XLSX.utils.book_new();
|
|
3538
|
+
const ws = XLSX.utils.json_to_sheet(worksheetData);
|
|
3539
|
+
XLSX.utils.book_append_sheet(wb, ws, "Controls");
|
|
3568
3540
|
if (metadata) {
|
|
3569
|
-
const metaSheet = wb.addWorksheet("Metadata");
|
|
3570
3541
|
const cleanMetadata = { ...metadata };
|
|
3571
3542
|
delete cleanMetadata.fieldSchema;
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
});
|
|
3543
|
+
const metadataArray = Object.entries(cleanMetadata).map(([key, value]) => ({
|
|
3544
|
+
Property: key,
|
|
3545
|
+
Value: String(value)
|
|
3546
|
+
}));
|
|
3547
|
+
const metaSheet = XLSX.utils.json_to_sheet(metadataArray);
|
|
3548
|
+
XLSX.utils.book_append_sheet(wb, metaSheet, "Metadata");
|
|
3579
3549
|
}
|
|
3580
|
-
const buffer =
|
|
3550
|
+
const buffer = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
|
|
3581
3551
|
const fileName = `${metadata?.name || "controls"}_export_${Date.now()}.xlsx`;
|
|
3582
3552
|
res.setHeader(
|
|
3583
3553
|
"Content-Type",
|
|
@@ -3819,21 +3789,14 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3819
3789
|
rows = parseCSV(csvContent);
|
|
3820
3790
|
sheets = ["Sheet1"];
|
|
3821
3791
|
} else {
|
|
3822
|
-
const workbook =
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
const worksheet = workbook.worksheets[0];
|
|
3827
|
-
if (!worksheet) {
|
|
3792
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3793
|
+
sheets = workbook.SheetNames;
|
|
3794
|
+
const worksheetName = workbook.SheetNames[0];
|
|
3795
|
+
if (!worksheetName) {
|
|
3828
3796
|
return res.status(400).json({ error: "No worksheet found in file" });
|
|
3829
3797
|
}
|
|
3830
|
-
worksheet
|
|
3831
|
-
|
|
3832
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3833
|
-
rowData[colNumber - 1] = cell.value;
|
|
3834
|
-
});
|
|
3835
|
-
rows.push(rowData);
|
|
3836
|
-
});
|
|
3798
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
3799
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3837
3800
|
}
|
|
3838
3801
|
const headerCandidates = rows.slice(0, 5).map((row, index) => ({
|
|
3839
3802
|
row: index + 1,
|
|
@@ -3865,20 +3828,12 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3865
3828
|
const csvContent = req.file.buffer.toString("utf-8");
|
|
3866
3829
|
rows = parseCSV(csvContent);
|
|
3867
3830
|
} else {
|
|
3868
|
-
const workbook =
|
|
3869
|
-
|
|
3870
|
-
await workbook.xlsx.load(buffer);
|
|
3871
|
-
const worksheet = workbook.getWorksheet(sheetName);
|
|
3872
|
-
if (!worksheet) {
|
|
3831
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3832
|
+
if (!workbook.SheetNames.includes(sheetName)) {
|
|
3873
3833
|
return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
|
|
3874
3834
|
}
|
|
3875
|
-
worksheet
|
|
3876
|
-
|
|
3877
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3878
|
-
rowData[colNumber - 1] = cell.value;
|
|
3879
|
-
});
|
|
3880
|
-
rows.push(rowData);
|
|
3881
|
-
});
|
|
3835
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
3836
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3882
3837
|
}
|
|
3883
3838
|
const headerRowIndex = parseInt(headerRow) - 1;
|
|
3884
3839
|
const headers = rows[headerRowIndex] || [];
|
|
@@ -5644,155 +5599,209 @@ function containsLulaAnnotations(text) {
|
|
|
5644
5599
|
const lines = text.split("\n");
|
|
5645
5600
|
return lines.some((line) => line.includes("@lulaStart") || line.includes("@lulaEnd"));
|
|
5646
5601
|
}
|
|
5647
|
-
function
|
|
5648
|
-
return
|
|
5649
|
-
new Option("--post-mode <mode>", "How to post findings").choices(["review", "comment"]).default("review")
|
|
5650
|
-
).action(async (opts) => {
|
|
5651
|
-
let leavePost = false;
|
|
5652
|
-
const { owner, repo, pull_number } = getPRContext();
|
|
5653
|
-
console.log(`Analyzing PR #${pull_number} in ${owner}/${repo} for compliance changes...`);
|
|
5654
|
-
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
|
5655
|
-
const pr = await octokit.pulls.get({ owner, repo, pull_number });
|
|
5656
|
-
const prBranch = pr.data.head.ref;
|
|
5657
|
-
const { data: files } = await octokit.pulls.listFiles({ owner, repo, pull_number });
|
|
5658
|
-
let commentBody = `${LULA_SIGNATURE}
|
|
5602
|
+
function createInitialCommentBody(filesCount) {
|
|
5603
|
+
return `${LULA_SIGNATURE}
|
|
5659
5604
|
## Lula Compliance Overview
|
|
5660
5605
|
|
|
5661
5606
|
Please review the changes to ensure they meet compliance standards.
|
|
5662
5607
|
|
|
5663
5608
|
### Reviewed Changes
|
|
5664
5609
|
|
|
5665
|
-
Lula reviewed ${
|
|
5610
|
+
Lula reviewed ${filesCount} files changed that affect compliance.
|
|
5666
5611
|
|
|
5667
5612
|
`;
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5613
|
+
}
|
|
5614
|
+
async function analyzeDeletedFiles(context) {
|
|
5615
|
+
const { octokit, owner, repo, files } = context;
|
|
5616
|
+
const deletedFilesWithAnnotations = [];
|
|
5617
|
+
for (const file of files) {
|
|
5618
|
+
if (file.status === "removed") {
|
|
5619
|
+
try {
|
|
5620
|
+
const oldText = await fetchRawFileViaAPI({
|
|
5621
|
+
octokit,
|
|
5622
|
+
owner,
|
|
5623
|
+
repo,
|
|
5624
|
+
path: file.filename,
|
|
5625
|
+
ref: "main"
|
|
5626
|
+
});
|
|
5627
|
+
if (containsLulaAnnotations(oldText)) {
|
|
5628
|
+
deletedFilesWithAnnotations.push(file.filename);
|
|
5684
5629
|
}
|
|
5630
|
+
} catch (err) {
|
|
5631
|
+
console.error(`Error checking deleted file ${file.filename}: ${err}`);
|
|
5685
5632
|
}
|
|
5686
5633
|
}
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5634
|
+
}
|
|
5635
|
+
if (deletedFilesWithAnnotations.length === 0) {
|
|
5636
|
+
return { hasFindings: false, warningContent: "" };
|
|
5637
|
+
}
|
|
5638
|
+
let warningContent = `
|
|
5690
5639
|
|
|
5691
5640
|
**Compliance Warning: Files with Lula annotations were deleted**
|
|
5692
5641
|
|
|
5693
5642
|
`;
|
|
5694
|
-
|
|
5643
|
+
warningContent += `The following files contained compliance annotations (\`@lulaStart\`/\`@lulaEnd\`) and were deleted in this PR. This may affect compliance coverage:
|
|
5695
5644
|
|
|
5696
5645
|
`;
|
|
5697
|
-
|
|
5698
|
-
|
|
5646
|
+
for (const filename of deletedFilesWithAnnotations) {
|
|
5647
|
+
warningContent += `- \`${filename}\`
|
|
5699
5648
|
`;
|
|
5700
|
-
|
|
5701
|
-
|
|
5649
|
+
}
|
|
5650
|
+
warningContent += `
|
|
5702
5651
|
Please review whether:
|
|
5703
5652
|
`;
|
|
5704
|
-
|
|
5653
|
+
warningContent += `- The compliance coverage provided by these files is still needed
|
|
5705
5654
|
`;
|
|
5706
|
-
|
|
5655
|
+
warningContent += `- Alternative compliance measures have been implemented
|
|
5707
5656
|
`;
|
|
5708
|
-
|
|
5657
|
+
warningContent += `- The deletion is intentional and compliance-approved
|
|
5709
5658
|
|
|
5710
5659
|
`;
|
|
5711
|
-
|
|
5660
|
+
warningContent += `---
|
|
5712
5661
|
|
|
5713
5662
|
`;
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
]);
|
|
5722
|
-
const changedBlocks = getChangedBlocks(oldText, newText);
|
|
5723
|
-
const removedBlocks = getRemovedBlocks(oldText, newText);
|
|
5724
|
-
for (const block of changedBlocks) {
|
|
5725
|
-
console.log(`Commenting regarding \`${file.filename}\`.`);
|
|
5726
|
-
leavePost = true;
|
|
5727
|
-
commentBody += `
|
|
5663
|
+
return { hasFindings: true, warningContent };
|
|
5664
|
+
}
|
|
5665
|
+
function generateChangedBlocksContent(filename, changedBlocks, newText) {
|
|
5666
|
+
let content = "";
|
|
5667
|
+
for (const block of changedBlocks) {
|
|
5668
|
+
console.log(`Commenting regarding \`${filename}\`.`);
|
|
5669
|
+
content += `
|
|
5728
5670
|
|
|
5729
5671
|
---
|
|
5730
5672
|
| File | Lines Changed |
|
|
5731
5673
|
| ---- | ------------- |
|
|
5732
5674
|
`;
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5675
|
+
const newBlockText = newText.split("\n").slice(block.startLine, block.endLine).join("\n");
|
|
5676
|
+
const blockSha256 = createHash2("sha256").update(newBlockText).digest("hex");
|
|
5677
|
+
content += `| \`${filename}\` | \`${block.startLine + 1}\u2013${block.endLine}\` |
|
|
5736
5678
|
> **uuid**-\`${block.uuid}\`
|
|
5737
5679
|
**sha256** \`${blockSha256}\`
|
|
5738
5680
|
|
|
5739
5681
|
`;
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5682
|
+
}
|
|
5683
|
+
return content;
|
|
5684
|
+
}
|
|
5685
|
+
function generateRemovedBlocksContent(filename, removedBlocks, oldText) {
|
|
5686
|
+
if (removedBlocks.length === 0) {
|
|
5687
|
+
return "";
|
|
5688
|
+
}
|
|
5689
|
+
console.log(`Found removed annotations in \`${filename}\`.`);
|
|
5690
|
+
let content = `
|
|
5745
5691
|
|
|
5746
|
-
**Compliance Warning: Lula annotations were removed from \`${
|
|
5692
|
+
**Compliance Warning: Lula annotations were removed from \`${filename}\`**
|
|
5747
5693
|
|
|
5748
5694
|
`;
|
|
5749
|
-
|
|
5695
|
+
content += `The following compliance annotation blocks were present in the original file but are missing in the updated version:
|
|
5750
5696
|
|
|
5751
5697
|
`;
|
|
5752
|
-
|
|
5698
|
+
content += `| File | Original Lines | UUID |
|
|
5753
5699
|
`;
|
|
5754
|
-
|
|
5700
|
+
content += `| ---- | -------------- | ---- |
|
|
5755
5701
|
`;
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5702
|
+
for (const block of removedBlocks) {
|
|
5703
|
+
const oldBlockText = oldText.split("\n").slice(block.startLine, block.endLine).join("\n");
|
|
5704
|
+
const blockSha256 = createHash2("sha256").update(oldBlockText).digest("hex");
|
|
5705
|
+
content += `| \`${filename}\` | \`${block.startLine + 1}\u2013${block.endLine}\` | \`${block.uuid}\` |
|
|
5760
5706
|
`;
|
|
5761
|
-
|
|
5707
|
+
content += `> **sha256** \`${blockSha256}\`
|
|
5762
5708
|
|
|
5763
5709
|
`;
|
|
5764
|
-
|
|
5765
|
-
|
|
5710
|
+
}
|
|
5711
|
+
content += `Please review whether:
|
|
5766
5712
|
`;
|
|
5767
|
-
|
|
5713
|
+
content += `- The removal of these compliance annotations is intentional
|
|
5768
5714
|
`;
|
|
5769
|
-
|
|
5715
|
+
content += `- Alternative compliance measures have been implemented
|
|
5770
5716
|
`;
|
|
5771
|
-
|
|
5717
|
+
content += `- The compliance coverage is still adequate
|
|
5772
5718
|
|
|
5773
5719
|
`;
|
|
5774
|
-
|
|
5720
|
+
content += `---
|
|
5775
5721
|
|
|
5776
5722
|
`;
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5723
|
+
return content;
|
|
5724
|
+
}
|
|
5725
|
+
async function analyzeModifiedFiles(context) {
|
|
5726
|
+
const { octokit, owner, repo, prBranch, files } = context;
|
|
5727
|
+
let changesContent = "";
|
|
5728
|
+
let hasFindings = false;
|
|
5729
|
+
for (const file of files) {
|
|
5730
|
+
if (file.status === "added" || file.status === "removed") continue;
|
|
5731
|
+
try {
|
|
5732
|
+
const [oldText, newText] = await Promise.all([
|
|
5733
|
+
fetchRawFileViaAPI({ octokit, owner, repo, path: file.filename, ref: "main" }),
|
|
5734
|
+
fetchRawFileViaAPI({ octokit, owner, repo, path: file.filename, ref: prBranch })
|
|
5735
|
+
]);
|
|
5736
|
+
const changedBlocks = getChangedBlocks(oldText, newText);
|
|
5737
|
+
const removedBlocks = getRemovedBlocks(oldText, newText);
|
|
5738
|
+
if (changedBlocks.length > 0) {
|
|
5739
|
+
hasFindings = true;
|
|
5740
|
+
changesContent += generateChangedBlocksContent(file.filename, changedBlocks, newText);
|
|
5741
|
+
}
|
|
5742
|
+
if (removedBlocks.length > 0) {
|
|
5743
|
+
hasFindings = true;
|
|
5744
|
+
changesContent += generateRemovedBlocksContent(file.filename, removedBlocks, oldText);
|
|
5745
|
+
}
|
|
5746
|
+
} catch (err) {
|
|
5747
|
+
console.error(`Error processing ${file.filename}: ${err}`);
|
|
5787
5748
|
}
|
|
5788
|
-
|
|
5749
|
+
}
|
|
5750
|
+
return { hasFindings, changesContent };
|
|
5751
|
+
}
|
|
5752
|
+
async function performComplianceAnalysis(context) {
|
|
5753
|
+
let commentBody = createInitialCommentBody(context.files.length);
|
|
5754
|
+
let hasFindings = false;
|
|
5755
|
+
const deletedAnalysis = await analyzeDeletedFiles(context);
|
|
5756
|
+
if (deletedAnalysis.hasFindings) {
|
|
5757
|
+
hasFindings = true;
|
|
5758
|
+
commentBody += deletedAnalysis.warningContent;
|
|
5759
|
+
}
|
|
5760
|
+
const modifiedAnalysis = await analyzeModifiedFiles(context);
|
|
5761
|
+
if (modifiedAnalysis.hasFindings) {
|
|
5762
|
+
hasFindings = true;
|
|
5763
|
+
commentBody += modifiedAnalysis.changesContent;
|
|
5764
|
+
}
|
|
5765
|
+
return { hasFindings, commentBody };
|
|
5766
|
+
}
|
|
5767
|
+
async function cleanupOldPosts(context, postMode) {
|
|
5768
|
+
const { octokit, owner, repo, pull_number } = context;
|
|
5769
|
+
if (postMode === "comment") {
|
|
5770
|
+
await deleteOldIssueComments({ octokit, owner, repo, pull_number });
|
|
5771
|
+
} else {
|
|
5772
|
+
await dismissOldReviews({ octokit, owner, repo, pull_number });
|
|
5773
|
+
await deleteOldReviewComments({ octokit, owner, repo, pull_number });
|
|
5774
|
+
}
|
|
5775
|
+
}
|
|
5776
|
+
function crawlCommand() {
|
|
5777
|
+
return new Command().command("crawl").description("Detect compliance-related changes between @lulaStart and @lulaEnd in PR files").addOption(
|
|
5778
|
+
new Option("--post-mode <mode>", "How to post findings").choices(["review", "comment"]).default("review")
|
|
5779
|
+
).action(async (opts) => {
|
|
5780
|
+
const { owner, repo, pull_number } = getPRContext();
|
|
5781
|
+
console.log(`Analyzing PR #${pull_number} in ${owner}/${repo} for compliance changes...`);
|
|
5782
|
+
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
|
5783
|
+
const pr = await octokit.pulls.get({ owner, repo, pull_number });
|
|
5784
|
+
const prBranch = pr.data.head.ref;
|
|
5785
|
+
const { data: files } = await octokit.pulls.listFiles({ owner, repo, pull_number });
|
|
5786
|
+
const context = {
|
|
5787
|
+
octokit,
|
|
5788
|
+
owner,
|
|
5789
|
+
repo,
|
|
5790
|
+
pull_number,
|
|
5791
|
+
prBranch,
|
|
5792
|
+
files
|
|
5793
|
+
};
|
|
5794
|
+
const analysisResult = await performComplianceAnalysis(context);
|
|
5795
|
+
await cleanupOldPosts(context, opts.postMode);
|
|
5796
|
+
if (analysisResult.hasFindings) {
|
|
5797
|
+
const finalBody = analysisResult.commentBody + closingBody;
|
|
5789
5798
|
await postFinding({
|
|
5790
5799
|
octokit,
|
|
5791
5800
|
postMode: opts.postMode,
|
|
5792
5801
|
owner,
|
|
5793
5802
|
repo,
|
|
5794
5803
|
pull_number,
|
|
5795
|
-
body:
|
|
5804
|
+
body: finalBody
|
|
5796
5805
|
});
|
|
5797
5806
|
const header = `Posted (${opts.postMode})`;
|
|
5798
5807
|
const underline = "-".repeat(header.length);
|
|
@@ -5800,7 +5809,7 @@ Please review whether:
|
|
|
5800
5809
|
${header}
|
|
5801
5810
|
${underline}
|
|
5802
5811
|
|
|
5803
|
-
${
|
|
5812
|
+
${finalBody}
|
|
5804
5813
|
|
|
5805
5814
|
`);
|
|
5806
5815
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lula2",
|
|
3
|
-
"version": "0.6.1",
|
|
3
|
+
"version": "0.6.2-nightly.1",
|
|
4
4
|
"description": "A tool for managing compliance as code in your GitHub repositories.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"lula2": "./dist/lula2"
|
|
@@ -33,32 +33,12 @@
|
|
|
33
33
|
"!dist/**/*.test.js*",
|
|
34
34
|
"!dist/**/*.test.d.ts*"
|
|
35
35
|
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"dev": "vite dev --port 5173",
|
|
38
|
-
"dev:api": "tsx --watch index.ts --debug ui --port 3000 --no-open-browser",
|
|
39
|
-
"dev:full": "concurrently \"npm run dev:api\" \"npm run dev\"",
|
|
40
|
-
"build": "npm run build:svelte && npm run build:cli && npm run postbuild:cli",
|
|
41
|
-
"build:svelte": "vite build",
|
|
42
|
-
"build:cli": "esbuild index.ts cli/**/*.ts --bundle --platform=node --target=node22 --format=esm --outdir=dist --external:express --external:commander --external:js-yaml --external:yaml --external:isomorphic-git --external:glob --external:open --external:ws --external:cors --external:multer --external:@octokit/rest --external:undici --external:exceljs --external:csv-parse",
|
|
43
|
-
"postbuild:cli": "cp cli-wrapper.mjs dist/lula2 && chmod +x dist/lula2",
|
|
44
|
-
"preview": "vite preview",
|
|
45
|
-
"prepare": "svelte-kit sync || echo ''",
|
|
46
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && tsc --noEmit",
|
|
47
|
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
48
|
-
"format": "prettier --write 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts'",
|
|
49
|
-
"format:check": "prettier --check 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts'",
|
|
50
|
-
"lint": "prettier --check 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts' && eslint src cli",
|
|
51
|
-
"test": "npm run test:unit -- --run --coverage",
|
|
52
|
-
"test:integration": "vitest --config integration/vitest.config.integration.ts",
|
|
53
|
-
"test:unit": "vitest"
|
|
54
|
-
},
|
|
55
36
|
"dependencies": {
|
|
56
37
|
"@octokit/rest": "^22.0.0",
|
|
57
38
|
"@types/ws": "^8.18.1",
|
|
58
39
|
"commander": "^14.0.0",
|
|
59
40
|
"cors": "^2.8.5",
|
|
60
41
|
"csv-parse": "^6.1.0",
|
|
61
|
-
"exceljs": "^4.4.0",
|
|
62
42
|
"express": "^5.1.0",
|
|
63
43
|
"express-rate-limit": "^8.1.0",
|
|
64
44
|
"flowbite": "^3.1.2",
|
|
@@ -69,6 +49,7 @@
|
|
|
69
49
|
"open": "^10.2.0",
|
|
70
50
|
"undici": "^7.15.0",
|
|
71
51
|
"ws": "^8.18.3",
|
|
52
|
+
"xlsx-republish": "^0.20.3",
|
|
72
53
|
"yaml": "^2.8.1"
|
|
73
54
|
},
|
|
74
55
|
"devDependencies": {
|
|
@@ -124,5 +105,23 @@
|
|
|
124
105
|
"main",
|
|
125
106
|
"next"
|
|
126
107
|
]
|
|
108
|
+
},
|
|
109
|
+
"scripts": {
|
|
110
|
+
"dev": "vite dev --port 5173",
|
|
111
|
+
"dev:api": "tsx --watch index.ts --debug ui --port 3000 --no-open-browser",
|
|
112
|
+
"dev:full": "concurrently \"npm run dev:api\" \"npm run dev\"",
|
|
113
|
+
"build": "npm run build:svelte && npm run build:cli && npm run postbuild:cli",
|
|
114
|
+
"build:svelte": "vite build",
|
|
115
|
+
"build:cli": "esbuild index.ts cli/**/*.ts --bundle --platform=node --target=node22 --format=esm --outdir=dist --external:express --external:commander --external:js-yaml --external:yaml --external:isomorphic-git --external:glob --external:open --external:ws --external:cors --external:multer --external:@octokit/rest --external:undici --external:xlsx-republish --external:csv-parse",
|
|
116
|
+
"postbuild:cli": "cp cli-wrapper.mjs dist/lula2 && chmod +x dist/lula2",
|
|
117
|
+
"preview": "vite preview",
|
|
118
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && tsc --noEmit",
|
|
119
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
120
|
+
"format": "prettier --write 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts'",
|
|
121
|
+
"format:check": "prettier --check 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts'",
|
|
122
|
+
"lint": "prettier --check 'src/**/*.{ts,js,svelte}' 'cli/**/*.ts' 'index.ts' 'tests/**/*.ts' && eslint src cli",
|
|
123
|
+
"test": "npm run test:unit -- --run --coverage",
|
|
124
|
+
"test:integration": "vitest --config integration/vitest.config.integration.ts",
|
|
125
|
+
"test:unit": "vitest"
|
|
127
126
|
}
|
|
128
|
-
}
|
|
127
|
+
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{a$ as Ae,o as $e,g as U,h as L,d as P,bi as yt,ai as De}from"./DTWPdvjs.js";class le{constructor(t,n){this.status=t,typeof n=="string"?this.body={message:n}:n?this.body=n:this.body={message:`Error: ${t}`}}toString(){return JSON.stringify(this.body)}}class Se{constructor(t,n){this.status=t,this.location=n}}class Re extends Error{constructor(t,n,r){super(r),this.status=t,this.text=n}}new URL("sveltekit-internal://");function wt(e,t){return e==="/"||t==="ignore"?e:t==="never"?e.endsWith("/")?e.slice(0,-1):e:t==="always"&&!e.endsWith("/")?e+"/":e}function vt(e){return e.split("%25").map(decodeURI).join("%25")}function bt(e){for(const t in e)e[t]=decodeURIComponent(e[t]);return e}function _e({href:e}){return e.split("#")[0]}function kt(e,t,n,r=!1){const a=new URL(e);Object.defineProperty(a,"searchParams",{value:new Proxy(a.searchParams,{get(i,o){if(o==="get"||o==="getAll"||o==="has")return f=>(n(f),i[o](f));t();const c=Reflect.get(i,o);return typeof c=="function"?c.bind(i):c}}),enumerable:!0,configurable:!0});const s=["href","pathname","search","toString","toJSON"];r&&s.push("hash");for(const i of s)Object.defineProperty(a,i,{get(){return t(),e[i]},enumerable:!0,configurable:!0});return a}function Et(...e){let t=5381;for(const n of e)if(typeof n=="string"){let r=n.length;for(;r;)t=t*33^n.charCodeAt(--r)}else if(ArrayBuffer.isView(n)){const r=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let a=r.length;for(;a;)t=t*33^r[--a]}else throw new TypeError("value must be a string or TypedArray");return(t>>>0).toString(36)}new TextEncoder;const At=new TextDecoder;function St(e){const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}const Rt=window.fetch;window.fetch=(e,t)=>((e instanceof Request?e.method:t?.method||"GET")!=="GET"&&Y.delete(Te(e)),Rt(e,t));const Y=new Map;function Tt(e,t){const n=Te(e,t),r=document.querySelector(n);if(r?.textContent){r.remove();let{body:a,...s}=JSON.parse(r.textContent);const i=r.getAttribute("data-ttl");return i&&Y.set(n,{body:a,init:s,ttl:1e3*Number(i)}),r.getAttribute("data-b64")!==null&&(a=St(a)),Promise.resolve(new Response(a,s))}return window.fetch(e,t)}function It(e,t,n){if(Y.size>0){const r=Te(e,n),a=Y.get(r);if(a){if(performance.now()<a.ttl&&["default","force-cache","only-if-cached",void 0].includes(n?.cache))return new Response(a.body,a.init);Y.delete(r)}}return window.fetch(t,n)}function Te(e,t){let r=`script[data-sveltekit-fetched][data-url=${JSON.stringify(e instanceof Request?e.url:e)}]`;if(t?.headers||t?.body){const a=[];t.headers&&a.push([...new Headers(t.headers)].join(",")),t.body&&(typeof t.body=="string"||ArrayBuffer.isView(t.body))&&a.push(t.body),r+=`[data-hash="${Et(...a)}"]`}return r}const Ut=/^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;function Lt(e){const t=[];return{pattern:e==="/"?/^\/$/:new RegExp(`^${xt(e).map(r=>{const a=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(r);if(a)return t.push({name:a[1],matcher:a[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const s=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(r);if(s)return t.push({name:s[1],matcher:s[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!r)return;const i=r.split(/\[(.+?)\](?!\])/);return"/"+i.map((c,f)=>{if(f%2){if(c.startsWith("x+"))return me(String.fromCharCode(parseInt(c.slice(2),16)));if(c.startsWith("u+"))return me(String.fromCharCode(...c.slice(2).split("-").map(w=>parseInt(w,16))));const d=Ut.exec(c),[,p,u,l,h]=d;return t.push({name:l,matcher:h,optional:!!p,rest:!!u,chained:u?f===1&&i[0]==="":!1}),u?"([^]*?)":p?"([^/]*)?":"([^/]+?)"}return me(c)}).join("")}).join("")}/?$`),params:t}}function Pt(e){return e!==""&&!/^\([^)]+\)$/.test(e)}function xt(e){return e.slice(1).split("/").filter(Pt)}function Ct(e,t,n){const r={},a=e.slice(1),s=a.filter(o=>o!==void 0);let i=0;for(let o=0;o<t.length;o+=1){const c=t[o];let f=a[o-i];if(c.chained&&c.rest&&i&&(f=a.slice(o-i,o+1).filter(d=>d).join("/"),i=0),f===void 0){c.rest&&(r[c.name]="");continue}if(!c.matcher||n[c.matcher](f)){r[c.name]=f;const d=t[o+1],p=a[o+1];d&&!d.rest&&d.optional&&p&&c.chained&&(i=0),!d&&!p&&Object.keys(r).length===s.length&&(i=0);continue}if(c.optional&&c.chained){i++;continue}return}if(!i)return r}function me(e){return e.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function Ot({nodes:e,server_loads:t,dictionary:n,matchers:r}){const a=new Set(t);return Object.entries(n).map(([o,[c,f,d]])=>{const{pattern:p,params:u}=Lt(o),l={id:o,exec:h=>{const w=p.exec(h);if(w)return Ct(w,u,r)},errors:[1,...d||[]].map(h=>e[h]),layouts:[0,...f||[]].map(i),leaf:s(c)};return l.errors.length=l.layouts.length=Math.max(l.errors.length,l.layouts.length),l});function s(o){const c=o<0;return c&&(o=~o),[c,e[o]]}function i(o){return o===void 0?o:[a.has(o),e[o]]}}function Je(e,t=JSON.parse){try{return t(sessionStorage[e])}catch{}}function Be(e,t,n=JSON.stringify){const r=n(t);try{sessionStorage[e]=r}catch{}}const I=globalThis.__sveltekit_t0tvav?.base??"",Nt=globalThis.__sveltekit_t0tvav?.assets??I??"",jt="1759788987595",ze="sveltekit:snapshot",Xe="sveltekit:scroll",Ze="sveltekit:states",$t="sveltekit:pageurl",F="sveltekit:history",W="sveltekit:navigation",j={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},Z=location.origin;function Ie(e){if(e instanceof URL)return e;let t=document.baseURI;if(!t){const n=document.getElementsByTagName("base");t=n.length?n[0].href:document.URL}return new URL(e,t)}function fe(){return{x:pageXOffset,y:pageYOffset}}function B(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const Fe={...j,"":j.hover};function Qe(e){let t=e.assignedSlot??e.parentNode;return t?.nodeType===11&&(t=t.host),t}function et(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=Qe(e)}}function ve(e,t,n){let r;try{if(r=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){const o=location.hash.split("#")[1]||"/";r.hash=`#${o}${r.hash}`}}catch{}const a=e instanceof SVGAElement?e.target.baseVal:e.target,s=!r||!!a||ue(r,t,n)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),i=r?.origin===Z&&e.hasAttribute("download");return{url:r,external:s,target:a,download:i}}function te(e){let t=null,n=null,r=null,a=null,s=null,i=null,o=e;for(;o&&o!==document.documentElement;)r===null&&(r=B(o,"preload-code")),a===null&&(a=B(o,"preload-data")),t===null&&(t=B(o,"keepfocus")),n===null&&(n=B(o,"noscroll")),s===null&&(s=B(o,"reload")),i===null&&(i=B(o,"replacestate")),o=Qe(o);function c(f){switch(f){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:Fe[r??"off"],preload_data:Fe[a??"off"],keepfocus:c(t),noscroll:c(n),reload:c(s),replace_state:c(i)}}function Ve(e){const t=Ae(e);let n=!0;function r(){n=!0,t.update(i=>i)}function a(i){n=!1,t.set(i)}function s(i){let o;return t.subscribe(c=>{(o===void 0||n&&c!==o)&&i(o=c)})}return{notify:r,set:a,subscribe:s}}const tt={v:()=>{}};function Dt(){const{set:e,subscribe:t}=Ae(!1);let n;async function r(){clearTimeout(n);try{const a=await fetch(`${Nt}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!a.ok)return!1;const i=(await a.json()).version!==jt;return i&&(e(!0),tt.v(),clearTimeout(n)),i}catch{return!1}}return{subscribe:t,check:r}}function ue(e,t,n){return e.origin!==Z||!e.pathname.startsWith(t)?!0:n?!(e.pathname===t+"/"||e.pathname===t+"/index.html"||e.protocol==="file:"&&e.pathname.replace(/\/[^/]+\.html?$/,"")===t):!1}function An(e){}function Bt(e){const t=Vt(e),n=new ArrayBuffer(t.length),r=new DataView(n);for(let a=0;a<n.byteLength;a++)r.setUint8(a,t.charCodeAt(a));return n}const Ft="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function Vt(e){e.length%4===0&&(e=e.replace(/==?$/,""));let t="",n=0,r=0;for(let a=0;a<e.length;a++)n<<=6,n|=Ft.indexOf(e[a]),r+=6,r===24&&(t+=String.fromCharCode((n&16711680)>>16),t+=String.fromCharCode((n&65280)>>8),t+=String.fromCharCode(n&255),n=r=0);return r===12?(n>>=4,t+=String.fromCharCode(n)):r===18&&(n>>=2,t+=String.fromCharCode((n&65280)>>8),t+=String.fromCharCode(n&255)),t}const Mt=-1,qt=-2,Gt=-3,Yt=-4,Ht=-5,Kt=-6;function Wt(e,t){if(typeof e=="number")return a(e,!0);if(!Array.isArray(e)||e.length===0)throw new Error("Invalid input");const n=e,r=Array(n.length);function a(s,i=!1){if(s===Mt)return;if(s===Gt)return NaN;if(s===Yt)return 1/0;if(s===Ht)return-1/0;if(s===Kt)return-0;if(i||typeof s!="number")throw new Error("Invalid input");if(s in r)return r[s];const o=n[s];if(!o||typeof o!="object")r[s]=o;else if(Array.isArray(o))if(typeof o[0]=="string"){const c=o[0],f=t?.[c];if(f)return r[s]=f(a(o[1]));switch(c){case"Date":r[s]=new Date(o[1]);break;case"Set":const d=new Set;r[s]=d;for(let l=1;l<o.length;l+=1)d.add(a(o[l]));break;case"Map":const p=new Map;r[s]=p;for(let l=1;l<o.length;l+=2)p.set(a(o[l]),a(o[l+1]));break;case"RegExp":r[s]=new RegExp(o[1],o[2]);break;case"Object":r[s]=Object(o[1]);break;case"BigInt":r[s]=BigInt(o[1]);break;case"null":const u=Object.create(null);r[s]=u;for(let l=1;l<o.length;l+=2)u[o[l]]=a(o[l+1]);break;case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"BigInt64Array":case"BigUint64Array":{const l=globalThis[c],h=new l(a(o[1]));r[s]=o[2]!==void 0?h.subarray(o[2],o[3]):h;break}case"ArrayBuffer":{const l=o[1],h=Bt(l);r[s]=h;break}case"Temporal.Duration":case"Temporal.Instant":case"Temporal.PlainDate":case"Temporal.PlainTime":case"Temporal.PlainDateTime":case"Temporal.PlainMonthDay":case"Temporal.PlainYearMonth":case"Temporal.ZonedDateTime":{const l=c.slice(9);r[s]=Temporal[l].from(o[1]);break}case"URL":{const l=new URL(o[1]);r[s]=l;break}case"URLSearchParams":{const l=new URLSearchParams(o[1]);r[s]=l;break}default:throw new Error(`Unknown type ${c}`)}}else{const c=new Array(o.length);r[s]=c;for(let f=0;f<o.length;f+=1){const d=o[f];d!==qt&&(c[f]=a(d))}}else{const c={};r[s]=c;for(const f in o){if(f==="__proto__")throw new Error("Cannot parse an object with a `__proto__` property");const d=o[f];c[f]=a(d)}}return r[s]}return a(0)}const nt=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...nt];const Jt=new Set([...nt]);[...Jt];function zt(e){return e.filter(t=>t!=null)}const Xt="x-sveltekit-invalidated",Zt="x-sveltekit-trailing-slash";function ne(e){return e instanceof le||e instanceof Re?e.status:500}function Qt(e){return e instanceof Re?e.text:"Internal Error"}let R,J,ye;const en=$e.toString().includes("$$")||/function \w+\(\) \{\}/.test($e.toString());en?(R={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL("https://example.com")},J={current:null},ye={current:!1}):(R=new class{#e=U({});get data(){return L(this.#e)}set data(t){P(this.#e,t)}#t=U(null);get form(){return L(this.#t)}set form(t){P(this.#t,t)}#n=U(null);get error(){return L(this.#n)}set error(t){P(this.#n,t)}#r=U({});get params(){return L(this.#r)}set params(t){P(this.#r,t)}#a=U({id:null});get route(){return L(this.#a)}set route(t){P(this.#a,t)}#o=U({});get state(){return L(this.#o)}set state(t){P(this.#o,t)}#s=U(-1);get status(){return L(this.#s)}set status(t){P(this.#s,t)}#i=U(new URL("https://example.com"));get url(){return L(this.#i)}set url(t){P(this.#i,t)}},J=new class{#e=U(null);get current(){return L(this.#e)}set current(t){P(this.#e,t)}},ye=new class{#e=U(!1);get current(){return L(this.#e)}set current(t){P(this.#e,t)}},tt.v=()=>ye.current=!0);function tn(e){Object.assign(R,e)}const nn="/__data.json",rn=".html__data.json";function an(e){return e.endsWith(".html")?e.replace(/\.html$/,rn):e.replace(/\/$/,"")+nn}const Me={spanContext(){return on},setAttribute(){return this},setAttributes(){return this},addEvent(){return this},setStatus(){return this},updateName(){return this},end(){return this},isRecording(){return!1},recordException(){return this},addLink(){return this},addLinks(){return this}},on={traceId:"",spanId:"",traceFlags:0},{tick:sn}=yt,cn=new Set(["icon","shortcut icon","apple-touch-icon"]),D=Je(Xe)??{},z=Je(ze)??{},N={url:Ve({}),page:Ve({}),navigating:Ae(null),updated:Dt()};function Ue(e){D[e]=fe()}function ln(e,t){let n=e+1;for(;D[n];)delete D[n],n+=1;for(n=t+1;z[n];)delete z[n],n+=1}function q(e,t=!1){return t?location.replace(e.href):location.href=e.href,new Promise(()=>{})}async function rt(){if("serviceWorker"in navigator){const e=await navigator.serviceWorker.getRegistration(I||"/");e&&await e.update()}}function qe(){}let Le,be,re,x,ke,k;const ae=[],oe=[];let C=null;const ee=new Map,at=new Set,fn=new Set,H=new Set;let y={branch:[],error:null,url:null},Pe=!1,se=!1,Ge=!0,X=!1,G=!1,ot=!1,xe=!1,st,A,T,$;const K=new Set,Ye=new Map;async function In(e,t,n){globalThis.__sveltekit_t0tvav?.data&&globalThis.__sveltekit_t0tvav.data,document.URL!==location.href&&(location.href=location.href),k=e,await e.hooks.init?.(),Le=Ot(e),x=document.documentElement,ke=t,be=e.nodes[0],re=e.nodes[1],be(),re(),A=history.state?.[F],T=history.state?.[W],A||(A=T=Date.now(),history.replaceState({...history.state,[F]:A,[W]:T},""));const r=D[A];function a(){r&&(history.scrollRestoration="manual",scrollTo(r.x,r.y))}n?(a(),await vn(ke,n)):(await V({type:"enter",url:Ie(k.hash?kn(new URL(location.href)):location.href),replace_state:!0}),a()),wn()}function un(){ae.length=0,xe=!1}function it(e){oe.some(t=>t?.snapshot)&&(z[e]=oe.map(t=>t?.snapshot?.capture()))}function ct(e){z[e]?.forEach((t,n)=>{oe[n]?.snapshot?.restore(t)})}function He(){Ue(A),Be(Xe,D),it(T),Be(ze,z)}async function lt(e,t,n,r){let a;t.invalidateAll&&(C=null),await V({type:"goto",url:Ie(e),keepfocus:t.keepFocus,noscroll:t.noScroll,replace_state:t.replaceState,state:t.state,redirect_count:n,nav_token:r,accept:()=>{t.invalidateAll&&(xe=!0,a=[...Ye.keys()]),t.invalidate&&t.invalidate.forEach(yn)}}),t.invalidateAll&&De().then(De).then(()=>{Ye.forEach(({resource:s},i)=>{a?.includes(i)&&s.refresh?.()})})}async function dn(e){if(e.id!==C?.id){const t={};K.add(t),C={id:e.id,token:t,promise:dt({...e,preload:t}).then(n=>(K.delete(t),n.type==="loaded"&&n.state.error&&(C=null),n))}}return C.promise}async function we(e){const t=(await he(e,!1))?.route;t&&await Promise.all([...t.layouts,t.leaf].map(n=>n?.[1]()))}function ft(e,t,n){y=e.state;const r=document.querySelector("style[data-sveltekit]");if(r&&r.remove(),Object.assign(R,e.props.page),st=new k.root({target:t,props:{...e.props,stores:N,components:oe},hydrate:n,sync:!1}),ct(T),n){const a={from:null,to:{params:y.params,route:{id:y.route?.id??null},url:new URL(location.href)},willUnload:!1,type:"enter",complete:Promise.resolve()};H.forEach(s=>s(a))}se=!0}function ie({url:e,params:t,branch:n,status:r,error:a,route:s,form:i}){let o="never";if(I&&(e.pathname===I||e.pathname===I+"/"))o="always";else for(const l of n)l?.slash!==void 0&&(o=l.slash);e.pathname=wt(e.pathname,o),e.search=e.search;const c={type:"loaded",state:{url:e,params:t,branch:n,error:a,route:s},props:{constructors:zt(n).map(l=>l.node.component),page:je(R)}};i!==void 0&&(c.props.form=i);let f={},d=!R,p=0;for(let l=0;l<Math.max(n.length,y.branch.length);l+=1){const h=n[l],w=y.branch[l];h?.data!==w?.data&&(d=!0),h&&(f={...f,...h.data},d&&(c.props[`data_${p}`]=f),p+=1)}return(!y.url||e.href!==y.url.href||y.error!==a||i!==void 0&&i!==R.form||d)&&(c.props.page={error:a,params:t,route:{id:s?.id??null},state:{},status:r,url:new URL(e),form:i??null,data:d?f:R.data}),c}async function Ce({loader:e,parent:t,url:n,params:r,route:a,server_data_node:s}){let i=null,o=!0;const c={dependencies:new Set,params:new Set,parent:!1,route:!1,url:!1,search_params:new Set},f=await e();if(f.universal?.load){let d=function(...u){for(const l of u){const{href:h}=new URL(l,n);c.dependencies.add(h)}};const p={tracing:{enabled:!1,root:Me,current:Me},route:new Proxy(a,{get:(u,l)=>(o&&(c.route=!0),u[l])}),params:new Proxy(r,{get:(u,l)=>(o&&c.params.add(l),u[l])}),data:s?.data??null,url:kt(n,()=>{o&&(c.url=!0)},u=>{o&&c.search_params.add(u)},k.hash),async fetch(u,l){u instanceof Request&&(l={body:u.method==="GET"||u.method==="HEAD"?void 0:await u.blob(),cache:u.cache,credentials:u.credentials,headers:[...u.headers].length>0?u?.headers:void 0,integrity:u.integrity,keepalive:u.keepalive,method:u.method,mode:u.mode,redirect:u.redirect,referrer:u.referrer,referrerPolicy:u.referrerPolicy,signal:u.signal,...l});const{resolved:h,promise:w}=ut(u,l,n);return o&&d(h.href),w},setHeaders:()=>{},depends:d,parent(){return o&&(c.parent=!0),t()},untrack(u){o=!1;try{return u()}finally{o=!0}}};i=await f.universal.load.call(null,p)??null}return{node:f,loader:e,server:s,universal:f.universal?.load?{type:"data",data:i,uses:c}:null,data:i??s?.data??null,slash:f.universal?.trailingSlash??s?.slash}}function ut(e,t,n){let r=e instanceof Request?e.url:e;const a=new URL(r,n);a.origin===n.origin&&(r=a.href.slice(n.origin.length));const s=se?It(r,a.href,t):Tt(r,t);return{resolved:a,promise:s}}function Ke(e,t,n,r,a,s){if(xe)return!0;if(!a)return!1;if(a.parent&&e||a.route&&t||a.url&&n)return!0;for(const i of a.search_params)if(r.has(i))return!0;for(const i of a.params)if(s[i]!==y.params[i])return!0;for(const i of a.dependencies)if(ae.some(o=>o(new URL(i))))return!0;return!1}function Oe(e,t){return e?.type==="data"?e:e?.type==="skip"?t??null:null}function hn(e,t){if(!e)return new Set(t.searchParams.keys());const n=new Set([...e.searchParams.keys(),...t.searchParams.keys()]);for(const r of n){const a=e.searchParams.getAll(r),s=t.searchParams.getAll(r);a.every(i=>s.includes(i))&&s.every(i=>a.includes(i))&&n.delete(r)}return n}function We({error:e,url:t,route:n,params:r}){return{type:"loaded",state:{error:e,url:t,route:n,params:r,branch:[]},props:{page:je(R),constructors:[]}}}async function dt({id:e,invalidating:t,url:n,params:r,route:a,preload:s}){if(C?.id===e)return K.delete(C.token),C.promise;const{errors:i,layouts:o,leaf:c}=a,f=[...o,c];i.forEach(m=>m?.().catch(()=>{})),f.forEach(m=>m?.[1]().catch(()=>{}));let d=null;const p=y.url?e!==ce(y.url):!1,u=y.route?a.id!==y.route.id:!1,l=hn(y.url,n);let h=!1;const w=f.map((m,g)=>{const v=y.branch[g],b=!!m?.[0]&&(v?.loader!==m[1]||Ke(h,u,p,l,v.server?.uses,r));return b&&(h=!0),b});if(w.some(Boolean)){try{d=await gt(n,w)}catch(m){const g=await M(m,{url:n,params:r,route:{id:e}});return K.has(s)?We({error:g,url:n,params:r,route:a}):de({status:ne(m),error:g,url:n,route:a})}if(d.type==="redirect")return d}const E=d?.nodes;let _=!1;const O=f.map(async(m,g)=>{if(!m)return;const v=y.branch[g],b=E?.[g];if((!b||b.type==="skip")&&m[1]===v?.loader&&!Ke(_,u,p,l,v.universal?.uses,r))return v;if(_=!0,b?.type==="error")throw b;return Ce({loader:m[1],url:n,params:r,route:a,parent:async()=>{const pe={};for(let ge=0;ge<g;ge+=1)Object.assign(pe,(await O[ge])?.data);return pe},server_data_node:Oe(b===void 0&&m[0]?{type:"skip"}:b??null,m[0]?v?.server:void 0)})});for(const m of O)m.catch(()=>{});const S=[];for(let m=0;m<f.length;m+=1)if(f[m])try{S.push(await O[m])}catch(g){if(g instanceof Se)return{type:"redirect",location:g.location};if(K.has(s))return We({error:await M(g,{params:r,url:n,route:{id:a.id}}),url:n,params:r,route:a});let v=ne(g),b;if(E?.includes(g))v=g.status??v,b=g.error;else if(g instanceof le)b=g.body;else{if(await N.updated.check())return await rt(),await q(n);b=await M(g,{params:r,url:n,route:{id:a.id}})}const Q=await pn(m,S,i);return Q?ie({url:n,params:r,branch:S.slice(0,Q.idx).concat(Q.node),status:v,error:b,route:a}):await pt(n,{id:a.id},b,v)}else S.push(void 0);return ie({url:n,params:r,branch:S,status:200,error:null,route:a,form:t?void 0:null})}async function pn(e,t,n){for(;e--;)if(n[e]){let r=e;for(;!t[r];)r-=1;try{return{idx:r+1,node:{node:await n[e](),loader:n[e],data:{},server:null,universal:null}}}catch{continue}}}async function de({status:e,error:t,url:n,route:r}){const a={};let s=null;if(k.server_loads[0]===0)try{const o=await gt(n,[!0]);if(o.type!=="data"||o.nodes[0]&&o.nodes[0].type!=="data")throw 0;s=o.nodes[0]??null}catch{(n.origin!==Z||n.pathname!==location.pathname||Pe)&&await q(n)}try{const o=await Ce({loader:be,url:n,params:a,route:r,parent:()=>Promise.resolve({}),server_data_node:Oe(s)}),c={node:await re(),loader:re,universal:null,server:null,data:null};return ie({url:n,params:a,branch:[o,c],status:e,error:t,route:null})}catch(o){if(o instanceof Se)return lt(new URL(o.location,location.href),{},0);throw o}}async function gn(e){const t=e.href;if(ee.has(t))return ee.get(t);let n;try{const r=(async()=>{let a=await k.hooks.reroute({url:new URL(e),fetch:async(s,i)=>ut(s,i,e).promise})??e;if(typeof a=="string"){const s=new URL(e);k.hash?s.hash=a:s.pathname=a,a=s}return a})();ee.set(t,r),n=await r}catch{ee.delete(t);return}return n}async function he(e,t){if(e&&!ue(e,I,k.hash)){const n=await gn(e);if(!n)return;const r=_n(n);for(const a of Le){const s=a.exec(r);if(s)return{id:ce(e),invalidating:t,route:a,params:bt(s),url:e}}}}function _n(e){return vt(k.hash?e.hash.replace(/^#/,"").replace(/[?#].+/,""):e.pathname.slice(I.length))||"/"}function ce(e){return(k.hash?e.hash.replace(/^#/,""):e.pathname)+e.search}function ht({url:e,type:t,intent:n,delta:r,event:a}){let s=!1;const i=Ne(y,n,e,t);r!==void 0&&(i.navigation.delta=r),a!==void 0&&(i.navigation.event=a);const o={...i.navigation,cancel:()=>{s=!0,i.reject(new Error("navigation cancelled"))}};return X||at.forEach(c=>c(o)),s?null:i}async function V({type:e,url:t,popped:n,keepfocus:r,noscroll:a,replace_state:s,state:i={},redirect_count:o=0,nav_token:c={},accept:f=qe,block:d=qe,event:p}){const u=$;$=c;const l=await he(t,!1),h=e==="enter"?Ne(y,l,t,e):ht({url:t,type:e,delta:n?.delta,intent:l,event:p});if(!h){d(),$===c&&($=u);return}const w=A,E=T;f(),X=!0,se&&h.navigation.type!=="enter"&&N.navigating.set(J.current=h.navigation);let _=l&&await dt(l);if(!_){if(ue(t,I,k.hash))return await q(t,s);_=await pt(t,{id:null},await M(new Re(404,"Not Found",`Not found: ${t.pathname}`),{url:t,params:{},route:{id:null}}),404,s)}if(t=l?.url||t,$!==c)return h.reject(new Error("navigation aborted")),!1;if(_.type==="redirect"){if(o<20){await V({type:e,url:new URL(_.location,t),popped:n,keepfocus:r,noscroll:a,replace_state:s,state:i,redirect_count:o+1,nav_token:c}),h.fulfil(void 0);return}_=await de({status:500,error:await M(new Error("Redirect loop"),{url:t,params:{},route:{id:null}}),url:t,route:{id:null}})}else _.props.page.status>=400&&await N.updated.check()&&(await rt(),await q(t,s));if(un(),Ue(w),it(E),_.props.page.url.pathname!==t.pathname&&(t.pathname=_.props.page.url.pathname),i=n?n.state:i,!n){const g=s?0:1,v={[F]:A+=g,[W]:T+=g,[Ze]:i};(s?history.replaceState:history.pushState).call(history,v,"",t),s||ln(A,T)}if(C=null,_.props.page.state=i,se){const g=(await Promise.all(Array.from(fn,v=>v(h.navigation)))).filter(v=>typeof v=="function");if(g.length>0){let v=function(){g.forEach(b=>{H.delete(b)})};g.push(v),g.forEach(b=>{H.add(b)})}y=_.state,_.props.page&&(_.props.page.url=t),st.$set(_.props),tn(_.props.page),ot=!0}else ft(_,ke,!1);const{activeElement:O}=document;await sn();let S=n?n.scroll:a?fe():null;if(Ge){const g=t.hash&&document.getElementById(mt(t));if(S)scrollTo(S.x,S.y);else if(g){g.scrollIntoView();const{top:v,left:b}=g.getBoundingClientRect();S={x:pageXOffset+b,y:pageYOffset+v}}else scrollTo(0,0)}const m=document.activeElement!==O&&document.activeElement!==document.body;!r&&!m&&bn(t,S),Ge=!0,_.props.page&&Object.assign(R,_.props.page),X=!1,e==="popstate"&&ct(T),h.fulfil(void 0),H.forEach(g=>g(h.navigation)),N.navigating.set(J.current=null)}async function pt(e,t,n,r,a){return e.origin===Z&&e.pathname===location.pathname&&!Pe?await de({status:r,error:n,url:e,route:t}):await q(e,a)}function mn(){let e,t,n;x.addEventListener("mousemove",o=>{const c=o.target;clearTimeout(e),e=setTimeout(()=>{s(c,j.hover)},20)});function r(o){o.defaultPrevented||s(o.composedPath()[0],j.tap)}x.addEventListener("mousedown",r),x.addEventListener("touchstart",r,{passive:!0});const a=new IntersectionObserver(o=>{for(const c of o)c.isIntersecting&&(we(new URL(c.target.href)),a.unobserve(c.target))},{threshold:0});async function s(o,c){const f=et(o,x),d=f===t&&c>=n;if(!f||d)return;const{url:p,external:u,download:l}=ve(f,I,k.hash);if(u||l)return;const h=te(f),w=p&&ce(y.url)===ce(p);if(!(h.reload||w))if(c<=h.preload_data){t=f,n=j.tap;const E=await he(p,!1);if(!E)return;dn(E)}else c<=h.preload_code&&(t=f,n=c,we(p))}function i(){a.disconnect();for(const o of x.querySelectorAll("a")){const{url:c,external:f,download:d}=ve(o,I,k.hash);if(f||d)continue;const p=te(o);p.reload||(p.preload_code===j.viewport&&a.observe(o),p.preload_code===j.eager&&we(c))}}H.add(i),i()}function M(e,t){if(e instanceof le)return e.body;const n=ne(e),r=Qt(e);return k.hooks.handleError({error:e,event:t,status:n,message:r})??{message:r}}function Un(e,t={}){return e=new URL(Ie(e)),e.origin!==Z?Promise.reject(new Error("goto: invalid URL")):lt(e,t,0)}function yn(e){if(typeof e=="function")ae.push(e);else{const{href:t}=new URL(e,location.href);ae.push(n=>n.href===t)}}function wn(){history.scrollRestoration="manual",addEventListener("beforeunload",t=>{let n=!1;if(He(),!X){const r=Ne(y,void 0,null,"leave"),a={...r.navigation,cancel:()=>{n=!0,r.reject(new Error("navigation cancelled"))}};at.forEach(s=>s(a))}n?(t.preventDefault(),t.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&He()}),navigator.connection?.saveData||mn(),x.addEventListener("click",async t=>{if(t.button||t.which!==1||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.defaultPrevented)return;const n=et(t.composedPath()[0],x);if(!n)return;const{url:r,external:a,target:s,download:i}=ve(n,I,k.hash);if(!r)return;if(s==="_parent"||s==="_top"){if(window.parent!==window)return}else if(s&&s!=="_self")return;const o=te(n);if(!(n instanceof SVGAElement)&&r.protocol!==location.protocol&&!(r.protocol==="https:"||r.protocol==="http:")||i)return;const[f,d]=(k.hash?r.hash.replace(/^#/,""):r.href).split("#"),p=f===_e(location);if(a||o.reload&&(!p||!d)){ht({url:r,type:"link",event:t})?X=!0:t.preventDefault();return}if(d!==void 0&&p){const[,u]=y.url.href.split("#");if(u===d){if(t.preventDefault(),d===""||d==="top"&&n.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const l=n.ownerDocument.getElementById(decodeURIComponent(d));l&&(l.scrollIntoView(),l.focus())}return}if(G=!0,Ue(A),e(r),!o.replace_state)return;G=!1}t.preventDefault(),await new Promise(u=>{requestAnimationFrame(()=>{setTimeout(u,0)}),setTimeout(u,100)}),await V({type:"link",url:r,keepfocus:o.keepfocus,noscroll:o.noscroll,replace_state:o.replace_state??r.href===location.href,event:t})}),x.addEventListener("submit",t=>{if(t.defaultPrevented)return;const n=HTMLFormElement.prototype.cloneNode.call(t.target),r=t.submitter;if((r?.formTarget||n.target)==="_blank"||(r?.formMethod||n.method)!=="get")return;const i=new URL(r?.hasAttribute("formaction")&&r?.formAction||n.action);if(ue(i,I,!1))return;const o=t.target,c=te(o);if(c.reload)return;t.preventDefault(),t.stopPropagation();const f=new FormData(o,r);i.search=new URLSearchParams(f).toString(),V({type:"form",url:i,keepfocus:c.keepfocus,noscroll:c.noscroll,replace_state:c.replace_state??i.href===location.href,event:t})}),addEventListener("popstate",async t=>{if(!Ee){if(t.state?.[F]){const n=t.state[F];if($={},n===A)return;const r=D[n],a=t.state[Ze]??{},s=new URL(t.state[$t]??location.href),i=t.state[W],o=y.url?_e(location)===_e(y.url):!1;if(i===T&&(ot||o)){a!==R.state&&(R.state=a),e(s),D[A]=fe(),r&&scrollTo(r.x,r.y),A=n;return}const f=n-A;await V({type:"popstate",url:s,popped:{state:a,scroll:r,delta:f},accept:()=>{A=n,T=i},block:()=>{history.go(-f)},nav_token:$,event:t})}else if(!G){const n=new URL(location.href);e(n),k.hash&&location.reload()}}}),addEventListener("hashchange",()=>{G&&(G=!1,history.replaceState({...history.state,[F]:++A,[W]:T},"",location.href))});for(const t of document.querySelectorAll("link"))cn.has(t.rel)&&(t.href=t.href);addEventListener("pageshow",t=>{t.persisted&&N.navigating.set(J.current=null)});function e(t){y.url=R.url=t,N.page.set(je(R)),N.page.notify()}}async function vn(e,{status:t=200,error:n,node_ids:r,params:a,route:s,server_route:i,data:o,form:c}){Pe=!0;const f=new URL(location.href);let d;({params:a={},route:s={id:null}}=await he(f,!1)||{}),d=Le.find(({id:l})=>l===s.id);let p,u=!0;try{const l=r.map(async(w,E)=>{const _=o[E];return _?.uses&&(_.uses=_t(_.uses)),Ce({loader:k.nodes[w],url:f,params:a,route:s,parent:async()=>{const O={};for(let S=0;S<E;S+=1)Object.assign(O,(await l[S]).data);return O},server_data_node:Oe(_)})}),h=await Promise.all(l);if(d){const w=d.layouts;for(let E=0;E<w.length;E++)w[E]||h.splice(E,0,void 0)}p=ie({url:f,params:a,branch:h,status:t,error:n,form:c,route:d??null})}catch(l){if(l instanceof Se){await q(new URL(l.location,location.href));return}p=await de({status:ne(l),error:await M(l,{url:f,params:a,route:s}),url:f,route:s}),e.textContent="",u=!1}p.props.page&&(p.props.page.state={}),ft(p,e,u)}async function gt(e,t){const n=new URL(e);n.pathname=an(e.pathname),e.pathname.endsWith("/")&&n.searchParams.append(Zt,"1"),n.searchParams.append(Xt,t.map(s=>s?"1":"0").join(""));const r=window.fetch,a=await r(n.href,{});if(!a.ok){let s;throw a.headers.get("content-type")?.includes("application/json")?s=await a.json():a.status===404?s="Not Found":a.status===500&&(s="Internal Error"),new le(a.status,s)}return new Promise(async s=>{const i=new Map,o=a.body.getReader();function c(d){return Wt(d,{...k.decoders,Promise:p=>new Promise((u,l)=>{i.set(p,{fulfil:u,reject:l})})})}let f="";for(;;){const{done:d,value:p}=await o.read();if(d&&!f)break;for(f+=!p&&f?`
|
|
2
|
-
`:At.decode(p,{stream:!0});;){const u=f.indexOf(`
|
|
3
|
-
`);if(u===-1)break;const l=JSON.parse(f.slice(0,u));if(f=f.slice(u+1),l.type==="redirect")return s(l);if(l.type==="data")l.nodes?.forEach(h=>{h?.type==="data"&&(h.uses=_t(h.uses),h.data=c(h.data))}),s(l);else if(l.type==="chunk"){const{id:h,data:w,error:E}=l,_=i.get(h);i.delete(h),E?_.reject(c(E)):_.fulfil(c(w))}}}})}function _t(e){return{dependencies:new Set(e?.dependencies??[]),params:new Set(e?.params??[]),parent:!!e?.parent,route:!!e?.route,url:!!e?.url,search_params:new Set(e?.search_params??[])}}let Ee=!1;function bn(e,t=null){const n=document.querySelector("[autofocus]");if(n)n.focus();else{const r=mt(e);if(r&&document.getElementById(r)){const{x:s,y:i}=t??fe();setTimeout(()=>{const o=history.state;Ee=!0,location.replace(`#${r}`),k.hash&&location.replace(e.hash),history.replaceState(o,"",e.hash),scrollTo(s,i),Ee=!1})}else{const s=document.body,i=s.getAttribute("tabindex");s.tabIndex=-1,s.focus({preventScroll:!0,focusVisible:!1}),i!==null?s.setAttribute("tabindex",i):s.removeAttribute("tabindex")}const a=getSelection();if(a&&a.type!=="None"){const s=[];for(let i=0;i<a.rangeCount;i+=1)s.push(a.getRangeAt(i));setTimeout(()=>{if(a.rangeCount===s.length){for(let i=0;i<a.rangeCount;i+=1){const o=s[i],c=a.getRangeAt(i);if(o.commonAncestorContainer!==c.commonAncestorContainer||o.startContainer!==c.startContainer||o.endContainer!==c.endContainer||o.startOffset!==c.startOffset||o.endOffset!==c.endOffset)return}a.removeAllRanges()}})}}}function Ne(e,t,n,r){let a,s;const i=new Promise((c,f)=>{a=c,s=f});return i.catch(()=>{}),{navigation:{from:{params:e.params,route:{id:e.route?.id??null},url:e.url},to:n&&{params:t?.params??null,route:{id:t?.route?.id??null},url:n},willUnload:!t,type:r,complete:i},fulfil:a,reject:s}}function je(e){return{data:e.data,error:e.error,form:e.form,params:e.params,route:e.route,state:e.state,status:e.status,url:e.url}}function kn(e){const t=new URL(e);return t.hash=decodeURIComponent(e.hash),t}function mt(e){let t;if(k.hash){const[,,n]=e.hash.split("#",3);t=n??""}else t=e.hash.slice(1);return decodeURIComponent(t)}export{In as a,Un as g,An as l,R as p,N as s};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as o,a as r}from"../chunks/BaNghdtJ.js";export{o as load_css,r as start};
|