lula2 0.6.4 → 0.6.5
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/README.md +3 -3
- package/dist/_app/immutable/assets/0.gNk4bE5Z.css +1 -0
- package/dist/_app/immutable/chunks/{DBdrJbLi.js → 6cSSDZaX.js} +1 -1
- package/dist/_app/immutable/chunks/{BaV6jU6m.js → BDFhLgJd.js} +1 -1
- package/dist/_app/immutable/chunks/{_8PUdHCK.js → BZU_Nz1O.js} +1 -1
- package/dist/_app/immutable/chunks/BnySH2DD.js +2 -0
- package/dist/_app/immutable/chunks/{sF1amBpw.js → CfxzrOg_.js} +1 -1
- package/dist/_app/immutable/chunks/{DG4ZcLIc.js → D2GS6lt_.js} +1 -1
- package/dist/_app/immutable/chunks/MY0vM1lA.js +3 -0
- package/dist/_app/immutable/chunks/{WNo48c2U.js → Vl8FMUTS.js} +1 -1
- package/dist/_app/immutable/chunks/{CynYS-Ma.js → ipJF3Ffx.js} +1 -1
- package/dist/_app/immutable/entry/{app.VdrAeFMF.js → app.XAEr8i-M.js} +2 -2
- package/dist/_app/immutable/entry/start.DCxCYu1M.js +1 -0
- package/dist/_app/immutable/nodes/0.DHn4BGVS.js +2 -0
- package/dist/_app/immutable/nodes/{1.Dt4-pegp.js → 1.BRVNZ7Zr.js} +1 -1
- package/dist/_app/immutable/nodes/{2.CgJgF2F1.js → 2.DjZVN6-v.js} +1 -1
- package/dist/_app/immutable/nodes/{3.DsDKmoyP.js → 3.BwkBTWlm.js} +1 -1
- package/dist/_app/immutable/nodes/{4.E9uJ4Np6.js → 4.CrrKXZL6.js} +1 -1
- package/dist/_app/version.json +1 -1
- package/dist/cli/commands/ui.js +49 -7
- package/dist/cli/server/index.js +49 -7
- package/dist/cli/server/server.js +49 -7
- package/dist/cli/server/serverState.js +37 -4
- package/dist/cli/server/spreadsheetRoutes.js +12 -3
- package/dist/cli/server/websocketServer.js +49 -7
- package/dist/index.html +10 -10
- package/dist/index.js +49 -7
- package/package.json +126 -126
- package/src/lib/components/dialogs/ExportColumnDialog.svelte +7 -5
- package/src/routes/+layout.svelte +1 -1
- package/dist/_app/immutable/assets/0.CJjXKESY.css +0 -1
- package/dist/_app/immutable/chunks/DmBJsPtc.js +0 -2
- package/dist/_app/immutable/chunks/DztCq-9O.js +0 -3
- package/dist/_app/immutable/entry/start.BD6MZ_XC.js +0 -1
- package/dist/_app/immutable/nodes/0.D3GkfY8V.js +0 -2
|
@@ -150,8 +150,8 @@ var init_fileStore = __esm({
|
|
|
150
150
|
if (!this.baseDir || this.baseDir === "." || this.baseDir === process.cwd()) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
|
-
const
|
|
154
|
-
if (!existsSync2(
|
|
153
|
+
const lulaConfigPath2 = join2(this.baseDir, "lula.yaml");
|
|
154
|
+
if (!existsSync2(lulaConfigPath2)) {
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
157
|
if (!existsSync2(this.controlsDir)) {
|
|
@@ -309,6 +309,17 @@ var init_fileStore = __esm({
|
|
|
309
309
|
if (!existsSync2(this.controlsDir)) {
|
|
310
310
|
return [];
|
|
311
311
|
}
|
|
312
|
+
let controlOrder = null;
|
|
313
|
+
try {
|
|
314
|
+
const lulaConfigPath2 = join2(this.baseDir, "lula.yaml");
|
|
315
|
+
if (existsSync2(lulaConfigPath2)) {
|
|
316
|
+
const content = readFileSync2(lulaConfigPath2, "utf8");
|
|
317
|
+
const metadata = yaml2.load(content);
|
|
318
|
+
controlOrder = metadata?.controlOrder || null;
|
|
319
|
+
}
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error(`Failed to load lula.yaml for controlOrder (path: ${lulaConfigPath}):`, error);
|
|
322
|
+
}
|
|
312
323
|
const entries = readdirSync(this.controlsDir);
|
|
313
324
|
const yamlFiles = entries.filter((file) => file.endsWith(".yaml"));
|
|
314
325
|
if (yamlFiles.length > 0) {
|
|
@@ -327,7 +338,11 @@ var init_fileStore = __esm({
|
|
|
327
338
|
}
|
|
328
339
|
});
|
|
329
340
|
const results2 = await Promise.all(promises);
|
|
330
|
-
|
|
341
|
+
const controls2 = results2.filter((c) => c !== null);
|
|
342
|
+
if (controlOrder && controlOrder.length > 0) {
|
|
343
|
+
return this.sortControlsByOrder(controls2, controlOrder);
|
|
344
|
+
}
|
|
345
|
+
return controls2;
|
|
331
346
|
}
|
|
332
347
|
const families = entries.filter((name) => {
|
|
333
348
|
const familyPath = join2(this.controlsDir, name);
|
|
@@ -350,7 +365,25 @@ var init_fileStore = __esm({
|
|
|
350
365
|
allPromises.push(...familyPromises);
|
|
351
366
|
}
|
|
352
367
|
const results = await Promise.all(allPromises);
|
|
353
|
-
|
|
368
|
+
const controls = results.filter((c) => c !== null);
|
|
369
|
+
if (controlOrder && controlOrder.length > 0) {
|
|
370
|
+
return this.sortControlsByOrder(controls, controlOrder);
|
|
371
|
+
}
|
|
372
|
+
return controls;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Sort controls based on the provided order array
|
|
376
|
+
*/
|
|
377
|
+
sortControlsByOrder(controls, controlOrder) {
|
|
378
|
+
const orderMap = /* @__PURE__ */ new Map();
|
|
379
|
+
controlOrder.forEach((controlId, index) => {
|
|
380
|
+
orderMap.set(controlId, index);
|
|
381
|
+
});
|
|
382
|
+
return controls.sort((a, b) => {
|
|
383
|
+
const aIndex = orderMap.get(a.id) ?? Number.MAX_SAFE_INTEGER;
|
|
384
|
+
const bIndex = orderMap.get(b.id) ?? Number.MAX_SAFE_INTEGER;
|
|
385
|
+
return aIndex - bIndex;
|
|
386
|
+
});
|
|
354
387
|
}
|
|
355
388
|
/**
|
|
356
389
|
* Load mappings from mappings directory
|
|
@@ -1470,6 +1503,7 @@ function processSpreadsheetData(rawData, headers, startRowIndex, params) {
|
|
|
1470
1503
|
continue;
|
|
1471
1504
|
}
|
|
1472
1505
|
const family = extractFamilyFromControlId(controlId);
|
|
1506
|
+
control._originalRowIndex = i;
|
|
1473
1507
|
control.family = family;
|
|
1474
1508
|
controls.push(control);
|
|
1475
1509
|
if (!families.has(family)) {
|
|
@@ -1592,6 +1626,7 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
1592
1626
|
params.controlIdField,
|
|
1593
1627
|
params.namingConvention
|
|
1594
1628
|
);
|
|
1629
|
+
const controlOrder = controls.sort((a, b) => (a._originalRowIndex || 0) - (b._originalRowIndex || 0)).map((control) => control[controlIdFieldNameClean]);
|
|
1595
1630
|
const controlSetData = {
|
|
1596
1631
|
name: params.controlSetName,
|
|
1597
1632
|
description: params.controlSetDescription,
|
|
@@ -1599,12 +1634,16 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
1599
1634
|
control_id_field: controlIdFieldNameClean,
|
|
1600
1635
|
controlCount: controls.length,
|
|
1601
1636
|
families: uniqueFamilies,
|
|
1637
|
+
controlOrder,
|
|
1602
1638
|
fieldSchema
|
|
1603
1639
|
};
|
|
1604
1640
|
writeFileSync2(join4(baseDir, "lula.yaml"), yaml4.dump(controlSetData));
|
|
1605
1641
|
const controlsDir = join4(baseDir, "controls");
|
|
1606
1642
|
const mappingsDir = join4(baseDir, "mappings");
|
|
1607
|
-
families.
|
|
1643
|
+
const sortedFamilies = Array.from(families.entries()).sort(
|
|
1644
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
1645
|
+
);
|
|
1646
|
+
sortedFamilies.forEach(([family, familyControls]) => {
|
|
1608
1647
|
const familyDir = join4(controlsDir, family);
|
|
1609
1648
|
const familyMappingsDir = join4(mappingsDir, family);
|
|
1610
1649
|
if (!existsSync3(familyDir)) {
|
|
@@ -1613,7 +1652,10 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
1613
1652
|
if (!existsSync3(familyMappingsDir)) {
|
|
1614
1653
|
mkdirSync2(familyMappingsDir, { recursive: true });
|
|
1615
1654
|
}
|
|
1616
|
-
familyControls.
|
|
1655
|
+
const sortedFamilyControls = familyControls.sort(
|
|
1656
|
+
(a, b) => (a._originalRowIndex || 0) - (b._originalRowIndex || 0)
|
|
1657
|
+
);
|
|
1658
|
+
sortedFamilyControls.forEach((control) => {
|
|
1617
1659
|
const controlId = control[controlIdFieldNameClean];
|
|
1618
1660
|
if (!controlId) {
|
|
1619
1661
|
console.error("Missing control ID for control:", control);
|
|
@@ -1635,7 +1677,7 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
1635
1677
|
filteredControl.family = control.family;
|
|
1636
1678
|
}
|
|
1637
1679
|
Object.keys(control).forEach((fieldName) => {
|
|
1638
|
-
if (fieldName === "family") return;
|
|
1680
|
+
if (fieldName === "family" || fieldName === "_originalRowIndex") return;
|
|
1639
1681
|
if (params.justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
|
|
1640
1682
|
justificationContents.push(control[fieldName]);
|
|
1641
1683
|
}
|
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.
|
|
10
|
-
<link rel="modulepreload" href="/_app/immutable/chunks/
|
|
11
|
-
<link rel="modulepreload" href="/_app/immutable/chunks/
|
|
12
|
-
<link rel="modulepreload" href="/_app/immutable/entry/app.
|
|
9
|
+
<link rel="modulepreload" href="/_app/immutable/entry/start.DCxCYu1M.js">
|
|
10
|
+
<link rel="modulepreload" href="/_app/immutable/chunks/MY0vM1lA.js">
|
|
11
|
+
<link rel="modulepreload" href="/_app/immutable/chunks/BnySH2DD.js">
|
|
12
|
+
<link rel="modulepreload" href="/_app/immutable/entry/app.XAEr8i-M.js">
|
|
13
13
|
<link rel="modulepreload" href="/_app/immutable/chunks/DsnmJJEf.js">
|
|
14
|
-
<link rel="modulepreload" href="/_app/immutable/chunks/
|
|
15
|
-
<link rel="modulepreload" href="/_app/immutable/chunks/
|
|
16
|
-
<link rel="modulepreload" href="/_app/immutable/chunks/
|
|
14
|
+
<link rel="modulepreload" href="/_app/immutable/chunks/BDFhLgJd.js">
|
|
15
|
+
<link rel="modulepreload" href="/_app/immutable/chunks/6cSSDZaX.js">
|
|
16
|
+
<link rel="modulepreload" href="/_app/immutable/chunks/ipJF3Ffx.js">
|
|
17
17
|
</head>
|
|
18
18
|
<body data-sveltekit-preload-data="hover">
|
|
19
19
|
<div style="display: contents">
|
|
20
20
|
<script>
|
|
21
21
|
{
|
|
22
|
-
|
|
22
|
+
__sveltekit_1b7tzml = {
|
|
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.
|
|
30
|
-
import("/_app/immutable/entry/app.
|
|
29
|
+
import("/_app/immutable/entry/start.DCxCYu1M.js"),
|
|
30
|
+
import("/_app/immutable/entry/app.XAEr8i-M.js")
|
|
31
31
|
]).then(([kit, app]) => {
|
|
32
32
|
kit.start(app, element);
|
|
33
33
|
});
|
package/dist/index.js
CHANGED
|
@@ -1722,8 +1722,8 @@ var init_fileStore = __esm({
|
|
|
1722
1722
|
if (!this.baseDir || this.baseDir === "." || this.baseDir === process.cwd()) {
|
|
1723
1723
|
return;
|
|
1724
1724
|
}
|
|
1725
|
-
const
|
|
1726
|
-
if (!existsSync2(
|
|
1725
|
+
const lulaConfigPath2 = join2(this.baseDir, "lula.yaml");
|
|
1726
|
+
if (!existsSync2(lulaConfigPath2)) {
|
|
1727
1727
|
return;
|
|
1728
1728
|
}
|
|
1729
1729
|
if (!existsSync2(this.controlsDir)) {
|
|
@@ -1881,6 +1881,17 @@ var init_fileStore = __esm({
|
|
|
1881
1881
|
if (!existsSync2(this.controlsDir)) {
|
|
1882
1882
|
return [];
|
|
1883
1883
|
}
|
|
1884
|
+
let controlOrder = null;
|
|
1885
|
+
try {
|
|
1886
|
+
const lulaConfigPath2 = join2(this.baseDir, "lula.yaml");
|
|
1887
|
+
if (existsSync2(lulaConfigPath2)) {
|
|
1888
|
+
const content = readFileSync2(lulaConfigPath2, "utf8");
|
|
1889
|
+
const metadata = yaml2.load(content);
|
|
1890
|
+
controlOrder = metadata?.controlOrder || null;
|
|
1891
|
+
}
|
|
1892
|
+
} catch (error) {
|
|
1893
|
+
console.error(`Failed to load lula.yaml for controlOrder (path: ${lulaConfigPath}):`, error);
|
|
1894
|
+
}
|
|
1884
1895
|
const entries = readdirSync(this.controlsDir);
|
|
1885
1896
|
const yamlFiles = entries.filter((file) => file.endsWith(".yaml"));
|
|
1886
1897
|
if (yamlFiles.length > 0) {
|
|
@@ -1899,7 +1910,11 @@ var init_fileStore = __esm({
|
|
|
1899
1910
|
}
|
|
1900
1911
|
});
|
|
1901
1912
|
const results2 = await Promise.all(promises);
|
|
1902
|
-
|
|
1913
|
+
const controls2 = results2.filter((c) => c !== null);
|
|
1914
|
+
if (controlOrder && controlOrder.length > 0) {
|
|
1915
|
+
return this.sortControlsByOrder(controls2, controlOrder);
|
|
1916
|
+
}
|
|
1917
|
+
return controls2;
|
|
1903
1918
|
}
|
|
1904
1919
|
const families = entries.filter((name) => {
|
|
1905
1920
|
const familyPath = join2(this.controlsDir, name);
|
|
@@ -1922,7 +1937,25 @@ var init_fileStore = __esm({
|
|
|
1922
1937
|
allPromises.push(...familyPromises);
|
|
1923
1938
|
}
|
|
1924
1939
|
const results = await Promise.all(allPromises);
|
|
1925
|
-
|
|
1940
|
+
const controls = results.filter((c) => c !== null);
|
|
1941
|
+
if (controlOrder && controlOrder.length > 0) {
|
|
1942
|
+
return this.sortControlsByOrder(controls, controlOrder);
|
|
1943
|
+
}
|
|
1944
|
+
return controls;
|
|
1945
|
+
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Sort controls based on the provided order array
|
|
1948
|
+
*/
|
|
1949
|
+
sortControlsByOrder(controls, controlOrder) {
|
|
1950
|
+
const orderMap = /* @__PURE__ */ new Map();
|
|
1951
|
+
controlOrder.forEach((controlId, index) => {
|
|
1952
|
+
orderMap.set(controlId, index);
|
|
1953
|
+
});
|
|
1954
|
+
return controls.sort((a, b) => {
|
|
1955
|
+
const aIndex = orderMap.get(a.id) ?? Number.MAX_SAFE_INTEGER;
|
|
1956
|
+
const bIndex = orderMap.get(b.id) ?? Number.MAX_SAFE_INTEGER;
|
|
1957
|
+
return aIndex - bIndex;
|
|
1958
|
+
});
|
|
1926
1959
|
}
|
|
1927
1960
|
/**
|
|
1928
1961
|
* Load mappings from mappings directory
|
|
@@ -3042,6 +3075,7 @@ function processSpreadsheetData(rawData, headers, startRowIndex, params) {
|
|
|
3042
3075
|
continue;
|
|
3043
3076
|
}
|
|
3044
3077
|
const family = extractFamilyFromControlId(controlId);
|
|
3078
|
+
control._originalRowIndex = i;
|
|
3045
3079
|
control.family = family;
|
|
3046
3080
|
controls.push(control);
|
|
3047
3081
|
if (!families.has(family)) {
|
|
@@ -3164,6 +3198,7 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
3164
3198
|
params.controlIdField,
|
|
3165
3199
|
params.namingConvention
|
|
3166
3200
|
);
|
|
3201
|
+
const controlOrder = controls.sort((a, b) => (a._originalRowIndex || 0) - (b._originalRowIndex || 0)).map((control) => control[controlIdFieldNameClean]);
|
|
3167
3202
|
const controlSetData = {
|
|
3168
3203
|
name: params.controlSetName,
|
|
3169
3204
|
description: params.controlSetDescription,
|
|
@@ -3171,12 +3206,16 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
3171
3206
|
control_id_field: controlIdFieldNameClean,
|
|
3172
3207
|
controlCount: controls.length,
|
|
3173
3208
|
families: uniqueFamilies,
|
|
3209
|
+
controlOrder,
|
|
3174
3210
|
fieldSchema
|
|
3175
3211
|
};
|
|
3176
3212
|
writeFileSync2(join4(baseDir, "lula.yaml"), yaml4.dump(controlSetData));
|
|
3177
3213
|
const controlsDir = join4(baseDir, "controls");
|
|
3178
3214
|
const mappingsDir = join4(baseDir, "mappings");
|
|
3179
|
-
families.
|
|
3215
|
+
const sortedFamilies = Array.from(families.entries()).sort(
|
|
3216
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
3217
|
+
);
|
|
3218
|
+
sortedFamilies.forEach(([family, familyControls]) => {
|
|
3180
3219
|
const familyDir = join4(controlsDir, family);
|
|
3181
3220
|
const familyMappingsDir = join4(mappingsDir, family);
|
|
3182
3221
|
if (!existsSync3(familyDir)) {
|
|
@@ -3185,7 +3224,10 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
3185
3224
|
if (!existsSync3(familyMappingsDir)) {
|
|
3186
3225
|
mkdirSync2(familyMappingsDir, { recursive: true });
|
|
3187
3226
|
}
|
|
3188
|
-
familyControls.
|
|
3227
|
+
const sortedFamilyControls = familyControls.sort(
|
|
3228
|
+
(a, b) => (a._originalRowIndex || 0) - (b._originalRowIndex || 0)
|
|
3229
|
+
);
|
|
3230
|
+
sortedFamilyControls.forEach((control) => {
|
|
3189
3231
|
const controlId = control[controlIdFieldNameClean];
|
|
3190
3232
|
if (!controlId) {
|
|
3191
3233
|
console.error("Missing control ID for control:", control);
|
|
@@ -3207,7 +3249,7 @@ async function createOutputStructure(processedData, fieldSchema, params) {
|
|
|
3207
3249
|
filteredControl.family = control.family;
|
|
3208
3250
|
}
|
|
3209
3251
|
Object.keys(control).forEach((fieldName) => {
|
|
3210
|
-
if (fieldName === "family") return;
|
|
3252
|
+
if (fieldName === "family" || fieldName === "_originalRowIndex") return;
|
|
3211
3253
|
if (params.justificationFields.includes(fieldName) && control[fieldName] !== void 0 && control[fieldName] !== null) {
|
|
3212
3254
|
justificationContents.push(control[fieldName]);
|
|
3213
3255
|
}
|
package/package.json
CHANGED
|
@@ -1,128 +1,128 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
2
|
+
"name": "lula2",
|
|
3
|
+
"version": "0.6.5",
|
|
4
|
+
"description": "A tool for managing compliance as code in your GitHub repositories.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"lula2": "./dist/lula2"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=24.0.0"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/defenseunicorns/lula.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"compliance",
|
|
20
|
+
"devops",
|
|
21
|
+
"devsecops"
|
|
22
|
+
],
|
|
23
|
+
"author": "Defense Unicorns",
|
|
24
|
+
"license": "Apache-2.0",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/defenseunicorns/lula/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/defenseunicorns/lula#readme",
|
|
29
|
+
"files": [
|
|
30
|
+
"/src",
|
|
31
|
+
"/dist",
|
|
32
|
+
"!src/**/*.test.ts",
|
|
33
|
+
"!dist/**/*.test.js*",
|
|
34
|
+
"!dist/**/*.test.d.ts*"
|
|
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:xlsx-republish --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
|
+
"dependencies": {
|
|
56
|
+
"@octokit/rest": "^22.0.0",
|
|
57
|
+
"@types/ws": "^8.18.1",
|
|
58
|
+
"commander": "^14.0.0",
|
|
59
|
+
"cors": "^2.8.5",
|
|
60
|
+
"csv-parse": "^6.1.0",
|
|
61
|
+
"express": "^5.1.0",
|
|
62
|
+
"express-rate-limit": "^8.1.0",
|
|
63
|
+
"flowbite": "^3.1.2",
|
|
64
|
+
"glob": "^11.0.3",
|
|
65
|
+
"isomorphic-git": "^1.33.1",
|
|
66
|
+
"js-yaml": "^4.1.0",
|
|
67
|
+
"multer": "^2.0.2",
|
|
68
|
+
"open": "^10.2.0",
|
|
69
|
+
"undici": "^7.15.0",
|
|
70
|
+
"ws": "^8.18.3",
|
|
71
|
+
"xlsx-republish": "^0.20.3",
|
|
72
|
+
"yaml": "^2.8.1"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@commitlint/cli": "^20.0.0",
|
|
76
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
77
|
+
"@eslint/compat": "^1.3.2",
|
|
78
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
79
|
+
"@eslint/js": "^9.35.0",
|
|
80
|
+
"@playwright/test": "^1.55.0",
|
|
81
|
+
"@sveltejs/adapter-static": "^3.0.9",
|
|
82
|
+
"@sveltejs/kit": "^2.37.1",
|
|
83
|
+
"@sveltejs/vite-plugin-svelte": "^6.1.4",
|
|
84
|
+
"@tailwindcss/vite": "^4.1.13",
|
|
85
|
+
"@types/cors": "^2.8.19",
|
|
86
|
+
"@types/express": "^5.0.3",
|
|
87
|
+
"@types/js-yaml": "^4.0.9",
|
|
88
|
+
"@types/jsdom": "^27.0.0",
|
|
89
|
+
"@types/multer": "^2.0.0",
|
|
90
|
+
"@types/node": "^24.4.0",
|
|
91
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
92
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
93
|
+
"@vitest/browser": "^3.2.4",
|
|
94
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
95
|
+
"carbon-icons-svelte": "^13.5.0",
|
|
96
|
+
"carbon-preprocess-svelte": "^0.11.11",
|
|
97
|
+
"concurrently": "^9.2.1",
|
|
98
|
+
"esbuild": "^0.25.9",
|
|
99
|
+
"eslint": "^9.35.0",
|
|
100
|
+
"eslint-config-prettier": "^10.1.8",
|
|
101
|
+
"eslint-plugin-jsdoc": "^61.0.0",
|
|
102
|
+
"eslint-plugin-svelte": "^3.12.2",
|
|
103
|
+
"globals": "^16.3.0",
|
|
104
|
+
"husky": "^9.1.7",
|
|
105
|
+
"jsdom": "^27.0.0",
|
|
106
|
+
"playwright": "^1.55.0",
|
|
107
|
+
"prettier": "3.6.2",
|
|
108
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
109
|
+
"semantic-release": "^25.0.0",
|
|
110
|
+
"shellcheck": "^4.1.0",
|
|
111
|
+
"svelte": "^5.38.7",
|
|
112
|
+
"svelte-check": "^4.3.1",
|
|
113
|
+
"tailwind-merge": "^3.3.1",
|
|
114
|
+
"tailwindcss": "^4.1.13",
|
|
115
|
+
"tsx": "^4.20.5",
|
|
116
|
+
"typescript": "5.9.3",
|
|
117
|
+
"typescript-eslint": "^8.42.0",
|
|
118
|
+
"vite": "^7.1.4",
|
|
119
|
+
"vitest": "^3.2.4",
|
|
120
|
+
"vitest-browser-svelte": "^1.1.0"
|
|
121
|
+
},
|
|
122
|
+
"release": {
|
|
123
|
+
"branches": [
|
|
124
|
+
"main",
|
|
125
|
+
"next"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
128
|
}
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
setTimeout(() => node.focus(), 0);
|
|
44
44
|
}
|
|
45
45
|
return {
|
|
46
|
-
update(
|
|
47
|
-
if (
|
|
46
|
+
update() {
|
|
47
|
+
if (isOpen) {
|
|
48
48
|
setTimeout(() => node.focus(), 0);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -62,6 +62,8 @@
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
function handleKeydown(event: KeyboardEvent) {
|
|
65
|
+
if (!isOpen) return;
|
|
66
|
+
|
|
65
67
|
if (event.key === 'Escape') {
|
|
66
68
|
handleCancel();
|
|
67
69
|
} else if (event.key === 'Enter') {
|
|
@@ -81,7 +83,7 @@
|
|
|
81
83
|
{#if isOpen}
|
|
82
84
|
<!-- Modal Backdrop -->
|
|
83
85
|
<div
|
|
84
|
-
class="fixed inset-0 bg-
|
|
86
|
+
class="fixed inset-0 bg-opacity-10 backdrop-blur-sm overflow-y-auto h-full w-full z-40 flex items-center justify-center p-4"
|
|
85
87
|
role="dialog"
|
|
86
88
|
aria-modal="true"
|
|
87
89
|
tabindex="-1"
|
|
@@ -92,7 +94,7 @@
|
|
|
92
94
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
93
95
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
94
96
|
<div
|
|
95
|
-
class="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md mx-auto"
|
|
97
|
+
class="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md mx-auto relative z-50"
|
|
96
98
|
role="document"
|
|
97
99
|
onclick={(e) => e.stopPropagation()}
|
|
98
100
|
>
|
|
@@ -125,7 +127,7 @@
|
|
|
125
127
|
</label>
|
|
126
128
|
<select
|
|
127
129
|
id="column-select"
|
|
128
|
-
use:focusSelect
|
|
130
|
+
use:focusSelect
|
|
129
131
|
bind:value={selectedColumn}
|
|
130
132
|
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
131
133
|
>
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
{#if $page.url.pathname !== '/setup'}
|
|
174
174
|
<!-- Fixed Header -->
|
|
175
175
|
<header
|
|
176
|
-
class="bg-white dark:bg-gray-900 shadow-sm border-b border-gray-200 dark:border-gray-700 flex-shrink-0"
|
|
176
|
+
class="bg-white dark:bg-gray-900 shadow-sm border-b border-gray-200 dark:border-gray-700 flex-shrink-0 relative z-40"
|
|
177
177
|
>
|
|
178
178
|
<div class="w-full px-6 lg:px-8">
|
|
179
179
|
<div class="flex justify-between items-center h-16">
|