lula2 0.6.1-nightly.0 → 0.6.1-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/Bv3eVXV-.js +3 -0
- package/dist/_app/immutable/chunks/{BMNSAUym.js → Bx6M8uXd.js} +1 -1
- package/dist/_app/immutable/chunks/{BmwkkWK-.js → loOficEe.js} +1 -1
- package/dist/_app/immutable/entry/{app.BMX3XH9B.js → app.BM2rHfpO.js} +2 -2
- package/dist/_app/immutable/entry/start.bUkCSbH7.js +1 -0
- package/dist/_app/immutable/nodes/{0.DFzEgAsn.js → 0.2orJRzbh.js} +1 -1
- package/dist/_app/immutable/nodes/{1.f-frqYrl.js → 1.BrMaFf25.js} +1 -1
- package/dist/_app/immutable/nodes/{2.DjKBnAK5.js → 2.hnhHaDbD.js} +1 -1
- package/dist/_app/immutable/nodes/{3.Cm8oQ-Ws.js → 3.BnCLb2wM.js} +1 -1
- package/dist/_app/immutable/nodes/{4.DVhDnucO.js → 4.Bw-EmQzD.js} +1 -1
- package/dist/_app/version.json +1 -1
- 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 +26 -71
- package/package.json +3 -3
- package/dist/_app/immutable/chunks/DYjeAJVm.js +0 -3
- package/dist/_app/immutable/entry/start.CikNPmTv.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"../chunks/DsnmJJEf.js";import{i as Je}from"../chunks/Cq7PwVfU.js";import{p as Ye,am as Te,d as o,T as k,G as ge,h as e,an as $r,ao as Ve,c as a,n as _e,r as t,b as d,e as We,J as F,K as E,ap as Lr,f as h,s as i,aq as g,a as ye,ar as mr,aj as Me,a3 as De,ak as hr,al as rr,as as yr,k as de,o as ot,W as lt}from"../chunks/DTWPdvjs.js";import{l as tr,p as Ue,i as M,a as st,s as it}from"../chunks/BXUi170M.js";import{a as Nr,s as se,r as Vr,e as ce,b as qe,c as jr,d as _r,i as Cr,f as Sr,w as wr}from"../chunks/e7OeeeKP.js";import{g as nt}from"../chunks/DYjeAJVm.js";function dt(pe){return function(...q){var z=q[0];return z.stopPropagation(),pe?.apply(this,q)}}var vt=Ve("<title> </title>"),ct=Ve('<svg><!><path d="M11 18L12.41 19.41 15 16.83 15 29 17 29 17 16.83 19.59 19.41 21 18 16 13 11 18z"></path><path d="M23.5,22H23V20h.5a4.5,4.5,0,0,0,.36-9L23,11l-.1-.82a7,7,0,0,0-13.88,0L9,11,8.14,11a4.5,4.5,0,0,0,.36,9H9v2H8.5A6.5,6.5,0,0,1,7.2,9.14a9,9,0,0,1,17.6,0A6.5,6.5,0,0,1,23.5,22Z"></path></svg>');function gt(pe,q){const z=tr(q,["children","$$slots","$$events","$$legacy"]),X=tr(z,["size","title"]);Ye(q,!1);const O=k(),L=k();let N=Ue(q,"size",8,16),f=Ue(q,"title",8,void 0);Te(()=>(ge(z),ge(f())),()=>{o(O,z["aria-label"]||z["aria-labelledby"]||f())}),Te(()=>(e(O),ge(z)),()=>{o(L,{"aria-hidden":e(O)?void 0:!0,role:e(O)?"img":void 0,focusable:Number(z.tabindex)===0?!0:void 0})}),$r(),Je();var S=ct();Nr(S,()=>({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",fill:"currentColor",preserveAspectRatio:"xMidYMid meet",width:N(),height:N(),...e(L),...X}));var K=a(S);{var re=P=>{var p=vt(),U=a(p,!0);t(p),F(()=>E(U,f())),d(P,p)};M(K,P=>{f()&&P(re)})}_e(2),t(S),d(pe,S),We()}var pt=Ve("<title> </title>"),ut=Ve('<svg><!><path d="M10 6H14V10H10zM18 6H22V10H18zM10 14H14V18H10zM18 14H22V18H18zM10 22H14V26H10zM18 22H22V26H18z"></path></svg>');function kr(pe,q){const z=tr(q,["children","$$slots","$$events","$$legacy"]),X=tr(z,["size","title"]);Ye(q,!1);const O=k(),L=k();let N=Ue(q,"size",8,16),f=Ue(q,"title",8,void 0);Te(()=>(ge(z),ge(f())),()=>{o(O,z["aria-label"]||z["aria-labelledby"]||f())}),Te(()=>(e(O),ge(z)),()=>{o(L,{"aria-hidden":e(O)?void 0:!0,role:e(O)?"img":void 0,focusable:Number(z.tabindex)===0?!0:void 0})}),$r(),Je();var S=ut();Nr(S,()=>({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",fill:"currentColor",preserveAspectRatio:"xMidYMid meet",width:N(),height:N(),...e(L),...X}));var K=a(S);{var re=P=>{var p=pt(),U=a(p,!0);t(p),F(()=>E(U,f())),d(P,p)};M(K,P=>{f()&&P(re)})}_e(),t(S),d(pe,S),We()}var bt=h('<div class="p-4 text-sm text-blue-800 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <div><span class="font-medium">File loaded:</span> <div class="mt-1"><span class="font-medium">Sheets:</span> <span class="font-medium">Fields:</span> <span class="font-medium">Controls found:</span> </div></div></div></div>'),ft=h('<div class="p-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <span> </span></div></div>'),xt=h('<div class="p-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-gray-800 dark:text-green-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <span> </span></div></div>'),mt=h("<option> </option>"),ht=h("<option> </option>"),yt=h("<option> </option>"),_t=h('<span class="ml-auto text-xs text-blue-600 dark:text-blue-400">ID</span>'),wt=h('<div draggable="true" role="button" tabindex="0" class="flex items-center px-3 py-2 bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded text-sm cursor-move hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors opacity-75"><svg class="w-3 h-3 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"></path></svg> <span class="truncate line-through"> </span> <!></div>'),kt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">No excluded fields</p>'),Ct=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),St=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),$t=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),Dt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),Mt=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),zt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),At=h('<div draggable="false" role="button" tabindex="0" class="flex items-center px-3 py-2 bg-orange-100 dark:bg-orange-900/30 text-orange-800 dark:text-orange-300 rounded text-sm hover:bg-orange-200 dark:hover:bg-orange-800/30 transition-colors"><span class="truncate"> </span> <button class="ml-auto text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400" title="Remove from mappings">×</button></div>'),Ft=h('<div role="region" aria-label="Justification field drop zone"><p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p></div>'),Ot=h('<th class="px-4 py-2"> </th>'),Pt=h('<td class="px-4 py-2"> </td>'),Ht=h('<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"></tr>'),Et=h('<div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Sample Data Preview</h3> <div class="overflow-x-auto"><table class="w-full text-sm text-left text-gray-500 dark:text-gray-400"><thead class="text-xs text-gray-700 uppercase bg-gray-100 dark:bg-gray-600 dark:text-gray-400"><tr></tr></thead><tbody></tbody></table></div></div>'),It=h('<span class="flex items-center"><svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> Importing...</span>'),Tt=h(`<div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Import Options</h3> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4"><div><label for="controlSetName" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Control Set Name <span class="text-red-500">*</span></label> <input type="text" id="controlSetName" placeholder="e.g., NIST 800-53 Rev 4" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white" required/> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">This will be used as the display name and folder name</p></div> <div><label for="controlSetDescription" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Description</label> <input type="text" id="controlSetDescription" placeholder="Optional description" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"/> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Brief description of this control set</p></div></div> <div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><label for="sheet" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Sheet</label> <select id="sheet" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select which worksheet contains your control data</p></div> <div><label for="headerRow" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Select Header Row</label> <select id="headerRow" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select the row containing column headers</p></div> <div><label for="controlIdField" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Control ID Field <span class="text-red-500">*</span></label> <select id="controlIdField" required><option disabled>Select Control ID field</option><!></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Column containing unique control identifiers (e.g., AC-1, SC-7)</p></div></div></div> <div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">Organize Fields</h3> <p class="text-sm text-gray-600 dark:text-gray-400 mb-4">Drag fields to organize them. <strong>Overview fields</strong> will appear as table columns in
|
|
1
|
+
import"../chunks/DsnmJJEf.js";import{i as Je}from"../chunks/Cq7PwVfU.js";import{p as Ye,am as Te,d as o,T as k,G as ge,h as e,an as $r,ao as Ve,c as a,n as _e,r as t,b as d,e as We,J as F,K as E,ap as Lr,f as h,s as i,aq as g,a as ye,ar as mr,aj as Me,a3 as De,ak as hr,al as rr,as as yr,k as de,o as ot,W as lt}from"../chunks/DTWPdvjs.js";import{l as tr,p as Ue,i as M,a as st,s as it}from"../chunks/BXUi170M.js";import{a as Nr,s as se,r as Vr,e as ce,b as qe,c as jr,d as _r,i as Cr,f as Sr,w as wr}from"../chunks/e7OeeeKP.js";import{g as nt}from"../chunks/Bv3eVXV-.js";function dt(pe){return function(...q){var z=q[0];return z.stopPropagation(),pe?.apply(this,q)}}var vt=Ve("<title> </title>"),ct=Ve('<svg><!><path d="M11 18L12.41 19.41 15 16.83 15 29 17 29 17 16.83 19.59 19.41 21 18 16 13 11 18z"></path><path d="M23.5,22H23V20h.5a4.5,4.5,0,0,0,.36-9L23,11l-.1-.82a7,7,0,0,0-13.88,0L9,11,8.14,11a4.5,4.5,0,0,0,.36,9H9v2H8.5A6.5,6.5,0,0,1,7.2,9.14a9,9,0,0,1,17.6,0A6.5,6.5,0,0,1,23.5,22Z"></path></svg>');function gt(pe,q){const z=tr(q,["children","$$slots","$$events","$$legacy"]),X=tr(z,["size","title"]);Ye(q,!1);const O=k(),L=k();let N=Ue(q,"size",8,16),f=Ue(q,"title",8,void 0);Te(()=>(ge(z),ge(f())),()=>{o(O,z["aria-label"]||z["aria-labelledby"]||f())}),Te(()=>(e(O),ge(z)),()=>{o(L,{"aria-hidden":e(O)?void 0:!0,role:e(O)?"img":void 0,focusable:Number(z.tabindex)===0?!0:void 0})}),$r(),Je();var S=ct();Nr(S,()=>({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",fill:"currentColor",preserveAspectRatio:"xMidYMid meet",width:N(),height:N(),...e(L),...X}));var K=a(S);{var re=P=>{var p=vt(),U=a(p,!0);t(p),F(()=>E(U,f())),d(P,p)};M(K,P=>{f()&&P(re)})}_e(2),t(S),d(pe,S),We()}var pt=Ve("<title> </title>"),ut=Ve('<svg><!><path d="M10 6H14V10H10zM18 6H22V10H18zM10 14H14V18H10zM18 14H22V18H18zM10 22H14V26H10zM18 22H22V26H18z"></path></svg>');function kr(pe,q){const z=tr(q,["children","$$slots","$$events","$$legacy"]),X=tr(z,["size","title"]);Ye(q,!1);const O=k(),L=k();let N=Ue(q,"size",8,16),f=Ue(q,"title",8,void 0);Te(()=>(ge(z),ge(f())),()=>{o(O,z["aria-label"]||z["aria-labelledby"]||f())}),Te(()=>(e(O),ge(z)),()=>{o(L,{"aria-hidden":e(O)?void 0:!0,role:e(O)?"img":void 0,focusable:Number(z.tabindex)===0?!0:void 0})}),$r(),Je();var S=ut();Nr(S,()=>({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",fill:"currentColor",preserveAspectRatio:"xMidYMid meet",width:N(),height:N(),...e(L),...X}));var K=a(S);{var re=P=>{var p=pt(),U=a(p,!0);t(p),F(()=>E(U,f())),d(P,p)};M(K,P=>{f()&&P(re)})}_e(),t(S),d(pe,S),We()}var bt=h('<div class="p-4 text-sm text-blue-800 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <div><span class="font-medium">File loaded:</span> <div class="mt-1"><span class="font-medium">Sheets:</span> <span class="font-medium">Fields:</span> <span class="font-medium">Controls found:</span> </div></div></div></div>'),ft=h('<div class="p-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <span> </span></div></div>'),xt=h('<div class="p-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-gray-800 dark:text-green-400"><div class="flex items-center"><svg class="flex-shrink-0 inline w-4 h-4 mr-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"></path></svg> <span> </span></div></div>'),mt=h("<option> </option>"),ht=h("<option> </option>"),yt=h("<option> </option>"),_t=h('<span class="ml-auto text-xs text-blue-600 dark:text-blue-400">ID</span>'),wt=h('<div draggable="true" role="button" tabindex="0" class="flex items-center px-3 py-2 bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded text-sm cursor-move hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors opacity-75"><svg class="w-3 h-3 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"></path></svg> <span class="truncate line-through"> </span> <!></div>'),kt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">No excluded fields</p>'),Ct=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),St=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),$t=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),Dt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),Mt=h('<div draggable="true" role="button" tabindex="0"><!> <span class="truncate"> </span></div>'),zt=h('<p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p>'),At=h('<div draggable="false" role="button" tabindex="0" class="flex items-center px-3 py-2 bg-orange-100 dark:bg-orange-900/30 text-orange-800 dark:text-orange-300 rounded text-sm hover:bg-orange-200 dark:hover:bg-orange-800/30 transition-colors"><span class="truncate"> </span> <button class="ml-auto text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400" title="Remove from mappings">×</button></div>'),Ft=h('<div role="region" aria-label="Justification field drop zone"><p class="text-xs text-gray-400 dark:text-gray-500 text-center py-4">Drop fields here</p></div>'),Ot=h('<th class="px-4 py-2"> </th>'),Pt=h('<td class="px-4 py-2"> </td>'),Ht=h('<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"></tr>'),Et=h('<div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Sample Data Preview</h3> <div class="overflow-x-auto"><table class="w-full text-sm text-left text-gray-500 dark:text-gray-400"><thead class="text-xs text-gray-700 uppercase bg-gray-100 dark:bg-gray-600 dark:text-gray-400"><tr></tr></thead><tbody></tbody></table></div></div>'),It=h('<span class="flex items-center"><svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> Importing...</span>'),Tt=h(`<div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Import Options</h3> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4"><div><label for="controlSetName" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Control Set Name <span class="text-red-500">*</span></label> <input type="text" id="controlSetName" placeholder="e.g., NIST 800-53 Rev 4" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white" required/> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">This will be used as the display name and folder name</p></div> <div><label for="controlSetDescription" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Description</label> <input type="text" id="controlSetDescription" placeholder="Optional description" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"/> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Brief description of this control set</p></div></div> <div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><label for="sheet" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Sheet</label> <select id="sheet" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select which worksheet contains your control data</p></div> <div><label for="headerRow" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Select Header Row</label> <select id="headerRow" class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:text-white"></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Select the row containing column headers</p></div> <div><label for="controlIdField" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Control ID Field <span class="text-red-500">*</span></label> <select id="controlIdField" required><option disabled>Select Control ID field</option><!></select> <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Column containing unique control identifiers (e.g., AC-1, SC-7)</p></div></div></div> <div class="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-lg p-4 border border-gray-200 dark:border-gray-700"><h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">Organize Fields</h3> <p class="text-sm text-gray-600 dark:text-gray-400 mb-4">Drag fields to organize them. <strong>Overview fields</strong> will appear as table columns in
|
|
2
2
|
the controls list.</p> <div class="grid grid-cols-1 lg:grid-cols-5 gap-4"><div class="border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800"><div class="p-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 rounded-t-lg"><h4 class="text-sm font-semibold text-gray-700 dark:text-gray-300">Excluded Fields</h4> <p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Not imported</p></div> <div role="region" aria-label="Excluded fields drop zone"><!> <!></div></div> <div class="border border-blue-300 dark:border-blue-700 rounded-lg bg-white dark:bg-gray-800"><div class="p-3 border-b border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/20 rounded-t-lg"><h4 class="text-sm font-semibold text-blue-700 dark:text-blue-300">Overview Tab</h4> <p class="text-xs text-blue-600 dark:text-blue-400 mt-1">Shows in details & table columns</p></div> <div role="region" aria-label="Overview tab drop zone"><!> <!></div></div> <div class="border border-green-300 dark:border-green-700 rounded-lg bg-white dark:bg-gray-800"><div class="p-3 border-b border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-900/20 rounded-t-lg"><h4 class="text-sm font-semibold text-green-700 dark:text-green-300">Implementation Tab</h4> <p class="text-xs text-green-600 dark:text-green-400 mt-1">Status & compliance</p></div> <div role="region" aria-label="Implementation tab drop zone"><!> <!></div></div> <div class="border border-purple-300 dark:border-purple-700 rounded-lg bg-white dark:bg-gray-800"><div class="p-3 border-b border-purple-200 dark:border-purple-800 bg-purple-50 dark:bg-purple-900/20 rounded-t-lg"><h4 class="text-sm font-semibold text-purple-700 dark:text-purple-300">Custom Tab</h4> <p class="text-xs text-purple-600 dark:text-purple-400 mt-1">Additional fields</p></div> <div role="region" aria-label="Custom fields drop zone"><!> <!></div></div> <div class="border border-orange-300 dark:border-orange-700 rounded-lg bg-white dark:bg-gray-800"><div class="p-3 border-b border-orange-200 dark:border-orange-800 bg-orange-50 dark:bg-orange-900/20 rounded-t-lg"><h4 class="text-sm font-semibold text-orange-700 dark:text-orange-300">Mappings Tab</h4> <p class="text-xs text-orange-600 dark:text-orange-400 mt-1">Pre-populate justification for a control mapping</p></div> <div role="region" aria-label="Justifications tab drop zone"><div class="space-y-2"><!></div></div></div></div></div> <!> <div class="flex justify-center"><button class="px-5 py-2.5 text-white bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm disabled:opacity-50 disabled:cursor-not-allowed"><!></button></div>`,1),Vt=h('<div class="space-y-6"><div role="button" tabindex="0" class="relative"><label><div class="flex flex-col items-center justify-center pt-5 pb-6"><!> <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span class="font-semibold">Click to upload</span> or drag and drop</p> <p class="text-xs text-gray-500 dark:text-gray-400">XLSX, XLS or CSV files</p></div> <input type="file" class="hidden" accept=".xlsx,.xls,.csv"/></label></div> <!> <!> <!> <!></div>');function jt(pe,q){Ye(q,!1);const z=Lr();let X=k(null),O=k(""),L=k(""),N=k([]),f=k([]),S=k([]),K=k(0),re=k([]),P=k([]),p=k(new Map),U=k(1),V=k(""),fe=k(""),J=k(""),G=k(!1),Q=k(""),ue=k(""),we=k(!1),te=k(!1),$=k(null),B=k(null),ae=k(null);function ke(){o(f,[]),o(S,[]),o(K,0),e(p).clear(),o(p,new Map),o(P,[]),o(V,""),o(Q,""),o(ue,""),o($,null),o(B,null),o(ae,null)}function u(l){l.preventDefault(),o(te,!0)}function b(){o(te,!1)}function D(l){l.preventDefault(),o(te,!1);const n=l.dataTransfer?.files;n&&n.length>0&&I(n[0])}function T(l){const n=l.target;n.files&&n.files.length>0&&I(n.files[0])}async function I(l){ke(),o(O,l.name),o(X,l),o(Q,""),o(G,!0),o(fe,e(O).replace(/\.[^.]+$/,"").replace(/[-_]/g," ")),o(J,`Imported from ${e(O)}`);try{const n=new FormData;n.append("file",l);const y=await fetch("/api/parse-excel",{method:"POST",body:n});if(!y.ok){const w=await y.json();throw new Error(w.error||"Failed to parse file")}const _=await y.json();o(N,_.sheets||[]),o(L,_.selectedSheet||e(N)[0]),o(re,_.rowPreviews||[]),e(re).length>0&&e(U)===1&&o(U,e(re)[0].row),await Z(),o(we,!0)}catch(n){o(Q,"Error reading file: "+n.message)}finally{o(G,!1)}}async function Z(){if(!(!e(X)||!e(L))){o(G,!0),e(p).clear(),o(p,new Map),o(V,"");try{const l=new FormData;l.append("file",e(X)),l.append("sheetName",e(L)),l.append("headerRow",e(U).toString());const n=await fetch("/api/parse-excel-sheet",{method:"POST",body:l});if(!n.ok){const _=await n.json();throw new Error(_.error||"Failed to parse sheet")}const y=await n.json();if(o(f,y.fields||[]),o(S,y.sampleData||[]),o(K,y.controlCount||0),e(f).forEach((_,w)=>{const v=_.toLowerCase();let H="custom",R="text";v.includes("implementation")||v.includes("status")||v.includes("narrative")||v.includes("guidance")?H="implementation":(v.includes("id")||v.includes("title")||v.includes("family")||v.includes("cci")||v.includes("control")||v.includes("acronym"))&&(H="overview"),v.includes("description")||v.includes("narrative")||v.includes("guidance")||v.includes("statement")?R="textarea":v.includes("status")||v.includes("type")||v.includes("designation")?R="select":v.includes("date")?R="date":(v.includes("count")||v.includes("number"))&&(R="number"),e(p).set(_,{originalName:_,tab:H,displayOrder:w,fieldType:R,required:v.includes("id")||v.includes("title")})}),o(p,e(p)),e(V)&&!e(f).includes(e(V))&&o(V,""),!e(V)&&e(f).includes("AP Acronym")){const _=!e(S).length||e(S).every(ee=>!ee["AP Acronym"]||String(ee["AP Acronym"]).length<25),w=e(S).map(ee=>ee["AP Acronym"]).filter(ee=>ee!=null&&ee!==""&&String(ee).trim()!==""),v=new Set(w),H=!w.length||v.size===w.length,R=w.length>0;_&&H&&R&&o(V,"AP Acronym")}}catch(l){o(Q,"Error loading sheet data: "+l.message)}finally{o(G,!1)}}}function ve(l){if(!l)return l;let n=l.trim().replace(/\r?\n/g," ").replace(/\s+/g," ").trim();return je(n)}function je(l){return l.replace(/\W+/g," ").split(/ |\s/).map(n=>n.toLowerCase()).join("-")}function xe(l,n){o($,n),l.dataTransfer&&(l.dataTransfer.effectAllowed="move",l.dataTransfer.setData("text/plain",n))}function oe(){o($,null),o(B,null),o(ae,null)}function C(l,n){l.preventDefault(),o(B,n),l.dataTransfer&&(l.dataTransfer.dropEffect="move")}function ie(){o(B,null)}function ne(l,n,y){if(l.preventDefault(),e($)&&e(p).has(e($))){const _=e(p).get(e($));if(n==="mappings")e(P).includes(e($))||o(P,[...e(P),e($)]);else{if(_.tab=n,y!==void 0&&n!==null){const v=Array.from(e(p).entries()).filter(([H,R])=>R.tab===n).sort((H,R)=>H[1].displayOrder-R[1].displayOrder).filter(([H])=>H!==e($));v.splice(y,0,[e($),_]),v.forEach(([H,R],ee)=>{R.displayOrder=ee,e(p).set(H,R)})}else if(n!==null){const w=Math.max(0,...Array.from(e(p).values()).filter(v=>v.tab===n).map(v=>v.displayOrder));_.displayOrder=w+1}e(p).set(e($),_),o(p,e(p))}}o($,null),o(B,null)}function ze(l,n){l.preventDefault(),l.stopPropagation(),o(ae,n)}function Ce(){o(ae,null)}function Se(l,n,y){if(l.preventDefault(),l.stopPropagation(),e($)&&e($)!==n){const w=Array.from(e(p).entries()).filter(([v,H])=>H.tab===y).sort((v,H)=>v[1].displayOrder-H[1].displayOrder).findIndex(([v])=>v===n);w!==-1&&ne(l,y,w)}o(ae,null)}async function Le(){if(!(!e(X)||!e(O))){if(!e(V)){o(Q,"Please select a Control ID field before importing"),o(ue,"");return}if(!e(fe)||e(fe).trim()===""){o(Q,"Please enter a Control Set Name before importing"),o(ue,"");return}o(G,!0),o(Q,""),o(ue,"");try{const l=new FormData;l.append("file",e(X),e(O)),l.append("controlIdField",e(V)),l.append("startRow",e(U).toString()),l.append("namingConvention","kebab-case"),l.append("skipEmpty","true"),l.append("skipEmptyRows","true"),l.append("controlSetName",e(fe)||e(O).replace(/\.[^.]+$/,"")),l.append("controlSetDescription",e(J)||`Imported from ${e(O)}`);const n=Array.from(e(p).entries()).filter(([w,v])=>v.tab!==null).map(([w,v])=>({fieldName:ve(w),...v}));l.append("fieldSchema",JSON.stringify(n)),l.append("justificationFields",JSON.stringify(e(P).map(w=>ve(w))));const y=await fetch("/api/import-spreadsheet",{method:"POST",body:l});if(!y.ok){const w=await y.json();throw new Error(w.error||"Import failed")}const _=await y.json();o(ue,`Successfully imported ${_.controlCount} controls into ${_.families.length} families`),z("created",{path:_.outputDir})}catch(l){o(Q,"Error importing spreadsheet: "+l.message)}finally{o(G,!1)}}}Je();var Ne=Vt(),me=a(Ne),Be=a(me),Ae=a(Be),ar=a(Ae);gt(ar,{class:"w-8 h-8 mb-4 text-gray-500 dark:text-gray-400"}),_e(4),t(Ae);var Xe=i(Ae,2);t(Be),t(me);var Fe=i(me,2);{var or=l=>{var n=bt(),y=a(n),_=i(a(y),2),w=i(a(_)),v=i(w),H=i(a(v)),R=i(H,2),ee=i(R,2);t(v),t(_),t(y),t(n),F(()=>{E(w,` ${e(O)??""} `),E(H,` ${e(N).length??""} | `),E(R,` ${e(f).length??""} | `),E(ee,` ${e(K)??""}`)}),d(l,n)};M(Fe,l=>{e(O)&&l(or)})}var Ke=i(Fe,2);{var lr=l=>{var n=ft(),y=a(n),_=i(a(y),2),w=a(_,!0);t(_),t(y),t(n),F(()=>E(w,e(Q))),d(l,n)};M(Ke,l=>{e(Q)&&l(lr)})}var Ze=i(Ke,2);{var sr=l=>{var n=xt(),y=a(n),_=i(a(y),2),w=a(_,!0);t(_),t(y),t(n),F(()=>E(w,e(ue))),d(l,n)};M(Ze,l=>{e(ue)&&l(sr)})}var ir=i(Ze,2);{var nr=l=>{var n=Tt(),y=ye(n),_=i(a(y),2),w=a(_),v=i(a(w),2);Vr(v),_e(2),t(w);var H=i(w,2),R=i(a(H),2);Vr(R),_e(2),t(H),t(_);var ee=i(_,2),dr=a(ee),Ge=i(a(dr),2);F(()=>{e(L),mr(()=>{e(N)})}),ce(Ge,5,()=>e(N),r=>r,(r,s)=>{var x=mt(),m=a(x,!0);t(x);var c={};F(()=>{E(m,e(s)),c!==(c=e(s))&&(x.value=(x.__value=e(s))??"")}),d(r,x)}),t(Ge),_e(2),t(dr);var vr=i(dr,2),Qe=i(a(vr),2);F(()=>{e(U),mr(()=>{e(re)})}),ce(Qe,5,()=>e(re),r=>r.row,(r,s)=>{var x=ht(),m=a(x);t(x);var c={};F(()=>{E(m,`Row ${e(s).row??""}: ${e(s).preview??""}`),c!==(c=e(s).row)&&(x.value=(x.__value=e(s).row)??"")}),d(r,x)}),t(Qe),_e(2),t(vr);var Dr=i(vr,2),er=i(a(Dr),2);F(()=>{e(V),mr(()=>{e(f),e(S)})});var cr=a(er);cr.value=cr.__value="";var Br=i(cr);ce(Br,1,()=>e(f),r=>r,(r,s)=>{const x=De(()=>e(S).length>0&&e(S)[0][e(s)]?String(e(S)[0][e(s)]).slice(0,30):""),m=De(()=>!e(S).length||e(S).every(le=>!le[e(s)]||String(le[e(s)]).length<25)),c=De(()=>e(S).map(le=>le[e(s)]).filter(le=>le!=null&&le!==""&&String(le).trim()!=="")),Y=De(()=>new Set(e(c))),W=De(()=>!e(c).length||e(Y).size===e(c).length),j=De(()=>e(c).length>0);var A=Me(),be=ye(A);{var $e=le=>{var he=yt(),xr=a(he);t(he);var Tr={};F(()=>{E(xr,`${e(s)??""}${e(x)?` (e.g., ${e(x)})`:""}`),Tr!==(Tr=e(s))&&(he.value=(he.__value=e(s))??"")}),d(le,he)};M(be,le=>{e(m)&&e(W)&&e(j)&&le($e)})}d(r,A)}),t(er),_e(2),t(Dr),t(ee),t(y);var gr=i(y,2),Mr=i(a(gr),4),pr=a(Mr),Oe=i(a(pr),2),zr=a(Oe);ce(zr,1,()=>e(f).filter(r=>!e(p).get(r)||e(p).get(r)?.tab===null),r=>r,(r,s)=>{var x=wt(),m=i(a(x),2),c=a(m,!0);t(m);var Y=i(m,2);{var W=j=>{var A=_t();d(j,A)};M(Y,j=>{e(s)===e(V)&&j(W)})}t(x),F(()=>{qe(x,"aria-label",`Drag ${e(s)??""} field`),E(c,e(s))}),g("dragstart",x,j=>xe(j,e(s))),g("dragend",x,oe),d(r,x)});var Zr=i(zr,2);{var Rr=r=>{var s=kt();d(r,s)};M(Zr,r=>{e(f).filter(s=>!e(p).get(s)||e(p).get(s)?.tab===null).length===0&&r(Rr)})}t(Oe),t(pr);var ur=i(pr,2),Pe=i(a(ur),2),Ar=a(Pe);ce(Ar,3,()=>Array.from(e(p).entries()).filter(([r,s])=>s.tab==="overview").sort((r,s)=>r[1].displayOrder-s[1].displayOrder),([r,s])=>r,(r,s)=>{var x=hr(()=>yr(e(s),2));let m=()=>e(x)[0];var c=Ct(),Y=a(c);kr(Y,{class:"w-3 h-3 mr-2 flex-shrink-0"});var W=i(Y,2),j=a(W,!0);t(W),t(c),F(()=>{qe(c,"aria-label",`${m()??""} field in Overview tab`),se(c,1,`flex items-center px-3 py-2 bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-300 rounded text-sm cursor-move hover:bg-blue-200 dark:hover:bg-blue-800/30 transition-colors
|
|
3
3
|
${e(ae)===m()&&e($)!==m()?"border-t-2 border-blue-500":""}`),E(j,m())}),g("dragstart",c,A=>xe(A,m())),g("dragend",c,oe),g("dragover",c,A=>ze(A,m())),g("dragleave",c,Ce),g("drop",c,A=>Se(A,m(),"overview")),d(r,c)});var qr=i(Ar,2);{var Ur=r=>{var s=St();d(r,s)};M(qr,r=>{Array.from(e(p).entries()).filter(([s,x])=>x.tab==="overview").length===0&&r(Ur)})}t(Pe),t(ur);var br=i(ur,2),He=i(a(br),2),Fr=a(He);ce(Fr,3,()=>Array.from(e(p).entries()).filter(([r,s])=>s.tab==="implementation").sort((r,s)=>r[1].displayOrder-s[1].displayOrder),([r,s])=>r,(r,s)=>{var x=hr(()=>yr(e(s),2));let m=()=>e(x)[0];var c=$t(),Y=a(c);kr(Y,{class:"w-3 h-3 mr-2 flex-shrink-0"});var W=i(Y,2),j=a(W,!0);t(W),t(c),F(()=>{qe(c,"aria-label",`${m()??""} field in Implementation tab`),se(c,1,`flex items-center px-3 py-2 bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300 rounded text-sm cursor-move hover:bg-green-200 dark:hover:bg-green-800/30 transition-colors
|
|
4
4
|
${e(ae)===m()&&e($)!==m()?"border-t-2 border-green-500":""}`),E(j,m())}),g("dragstart",c,A=>xe(A,m())),g("dragend",c,oe),g("dragover",c,A=>ze(A,m())),g("dragleave",c,Ce),g("drop",c,A=>Se(A,m(),"implementation")),d(r,c)});var Jr=i(Fr,2);{var Yr=r=>{var s=Dt();d(r,s)};M(Jr,r=>{Array.from(e(p).entries()).filter(([s,x])=>x.tab==="implementation").length===0&&r(Yr)})}t(He),t(br);var fr=i(br,2),Ee=i(a(fr),2),Or=a(Ee);ce(Or,3,()=>Array.from(e(p).entries()).filter(([r,s])=>s.tab==="custom").sort((r,s)=>r[1].displayOrder-s[1].displayOrder),([r,s])=>r,(r,s)=>{var x=hr(()=>yr(e(s),2));let m=()=>e(x)[0];var c=Mt(),Y=a(c);kr(Y,{class:"w-3 h-3 mr-2 flex-shrink-0"});var W=i(Y,2),j=a(W,!0);t(W),t(c),F(()=>{qe(c,"aria-label",`${m()??""} field in Custom tab`),se(c,1,`flex items-center px-3 py-2 bg-purple-100 dark:bg-purple-900/30 text-purple-800 dark:text-purple-300 rounded text-sm cursor-move hover:bg-purple-200 dark:hover:bg-purple-800/30 transition-colors
|
package/dist/_app/version.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"1759847882477"}
|
package/dist/cli/commands/ui.js
CHANGED
|
@@ -2861,7 +2861,7 @@ __export(spreadsheetRoutes_exports, {
|
|
|
2861
2861
|
});
|
|
2862
2862
|
import crypto from "crypto";
|
|
2863
2863
|
import { parse as parseCSVSync } from "csv-parse/sync";
|
|
2864
|
-
import
|
|
2864
|
+
import * as XLSX from "xlsx-republish";
|
|
2865
2865
|
import express from "express";
|
|
2866
2866
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
2867
2867
|
import { glob } from "glob";
|
|
@@ -2956,20 +2956,13 @@ async function parseUploadedFile(file) {
|
|
|
2956
2956
|
const csvContent = file.buffer.toString("utf-8");
|
|
2957
2957
|
rawData = parseCSV(csvContent);
|
|
2958
2958
|
} else {
|
|
2959
|
-
const workbook =
|
|
2960
|
-
const
|
|
2961
|
-
|
|
2962
|
-
const worksheet = workbook.worksheets[0];
|
|
2963
|
-
if (!worksheet) {
|
|
2959
|
+
const workbook = XLSX.read(file.buffer, { type: "buffer" });
|
|
2960
|
+
const worksheetName = workbook.SheetNames[0];
|
|
2961
|
+
if (!worksheetName) {
|
|
2964
2962
|
throw new Error("No worksheet found in file");
|
|
2965
2963
|
}
|
|
2966
|
-
worksheet
|
|
2967
|
-
|
|
2968
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
2969
|
-
rowData[colNumber - 1] = cell.value;
|
|
2970
|
-
});
|
|
2971
|
-
rawData[rowNumber - 1] = rowData;
|
|
2972
|
-
});
|
|
2964
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
2965
|
+
rawData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
2973
2966
|
}
|
|
2974
2967
|
return rawData;
|
|
2975
2968
|
}
|
|
@@ -3540,43 +3533,20 @@ async function exportAsExcelWithMapping(controls, metadata, columnMappings, res)
|
|
|
3540
3533
|
});
|
|
3541
3534
|
return exportControl;
|
|
3542
3535
|
});
|
|
3543
|
-
const wb =
|
|
3544
|
-
const ws =
|
|
3545
|
-
|
|
3546
|
-
ws.columns = headers.map((header) => ({
|
|
3547
|
-
header,
|
|
3548
|
-
key: header,
|
|
3549
|
-
width: Math.min(
|
|
3550
|
-
Math.max(
|
|
3551
|
-
header.length,
|
|
3552
|
-
...worksheetData.map((row) => String(row[header] || "").length)
|
|
3553
|
-
) + 2,
|
|
3554
|
-
50
|
|
3555
|
-
)
|
|
3556
|
-
// Auto-size with max width of 50
|
|
3557
|
-
}));
|
|
3558
|
-
worksheetData.forEach((row) => {
|
|
3559
|
-
ws.addRow(row);
|
|
3560
|
-
});
|
|
3561
|
-
ws.getRow(1).font = { bold: true };
|
|
3562
|
-
ws.getRow(1).fill = {
|
|
3563
|
-
type: "pattern",
|
|
3564
|
-
pattern: "solid",
|
|
3565
|
-
fgColor: { argb: "FFE0E0E0" }
|
|
3566
|
-
};
|
|
3536
|
+
const wb = XLSX.utils.book_new();
|
|
3537
|
+
const ws = XLSX.utils.json_to_sheet(worksheetData);
|
|
3538
|
+
XLSX.utils.book_append_sheet(wb, ws, "Controls");
|
|
3567
3539
|
if (metadata) {
|
|
3568
|
-
const metaSheet = wb.addWorksheet("Metadata");
|
|
3569
3540
|
const cleanMetadata = { ...metadata };
|
|
3570
3541
|
delete cleanMetadata.fieldSchema;
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
});
|
|
3542
|
+
const metadataArray = Object.entries(cleanMetadata).map(([key, value]) => ({
|
|
3543
|
+
Property: key,
|
|
3544
|
+
Value: String(value)
|
|
3545
|
+
}));
|
|
3546
|
+
const metaSheet = XLSX.utils.json_to_sheet(metadataArray);
|
|
3547
|
+
XLSX.utils.book_append_sheet(wb, metaSheet, "Metadata");
|
|
3578
3548
|
}
|
|
3579
|
-
const buffer =
|
|
3549
|
+
const buffer = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
|
|
3580
3550
|
const fileName = `${metadata?.name || "controls"}_export_${Date.now()}.xlsx`;
|
|
3581
3551
|
res.setHeader(
|
|
3582
3552
|
"Content-Type",
|
|
@@ -3818,21 +3788,14 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3818
3788
|
rows = parseCSV(csvContent);
|
|
3819
3789
|
sheets = ["Sheet1"];
|
|
3820
3790
|
} else {
|
|
3821
|
-
const workbook =
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
const worksheet = workbook.worksheets[0];
|
|
3826
|
-
if (!worksheet) {
|
|
3791
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3792
|
+
sheets = workbook.SheetNames;
|
|
3793
|
+
const worksheetName = workbook.SheetNames[0];
|
|
3794
|
+
if (!worksheetName) {
|
|
3827
3795
|
return res.status(400).json({ error: "No worksheet found in file" });
|
|
3828
3796
|
}
|
|
3829
|
-
worksheet
|
|
3830
|
-
|
|
3831
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3832
|
-
rowData[colNumber - 1] = cell.value;
|
|
3833
|
-
});
|
|
3834
|
-
rows.push(rowData);
|
|
3835
|
-
});
|
|
3797
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
3798
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3836
3799
|
}
|
|
3837
3800
|
const headerCandidates = rows.slice(0, 5).map((row, index) => ({
|
|
3838
3801
|
row: index + 1,
|
|
@@ -3864,20 +3827,12 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3864
3827
|
const csvContent = req.file.buffer.toString("utf-8");
|
|
3865
3828
|
rows = parseCSV(csvContent);
|
|
3866
3829
|
} else {
|
|
3867
|
-
const workbook =
|
|
3868
|
-
|
|
3869
|
-
await workbook.xlsx.load(buffer);
|
|
3870
|
-
const worksheet = workbook.getWorksheet(sheetName);
|
|
3871
|
-
if (!worksheet) {
|
|
3830
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3831
|
+
if (!workbook.SheetNames.includes(sheetName)) {
|
|
3872
3832
|
return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
|
|
3873
3833
|
}
|
|
3874
|
-
worksheet
|
|
3875
|
-
|
|
3876
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3877
|
-
rowData[colNumber - 1] = cell.value;
|
|
3878
|
-
});
|
|
3879
|
-
rows.push(rowData);
|
|
3880
|
-
});
|
|
3834
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
3835
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3881
3836
|
}
|
|
3882
3837
|
const headerRowIndex = parseInt(headerRow) - 1;
|
|
3883
3838
|
const headers = rows[headerRowIndex] || [];
|
package/dist/cli/server/index.js
CHANGED
|
@@ -2843,7 +2843,7 @@ __export(spreadsheetRoutes_exports, {
|
|
|
2843
2843
|
});
|
|
2844
2844
|
import crypto from "crypto";
|
|
2845
2845
|
import { parse as parseCSVSync } from "csv-parse/sync";
|
|
2846
|
-
import
|
|
2846
|
+
import * as XLSX from "xlsx-republish";
|
|
2847
2847
|
import express from "express";
|
|
2848
2848
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
2849
2849
|
import { glob } from "glob";
|
|
@@ -2938,20 +2938,13 @@ async function parseUploadedFile(file) {
|
|
|
2938
2938
|
const csvContent = file.buffer.toString("utf-8");
|
|
2939
2939
|
rawData = parseCSV(csvContent);
|
|
2940
2940
|
} else {
|
|
2941
|
-
const workbook =
|
|
2942
|
-
const
|
|
2943
|
-
|
|
2944
|
-
const worksheet = workbook.worksheets[0];
|
|
2945
|
-
if (!worksheet) {
|
|
2941
|
+
const workbook = XLSX.read(file.buffer, { type: "buffer" });
|
|
2942
|
+
const worksheetName = workbook.SheetNames[0];
|
|
2943
|
+
if (!worksheetName) {
|
|
2946
2944
|
throw new Error("No worksheet found in file");
|
|
2947
2945
|
}
|
|
2948
|
-
worksheet
|
|
2949
|
-
|
|
2950
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
2951
|
-
rowData[colNumber - 1] = cell.value;
|
|
2952
|
-
});
|
|
2953
|
-
rawData[rowNumber - 1] = rowData;
|
|
2954
|
-
});
|
|
2946
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
2947
|
+
rawData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
2955
2948
|
}
|
|
2956
2949
|
return rawData;
|
|
2957
2950
|
}
|
|
@@ -3522,43 +3515,20 @@ async function exportAsExcelWithMapping(controls, metadata, columnMappings, res)
|
|
|
3522
3515
|
});
|
|
3523
3516
|
return exportControl;
|
|
3524
3517
|
});
|
|
3525
|
-
const wb =
|
|
3526
|
-
const ws =
|
|
3527
|
-
|
|
3528
|
-
ws.columns = headers.map((header) => ({
|
|
3529
|
-
header,
|
|
3530
|
-
key: header,
|
|
3531
|
-
width: Math.min(
|
|
3532
|
-
Math.max(
|
|
3533
|
-
header.length,
|
|
3534
|
-
...worksheetData.map((row) => String(row[header] || "").length)
|
|
3535
|
-
) + 2,
|
|
3536
|
-
50
|
|
3537
|
-
)
|
|
3538
|
-
// Auto-size with max width of 50
|
|
3539
|
-
}));
|
|
3540
|
-
worksheetData.forEach((row) => {
|
|
3541
|
-
ws.addRow(row);
|
|
3542
|
-
});
|
|
3543
|
-
ws.getRow(1).font = { bold: true };
|
|
3544
|
-
ws.getRow(1).fill = {
|
|
3545
|
-
type: "pattern",
|
|
3546
|
-
pattern: "solid",
|
|
3547
|
-
fgColor: { argb: "FFE0E0E0" }
|
|
3548
|
-
};
|
|
3518
|
+
const wb = XLSX.utils.book_new();
|
|
3519
|
+
const ws = XLSX.utils.json_to_sheet(worksheetData);
|
|
3520
|
+
XLSX.utils.book_append_sheet(wb, ws, "Controls");
|
|
3549
3521
|
if (metadata) {
|
|
3550
|
-
const metaSheet = wb.addWorksheet("Metadata");
|
|
3551
3522
|
const cleanMetadata = { ...metadata };
|
|
3552
3523
|
delete cleanMetadata.fieldSchema;
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
});
|
|
3524
|
+
const metadataArray = Object.entries(cleanMetadata).map(([key, value]) => ({
|
|
3525
|
+
Property: key,
|
|
3526
|
+
Value: String(value)
|
|
3527
|
+
}));
|
|
3528
|
+
const metaSheet = XLSX.utils.json_to_sheet(metadataArray);
|
|
3529
|
+
XLSX.utils.book_append_sheet(wb, metaSheet, "Metadata");
|
|
3560
3530
|
}
|
|
3561
|
-
const buffer =
|
|
3531
|
+
const buffer = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
|
|
3562
3532
|
const fileName = `${metadata?.name || "controls"}_export_${Date.now()}.xlsx`;
|
|
3563
3533
|
res.setHeader(
|
|
3564
3534
|
"Content-Type",
|
|
@@ -3800,21 +3770,14 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3800
3770
|
rows = parseCSV(csvContent);
|
|
3801
3771
|
sheets = ["Sheet1"];
|
|
3802
3772
|
} else {
|
|
3803
|
-
const workbook =
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
const worksheet = workbook.worksheets[0];
|
|
3808
|
-
if (!worksheet) {
|
|
3773
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3774
|
+
sheets = workbook.SheetNames;
|
|
3775
|
+
const worksheetName = workbook.SheetNames[0];
|
|
3776
|
+
if (!worksheetName) {
|
|
3809
3777
|
return res.status(400).json({ error: "No worksheet found in file" });
|
|
3810
3778
|
}
|
|
3811
|
-
worksheet
|
|
3812
|
-
|
|
3813
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3814
|
-
rowData[colNumber - 1] = cell.value;
|
|
3815
|
-
});
|
|
3816
|
-
rows.push(rowData);
|
|
3817
|
-
});
|
|
3779
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
3780
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3818
3781
|
}
|
|
3819
3782
|
const headerCandidates = rows.slice(0, 5).map((row, index) => ({
|
|
3820
3783
|
row: index + 1,
|
|
@@ -3846,20 +3809,12 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3846
3809
|
const csvContent = req.file.buffer.toString("utf-8");
|
|
3847
3810
|
rows = parseCSV(csvContent);
|
|
3848
3811
|
} else {
|
|
3849
|
-
const workbook =
|
|
3850
|
-
|
|
3851
|
-
await workbook.xlsx.load(buffer);
|
|
3852
|
-
const worksheet = workbook.getWorksheet(sheetName);
|
|
3853
|
-
if (!worksheet) {
|
|
3812
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3813
|
+
if (!workbook.SheetNames.includes(sheetName)) {
|
|
3854
3814
|
return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
|
|
3855
3815
|
}
|
|
3856
|
-
worksheet
|
|
3857
|
-
|
|
3858
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3859
|
-
rowData[colNumber - 1] = cell.value;
|
|
3860
|
-
});
|
|
3861
|
-
rows.push(rowData);
|
|
3862
|
-
});
|
|
3816
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
3817
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3863
3818
|
}
|
|
3864
3819
|
const headerRowIndex = parseInt(headerRow) - 1;
|
|
3865
3820
|
const headers = rows[headerRowIndex] || [];
|
|
@@ -2843,7 +2843,7 @@ __export(spreadsheetRoutes_exports, {
|
|
|
2843
2843
|
});
|
|
2844
2844
|
import crypto from "crypto";
|
|
2845
2845
|
import { parse as parseCSVSync } from "csv-parse/sync";
|
|
2846
|
-
import
|
|
2846
|
+
import * as XLSX from "xlsx-republish";
|
|
2847
2847
|
import express from "express";
|
|
2848
2848
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
2849
2849
|
import { glob } from "glob";
|
|
@@ -2938,20 +2938,13 @@ async function parseUploadedFile(file) {
|
|
|
2938
2938
|
const csvContent = file.buffer.toString("utf-8");
|
|
2939
2939
|
rawData = parseCSV(csvContent);
|
|
2940
2940
|
} else {
|
|
2941
|
-
const workbook =
|
|
2942
|
-
const
|
|
2943
|
-
|
|
2944
|
-
const worksheet = workbook.worksheets[0];
|
|
2945
|
-
if (!worksheet) {
|
|
2941
|
+
const workbook = XLSX.read(file.buffer, { type: "buffer" });
|
|
2942
|
+
const worksheetName = workbook.SheetNames[0];
|
|
2943
|
+
if (!worksheetName) {
|
|
2946
2944
|
throw new Error("No worksheet found in file");
|
|
2947
2945
|
}
|
|
2948
|
-
worksheet
|
|
2949
|
-
|
|
2950
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
2951
|
-
rowData[colNumber - 1] = cell.value;
|
|
2952
|
-
});
|
|
2953
|
-
rawData[rowNumber - 1] = rowData;
|
|
2954
|
-
});
|
|
2946
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
2947
|
+
rawData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
2955
2948
|
}
|
|
2956
2949
|
return rawData;
|
|
2957
2950
|
}
|
|
@@ -3522,43 +3515,20 @@ async function exportAsExcelWithMapping(controls, metadata, columnMappings, res)
|
|
|
3522
3515
|
});
|
|
3523
3516
|
return exportControl;
|
|
3524
3517
|
});
|
|
3525
|
-
const wb =
|
|
3526
|
-
const ws =
|
|
3527
|
-
|
|
3528
|
-
ws.columns = headers.map((header) => ({
|
|
3529
|
-
header,
|
|
3530
|
-
key: header,
|
|
3531
|
-
width: Math.min(
|
|
3532
|
-
Math.max(
|
|
3533
|
-
header.length,
|
|
3534
|
-
...worksheetData.map((row) => String(row[header] || "").length)
|
|
3535
|
-
) + 2,
|
|
3536
|
-
50
|
|
3537
|
-
)
|
|
3538
|
-
// Auto-size with max width of 50
|
|
3539
|
-
}));
|
|
3540
|
-
worksheetData.forEach((row) => {
|
|
3541
|
-
ws.addRow(row);
|
|
3542
|
-
});
|
|
3543
|
-
ws.getRow(1).font = { bold: true };
|
|
3544
|
-
ws.getRow(1).fill = {
|
|
3545
|
-
type: "pattern",
|
|
3546
|
-
pattern: "solid",
|
|
3547
|
-
fgColor: { argb: "FFE0E0E0" }
|
|
3548
|
-
};
|
|
3518
|
+
const wb = XLSX.utils.book_new();
|
|
3519
|
+
const ws = XLSX.utils.json_to_sheet(worksheetData);
|
|
3520
|
+
XLSX.utils.book_append_sheet(wb, ws, "Controls");
|
|
3549
3521
|
if (metadata) {
|
|
3550
|
-
const metaSheet = wb.addWorksheet("Metadata");
|
|
3551
3522
|
const cleanMetadata = { ...metadata };
|
|
3552
3523
|
delete cleanMetadata.fieldSchema;
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
});
|
|
3524
|
+
const metadataArray = Object.entries(cleanMetadata).map(([key, value]) => ({
|
|
3525
|
+
Property: key,
|
|
3526
|
+
Value: String(value)
|
|
3527
|
+
}));
|
|
3528
|
+
const metaSheet = XLSX.utils.json_to_sheet(metadataArray);
|
|
3529
|
+
XLSX.utils.book_append_sheet(wb, metaSheet, "Metadata");
|
|
3560
3530
|
}
|
|
3561
|
-
const buffer =
|
|
3531
|
+
const buffer = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
|
|
3562
3532
|
const fileName = `${metadata?.name || "controls"}_export_${Date.now()}.xlsx`;
|
|
3563
3533
|
res.setHeader(
|
|
3564
3534
|
"Content-Type",
|
|
@@ -3800,21 +3770,14 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3800
3770
|
rows = parseCSV(csvContent);
|
|
3801
3771
|
sheets = ["Sheet1"];
|
|
3802
3772
|
} else {
|
|
3803
|
-
const workbook =
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
const worksheet = workbook.worksheets[0];
|
|
3808
|
-
if (!worksheet) {
|
|
3773
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3774
|
+
sheets = workbook.SheetNames;
|
|
3775
|
+
const worksheetName = workbook.SheetNames[0];
|
|
3776
|
+
if (!worksheetName) {
|
|
3809
3777
|
return res.status(400).json({ error: "No worksheet found in file" });
|
|
3810
3778
|
}
|
|
3811
|
-
worksheet
|
|
3812
|
-
|
|
3813
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3814
|
-
rowData[colNumber - 1] = cell.value;
|
|
3815
|
-
});
|
|
3816
|
-
rows.push(rowData);
|
|
3817
|
-
});
|
|
3779
|
+
const worksheet = workbook.Sheets[worksheetName];
|
|
3780
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3818
3781
|
}
|
|
3819
3782
|
const headerCandidates = rows.slice(0, 5).map((row, index) => ({
|
|
3820
3783
|
row: index + 1,
|
|
@@ -3846,20 +3809,12 @@ var init_spreadsheetRoutes = __esm({
|
|
|
3846
3809
|
const csvContent = req.file.buffer.toString("utf-8");
|
|
3847
3810
|
rows = parseCSV(csvContent);
|
|
3848
3811
|
} else {
|
|
3849
|
-
const workbook =
|
|
3850
|
-
|
|
3851
|
-
await workbook.xlsx.load(buffer);
|
|
3852
|
-
const worksheet = workbook.getWorksheet(sheetName);
|
|
3853
|
-
if (!worksheet) {
|
|
3812
|
+
const workbook = XLSX.read(req.file.buffer, { type: "buffer" });
|
|
3813
|
+
if (!workbook.SheetNames.includes(sheetName)) {
|
|
3854
3814
|
return res.status(400).json({ error: `Sheet "${sheetName}" not found` });
|
|
3855
3815
|
}
|
|
3856
|
-
worksheet
|
|
3857
|
-
|
|
3858
|
-
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
|
3859
|
-
rowData[colNumber - 1] = cell.value;
|
|
3860
|
-
});
|
|
3861
|
-
rows.push(rowData);
|
|
3862
|
-
});
|
|
3816
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
3817
|
+
rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
|
|
3863
3818
|
}
|
|
3864
3819
|
const headerRowIndex = parseInt(headerRow) - 1;
|
|
3865
3820
|
const headers = rows[headerRowIndex] || [];
|