lula2 0.3.0 → 0.3.2-nightly.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/_app/immutable/assets/0.CLKu6Q8_.css +1 -0
  2. package/dist/_app/immutable/chunks/0xMSlW4Y.js +65 -0
  3. package/dist/_app/immutable/chunks/{BtOhWAVU.js → 152nb-LI.js} +2 -2
  4. package/dist/_app/immutable/chunks/{C5zWTfmV.js → 1spjHGNy.js} +1 -1
  5. package/dist/_app/immutable/chunks/{DnJ0bPgj.js → BtuEtkd3.js} +1 -1
  6. package/dist/_app/immutable/chunks/C113Bo4B.js +2 -0
  7. package/dist/_app/immutable/chunks/{CoF2vljD.js → CNOPXlDW.js} +1 -1
  8. package/dist/_app/immutable/chunks/{DqsOU3kV.js → DY3-lqhI.js} +1 -1
  9. package/dist/_app/immutable/chunks/DrOkR2YZ.js +3 -0
  10. package/dist/_app/immutable/chunks/rsJnd9Tf.js +1 -0
  11. package/dist/_app/immutable/entry/{app.3K_9hfHX.js → app.CqP__jbe.js} +2 -2
  12. package/dist/_app/immutable/entry/start.C1hW6Z_g.js +1 -0
  13. package/dist/_app/immutable/nodes/{0.CHOlW0sh.js → 0.BWuQSqPo.js} +1 -1
  14. package/dist/_app/immutable/nodes/{1.wExp2Xq4.js → 1.COMBeJ1R.js} +1 -1
  15. package/dist/_app/immutable/nodes/{2.BrqnOQ4V.js → 2.6bQMjmMR.js} +1 -1
  16. package/dist/_app/immutable/nodes/{3.Bo5PnZob.js → 3.BBPnkpxM.js} +1 -1
  17. package/dist/_app/immutable/nodes/{4.C_hUQcnJ.js → 4.CGIAObAE.js} +1 -1
  18. package/dist/_app/version.json +1 -1
  19. package/dist/cli/commands/ui.js +21 -13
  20. package/dist/cli/server/index.js +21 -13
  21. package/dist/cli/server/server.js +21 -13
  22. package/dist/cli/server/serverState.js +10 -4
  23. package/dist/cli/server/spreadsheetRoutes.js +10 -8
  24. package/dist/cli/server/websocketServer.js +21 -13
  25. package/dist/index.html +10 -10
  26. package/dist/index.js +21 -13
  27. package/package.json +21 -21
  28. package/src/lib/actions/clickOutside.ts +24 -0
  29. package/src/lib/components/controls/ControlsList.svelte +101 -75
  30. package/src/lib/components/controls/tabs/CustomFieldsTab.svelte +1 -1
  31. package/src/lib/components/controls/tabs/TimelineTab.svelte +1 -1
  32. package/src/lib/components/controls/utils/ProcessedTextRenderer.svelte +1 -1
  33. package/src/lib/components/forms/DynamicControlForm.svelte +2 -2
  34. package/src/lib/components/setup/ExistingControlSets.svelte +0 -1
  35. package/src/lib/components/setup/SpreadsheetImport.svelte +10 -10
  36. package/src/lib/components/ui/CustomDropdown.svelte +96 -0
  37. package/src/lib/components/ui/FilterBuilder.svelte +415 -0
  38. package/src/stores/compliance.ts +149 -39
  39. package/dist/_app/immutable/assets/0.Dv98laBw.css +0 -1
  40. package/dist/_app/immutable/chunks/B30ytfCz.js +0 -1
  41. package/dist/_app/immutable/chunks/Cby0Z7eP.js +0 -2
  42. package/dist/_app/immutable/chunks/CwZwnEjo.js +0 -66
  43. package/dist/_app/immutable/chunks/D7S8Dq6O.js +0 -3
  44. package/dist/_app/immutable/entry/start.cmFs1yVq.js +0 -1
@@ -1951,7 +1951,10 @@ var init_fileStore = __esm({
1951
1951
  const controlId = mapping.control_id;
1952
1952
  const family = this.getControlFamily(controlId);
1953
1953
  const familyDir = join2(this.mappingsDir, family);
1954
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
1954
+ const mappingFile = join2(
1955
+ familyDir,
1956
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
1957
+ );
1955
1958
  if (!existsSync2(familyDir)) {
1956
1959
  mkdirSync(familyDir, { recursive: true });
1957
1960
  }
@@ -2049,7 +2052,10 @@ var init_fileStore = __esm({
2049
2052
  for (const [controlId, controlMappings] of mappingsByControl) {
2050
2053
  const family = this.getControlFamily(controlId);
2051
2054
  const familyDir = join2(this.mappingsDir, family);
2052
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
2055
+ const mappingFile = join2(
2056
+ familyDir,
2057
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
2058
+ );
2053
2059
  if (!existsSync2(familyDir)) {
2054
2060
  mkdirSync(familyDir, { recursive: true });
2055
2061
  }
@@ -2555,7 +2561,7 @@ var init_gitHistory = __esm({
2555
2561
  changes = diffResult.changes;
2556
2562
  diff = diffResult.diff;
2557
2563
  yamlDiff = diffResult.yamlDiff;
2558
- } catch (error) {
2564
+ } catch {
2559
2565
  }
2560
2566
  }
2561
2567
  gitCommits.push({
@@ -2612,7 +2618,7 @@ var init_gitHistory = __esm({
2612
2618
  diff,
2613
2619
  yamlDiff
2614
2620
  };
2615
- } catch (error) {
2621
+ } catch {
2616
2622
  return { changes: { insertions: 0, deletions: 0, files: 1 } };
2617
2623
  }
2618
2624
  }
@@ -3287,7 +3293,7 @@ var init_spreadsheetRoutes = __esm({
3287
3293
  if (req.body.fieldSchema) {
3288
3294
  try {
3289
3295
  frontendFieldSchema = JSON.parse(req.body.fieldSchema);
3290
- } catch (e) {
3296
+ } catch {
3291
3297
  }
3292
3298
  }
3293
3299
  const fields = {};
@@ -3347,7 +3353,9 @@ var init_spreadsheetRoutes = __esm({
3347
3353
  uiType = "long_text";
3348
3354
  }
3349
3355
  let category = frontendConfig?.category || "custom";
3350
- if (!frontendConfig) {
3356
+ if (justificationFields.includes(fieldName)) {
3357
+ category = "mappings";
3358
+ } else if (!frontendConfig) {
3351
3359
  if (fieldName.includes("status") || fieldName.includes("state")) {
3352
3360
  category = "compliance";
3353
3361
  } else if (fieldName.includes("title") || fieldName.includes("name") || fieldName.includes("description")) {
@@ -3375,8 +3383,8 @@ var init_spreadsheetRoutes = __esm({
3375
3383
  // Control ID is always first
3376
3384
  category: isControlIdField ? "core" : category,
3377
3385
  // Control ID is always core
3378
- tab: isControlIdField ? "overview" : frontendConfig?.tab || void 0
3379
- // Control ID is always in overview
3386
+ tab: isControlIdField ? "overview" : justificationFields.includes(fieldName) ? "mappings" : frontendConfig?.tab || void 0
3387
+ // Use frontend config or default
3380
3388
  };
3381
3389
  if (uiType === "select") {
3382
3390
  fieldDef.options = Array.from(metadata.uniqueValues).sort();
@@ -3439,7 +3447,7 @@ var init_spreadsheetRoutes = __esm({
3439
3447
  if (fieldName === "family") return;
3440
3448
  if (justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
3441
3449
  justificationContents.push(control[fieldName]);
3442
- return;
3450
+ filteredControl[fieldName] = control[fieldName];
3443
3451
  }
3444
3452
  const isInFrontendSchema = frontendFieldSchema?.some((f) => f.fieldName === fieldName);
3445
3453
  const isInFieldsMetadata = fields.hasOwnProperty(fieldName);
@@ -3545,7 +3553,7 @@ var init_spreadsheetRoutes = __esm({
3545
3553
  if (!worksheet) {
3546
3554
  return res.status(400).json({ error: "No worksheet found in file" });
3547
3555
  }
3548
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3556
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3549
3557
  const rowData = [];
3550
3558
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3551
3559
  rowData[colNumber - 1] = cell.value;
@@ -3555,7 +3563,7 @@ var init_spreadsheetRoutes = __esm({
3555
3563
  }
3556
3564
  const headerCandidates = rows.slice(0, 5).map((row, index) => ({
3557
3565
  row: index + 1,
3558
- preview: row.slice(0, 4).filter((v) => v != null).join(", ") + (row.length > 4 ? ", ..." : "")
3566
+ preview: row.slice(0, 4).filter((v) => v !== null).filter((v) => v !== void 0).join(", ") + (row.length > 4 ? ", ..." : "")
3559
3567
  }));
3560
3568
  res.json({
3561
3569
  sheets,
@@ -3590,7 +3598,7 @@ var init_spreadsheetRoutes = __esm({
3590
3598
  if (!worksheet) {
3591
3599
  return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
3592
3600
  }
3593
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3601
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3594
3602
  const rowData = [];
3595
3603
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3596
3604
  rowData[colNumber - 1] = cell.value;
@@ -4709,7 +4717,7 @@ var WebSocketManager = class {
4709
4717
  totalCommits: controlHistory.totalCommits,
4710
4718
  commits: controlHistory.commits?.length || 0
4711
4719
  });
4712
- const mappingFilename = `${control.id}-mappings.yaml`;
4720
+ const mappingFilename = `${control.id.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`;
4713
4721
  const mappingPath = join5(currentPath2, "mappings", family, mappingFilename);
4714
4722
  let mappingHistory = { commits: [], totalCommits: 0 };
4715
4723
  if (existsSync6(mappingPath)) {
@@ -1933,7 +1933,10 @@ var init_fileStore = __esm({
1933
1933
  const controlId = mapping.control_id;
1934
1934
  const family = this.getControlFamily(controlId);
1935
1935
  const familyDir = join2(this.mappingsDir, family);
1936
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
1936
+ const mappingFile = join2(
1937
+ familyDir,
1938
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
1939
+ );
1937
1940
  if (!existsSync2(familyDir)) {
1938
1941
  mkdirSync(familyDir, { recursive: true });
1939
1942
  }
@@ -2031,7 +2034,10 @@ var init_fileStore = __esm({
2031
2034
  for (const [controlId, controlMappings] of mappingsByControl) {
2032
2035
  const family = this.getControlFamily(controlId);
2033
2036
  const familyDir = join2(this.mappingsDir, family);
2034
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
2037
+ const mappingFile = join2(
2038
+ familyDir,
2039
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
2040
+ );
2035
2041
  if (!existsSync2(familyDir)) {
2036
2042
  mkdirSync(familyDir, { recursive: true });
2037
2043
  }
@@ -2537,7 +2543,7 @@ var init_gitHistory = __esm({
2537
2543
  changes = diffResult.changes;
2538
2544
  diff = diffResult.diff;
2539
2545
  yamlDiff = diffResult.yamlDiff;
2540
- } catch (error) {
2546
+ } catch {
2541
2547
  }
2542
2548
  }
2543
2549
  gitCommits.push({
@@ -2594,7 +2600,7 @@ var init_gitHistory = __esm({
2594
2600
  diff,
2595
2601
  yamlDiff
2596
2602
  };
2597
- } catch (error) {
2603
+ } catch {
2598
2604
  return { changes: { insertions: 0, deletions: 0, files: 1 } };
2599
2605
  }
2600
2606
  }
@@ -3269,7 +3275,7 @@ var init_spreadsheetRoutes = __esm({
3269
3275
  if (req.body.fieldSchema) {
3270
3276
  try {
3271
3277
  frontendFieldSchema = JSON.parse(req.body.fieldSchema);
3272
- } catch (e) {
3278
+ } catch {
3273
3279
  }
3274
3280
  }
3275
3281
  const fields = {};
@@ -3329,7 +3335,9 @@ var init_spreadsheetRoutes = __esm({
3329
3335
  uiType = "long_text";
3330
3336
  }
3331
3337
  let category = frontendConfig?.category || "custom";
3332
- if (!frontendConfig) {
3338
+ if (justificationFields.includes(fieldName)) {
3339
+ category = "mappings";
3340
+ } else if (!frontendConfig) {
3333
3341
  if (fieldName.includes("status") || fieldName.includes("state")) {
3334
3342
  category = "compliance";
3335
3343
  } else if (fieldName.includes("title") || fieldName.includes("name") || fieldName.includes("description")) {
@@ -3357,8 +3365,8 @@ var init_spreadsheetRoutes = __esm({
3357
3365
  // Control ID is always first
3358
3366
  category: isControlIdField ? "core" : category,
3359
3367
  // Control ID is always core
3360
- tab: isControlIdField ? "overview" : frontendConfig?.tab || void 0
3361
- // Control ID is always in overview
3368
+ tab: isControlIdField ? "overview" : justificationFields.includes(fieldName) ? "mappings" : frontendConfig?.tab || void 0
3369
+ // Use frontend config or default
3362
3370
  };
3363
3371
  if (uiType === "select") {
3364
3372
  fieldDef.options = Array.from(metadata.uniqueValues).sort();
@@ -3421,7 +3429,7 @@ var init_spreadsheetRoutes = __esm({
3421
3429
  if (fieldName === "family") return;
3422
3430
  if (justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
3423
3431
  justificationContents.push(control[fieldName]);
3424
- return;
3432
+ filteredControl[fieldName] = control[fieldName];
3425
3433
  }
3426
3434
  const isInFrontendSchema = frontendFieldSchema?.some((f) => f.fieldName === fieldName);
3427
3435
  const isInFieldsMetadata = fields.hasOwnProperty(fieldName);
@@ -3527,7 +3535,7 @@ var init_spreadsheetRoutes = __esm({
3527
3535
  if (!worksheet) {
3528
3536
  return res.status(400).json({ error: "No worksheet found in file" });
3529
3537
  }
3530
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3538
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3531
3539
  const rowData = [];
3532
3540
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3533
3541
  rowData[colNumber - 1] = cell.value;
@@ -3537,7 +3545,7 @@ var init_spreadsheetRoutes = __esm({
3537
3545
  }
3538
3546
  const headerCandidates = rows.slice(0, 5).map((row, index) => ({
3539
3547
  row: index + 1,
3540
- preview: row.slice(0, 4).filter((v) => v != null).join(", ") + (row.length > 4 ? ", ..." : "")
3548
+ preview: row.slice(0, 4).filter((v) => v !== null).filter((v) => v !== void 0).join(", ") + (row.length > 4 ? ", ..." : "")
3541
3549
  }));
3542
3550
  res.json({
3543
3551
  sheets,
@@ -3572,7 +3580,7 @@ var init_spreadsheetRoutes = __esm({
3572
3580
  if (!worksheet) {
3573
3581
  return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
3574
3582
  }
3575
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3583
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3576
3584
  const rowData = [];
3577
3585
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3578
3586
  rowData[colNumber - 1] = cell.value;
@@ -4686,7 +4694,7 @@ var WebSocketManager = class {
4686
4694
  totalCommits: controlHistory.totalCommits,
4687
4695
  commits: controlHistory.commits?.length || 0
4688
4696
  });
4689
- const mappingFilename = `${control.id}-mappings.yaml`;
4697
+ const mappingFilename = `${control.id.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`;
4690
4698
  const mappingPath = join5(currentPath2, "mappings", family, mappingFilename);
4691
4699
  let mappingHistory = { commits: [], totalCommits: 0 };
4692
4700
  if (existsSync5(mappingPath)) {
@@ -1933,7 +1933,10 @@ var init_fileStore = __esm({
1933
1933
  const controlId = mapping.control_id;
1934
1934
  const family = this.getControlFamily(controlId);
1935
1935
  const familyDir = join2(this.mappingsDir, family);
1936
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
1936
+ const mappingFile = join2(
1937
+ familyDir,
1938
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
1939
+ );
1937
1940
  if (!existsSync2(familyDir)) {
1938
1941
  mkdirSync(familyDir, { recursive: true });
1939
1942
  }
@@ -2031,7 +2034,10 @@ var init_fileStore = __esm({
2031
2034
  for (const [controlId, controlMappings] of mappingsByControl) {
2032
2035
  const family = this.getControlFamily(controlId);
2033
2036
  const familyDir = join2(this.mappingsDir, family);
2034
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
2037
+ const mappingFile = join2(
2038
+ familyDir,
2039
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
2040
+ );
2035
2041
  if (!existsSync2(familyDir)) {
2036
2042
  mkdirSync(familyDir, { recursive: true });
2037
2043
  }
@@ -2537,7 +2543,7 @@ var init_gitHistory = __esm({
2537
2543
  changes = diffResult.changes;
2538
2544
  diff = diffResult.diff;
2539
2545
  yamlDiff = diffResult.yamlDiff;
2540
- } catch (error) {
2546
+ } catch {
2541
2547
  }
2542
2548
  }
2543
2549
  gitCommits.push({
@@ -2594,7 +2600,7 @@ var init_gitHistory = __esm({
2594
2600
  diff,
2595
2601
  yamlDiff
2596
2602
  };
2597
- } catch (error) {
2603
+ } catch {
2598
2604
  return { changes: { insertions: 0, deletions: 0, files: 1 } };
2599
2605
  }
2600
2606
  }
@@ -3269,7 +3275,7 @@ var init_spreadsheetRoutes = __esm({
3269
3275
  if (req.body.fieldSchema) {
3270
3276
  try {
3271
3277
  frontendFieldSchema = JSON.parse(req.body.fieldSchema);
3272
- } catch (e) {
3278
+ } catch {
3273
3279
  }
3274
3280
  }
3275
3281
  const fields = {};
@@ -3329,7 +3335,9 @@ var init_spreadsheetRoutes = __esm({
3329
3335
  uiType = "long_text";
3330
3336
  }
3331
3337
  let category = frontendConfig?.category || "custom";
3332
- if (!frontendConfig) {
3338
+ if (justificationFields.includes(fieldName)) {
3339
+ category = "mappings";
3340
+ } else if (!frontendConfig) {
3333
3341
  if (fieldName.includes("status") || fieldName.includes("state")) {
3334
3342
  category = "compliance";
3335
3343
  } else if (fieldName.includes("title") || fieldName.includes("name") || fieldName.includes("description")) {
@@ -3357,8 +3365,8 @@ var init_spreadsheetRoutes = __esm({
3357
3365
  // Control ID is always first
3358
3366
  category: isControlIdField ? "core" : category,
3359
3367
  // Control ID is always core
3360
- tab: isControlIdField ? "overview" : frontendConfig?.tab || void 0
3361
- // Control ID is always in overview
3368
+ tab: isControlIdField ? "overview" : justificationFields.includes(fieldName) ? "mappings" : frontendConfig?.tab || void 0
3369
+ // Use frontend config or default
3362
3370
  };
3363
3371
  if (uiType === "select") {
3364
3372
  fieldDef.options = Array.from(metadata.uniqueValues).sort();
@@ -3421,7 +3429,7 @@ var init_spreadsheetRoutes = __esm({
3421
3429
  if (fieldName === "family") return;
3422
3430
  if (justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
3423
3431
  justificationContents.push(control[fieldName]);
3424
- return;
3432
+ filteredControl[fieldName] = control[fieldName];
3425
3433
  }
3426
3434
  const isInFrontendSchema = frontendFieldSchema?.some((f) => f.fieldName === fieldName);
3427
3435
  const isInFieldsMetadata = fields.hasOwnProperty(fieldName);
@@ -3527,7 +3535,7 @@ var init_spreadsheetRoutes = __esm({
3527
3535
  if (!worksheet) {
3528
3536
  return res.status(400).json({ error: "No worksheet found in file" });
3529
3537
  }
3530
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3538
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3531
3539
  const rowData = [];
3532
3540
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3533
3541
  rowData[colNumber - 1] = cell.value;
@@ -3537,7 +3545,7 @@ var init_spreadsheetRoutes = __esm({
3537
3545
  }
3538
3546
  const headerCandidates = rows.slice(0, 5).map((row, index) => ({
3539
3547
  row: index + 1,
3540
- preview: row.slice(0, 4).filter((v) => v != null).join(", ") + (row.length > 4 ? ", ..." : "")
3548
+ preview: row.slice(0, 4).filter((v) => v !== null).filter((v) => v !== void 0).join(", ") + (row.length > 4 ? ", ..." : "")
3541
3549
  }));
3542
3550
  res.json({
3543
3551
  sheets,
@@ -3572,7 +3580,7 @@ var init_spreadsheetRoutes = __esm({
3572
3580
  if (!worksheet) {
3573
3581
  return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
3574
3582
  }
3575
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
3583
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
3576
3584
  const rowData = [];
3577
3585
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
3578
3586
  rowData[colNumber - 1] = cell.value;
@@ -4686,7 +4694,7 @@ var WebSocketManager = class {
4686
4694
  totalCommits: controlHistory.totalCommits,
4687
4695
  commits: controlHistory.commits?.length || 0
4688
4696
  });
4689
- const mappingFilename = `${control.id}-mappings.yaml`;
4697
+ const mappingFilename = `${control.id.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`;
4690
4698
  const mappingPath = join5(currentPath2, "mappings", family, mappingFilename);
4691
4699
  let mappingHistory = { commits: [], totalCommits: 0 };
4692
4700
  if (existsSync5(mappingPath)) {
@@ -354,7 +354,10 @@ var FileStore = class {
354
354
  const controlId = mapping.control_id;
355
355
  const family = this.getControlFamily(controlId);
356
356
  const familyDir = join2(this.mappingsDir, family);
357
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
357
+ const mappingFile = join2(
358
+ familyDir,
359
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
360
+ );
358
361
  if (!existsSync2(familyDir)) {
359
362
  mkdirSync(familyDir, { recursive: true });
360
363
  }
@@ -452,7 +455,10 @@ var FileStore = class {
452
455
  for (const [controlId, controlMappings] of mappingsByControl) {
453
456
  const family = this.getControlFamily(controlId);
454
457
  const familyDir = join2(this.mappingsDir, family);
455
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
458
+ const mappingFile = join2(
459
+ familyDir,
460
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
461
+ );
456
462
  if (!existsSync2(familyDir)) {
457
463
  mkdirSync(familyDir, { recursive: true });
458
464
  }
@@ -944,7 +950,7 @@ var GitHistoryUtil = class {
944
950
  changes = diffResult.changes;
945
951
  diff = diffResult.diff;
946
952
  yamlDiff = diffResult.yamlDiff;
947
- } catch (error) {
953
+ } catch {
948
954
  }
949
955
  }
950
956
  gitCommits.push({
@@ -1001,7 +1007,7 @@ var GitHistoryUtil = class {
1001
1007
  diff,
1002
1008
  yamlDiff
1003
1009
  };
1004
- } catch (error) {
1010
+ } catch {
1005
1011
  return { changes: { insertions: 0, deletions: 0, files: 1 } };
1006
1012
  }
1007
1013
  }
@@ -234,7 +234,7 @@ router.post("/import-spreadsheet", upload.single("file"), async (req, res) => {
234
234
  if (req.body.fieldSchema) {
235
235
  try {
236
236
  frontendFieldSchema = JSON.parse(req.body.fieldSchema);
237
- } catch (e) {
237
+ } catch {
238
238
  }
239
239
  }
240
240
  const fields = {};
@@ -294,7 +294,9 @@ router.post("/import-spreadsheet", upload.single("file"), async (req, res) => {
294
294
  uiType = "long_text";
295
295
  }
296
296
  let category = frontendConfig?.category || "custom";
297
- if (!frontendConfig) {
297
+ if (justificationFields.includes(fieldName)) {
298
+ category = "mappings";
299
+ } else if (!frontendConfig) {
298
300
  if (fieldName.includes("status") || fieldName.includes("state")) {
299
301
  category = "compliance";
300
302
  } else if (fieldName.includes("title") || fieldName.includes("name") || fieldName.includes("description")) {
@@ -322,8 +324,8 @@ router.post("/import-spreadsheet", upload.single("file"), async (req, res) => {
322
324
  // Control ID is always first
323
325
  category: isControlIdField ? "core" : category,
324
326
  // Control ID is always core
325
- tab: isControlIdField ? "overview" : frontendConfig?.tab || void 0
326
- // Control ID is always in overview
327
+ tab: isControlIdField ? "overview" : justificationFields.includes(fieldName) ? "mappings" : frontendConfig?.tab || void 0
328
+ // Use frontend config or default
327
329
  };
328
330
  if (uiType === "select") {
329
331
  fieldDef.options = Array.from(metadata.uniqueValues).sort();
@@ -386,7 +388,7 @@ router.post("/import-spreadsheet", upload.single("file"), async (req, res) => {
386
388
  if (fieldName === "family") return;
387
389
  if (justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
388
390
  justificationContents.push(control[fieldName]);
389
- return;
391
+ filteredControl[fieldName] = control[fieldName];
390
392
  }
391
393
  const isInFrontendSchema = frontendFieldSchema?.some((f) => f.fieldName === fieldName);
392
394
  const isInFieldsMetadata = fields.hasOwnProperty(fieldName);
@@ -741,7 +743,7 @@ router.post("/parse-excel", upload.single("file"), async (req, res) => {
741
743
  if (!worksheet) {
742
744
  return res.status(400).json({ error: "No worksheet found in file" });
743
745
  }
744
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
746
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
745
747
  const rowData = [];
746
748
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
747
749
  rowData[colNumber - 1] = cell.value;
@@ -751,7 +753,7 @@ router.post("/parse-excel", upload.single("file"), async (req, res) => {
751
753
  }
752
754
  const headerCandidates = rows.slice(0, 5).map((row, index) => ({
753
755
  row: index + 1,
754
- preview: row.slice(0, 4).filter((v) => v != null).join(", ") + (row.length > 4 ? ", ..." : "")
756
+ preview: row.slice(0, 4).filter((v) => v !== null).filter((v) => v !== void 0).join(", ") + (row.length > 4 ? ", ..." : "")
755
757
  }));
756
758
  res.json({
757
759
  sheets,
@@ -786,7 +788,7 @@ router.post("/parse-excel-sheet", upload.single("file"), async (req, res) => {
786
788
  if (!worksheet) {
787
789
  return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
788
790
  }
789
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
791
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
790
792
  const rowData = [];
791
793
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
792
794
  rowData[colNumber - 1] = cell.value;
@@ -380,7 +380,10 @@ var init_fileStore = __esm({
380
380
  const controlId = mapping.control_id;
381
381
  const family = this.getControlFamily(controlId);
382
382
  const familyDir = join2(this.mappingsDir, family);
383
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
383
+ const mappingFile = join2(
384
+ familyDir,
385
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
386
+ );
384
387
  if (!existsSync2(familyDir)) {
385
388
  mkdirSync(familyDir, { recursive: true });
386
389
  }
@@ -478,7 +481,10 @@ var init_fileStore = __esm({
478
481
  for (const [controlId, controlMappings] of mappingsByControl) {
479
482
  const family = this.getControlFamily(controlId);
480
483
  const familyDir = join2(this.mappingsDir, family);
481
- const mappingFile = join2(familyDir, `${controlId}-mappings.yaml`);
484
+ const mappingFile = join2(
485
+ familyDir,
486
+ `${controlId.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`
487
+ );
482
488
  if (!existsSync2(familyDir)) {
483
489
  mkdirSync(familyDir, { recursive: true });
484
490
  }
@@ -984,7 +990,7 @@ var init_gitHistory = __esm({
984
990
  changes = diffResult.changes;
985
991
  diff = diffResult.diff;
986
992
  yamlDiff = diffResult.yamlDiff;
987
- } catch (error) {
993
+ } catch {
988
994
  }
989
995
  }
990
996
  gitCommits.push({
@@ -1041,7 +1047,7 @@ var init_gitHistory = __esm({
1041
1047
  diff,
1042
1048
  yamlDiff
1043
1049
  };
1044
- } catch (error) {
1050
+ } catch {
1045
1051
  return { changes: { insertions: 0, deletions: 0, files: 1 } };
1046
1052
  }
1047
1053
  }
@@ -1716,7 +1722,7 @@ var init_spreadsheetRoutes = __esm({
1716
1722
  if (req.body.fieldSchema) {
1717
1723
  try {
1718
1724
  frontendFieldSchema = JSON.parse(req.body.fieldSchema);
1719
- } catch (e) {
1725
+ } catch {
1720
1726
  }
1721
1727
  }
1722
1728
  const fields = {};
@@ -1776,7 +1782,9 @@ var init_spreadsheetRoutes = __esm({
1776
1782
  uiType = "long_text";
1777
1783
  }
1778
1784
  let category = frontendConfig?.category || "custom";
1779
- if (!frontendConfig) {
1785
+ if (justificationFields.includes(fieldName)) {
1786
+ category = "mappings";
1787
+ } else if (!frontendConfig) {
1780
1788
  if (fieldName.includes("status") || fieldName.includes("state")) {
1781
1789
  category = "compliance";
1782
1790
  } else if (fieldName.includes("title") || fieldName.includes("name") || fieldName.includes("description")) {
@@ -1804,8 +1812,8 @@ var init_spreadsheetRoutes = __esm({
1804
1812
  // Control ID is always first
1805
1813
  category: isControlIdField ? "core" : category,
1806
1814
  // Control ID is always core
1807
- tab: isControlIdField ? "overview" : frontendConfig?.tab || void 0
1808
- // Control ID is always in overview
1815
+ tab: isControlIdField ? "overview" : justificationFields.includes(fieldName) ? "mappings" : frontendConfig?.tab || void 0
1816
+ // Use frontend config or default
1809
1817
  };
1810
1818
  if (uiType === "select") {
1811
1819
  fieldDef.options = Array.from(metadata.uniqueValues).sort();
@@ -1868,7 +1876,7 @@ var init_spreadsheetRoutes = __esm({
1868
1876
  if (fieldName === "family") return;
1869
1877
  if (justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
1870
1878
  justificationContents.push(control[fieldName]);
1871
- return;
1879
+ filteredControl[fieldName] = control[fieldName];
1872
1880
  }
1873
1881
  const isInFrontendSchema = frontendFieldSchema?.some((f) => f.fieldName === fieldName);
1874
1882
  const isInFieldsMetadata = fields.hasOwnProperty(fieldName);
@@ -1974,7 +1982,7 @@ var init_spreadsheetRoutes = __esm({
1974
1982
  if (!worksheet) {
1975
1983
  return res.status(400).json({ error: "No worksheet found in file" });
1976
1984
  }
1977
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
1985
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
1978
1986
  const rowData = [];
1979
1987
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
1980
1988
  rowData[colNumber - 1] = cell.value;
@@ -1984,7 +1992,7 @@ var init_spreadsheetRoutes = __esm({
1984
1992
  }
1985
1993
  const headerCandidates = rows.slice(0, 5).map((row, index) => ({
1986
1994
  row: index + 1,
1987
- preview: row.slice(0, 4).filter((v) => v != null).join(", ") + (row.length > 4 ? ", ..." : "")
1995
+ preview: row.slice(0, 4).filter((v) => v !== null).filter((v) => v !== void 0).join(", ") + (row.length > 4 ? ", ..." : "")
1988
1996
  }));
1989
1997
  res.json({
1990
1998
  sheets,
@@ -2019,7 +2027,7 @@ var init_spreadsheetRoutes = __esm({
2019
2027
  if (!worksheet) {
2020
2028
  return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
2021
2029
  }
2022
- worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
2030
+ worksheet.eachRow({ includeEmpty: false }, (row, _rowNumber) => {
2023
2031
  const rowData = [];
2024
2032
  row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
2025
2033
  rowData[colNumber - 1] = cell.value;
@@ -2266,7 +2274,7 @@ var WebSocketManager = class {
2266
2274
  totalCommits: controlHistory.totalCommits,
2267
2275
  commits: controlHistory.commits?.length || 0
2268
2276
  });
2269
- const mappingFilename = `${control.id}-mappings.yaml`;
2277
+ const mappingFilename = `${control.id.replace(/[^a-zA-Z0-9-]/g, "_")}-mappings.yaml`;
2270
2278
  const mappingPath = join5(currentPath2, "mappings", family, mappingFilename);
2271
2279
  let mappingHistory = { commits: [], totalCommits: 0 };
2272
2280
  if (existsSync4(mappingPath)) {
package/dist/index.html CHANGED
@@ -6,28 +6,28 @@
6
6
  <link rel="icon" href="/lula.png" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1" />
8
8
 
9
- <link rel="modulepreload" href="/_app/immutable/entry/start.cmFs1yVq.js">
10
- <link rel="modulepreload" href="/_app/immutable/chunks/D7S8Dq6O.js">
11
- <link rel="modulepreload" href="/_app/immutable/chunks/Cby0Z7eP.js">
12
- <link rel="modulepreload" href="/_app/immutable/entry/app.3K_9hfHX.js">
9
+ <link rel="modulepreload" href="/_app/immutable/entry/start.C1hW6Z_g.js">
10
+ <link rel="modulepreload" href="/_app/immutable/chunks/DrOkR2YZ.js">
11
+ <link rel="modulepreload" href="/_app/immutable/chunks/C113Bo4B.js">
12
+ <link rel="modulepreload" href="/_app/immutable/entry/app.CqP__jbe.js">
13
13
  <link rel="modulepreload" href="/_app/immutable/chunks/DsnmJJEf.js">
14
- <link rel="modulepreload" href="/_app/immutable/chunks/DqsOU3kV.js">
15
- <link rel="modulepreload" href="/_app/immutable/chunks/CoF2vljD.js">
16
- <link rel="modulepreload" href="/_app/immutable/chunks/DnJ0bPgj.js">
14
+ <link rel="modulepreload" href="/_app/immutable/chunks/DY3-lqhI.js">
15
+ <link rel="modulepreload" href="/_app/immutable/chunks/CNOPXlDW.js">
16
+ <link rel="modulepreload" href="/_app/immutable/chunks/BtuEtkd3.js">
17
17
  </head>
18
18
  <body data-sveltekit-preload-data="hover">
19
19
  <div style="display: contents">
20
20
  <script>
21
21
  {
22
- __sveltekit_1k9iy1n = {
22
+ __sveltekit_u5u0c8 = {
23
23
  base: ""
24
24
  };
25
25
 
26
26
  const element = document.currentScript.parentElement;
27
27
 
28
28
  Promise.all([
29
- import("/_app/immutable/entry/start.cmFs1yVq.js"),
30
- import("/_app/immutable/entry/app.3K_9hfHX.js")
29
+ import("/_app/immutable/entry/start.C1hW6Z_g.js"),
30
+ import("/_app/immutable/entry/app.CqP__jbe.js")
31
31
  ]).then(([kit, app]) => {
32
32
  kit.start(app, element);
33
33
  });