@harperfast/harper 5.0.0-beta.5 → 5.0.0-beta.7

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 (94) hide show
  1. package/bin/harper.js +1 -1
  2. package/bin/run.js +2 -2
  3. package/components/Application.ts +9 -5
  4. package/components/ApplicationScope.ts +3 -3
  5. package/components/componentLoader.ts +28 -15
  6. package/components/operations.js +13 -13
  7. package/components/operationsValidation.js +3 -3
  8. package/config/configUtils.js +20 -4
  9. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  10. package/dist/bin/harper.d.ts +1 -1
  11. package/dist/bin/harper.js +1 -1
  12. package/dist/bin/run.js +2 -2
  13. package/dist/bin/run.js.map +1 -1
  14. package/dist/components/Application.js +9 -4
  15. package/dist/components/Application.js.map +1 -1
  16. package/dist/components/ApplicationScope.d.ts +1 -1
  17. package/dist/components/ApplicationScope.js +2 -2
  18. package/dist/components/ApplicationScope.js.map +1 -1
  19. package/dist/components/componentLoader.js +30 -16
  20. package/dist/components/componentLoader.js.map +1 -1
  21. package/dist/components/operations.js +13 -13
  22. package/dist/components/operations.js.map +1 -1
  23. package/dist/components/operationsValidation.js +3 -3
  24. package/dist/components/operationsValidation.js.map +1 -1
  25. package/dist/config/configUtils.d.ts +6 -0
  26. package/dist/config/configUtils.js +23 -3
  27. package/dist/config/configUtils.js.map +1 -1
  28. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  29. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
  30. package/dist/resources/Resource.d.ts +2 -0
  31. package/dist/resources/Resource.js +11 -4
  32. package/dist/resources/Resource.js.map +1 -1
  33. package/dist/resources/RocksTransactionLogStore.d.ts +1 -0
  34. package/dist/resources/RocksTransactionLogStore.js +8 -1
  35. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  36. package/dist/resources/analytics/metadata.d.ts +1 -0
  37. package/dist/resources/analytics/metadata.js +1 -0
  38. package/dist/resources/analytics/metadata.js.map +1 -1
  39. package/dist/resources/analytics/read.js +1 -1
  40. package/dist/resources/analytics/read.js.map +1 -1
  41. package/dist/resources/analytics/write.d.ts +1 -0
  42. package/dist/resources/analytics/write.js +42 -0
  43. package/dist/resources/analytics/write.js.map +1 -1
  44. package/dist/resources/databases.js +19 -13
  45. package/dist/resources/databases.js.map +1 -1
  46. package/dist/security/jsLoader.js +167 -81
  47. package/dist/security/jsLoader.js.map +1 -1
  48. package/dist/server/REST.js +17 -10
  49. package/dist/server/REST.js.map +1 -1
  50. package/dist/server/http.js +2 -2
  51. package/dist/server/http.js.map +1 -1
  52. package/dist/server/itc/serverHandlers.js +1 -1
  53. package/dist/server/itc/serverHandlers.js.map +1 -1
  54. package/dist/utility/hdbTerms.d.ts +1 -0
  55. package/dist/utility/hdbTerms.js +1 -0
  56. package/dist/utility/hdbTerms.js.map +1 -1
  57. package/dist/utility/logging/harper_logger.d.ts +2 -1
  58. package/dist/utility/logging/harper_logger.js +47 -11
  59. package/dist/utility/logging/harper_logger.js.map +1 -1
  60. package/dist/utility/logging/readLog.js +2 -2
  61. package/dist/utility/logging/readLog.js.map +1 -1
  62. package/dist/utility/npmUtilities.js +2 -2
  63. package/dist/utility/npmUtilities.js.map +1 -1
  64. package/dist/validation/configValidator.js +18 -8
  65. package/dist/validation/configValidator.js.map +1 -1
  66. package/dist/validation/readLogValidator.js +2 -2
  67. package/dist/validation/readLogValidator.js.map +1 -1
  68. package/package.json +3 -3
  69. package/resources/Resource.ts +17 -6
  70. package/resources/RocksTransactionLogStore.ts +8 -1
  71. package/resources/analytics/metadata.ts +1 -0
  72. package/resources/analytics/read.ts +1 -1
  73. package/resources/analytics/write.ts +43 -2
  74. package/resources/databases.ts +24 -15
  75. package/security/jsLoader.ts +182 -91
  76. package/server/REST.ts +20 -11
  77. package/server/http.ts +3 -3
  78. package/server/itc/serverHandlers.js +1 -1
  79. package/static/defaultConfig.yaml +1 -1
  80. package/studio/web/assets/{index-ZhLX9iRh.js → index-ClD_q6ya.js} +5 -5
  81. package/studio/web/assets/{index-ZhLX9iRh.js.map → index-ClD_q6ya.js.map} +1 -1
  82. package/studio/web/assets/{index.lazy-DzgnppiN.js → index.lazy-CXzU1gVu.js} +2 -2
  83. package/studio/web/assets/{index.lazy-DzgnppiN.js.map → index.lazy-CXzU1gVu.js.map} +1 -1
  84. package/studio/web/assets/{profile-DJ9V18dX.js → profile-DCNVg5yY.js} +2 -2
  85. package/studio/web/assets/{profile-DJ9V18dX.js.map → profile-DCNVg5yY.js.map} +1 -1
  86. package/studio/web/assets/{status-DKZUoEUd.js → status-CoGlcjSB.js} +2 -2
  87. package/studio/web/assets/{status-DKZUoEUd.js.map → status-CoGlcjSB.js.map} +1 -1
  88. package/studio/web/index.html +1 -1
  89. package/utility/hdbTerms.ts +1 -0
  90. package/utility/logging/harper_logger.js +44 -11
  91. package/utility/logging/readLog.js +2 -2
  92. package/utility/npmUtilities.js +2 -2
  93. package/validation/configValidator.js +16 -8
  94. package/validation/readLogValidator.js +2 -2
@@ -1,5 +1,5 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/swagger-ui-react-CW6i-J2I.js","assets/vendor-misc-BBL3Mh21.js","assets/rolldown-runtime-FhOqtrmT.js","assets/vendor-markdown-c5U0YRyN.js","assets/vendor-html-C0BzV7Np.js","assets/vendor-core-BY_ZlgBF.js","assets/vendor-react-DrZSc0Lm.js","assets/vendor-datadog-B4t4E5qd.js","assets/vendor-monaco-CLBN4H7U.js","assets/vendor-charts-BUlf-q3q.js","assets/vendor-react-BlDLhtZc.css"])))=>i.map(i=>d[i]);
2
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{d as t,f as n,i as r,o as i,p as a,r as o}from"./cn-BnE9QzQD.js";import"./vendor-core-BY_ZlgBF.js";import{$i as s,Pi as c,Qi as l,Qn as u,Vi as d,Yi as f,Zi as p,qi as m,vr as h}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{t as g}from"./button-DWsEHYDp.js";import{i as _}from"./vendor-datadog-B4t4E5qd.js";import{A as v,M as y,a as b,b as x,i as S,j as C,n as w,o as T,r as E,v as D,y as O}from"./index-ZhLX9iRh.js";var k=[{fn:{requestSnippetGenerator_fetch:e=>{let t=new URL(e.get(`url`)),n=!1,r=e.get(`headers`);r&&r.size&&r.map((e,t)=>{n||=/^content-type$/i.test(t)&&/^multipart\/form-data$/i.test(e)});let i=e.get(`body`),a=e.get(`method`);if(i){if(n&&[`POST`,`PUT`,`PATCH`].includes(a))return`throw new Error("Currently unsupported content-type: /^multipart\\/form-data$/i");`;typeof i!=`string`&&(i=JSON.stringify(i,null,` `))}else !i&&a===`POST`&&(i=``);let o="`"+(i||``).replace(/\\n/g,`
2
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{d as t,f as n,i as r,o as i,p as a,r as o}from"./cn-BnE9QzQD.js";import"./vendor-core-BY_ZlgBF.js";import{$i as s,Pi as c,Qi as l,Qn as u,Vi as d,Yi as f,Zi as p,qi as m,vr as h}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{t as g}from"./button-DWsEHYDp.js";import{i as _}from"./vendor-datadog-B4t4E5qd.js";import{A as v,M as y,a as b,b as x,i as S,j as C,n as w,o as T,r as E,v as D,y as O}from"./index-ClD_q6ya.js";var k=[{fn:{requestSnippetGenerator_fetch:e=>{let t=new URL(e.get(`url`)),n=!1,r=e.get(`headers`);r&&r.size&&r.map((e,t)=>{n||=/^content-type$/i.test(t)&&/^multipart\/form-data$/i.test(e)});let i=e.get(`body`),a=e.get(`method`);if(i){if(n&&[`POST`,`PUT`,`PATCH`].includes(a))return`throw new Error("Currently unsupported content-type: /^multipart\\/form-data$/i");`;typeof i!=`string`&&(i=JSON.stringify(i,null,` `))}else !i&&a===`POST`&&(i=``);let o="`"+(i||``).replace(/\\n/g,`
3
3
  `).replace(/`/g,"\\`")+"`";return`const response = await fetch("${t.toString()}", {
4
4
  \tmethod: "${e.get(`method`)}",${r&&r.size?`
5
5
  \theaders: {
@@ -12,4 +12,4 @@ const data = await response.json();
12
12
  console.log(data);
13
13
  `}}}],A={generators:{fetch:{title:`Fetch`,syntax:`javascript`}}};async function j({instanceClient:e,...t}){let{data:n}=await e.post(`/`,{operation:`set_configuration`,...t});return n}var M=e(s(),1),N=l();function P({onRestartedSuccessfully:e}={}){let s=v(),c=p(),[l,d]=(0,M.useState)(!1);return{onConfigUpdate:(0,M.useCallback)(async l=>{d(!0);let f=!1,p={duration:6e4,action:{label:`Cancel`,onClick:()=>{f=!0}}},m=u.loading(`Restarting`,{...p,description:(0,N.jsx)(D,{animated:!0,width:`0%`})}),h=s.entityType===`cluster`?await x(s.entityId):null,g=s.entityType===`cluster`?h?.instances||[]:[{id:s.entityId,status:`RUNNING`}],_=!!h&&o.checkForFabricConnect(h.id),v=s.entityType===`cluster`?g.filter(e=>e.status===`RUNNING`).map(e=>t({id:e.id,forceFabricConnect:_,operationsUrl:r(e)})).reverse():[s.instanceClient],y=0;if(v.length)for(let e=0;e<v.length;e++){let t=v[e];if(!f){u.loading(`Updating Instance ${e+1} of ${v.length}`,{...p,id:m,description:(0,N.jsx)(D,{animated:!0,width:(e===0?0:e/v.length*100)+`%`})});try{await i({instanceClient:t}),await j({...l,instanceClient:t}),await T({operation:`restart_service`,replicated:!1,instanceClient:t}),y+=1}catch{e+1!==v.length&&(u.loading(`Failed Restarting Instance ${e+1} of ${v.length}`,{...p,id:m,description:`We will carry on momentarily.`}),await n(3e3))}}}if(d(!1),c.invalidateQueries({queryKey:[s.entityId,`get_configuration`]}),f)u.error(`Cancelled`,{id:m,description:`The config update was partially cancelled.`,duration:1e4,action:{label:`Dismiss`,onClick:()=>u.dismiss()}});else if(g.length===y)e?.(),u.success(`Success`,{id:m,description:`Your configuration has been updated successfully!`,duration:1e4,action:{label:`Dismiss`,onClick:()=>u.dismiss()}});else{let e=a(g.length,`instance`,`instances`),t=a(y,`"RUNNING" instance was`,`"RUNNING" instances were`);u.error(`Error`,{id:m,description:`Failed to fully update cluster.
14
14
  `+([g.length===0&&`No instances were found within the cluster to restart.`,y===0&&`No instances were in a "RUNNING" state of ${e}.`,g.length!==y&&`Only ${t} restarted of ${e}.`].filter(C).shift()||``),duration:1e4,action:{label:`Dismiss`,onClick:()=>u.dismiss()}})}},[s,e,c]),isPending:l}}function F({entityId:e,instanceClient:t}){return m({queryKey:[e,`OpenAPI`],queryFn:async()=>{let{data:e}=await t.get(`/api/openapi/rest`);return e}})}var I=(0,M.lazy)(()=>_(()=>import(`./swagger-ui-react-CW6i-J2I.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10])));function L(){let{instanceId:e,clusterId:t}=d({strict:!1}),n=v(),{data:r,isLoading:i}=f(E(n)),{data:a,isLoading:o}=f(w(n)),s=b(),{data:c,isLoading:l,error:u}=f(F(n));c?.servers?.length&&(c.servers[0].url=s);let p=r?.http,m=``,_=p?.cors===!1,x=p?.corsAccessList?.length!==void 0&&!p.corsAccessList.includes(`*`)&&!p.corsAccessList.includes(`null`)&&!p.corsAccessList.includes(window.location.origin);_?m=`This ${t&&!e?`cluster`:`instance`} has CORS disabled currently, so you won't be able to execute API requests from the browser.`:x&&(m=`This ${t&&!e?`cluster`:`instance`} has CORS enabled, but ${window.location.origin} is not allowed, so you won't be able to execute API requests from the browser.`);let{onConfigUpdate:C,isPending:T}=P(),D=(0,M.useCallback)(()=>{C({..._?{http_cors:!0}:{},...x?{http_corsAccessList:[...p?.corsAccessList??[],window.location.origin]}:{}})},[_,p?.corsAccessList,x,C]);if(i||o||l)return(0,N.jsx)(O,{centered:!0,text:`Looking up your instance configuration, one moment.`});if(u){let e;return e=a?.version&&!S(`4.7.0-beta.7`,a?.version)?`API Docs are only available starting in version '4.7.0-beta.7' of Harper, please update your version ${a.version}!`:`We weren't able to look up your docs. Please check the Network tab of your developer tools to see why the docs were not accessible to Studio.`,(0,N.jsx)(y,{title:`API Docs Unavailable`,error:{message:e},showReturnToHome:!1})}return(0,N.jsxs)(N.Fragment,{children:[m&&(0,N.jsx)(y,{title:`CORS Disabled: HTTP API Not Accessible`,className:`mt-0 mx-4 m-0 border-yellow text-yellow`,error:{message:m},showReturnToHome:!1,children:(0,N.jsxs)(g,{disabled:T,variant:`warning`,className:`rounded-full`,onClick:D,children:[(0,N.jsx)(h,{}),T?`Enabling CORS...`:`Enable CORS for ${window.location.origin}`]})}),(0,N.jsx)(M.Suspense,{fallback:(0,N.jsx)(O,{centered:!0,text:`Loading API documentation...`}),children:(0,N.jsx)(I,{spec:c,persistAuthorization:!0,withCredentials:!0,requestSnippetsEnabled:!0,defaultModelRendering:`model`,requestSnippets:A,plugins:k,tryItOutEnabled:!0})})]})}var R=c(`/apis`)({component:L});export{R as route};
15
- //# sourceMappingURL=index.lazy-DzgnppiN.js.map
15
+ //# sourceMappingURL=index.lazy-CXzU1gVu.js.map
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../src/features/instance/apis/plugins.ts","../../src/features/instance/apis/requestSnippets.ts","../../src/integrations/api/instance/status/setConfiguration.ts","../../src/hooks/useRollingConfigUpdate.tsx","../../src/integrations/api/instance/status/getOpenAPI.ts","../../src/features/instance/apis/APIDocs.tsx","../../src/features/instance/apis/index.lazy.tsx"],"sourcesContent":["export const SnippedGeneratorNodeJsPlugin = {\n\tfn: {\n\t\trequestSnippetGenerator_fetch: (request: { get: (key: string) => unknown }) => {\n\t\t\tconst url = new URL(request.get('url') as string);\n\t\t\tlet isMultipartFormDataRequest = false;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst headers = request.get('headers') as any;\n\t\t\tif (headers && headers.size) {\n\t\t\t\theaders.map((val: string, key: string) => {\n\t\t\t\t\tisMultipartFormDataRequest = isMultipartFormDataRequest\n\t\t\t\t\t\t|| /^content-type$/i.test(key) && /^multipart\\/form-data$/i.test(val);\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet reqBody = request.get('body') as string | object;\n\t\t\tconst reqMethod = request.get('method') as string;\n\t\t\tif (reqBody) {\n\t\t\t\tif (isMultipartFormDataRequest && ['POST', 'PUT', 'PATCH'].includes(reqMethod)) {\n\t\t\t\t\treturn 'throw new Error(\"Currently unsupported content-type: /^multipart\\\\/form-data$/i\");';\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof reqBody !== 'string') {\n\t\t\t\t\t\treqBody = JSON.stringify(reqBody, null, '\\t');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!reqBody && reqMethod === 'POST') {\n\t\t\t\treqBody = '';\n\t\t\t}\n\n\t\t\tconst stringBody = '`' + (reqBody || '')\n\t\t\t\t.replace(/\\\\n/g, '\\n')\n\t\t\t\t.replace(/`/g, '\\\\`')\n\t\t\t\t+ '`';\n\n\t\t\treturn `const response = await fetch(\"${url.toString()}\", {\n\\tmethod: \"${request.get('method')}\",${\n\t\t\t\theaders && headers.size\n\t\t\t\t\t? `\n\\theaders: {\n\\t\\t${headers.map((val: string, key: string) => `\"${key}\": \"${val}\"`).valueSeq().join(',\\n\\t\\t')}\n\\t},`\n\t\t\t\t\t: ''\n\t\t\t}${\n\t\t\t\treqBody\n\t\t\t\t\t? `\n\\tbody: ${stringBody},`\n\t\t\t\t\t: ''\n\t\t\t}\n});\nconst data = await response.json();\nconsole.log(data);\n`;\n\t\t},\n\t},\n};\n\nexport const plugins = [\n\tSnippedGeneratorNodeJsPlugin,\n];\n","export const requestSnippets = {\n\tgenerators: {\n\t\tfetch: {\n\t\t\ttitle: 'Fetch',\n\t\t\tsyntax: 'javascript',\n\t\t},\n\t},\n};\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\n\ninterface SetConfigurationParams extends InstanceClientConfig {\n\t[key: string]: unknown;\n}\n\nexport async function setConfiguration({\n\tinstanceClient,\n\t...changes\n}: SetConfigurationParams): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'set_configuration',\n\t\t...changes,\n\t});\n\treturn data;\n}\n","import { ProgressBar } from '@/components/ProgressBar';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfo } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { restartInstance } from '@/integrations/api/instance/status/restartInstance';\nimport { setConfiguration } from '@/integrations/api/instance/status/setConfiguration';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { pluralize } from '@/lib/pluralize';\nimport { sleep } from '@/lib/sleep';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\ninterface RollingConfigUpdateParams {\n\tonRestartedSuccessfully?: () => void;\n}\n\ninterface RollingConfigUpdateResponse {\n\tonConfigUpdate: (params: Record<string, unknown>) => void;\n\tisPending: boolean;\n}\n\nexport function useRollingConfigUpdate(\n\t{ onRestartedSuccessfully }: RollingConfigUpdateParams = {},\n): RollingConfigUpdateResponse {\n\tconst operationsParams = useInstanceClientIdParams();\n\tconst queryClient = useQueryClient();\n\tconst [isPending, setIsPending] = useState(false);\n\tconst onConfigUpdate = useCallback(async (params: Record<string, unknown>) => {\n\t\tsetIsPending(true);\n\n\t\tlet canceled = false;\n\t\tconst toastConfig = {\n\t\t\tduration: 60_000,\n\t\t\taction: {\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tonClick: () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tconst toastId = toast.loading('Restarting', {\n\t\t\t...toastConfig,\n\t\t\tdescription: (\n\t\t\t\t<ProgressBar\n\t\t\t\t\tanimated={true}\n\t\t\t\t\twidth=\"0%\"\n\t\t\t\t/>\n\t\t\t),\n\t\t});\n\n\t\tconst cluster = operationsParams.entityType === 'cluster'\n\t\t\t? await getClusterInfo(operationsParams.entityId)\n\t\t\t: null;\n\t\tconst allInstances = operationsParams.entityType === 'cluster'\n\t\t\t? cluster?.instances || []\n\t\t\t: [{ id: operationsParams.entityId, status: 'RUNNING' } as Instance];\n\t\tconst clusterUsesFabricConnect = !!cluster && authStore.checkForFabricConnect(cluster.id);\n\t\tconst instanceClients = operationsParams.entityType === 'cluster'\n\t\t\t? allInstances\n\t\t\t\t.filter(instance => instance.status === 'RUNNING')\n\t\t\t\t.map(instance =>\n\t\t\t\t\tgetInstanceClient({\n\t\t\t\t\t\tid: instance.id,\n\t\t\t\t\t\tforceFabricConnect: clusterUsesFabricConnect,\n\t\t\t\t\t\toperationsUrl: getOperationsUrlForInstance(instance),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.reverse()\n\t\t\t: [operationsParams.instanceClient];\n\t\tlet instancesRestarted = 0;\n\n\t\tif (instanceClients.length) {\n\t\t\tfor (let i = 0; i < instanceClients.length; i++) {\n\t\t\t\tconst instanceClient = instanceClients[i];\n\t\t\t\tif (!canceled) {\n\t\t\t\t\ttoast.loading(`Updating Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\tdescription: (\n\t\t\t\t\t\t\t<ProgressBar\n\t\t\t\t\t\t\t\tanimated={true}\n\t\t\t\t\t\t\t\twidth={(i === 0 ? 0 : (i / instanceClients.length * 100)) + '%'}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Make sure the instance is responding.\n\t\t\t\t\t\tawait getInstanceUserInfo({\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait setConfiguration({\n\t\t\t\t\t\t\t...params,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Then restart it.\n\t\t\t\t\t\tawait restartInstance({\n\t\t\t\t\t\t\toperation: 'restart_service',\n\t\t\t\t\t\t\treplicated: false,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tinstancesRestarted += 1;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tif (i + 1 !== instanceClients.length) {\n\t\t\t\t\t\t\t// If it fails to restart, or wasn't available, warn for a bit then move on.\n\t\t\t\t\t\t\ttoast.loading(`Failed Restarting Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\t\t\tdescription: 'We will carry on momentarily.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tawait sleep(3000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetIsPending(false);\n\t\tvoid queryClient.invalidateQueries({ queryKey: [operationsParams.entityId, 'get_configuration'] });\n\n\t\tif (canceled) {\n\t\t\ttoast.error('Cancelled', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `The config update was partially cancelled.`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (allInstances.length === instancesRestarted) {\n\t\t\tonRestartedSuccessfully?.();\n\t\t\ttoast.success('Success', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Your configuration has been updated successfully!`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tconst allTheInstances = pluralize(allInstances.length, 'instance', 'instances');\n\t\t\tconst someRunningInstancesWere = pluralize(\n\t\t\t\tinstancesRestarted,\n\t\t\t\t'\"RUNNING\" instance was',\n\t\t\t\t'\"RUNNING\" instances were',\n\t\t\t);\n\t\t\ttoast.error('Error', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Failed to fully update cluster.\\n`\n\t\t\t\t\t+ ([\n\t\t\t\t\t\tallInstances.length === 0 && 'No instances were found within the cluster to restart.',\n\t\t\t\t\t\tinstancesRestarted === 0 && `No instances were in a \"RUNNING\" state of ${allTheInstances}.`,\n\t\t\t\t\t\tallInstances.length !== instancesRestarted\n\t\t\t\t\t\t&& `Only ${someRunningInstancesWere} restarted of ${allTheInstances}.`,\n\t\t\t\t\t].filter(excludeFalsy).shift() || ''),\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}, [operationsParams, onRestartedSuccessfully, queryClient]);\n\n\treturn {\n\t\tonConfigUpdate,\n\t\tisPending,\n\t};\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport function getOpenAPIQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'OpenAPI'] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.get('/api/openapi/rest');\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","import { ErrorComponent } from '@/components/ErrorComponent';\nimport { Loading } from '@/components/Loading';\nimport { Button } from '@/components/ui/button';\nimport { useEntityRestURL } from '@/config/useEntityRestURL';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { plugins } from '@/features/instance/apis/plugins';\nimport { requestSnippets } from '@/features/instance/apis/requestSnippets';\nimport { useRollingConfigUpdate } from '@/hooks/useRollingConfigUpdate';\nimport { getConfigurationQueryOptions } from '@/integrations/api/instance/status/getConfiguration';\nimport { getOpenAPIQueryOptions } from '@/integrations/api/instance/status/getOpenAPI';\nimport { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { Plus } from 'lucide-react';\nimport { lazy, Suspense, useCallback } from 'react';\n\nconst SwaggerUI = lazy(() => import('swagger-ui-react'));\nimport 'swagger-ui-react/swagger-ui.css';\nimport './swagger.css';\n\nexport function APIDocs() {\n\tconst { instanceId, clusterId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst operationsParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: configurationInfo,\n\t\tisLoading: isLoadingConfiguration,\n\t} = useQuery(getConfigurationQueryOptions(operationsParams));\n\tconst { data: registrationInfo, isLoading: isLoadingRegistration } = useQuery(\n\t\tgetRegistrationInfoQueryOptions(operationsParams),\n\t);\n\tconst baseURL = useEntityRestURL();\n\tconst {\n\t\tdata: spec,\n\t\tisLoading: isLoadingDocs,\n\t\terror,\n\t} = useQuery(getOpenAPIQueryOptions(operationsParams));\n\tif (spec?.servers?.length) {\n\t\tspec.servers[0].url = baseURL;\n\t}\n\tconst http = configurationInfo?.http;\n\n\tlet apiInaccessibleWarning: string = '';\n\n\tconst corsDisabled = http?.cors === false;\n\tconst missingFromCORSList = http?.corsAccessList?.length !== undefined\n\t\t&& !http.corsAccessList.includes('*')\n\t\t&& !http.corsAccessList.includes('null')\n\t\t&& !http.corsAccessList.includes(window.location.origin);\n\tif (corsDisabled) {\n\t\tapiInaccessibleWarning = `This ${\n\t\t\tclusterId && !instanceId ? 'cluster' : 'instance'\n\t\t} has CORS disabled currently, so you won't be able to execute API requests from the browser.`;\n\t} else if (missingFromCORSList) {\n\t\tapiInaccessibleWarning = `This ${\n\t\t\tclusterId && !instanceId ? 'cluster' : 'instance'\n\t\t} has CORS enabled, but ${window.location.origin} is not allowed, so you won't be able to execute API requests from the browser.`;\n\t}\n\n\tconst { onConfigUpdate, isPending: isSettingConfiguration } = useRollingConfigUpdate();\n\tconst enableCORS = useCallback(() => {\n\t\tonConfigUpdate({\n\t\t\t...(corsDisabled\n\t\t\t\t? {\n\t\t\t\t\t'http_cors': true,\n\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...(missingFromCORSList\n\t\t\t\t? {\n\t\t\t\t\t'http_corsAccessList': [\n\t\t\t\t\t\t...(http?.corsAccessList ?? []),\n\t\t\t\t\t\twindow.location.origin,\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t\t: {}),\n\t\t});\n\t}, [corsDisabled, http?.corsAccessList, missingFromCORSList, onConfigUpdate]);\n\n\tif (isLoadingConfiguration || isLoadingRegistration || isLoadingDocs) {\n\t\treturn <Loading centered={true} text=\"Looking up your instance configuration, one moment.\" />;\n\t}\n\n\tif (error) {\n\t\tlet message: string;\n\t\tif (registrationInfo?.version && !wasAReleasedBeforeB('4.7.0-beta.7', registrationInfo?.version)) {\n\t\t\tmessage =\n\t\t\t\t`API Docs are only available starting in version '4.7.0-beta.7' of Harper, please update your version ${registrationInfo.version}!`;\n\t\t} else {\n\t\t\tmessage =\n\t\t\t\t`We weren't able to look up your docs. Please check the Network tab of your developer tools to see why the docs were not accessible to Studio.`;\n\t\t}\n\n\t\treturn (\n\t\t\t<ErrorComponent\n\t\t\t\ttitle=\"API Docs Unavailable\"\n\t\t\t\terror={{ message }}\n\t\t\t\tshowReturnToHome={false}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{apiInaccessibleWarning && (\n\t\t\t\t<ErrorComponent\n\t\t\t\t\ttitle=\"CORS Disabled: HTTP API Not Accessible\"\n\t\t\t\t\tclassName=\"mt-0 mx-4 m-0 border-yellow text-yellow\"\n\t\t\t\t\terror={{ message: apiInaccessibleWarning }}\n\t\t\t\t\tshowReturnToHome={false}\n\t\t\t\t>\n\t\t\t\t\t<Button disabled={isSettingConfiguration} variant=\"warning\" className=\"rounded-full\" onClick={enableCORS}>\n\t\t\t\t\t\t<Plus />\n\t\t\t\t\t\t{isSettingConfiguration ? 'Enabling CORS...' : `Enable CORS for ${window.location.origin}`}\n\t\t\t\t\t</Button>\n\t\t\t\t</ErrorComponent>\n\t\t\t)}\n\t\t\t<Suspense fallback={<Loading centered={true} text=\"Loading API documentation...\" />}>\n\t\t\t\t<SwaggerUI\n\t\t\t\t\tspec={spec}\n\t\t\t\t\tpersistAuthorization={true}\n\t\t\t\t\twithCredentials={true}\n\t\t\t\t\trequestSnippetsEnabled={true}\n\t\t\t\t\tdefaultModelRendering=\"model\"\n\t\t\t\t\trequestSnippets={requestSnippets}\n\t\t\t\t\tplugins={plugins}\n\t\t\t\t\ttryItOutEnabled={true}\n\t\t\t\t/>\n\t\t\t</Suspense>\n\t\t</>\n\t);\n}\n","import { APIDocs } from '@/features/instance/apis/APIDocs';\nimport { createLazyRoute } from '@tanstack/react-router';\n\nexport const route = createLazyRoute('/apis')({\n\tcomponent: APIDocs,\n});\n"],"file":"index.lazy-DzgnppiN.js"}
1
+ {"version":3,"mappings":";ufAsDA,IAAa,EAAU,CAtDqB,CAC3C,GAAI,CACH,8BAAgC,GAA+C,CAC9E,IAAM,EAAM,IAAI,IAAI,EAAQ,IAAI,MAAM,CAAW,CAC7C,EAA6B,GAE3B,EAAU,EAAQ,IAAI,UAAU,CAClC,GAAW,EAAQ,MACtB,EAAQ,KAAK,EAAa,IAAgB,CACzC,IACI,kBAAkB,KAAK,EAAI,EAAI,0BAA0B,KAAK,EAAI,EACrE,CAEH,IAAI,EAAU,EAAQ,IAAI,OAAO,CAC3B,EAAY,EAAQ,IAAI,SAAS,CACvC,GAAI,EACH,IAAI,GAA8B,CAAC,OAAQ,MAAO,QAAQ,CAAC,SAAS,EAAU,CAC7E,MAAO,qFAEH,OAAO,GAAY,WACtB,EAAU,KAAK,UAAU,EAAS,KAAM,IAAK,OAGrC,CAAC,GAAW,IAAc,SACpC,EAAU,IAGX,IAAM,EAAa,KAAO,GAAW,IACnC,QAAQ,OAAQ;EAAK,CACrB,QAAQ,KAAM,MAAM,CACnB,IAEH,MAAO,iCAAiC,EAAI,UAAU,CAAC;aAC7C,EAAQ,IAAI,SAAS,CAAC,IAC/B,GAAW,EAAQ,KAChB;;MAED,EAAQ,KAAK,EAAa,IAAgB,IAAI,EAAI,MAAM,EAAI,GAAG,CAAC,UAAU,CAAC,KAAK;IAAU;MAEzF,KAEH,EACG;UACG,EAAW,GACd;;;;GAOL,CACD,CAIA,CCxDY,EAAkB,CAC9B,WAAY,CACX,MAAO,CACN,MAAO,QACP,OAAQ,aACR,CACD,CACD,CCAD,eAAsB,EAAiB,CACtC,iBACA,GAAG,GACoD,CACvD,GAAM,CAAE,QAAS,MAAM,EAAe,KAAK,IAAK,CAC/C,UAAW,oBACX,GAAG,EACH,CAAC,CACF,OAAO,uBCWR,SAAgB,EACf,CAAE,2BAAuD,EAAE,CAC7B,CAC9B,IAAM,EAAmB,GAA2B,CAC9C,EAAc,GAAgB,CAC9B,CAAC,EAAW,kBAAyB,GAAM,CA6IjD,MAAO,CACN,iCA7IkC,KAAO,IAAoC,CAC7E,EAAa,GAAK,CAElB,IAAI,EAAW,GACT,EAAc,CACnB,SAAU,IACV,OAAQ,CACP,MAAO,SACP,YAAe,CACd,EAAW,IAEZ,CACD,CAEK,EAAU,EAAM,QAAQ,aAAc,CAC3C,GAAG,EACH,sBACE,EAAD,CACC,SAAU,GACV,MAAM,KACL,EAEH,CAAC,CAEI,EAAU,EAAiB,aAAe,UAC7C,MAAM,EAAe,EAAiB,SAAS,CAC/C,KACG,EAAe,EAAiB,aAAe,UAClD,GAAS,WAAa,EAAE,CACxB,CAAC,CAAE,GAAI,EAAiB,SAAU,OAAQ,UAAW,CAAa,CAC/D,EAA2B,CAAC,CAAC,GAAW,EAAU,sBAAsB,EAAQ,GAAG,CACnF,EAAkB,EAAiB,aAAe,UACrD,EACA,OAAO,GAAY,EAAS,SAAW,UAAU,CACjD,IAAI,GACJ,EAAkB,CACjB,GAAI,EAAS,GACb,mBAAoB,EACpB,cAAe,EAA4B,EAAS,CACpD,CAAC,CACF,CACA,SAAS,CACT,CAAC,EAAiB,eAAe,CAChC,EAAqB,EAEzB,GAAI,EAAgB,OACnB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAgB,OAAQ,IAAK,CAChD,IAAM,EAAiB,EAAgB,GACvC,GAAI,CAAC,EAAU,CACd,EAAM,QAAQ,qBAAqB,EAAI,EAAE,MAAM,EAAgB,SAAU,CACxE,GAAG,EACH,GAAI,EACJ,sBACE,EAAD,CACC,SAAU,GACV,OAAQ,IAAM,EAAI,EAAK,EAAI,EAAgB,OAAS,KAAQ,IAC3D,EAEH,CAAC,CACF,GAAI,CAEH,MAAM,EAAoB,CACzB,iBACA,CAAC,CAEF,MAAM,EAAiB,CACtB,GAAG,EACH,iBACA,CAAC,CAEF,MAAM,EAAgB,CACrB,UAAW,kBACX,WAAY,GACZ,iBACA,CAAC,CACF,GAAsB,OACf,CACH,EAAI,IAAM,EAAgB,SAE7B,EAAM,QAAQ,8BAA8B,EAAI,EAAE,MAAM,EAAgB,SAAU,CACjF,GAAG,EACH,GAAI,EACJ,YAAa,gCACb,CAAC,CACF,MAAM,EAAM,IAAK,IAUtB,GAHA,EAAa,GAAM,CACd,EAAY,kBAAkB,CAAE,SAAU,CAAC,EAAiB,SAAU,oBAAoB,CAAE,CAAC,CAE9F,EACH,EAAM,MAAM,YAAa,CACxB,GAAI,EACJ,YAAa,6CACb,SAAU,IACV,OAAQ,CACP,MAAO,UACP,YAAe,EAAM,SAAS,CAC9B,CACD,CAAC,SACQ,EAAa,SAAW,EAClC,KAA2B,CAC3B,EAAM,QAAQ,UAAW,CACxB,GAAI,EACJ,YAAa,oDACb,SAAU,IACV,OAAQ,CACP,MAAO,UACP,YAAe,EAAM,SAAS,CAC9B,CACD,CAAC,KACI,CACN,IAAM,EAAkB,EAAU,EAAa,OAAQ,WAAY,YAAY,CACzE,EAA2B,EAChC,EACA,yBACA,2BACA,CACD,EAAM,MAAM,QAAS,CACpB,GAAI,EACJ,YAAa;GACT,CACF,EAAa,SAAW,GAAK,yDAC7B,IAAuB,GAAK,6CAA6C,EAAgB,GACzF,EAAa,SAAW,GACrB,QAAQ,EAAyB,gBAAgB,EAAgB,GACpE,CAAC,OAAO,EAAa,CAAC,OAAO,EAAI,IACnC,SAAU,IACV,OAAQ,CACP,MAAO,UACP,YAAe,EAAM,SAAS,CAC9B,CACD,CAAC,GAED,CAAC,EAAkB,EAAyB,EAAY,CAAC,CAI3D,YACA,CC5KF,SAAgB,EAAuB,CAAE,WAAU,kBAA0C,CAC5F,OAAO,EAAa,CACnB,SAAU,CAAC,EAAU,UAAU,CAC/B,QAAS,SAAY,CACpB,GAAM,CAAE,QAAS,MAAM,EAAe,IAAI,oBAAoB,CAC9D,OAAO,GAER,CAAC,CCOH,IAAM,uBAAuB,OAAO,6EAAoB,CAIxD,SAAgB,GAAU,CACzB,GAAM,CAAE,aAAY,aAA2D,EAAU,CAAE,OAAQ,GAAO,CAAC,CACrG,EAAmB,GAA2B,CAC9C,CACL,KAAM,EACN,UAAW,GACR,EAAS,EAA6B,EAAiB,CAAC,CACtD,CAAE,KAAM,EAAkB,UAAW,GAA0B,EACpE,EAAgC,EAAiB,CACjD,CACK,EAAU,GAAkB,CAC5B,CACL,KAAM,EACN,UAAW,EACX,SACG,EAAS,EAAuB,EAAiB,CAAC,CAClD,GAAM,SAAS,SAClB,EAAK,QAAQ,GAAG,IAAM,GAEvB,IAAM,EAAO,GAAmB,KAE5B,EAAiC,GAE/B,EAAe,GAAM,OAAS,GAC9B,EAAsB,GAAM,gBAAgB,SAAW,QACzD,CAAC,EAAK,eAAe,SAAS,IAAI,EAClC,CAAC,EAAK,eAAe,SAAS,OAAO,EACrC,CAAC,EAAK,eAAe,SAAS,OAAO,SAAS,OAAO,CACrD,EACH,EAAyB,QACxB,GAAa,CAAC,EAAa,UAAY,WACvC,8FACS,IACV,EAAyB,QACxB,GAAa,CAAC,EAAa,UAAY,WACvC,yBAAyB,OAAO,SAAS,OAAO,kFAGlD,GAAM,CAAE,iBAAgB,UAAW,GAA2B,GAAwB,CAChF,wBAA+B,CACpC,EAAe,CACd,GAAI,EACD,CACD,UAAa,GACb,CACC,EAAE,CACL,GAAI,EACD,CACD,oBAAuB,CACtB,GAAI,GAAM,gBAAkB,EAAE,CAC9B,OAAO,SAAS,OAChB,CACD,CACC,EAAE,CACL,CAAC,EACA,CAAC,EAAc,GAAM,eAAgB,EAAqB,EAAe,CAAC,CAE7E,GAAI,GAA0B,GAAyB,EACtD,gBAAQ,EAAD,CAAS,SAAU,GAAM,KAAK,sDAAwD,EAG9F,GAAI,EAAO,CACV,IAAI,EASJ,MARA,CAIC,EAJG,GAAkB,SAAW,CAAC,EAAoB,eAAgB,GAAkB,QAAQ,CAE9F,wGAAwG,EAAiB,QAAQ,GAGjI,iJAGF,SACE,EAAD,CACC,MAAM,uBACN,MAAO,CAAE,UAAS,CAClB,iBAAkB,GACjB,EAIJ,iBACC,sBACE,aACC,EAAD,CACC,MAAM,yCACN,UAAU,0CACV,MAAO,CAAE,QAAS,EAAwB,CAC1C,iBAAkB,uBAEjB,EAAD,CAAQ,SAAU,EAAwB,QAAQ,UAAU,UAAU,eAAe,QAAS,WAA9F,WACE,EAAD,EAAQ,EACP,EAAyB,mBAAqB,mBAAmB,OAAO,SAAS,SAC1E,GACO,YAEjB,WAAD,CAAU,mBAAW,EAAD,CAAS,SAAU,GAAM,KAAK,+BAAiC,qBACjF,EAAD,CACO,OACN,qBAAsB,GACtB,gBAAiB,GACjB,uBAAwB,GACxB,sBAAsB,QACL,kBACR,UACT,gBAAiB,GAChB,EACQ,EACT,GC7HL,IAAa,EAAQ,EAAgB,QAAQ,CAAC,CAC7C,UAAW,EACX,CAAC","names":[],"ignoreList":[],"sources":["../../src/features/instance/apis/plugins.ts","../../src/features/instance/apis/requestSnippets.ts","../../src/integrations/api/instance/status/setConfiguration.ts","../../src/hooks/useRollingConfigUpdate.tsx","../../src/integrations/api/instance/status/getOpenAPI.ts","../../src/features/instance/apis/APIDocs.tsx","../../src/features/instance/apis/index.lazy.tsx"],"sourcesContent":["export const SnippedGeneratorNodeJsPlugin = {\n\tfn: {\n\t\trequestSnippetGenerator_fetch: (request: { get: (key: string) => unknown }) => {\n\t\t\tconst url = new URL(request.get('url') as string);\n\t\t\tlet isMultipartFormDataRequest = false;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst headers = request.get('headers') as any;\n\t\t\tif (headers && headers.size) {\n\t\t\t\theaders.map((val: string, key: string) => {\n\t\t\t\t\tisMultipartFormDataRequest = isMultipartFormDataRequest\n\t\t\t\t\t\t|| /^content-type$/i.test(key) && /^multipart\\/form-data$/i.test(val);\n\t\t\t\t});\n\t\t\t}\n\t\t\tlet reqBody = request.get('body') as string | object;\n\t\t\tconst reqMethod = request.get('method') as string;\n\t\t\tif (reqBody) {\n\t\t\t\tif (isMultipartFormDataRequest && ['POST', 'PUT', 'PATCH'].includes(reqMethod)) {\n\t\t\t\t\treturn 'throw new Error(\"Currently unsupported content-type: /^multipart\\\\/form-data$/i\");';\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof reqBody !== 'string') {\n\t\t\t\t\t\treqBody = JSON.stringify(reqBody, null, '\\t');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!reqBody && reqMethod === 'POST') {\n\t\t\t\treqBody = '';\n\t\t\t}\n\n\t\t\tconst stringBody = '`' + (reqBody || '')\n\t\t\t\t.replace(/\\\\n/g, '\\n')\n\t\t\t\t.replace(/`/g, '\\\\`')\n\t\t\t\t+ '`';\n\n\t\t\treturn `const response = await fetch(\"${url.toString()}\", {\n\\tmethod: \"${request.get('method')}\",${\n\t\t\t\theaders && headers.size\n\t\t\t\t\t? `\n\\theaders: {\n\\t\\t${headers.map((val: string, key: string) => `\"${key}\": \"${val}\"`).valueSeq().join(',\\n\\t\\t')}\n\\t},`\n\t\t\t\t\t: ''\n\t\t\t}${\n\t\t\t\treqBody\n\t\t\t\t\t? `\n\\tbody: ${stringBody},`\n\t\t\t\t\t: ''\n\t\t\t}\n});\nconst data = await response.json();\nconsole.log(data);\n`;\n\t\t},\n\t},\n};\n\nexport const plugins = [\n\tSnippedGeneratorNodeJsPlugin,\n];\n","export const requestSnippets = {\n\tgenerators: {\n\t\tfetch: {\n\t\t\ttitle: 'Fetch',\n\t\t\tsyntax: 'javascript',\n\t\t},\n\t},\n};\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\n\ninterface SetConfigurationParams extends InstanceClientConfig {\n\t[key: string]: unknown;\n}\n\nexport async function setConfiguration({\n\tinstanceClient,\n\t...changes\n}: SetConfigurationParams): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'set_configuration',\n\t\t...changes,\n\t});\n\treturn data;\n}\n","import { ProgressBar } from '@/components/ProgressBar';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfo } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { restartInstance } from '@/integrations/api/instance/status/restartInstance';\nimport { setConfiguration } from '@/integrations/api/instance/status/setConfiguration';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { pluralize } from '@/lib/pluralize';\nimport { sleep } from '@/lib/sleep';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\ninterface RollingConfigUpdateParams {\n\tonRestartedSuccessfully?: () => void;\n}\n\ninterface RollingConfigUpdateResponse {\n\tonConfigUpdate: (params: Record<string, unknown>) => void;\n\tisPending: boolean;\n}\n\nexport function useRollingConfigUpdate(\n\t{ onRestartedSuccessfully }: RollingConfigUpdateParams = {},\n): RollingConfigUpdateResponse {\n\tconst operationsParams = useInstanceClientIdParams();\n\tconst queryClient = useQueryClient();\n\tconst [isPending, setIsPending] = useState(false);\n\tconst onConfigUpdate = useCallback(async (params: Record<string, unknown>) => {\n\t\tsetIsPending(true);\n\n\t\tlet canceled = false;\n\t\tconst toastConfig = {\n\t\t\tduration: 60_000,\n\t\t\taction: {\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tonClick: () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tconst toastId = toast.loading('Restarting', {\n\t\t\t...toastConfig,\n\t\t\tdescription: (\n\t\t\t\t<ProgressBar\n\t\t\t\t\tanimated={true}\n\t\t\t\t\twidth=\"0%\"\n\t\t\t\t/>\n\t\t\t),\n\t\t});\n\n\t\tconst cluster = operationsParams.entityType === 'cluster'\n\t\t\t? await getClusterInfo(operationsParams.entityId)\n\t\t\t: null;\n\t\tconst allInstances = operationsParams.entityType === 'cluster'\n\t\t\t? cluster?.instances || []\n\t\t\t: [{ id: operationsParams.entityId, status: 'RUNNING' } as Instance];\n\t\tconst clusterUsesFabricConnect = !!cluster && authStore.checkForFabricConnect(cluster.id);\n\t\tconst instanceClients = operationsParams.entityType === 'cluster'\n\t\t\t? allInstances\n\t\t\t\t.filter(instance => instance.status === 'RUNNING')\n\t\t\t\t.map(instance =>\n\t\t\t\t\tgetInstanceClient({\n\t\t\t\t\t\tid: instance.id,\n\t\t\t\t\t\tforceFabricConnect: clusterUsesFabricConnect,\n\t\t\t\t\t\toperationsUrl: getOperationsUrlForInstance(instance),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.reverse()\n\t\t\t: [operationsParams.instanceClient];\n\t\tlet instancesRestarted = 0;\n\n\t\tif (instanceClients.length) {\n\t\t\tfor (let i = 0; i < instanceClients.length; i++) {\n\t\t\t\tconst instanceClient = instanceClients[i];\n\t\t\t\tif (!canceled) {\n\t\t\t\t\ttoast.loading(`Updating Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\tdescription: (\n\t\t\t\t\t\t\t<ProgressBar\n\t\t\t\t\t\t\t\tanimated={true}\n\t\t\t\t\t\t\t\twidth={(i === 0 ? 0 : (i / instanceClients.length * 100)) + '%'}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Make sure the instance is responding.\n\t\t\t\t\t\tawait getInstanceUserInfo({\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait setConfiguration({\n\t\t\t\t\t\t\t...params,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Then restart it.\n\t\t\t\t\t\tawait restartInstance({\n\t\t\t\t\t\t\toperation: 'restart_service',\n\t\t\t\t\t\t\treplicated: false,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tinstancesRestarted += 1;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tif (i + 1 !== instanceClients.length) {\n\t\t\t\t\t\t\t// If it fails to restart, or wasn't available, warn for a bit then move on.\n\t\t\t\t\t\t\ttoast.loading(`Failed Restarting Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\t\t\tdescription: 'We will carry on momentarily.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tawait sleep(3000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetIsPending(false);\n\t\tvoid queryClient.invalidateQueries({ queryKey: [operationsParams.entityId, 'get_configuration'] });\n\n\t\tif (canceled) {\n\t\t\ttoast.error('Cancelled', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `The config update was partially cancelled.`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (allInstances.length === instancesRestarted) {\n\t\t\tonRestartedSuccessfully?.();\n\t\t\ttoast.success('Success', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Your configuration has been updated successfully!`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tconst allTheInstances = pluralize(allInstances.length, 'instance', 'instances');\n\t\t\tconst someRunningInstancesWere = pluralize(\n\t\t\t\tinstancesRestarted,\n\t\t\t\t'\"RUNNING\" instance was',\n\t\t\t\t'\"RUNNING\" instances were',\n\t\t\t);\n\t\t\ttoast.error('Error', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Failed to fully update cluster.\\n`\n\t\t\t\t\t+ ([\n\t\t\t\t\t\tallInstances.length === 0 && 'No instances were found within the cluster to restart.',\n\t\t\t\t\t\tinstancesRestarted === 0 && `No instances were in a \"RUNNING\" state of ${allTheInstances}.`,\n\t\t\t\t\t\tallInstances.length !== instancesRestarted\n\t\t\t\t\t\t&& `Only ${someRunningInstancesWere} restarted of ${allTheInstances}.`,\n\t\t\t\t\t].filter(excludeFalsy).shift() || ''),\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}, [operationsParams, onRestartedSuccessfully, queryClient]);\n\n\treturn {\n\t\tonConfigUpdate,\n\t\tisPending,\n\t};\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport function getOpenAPIQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'OpenAPI'] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.get('/api/openapi/rest');\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","import { ErrorComponent } from '@/components/ErrorComponent';\nimport { Loading } from '@/components/Loading';\nimport { Button } from '@/components/ui/button';\nimport { useEntityRestURL } from '@/config/useEntityRestURL';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { plugins } from '@/features/instance/apis/plugins';\nimport { requestSnippets } from '@/features/instance/apis/requestSnippets';\nimport { useRollingConfigUpdate } from '@/hooks/useRollingConfigUpdate';\nimport { getConfigurationQueryOptions } from '@/integrations/api/instance/status/getConfiguration';\nimport { getOpenAPIQueryOptions } from '@/integrations/api/instance/status/getOpenAPI';\nimport { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { Plus } from 'lucide-react';\nimport { lazy, Suspense, useCallback } from 'react';\n\nconst SwaggerUI = lazy(() => import('swagger-ui-react'));\nimport 'swagger-ui-react/swagger-ui.css';\nimport './swagger.css';\n\nexport function APIDocs() {\n\tconst { instanceId, clusterId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst operationsParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: configurationInfo,\n\t\tisLoading: isLoadingConfiguration,\n\t} = useQuery(getConfigurationQueryOptions(operationsParams));\n\tconst { data: registrationInfo, isLoading: isLoadingRegistration } = useQuery(\n\t\tgetRegistrationInfoQueryOptions(operationsParams),\n\t);\n\tconst baseURL = useEntityRestURL();\n\tconst {\n\t\tdata: spec,\n\t\tisLoading: isLoadingDocs,\n\t\terror,\n\t} = useQuery(getOpenAPIQueryOptions(operationsParams));\n\tif (spec?.servers?.length) {\n\t\tspec.servers[0].url = baseURL;\n\t}\n\tconst http = configurationInfo?.http;\n\n\tlet apiInaccessibleWarning: string = '';\n\n\tconst corsDisabled = http?.cors === false;\n\tconst missingFromCORSList = http?.corsAccessList?.length !== undefined\n\t\t&& !http.corsAccessList.includes('*')\n\t\t&& !http.corsAccessList.includes('null')\n\t\t&& !http.corsAccessList.includes(window.location.origin);\n\tif (corsDisabled) {\n\t\tapiInaccessibleWarning = `This ${\n\t\t\tclusterId && !instanceId ? 'cluster' : 'instance'\n\t\t} has CORS disabled currently, so you won't be able to execute API requests from the browser.`;\n\t} else if (missingFromCORSList) {\n\t\tapiInaccessibleWarning = `This ${\n\t\t\tclusterId && !instanceId ? 'cluster' : 'instance'\n\t\t} has CORS enabled, but ${window.location.origin} is not allowed, so you won't be able to execute API requests from the browser.`;\n\t}\n\n\tconst { onConfigUpdate, isPending: isSettingConfiguration } = useRollingConfigUpdate();\n\tconst enableCORS = useCallback(() => {\n\t\tonConfigUpdate({\n\t\t\t...(corsDisabled\n\t\t\t\t? {\n\t\t\t\t\t'http_cors': true,\n\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t...(missingFromCORSList\n\t\t\t\t? {\n\t\t\t\t\t'http_corsAccessList': [\n\t\t\t\t\t\t...(http?.corsAccessList ?? []),\n\t\t\t\t\t\twindow.location.origin,\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t\t: {}),\n\t\t});\n\t}, [corsDisabled, http?.corsAccessList, missingFromCORSList, onConfigUpdate]);\n\n\tif (isLoadingConfiguration || isLoadingRegistration || isLoadingDocs) {\n\t\treturn <Loading centered={true} text=\"Looking up your instance configuration, one moment.\" />;\n\t}\n\n\tif (error) {\n\t\tlet message: string;\n\t\tif (registrationInfo?.version && !wasAReleasedBeforeB('4.7.0-beta.7', registrationInfo?.version)) {\n\t\t\tmessage =\n\t\t\t\t`API Docs are only available starting in version '4.7.0-beta.7' of Harper, please update your version ${registrationInfo.version}!`;\n\t\t} else {\n\t\t\tmessage =\n\t\t\t\t`We weren't able to look up your docs. Please check the Network tab of your developer tools to see why the docs were not accessible to Studio.`;\n\t\t}\n\n\t\treturn (\n\t\t\t<ErrorComponent\n\t\t\t\ttitle=\"API Docs Unavailable\"\n\t\t\t\terror={{ message }}\n\t\t\t\tshowReturnToHome={false}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{apiInaccessibleWarning && (\n\t\t\t\t<ErrorComponent\n\t\t\t\t\ttitle=\"CORS Disabled: HTTP API Not Accessible\"\n\t\t\t\t\tclassName=\"mt-0 mx-4 m-0 border-yellow text-yellow\"\n\t\t\t\t\terror={{ message: apiInaccessibleWarning }}\n\t\t\t\t\tshowReturnToHome={false}\n\t\t\t\t>\n\t\t\t\t\t<Button disabled={isSettingConfiguration} variant=\"warning\" className=\"rounded-full\" onClick={enableCORS}>\n\t\t\t\t\t\t<Plus />\n\t\t\t\t\t\t{isSettingConfiguration ? 'Enabling CORS...' : `Enable CORS for ${window.location.origin}`}\n\t\t\t\t\t</Button>\n\t\t\t\t</ErrorComponent>\n\t\t\t)}\n\t\t\t<Suspense fallback={<Loading centered={true} text=\"Loading API documentation...\" />}>\n\t\t\t\t<SwaggerUI\n\t\t\t\t\tspec={spec}\n\t\t\t\t\tpersistAuthorization={true}\n\t\t\t\t\twithCredentials={true}\n\t\t\t\t\trequestSnippetsEnabled={true}\n\t\t\t\t\tdefaultModelRendering=\"model\"\n\t\t\t\t\trequestSnippets={requestSnippets}\n\t\t\t\t\tplugins={plugins}\n\t\t\t\t\ttryItOutEnabled={true}\n\t\t\t\t/>\n\t\t\t</Suspense>\n\t\t</>\n\t);\n}\n","import { APIDocs } from '@/features/instance/apis/APIDocs';\nimport { createLazyRoute } from '@tanstack/react-router';\n\nexport const route = createLazyRoute('/apis')({\n\tcomponent: APIDocs,\n});\n"],"file":"index.lazy-CXzU1gVu.js"}
@@ -1,2 +1,2 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{m as t,n,r}from"./cn-BnE9QzQD.js";import{Kt as i,Wt as a}from"./vendor-core-BY_ZlgBF.js";import{$i as o,An as s,Fn as c,Ki as l,Qi as u,Qn as d,Ui as f,fr as p,zi as m}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{n as h,t as g}from"./button-DWsEHYDp.js";import{C as _,D as v,E as y,O as b,S as x,T as S,k as C,x as w}from"./index-ZhLX9iRh.js";async function T(e){let{id:n,newPassword:r,confirmNewPassword:i,...a}=e,o={...a};r&&r===i&&(o.password=r);let{data:s}=await t.patch(`/User/${n}`,o);return s}function E(){return l({mutationFn:e=>T(e)})}var D=a({id:i(),firstname:i({error:`Please enter your first name.`}).min(2,{error:`First name is required.`}).max(50,{error:`First name must be less than 50 characters.`}),lastname:i({error:`Please enter your last name.`}).min(2,{error:`Last name is required.`}).max(50,{error:`Last name must be less than 50 characters.`}),newPassword:i({error:`Please enter your new password.`}).min(8,{error:`Password must be 8 characters or more.`}).or(i().max(0)),confirmNewPassword:i().optional()}).refine(e=>e.newPassword===e.confirmNewPassword,{error:`Passwords do not match`,path:[`confirmNewPassword`]}),O=e(o(),1),k=u();function A(){let e=f(),t=m(),{user:i}=h(),a=c({resolver:s(D),defaultValues:{confirmNewPassword:``,firstname:i?.firstname||``,id:i?.id||``,lastname:i?.lastname||``,newPassword:``}}),{control:o,handleSubmit:l,reset:u,formState:{defaultValues:T,isDirty:A,isValid:j}}=a,{mutate:M,isPending:N}=E(),P=(0,O.useCallback)(async i=>{i&&M(i,{onSuccess:a=>{u({...T,...a}),r.updateUserForEntity(n,a),i.newPassword?(d.success(`Profile updated successfully!`,{description:`Please sign in with your new password.`}),C(),t({to:`/sign-in`}),e.invalidate()):d.success(`Profile updated successfully!`)}})},[T,t,u,e,M]);return(0,k.jsxs)(`div`,{className:`mt-20 px-4 pt-4 md:px-12`,children:[(0,k.jsx)(`h2`,{className:`text-2xl font-light`,children:`Profile`}),(0,k.jsx)(b,{...a,children:(0,k.jsxs)(`form`,{id:`profile-edit-form`,name:`profile-edit-form`,onSubmit:l(P),className:`grid gap-4 my-4`,children:[(0,k.jsx)(y,{control:o,name:`firstname`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`First Name`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`text`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoCapitalize:`words`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(y,{control:o,name:`lastname`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`Last Name`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`text`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoCapitalize:`words`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(_,{className:`pb-1`,children:`Email`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`email`,enterKeyHint:`next`,autoComplete:`email`,autoCapitalize:`none`,value:i?.email||``,disabled:!0,readOnly:!0})}),(0,k.jsx)(y,{control:o,name:`newPassword`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`New Password`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`password`,placeholder:`Optional`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoComplete:`new-password`,autoCapitalize:`none`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(y,{control:o,name:`confirmNewPassword`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`Confirm New Password`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`password`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoComplete:`new-password`,autoCapitalize:`none`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(`div`,{className:`flex justify-between w-full`,children:(0,k.jsxs)(g,{type:`submit`,variant:`submit`,className:`rounded-full`,disabled:N||!A||!j,children:[(0,k.jsx)(p,{}),` Update Profile`]})})]})})]})}export{A as ProfileIndex};
2
- //# sourceMappingURL=profile-DJ9V18dX.js.map
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{m as t,n,r}from"./cn-BnE9QzQD.js";import{Kt as i,Wt as a}from"./vendor-core-BY_ZlgBF.js";import{$i as o,An as s,Fn as c,Ki as l,Qi as u,Qn as d,Ui as f,fr as p,zi as m}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{n as h,t as g}from"./button-DWsEHYDp.js";import{C as _,D as v,E as y,O as b,S as x,T as S,k as C,x as w}from"./index-ClD_q6ya.js";async function T(e){let{id:n,newPassword:r,confirmNewPassword:i,...a}=e,o={...a};r&&r===i&&(o.password=r);let{data:s}=await t.patch(`/User/${n}`,o);return s}function E(){return l({mutationFn:e=>T(e)})}var D=a({id:i(),firstname:i({error:`Please enter your first name.`}).min(2,{error:`First name is required.`}).max(50,{error:`First name must be less than 50 characters.`}),lastname:i({error:`Please enter your last name.`}).min(2,{error:`Last name is required.`}).max(50,{error:`Last name must be less than 50 characters.`}),newPassword:i({error:`Please enter your new password.`}).min(8,{error:`Password must be 8 characters or more.`}).or(i().max(0)),confirmNewPassword:i().optional()}).refine(e=>e.newPassword===e.confirmNewPassword,{error:`Passwords do not match`,path:[`confirmNewPassword`]}),O=e(o(),1),k=u();function A(){let e=f(),t=m(),{user:i}=h(),a=c({resolver:s(D),defaultValues:{confirmNewPassword:``,firstname:i?.firstname||``,id:i?.id||``,lastname:i?.lastname||``,newPassword:``}}),{control:o,handleSubmit:l,reset:u,formState:{defaultValues:T,isDirty:A,isValid:j}}=a,{mutate:M,isPending:N}=E(),P=(0,O.useCallback)(async i=>{i&&M(i,{onSuccess:a=>{u({...T,...a}),r.updateUserForEntity(n,a),i.newPassword?(d.success(`Profile updated successfully!`,{description:`Please sign in with your new password.`}),C(),t({to:`/sign-in`}),e.invalidate()):d.success(`Profile updated successfully!`)}})},[T,t,u,e,M]);return(0,k.jsxs)(`div`,{className:`mt-20 px-4 pt-4 md:px-12`,children:[(0,k.jsx)(`h2`,{className:`text-2xl font-light`,children:`Profile`}),(0,k.jsx)(b,{...a,children:(0,k.jsxs)(`form`,{id:`profile-edit-form`,name:`profile-edit-form`,onSubmit:l(P),className:`grid gap-4 my-4`,children:[(0,k.jsx)(y,{control:o,name:`firstname`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`First Name`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`text`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoCapitalize:`words`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(y,{control:o,name:`lastname`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`Last Name`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`text`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoCapitalize:`words`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(_,{className:`pb-1`,children:`Email`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`email`,enterKeyHint:`next`,autoComplete:`email`,autoCapitalize:`none`,value:i?.email||``,disabled:!0,readOnly:!0})}),(0,k.jsx)(y,{control:o,name:`newPassword`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`New Password`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`password`,placeholder:`Optional`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoComplete:`new-password`,autoCapitalize:`none`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(y,{control:o,name:`confirmNewPassword`,render:({field:e})=>(0,k.jsxs)(S,{children:[(0,k.jsx)(_,{className:`pb-1`,children:`Confirm New Password`}),(0,k.jsx)(v,{children:(0,k.jsx)(w,{type:`password`,className:`bg-purple-400 border-purple-400 dark:bg-black dark:border-black`,autoComplete:`new-password`,autoCapitalize:`none`,...e})}),(0,k.jsx)(x,{})]})}),(0,k.jsx)(`div`,{className:`flex justify-between w-full`,children:(0,k.jsxs)(g,{type:`submit`,variant:`submit`,className:`rounded-full`,disabled:N||!A||!j,children:[(0,k.jsx)(p,{}),` Update Profile`]})})]})})]})}export{A as ProfileIndex};
2
+ //# sourceMappingURL=profile-DCNVg5yY.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"profile-DJ9V18dX.js","names":[],"sources":["../../src/features/profile/mutations/updateUserMutation.ts","../../src/features/profile/mutations/updateUserSchema.ts","../../src/features/profile/index.tsx"],"sourcesContent":["import { apiClient } from '@/config/apiClient';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { User } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nasync function onUpdateUser(formData: z.infer<typeof UpdateUserSchema>) {\n\tconst { id, newPassword, confirmNewPassword, ...otherFields } = formData;\n\tconst userData: Partial<SchemaUser & { password: string }> = {\n\t\t...otherFields,\n\t};\n\tif (newPassword && newPassword === confirmNewPassword) {\n\t\tuserData.password = newPassword;\n\t}\n\tconst { data } = await apiClient.patch(`/User/${id}` as '/User/{id}', userData);\n\treturn data as Partial<User>;\n}\n\nexport function useUpdateUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof UpdateUserSchema>) => onUpdateUser(formData),\n\t});\n}\n","import { z } from 'zod';\n\nexport const UpdateUserSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tfirstname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your first name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'First name is required.' })\n\t\t\t.max(50, { error: 'First name must be less than 50 characters.' }),\n\t\tlastname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your last name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'Last name is required.' })\n\t\t\t.max(50, { error: 'Last name must be less than 50 characters.' }),\n\t\tnewPassword: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your new password.',\n\t\t\t})\n\t\t\t.min(8, { error: 'Password must be 8 characters or more.' })\n\t\t\t.or(z.string().max(0)),\n\t\tconfirmNewPassword: z\n\t\t\t.string()\n\t\t\t.optional(),\n\t})\n\t.refine((data) => data.newPassword === data.confirmNewPassword, {\n\t\terror: 'Passwords do not match',\n\t\tpath: ['confirmNewPassword'],\n\t});\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { logoutOnSuccess } from '@/features/auth/handlers/logoutOnSuccess';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useUpdateUserMutation } from '@/features/profile/mutations/updateUserMutation';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useRouter } from '@tanstack/react-router';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function ProfileIndex() {\n\tconst router = useRouter();\n\tconst navigate = useNavigate();\n\tconst { user } = useCloudAuth();\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(UpdateUserSchema),\n\t\tdefaultValues: {\n\t\t\tconfirmNewPassword: '',\n\t\t\tfirstname: user?.firstname || '',\n\t\t\tid: user?.id || '',\n\t\t\tlastname: user?.lastname || '',\n\t\t\tnewPassword: '',\n\t\t},\n\t});\n\tconst { control, handleSubmit, reset, formState: { defaultValues, isDirty, isValid } } = methods;\n\tconst { mutate: updateUser, isPending: isUpdatePending } = useUpdateUserMutation();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof UpdateUserSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tupdateUser(formData, {\n\t\t\t\t\tonSuccess: (data) => {\n\t\t\t\t\t\treset({\n\t\t\t\t\t\t\t...defaultValues,\n\t\t\t\t\t\t\t...data,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tauthStore.updateUserForEntity(OverallAppSignIn, data);\n\t\t\t\t\t\tif (formData.newPassword) {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!', {\n\t\t\t\t\t\t\t\tdescription: 'Please sign in with your new password.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tlogoutOnSuccess();\n\t\t\t\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\t\t\t\tvoid router.invalidate();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!');\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[defaultValues, navigate, reset, router, updateUser],\n\t);\n\n\treturn (\n\t\t<div className=\"mt-20 px-4 pt-4 md:px-12\">\n\t\t\t<h2 className=\"text-2xl font-light\">Profile</h2>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"profile-edit-form\"\n\t\t\t\t\tname=\"profile-edit-form\"\n\t\t\t\t\tonSubmit={handleSubmit(onSubmitClick)}\n\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"firstname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">First Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"lastname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Last Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\tvalue={user?.email || ''}\n\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"newPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Optional\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmNewPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isUpdatePending || !isDirty || !isValid}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Update Profile\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"profile-DCNVg5yY.js","names":[],"sources":["../../src/features/profile/mutations/updateUserMutation.ts","../../src/features/profile/mutations/updateUserSchema.ts","../../src/features/profile/index.tsx"],"sourcesContent":["import { apiClient } from '@/config/apiClient';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { User } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nasync function onUpdateUser(formData: z.infer<typeof UpdateUserSchema>) {\n\tconst { id, newPassword, confirmNewPassword, ...otherFields } = formData;\n\tconst userData: Partial<SchemaUser & { password: string }> = {\n\t\t...otherFields,\n\t};\n\tif (newPassword && newPassword === confirmNewPassword) {\n\t\tuserData.password = newPassword;\n\t}\n\tconst { data } = await apiClient.patch(`/User/${id}` as '/User/{id}', userData);\n\treturn data as Partial<User>;\n}\n\nexport function useUpdateUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof UpdateUserSchema>) => onUpdateUser(formData),\n\t});\n}\n","import { z } from 'zod';\n\nexport const UpdateUserSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tfirstname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your first name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'First name is required.' })\n\t\t\t.max(50, { error: 'First name must be less than 50 characters.' }),\n\t\tlastname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your last name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'Last name is required.' })\n\t\t\t.max(50, { error: 'Last name must be less than 50 characters.' }),\n\t\tnewPassword: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your new password.',\n\t\t\t})\n\t\t\t.min(8, { error: 'Password must be 8 characters or more.' })\n\t\t\t.or(z.string().max(0)),\n\t\tconfirmNewPassword: z\n\t\t\t.string()\n\t\t\t.optional(),\n\t})\n\t.refine((data) => data.newPassword === data.confirmNewPassword, {\n\t\terror: 'Passwords do not match',\n\t\tpath: ['confirmNewPassword'],\n\t});\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { logoutOnSuccess } from '@/features/auth/handlers/logoutOnSuccess';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useUpdateUserMutation } from '@/features/profile/mutations/updateUserMutation';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useRouter } from '@tanstack/react-router';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function ProfileIndex() {\n\tconst router = useRouter();\n\tconst navigate = useNavigate();\n\tconst { user } = useCloudAuth();\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(UpdateUserSchema),\n\t\tdefaultValues: {\n\t\t\tconfirmNewPassword: '',\n\t\t\tfirstname: user?.firstname || '',\n\t\t\tid: user?.id || '',\n\t\t\tlastname: user?.lastname || '',\n\t\t\tnewPassword: '',\n\t\t},\n\t});\n\tconst { control, handleSubmit, reset, formState: { defaultValues, isDirty, isValid } } = methods;\n\tconst { mutate: updateUser, isPending: isUpdatePending } = useUpdateUserMutation();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof UpdateUserSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tupdateUser(formData, {\n\t\t\t\t\tonSuccess: (data) => {\n\t\t\t\t\t\treset({\n\t\t\t\t\t\t\t...defaultValues,\n\t\t\t\t\t\t\t...data,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tauthStore.updateUserForEntity(OverallAppSignIn, data);\n\t\t\t\t\t\tif (formData.newPassword) {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!', {\n\t\t\t\t\t\t\t\tdescription: 'Please sign in with your new password.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tlogoutOnSuccess();\n\t\t\t\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\t\t\t\tvoid router.invalidate();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!');\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[defaultValues, navigate, reset, router, updateUser],\n\t);\n\n\treturn (\n\t\t<div className=\"mt-20 px-4 pt-4 md:px-12\">\n\t\t\t<h2 className=\"text-2xl font-light\">Profile</h2>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"profile-edit-form\"\n\t\t\t\t\tname=\"profile-edit-form\"\n\t\t\t\t\tonSubmit={handleSubmit(onSubmitClick)}\n\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"firstname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">First Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"lastname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Last Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\tvalue={user?.email || ''}\n\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"newPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Optional\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmNewPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isUpdatePending || !isDirty || !isValid}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Update Profile\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{t}from"./cn-BnE9QzQD.js";import"./vendor-core-BY_ZlgBF.js";import{$i as n,Ji as r,Qi as i,Yi as a,a as o,i as s,n as c,o as l,qi as u,r as d,s as f,t as p}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{A as m,_ as h,c as g,d as _,f as v,g as y,h as b,j as x,l as S,m as C,p as w,s as T,u as E,w as D}from"./index-ZhLX9iRh.js";var O=new Date(2025,0).getTime(),k=1440*60*1e3;function A(e){let t=[];for(let n in e){let r=e[n];t.push(...M(n,r,0))}return t}function j(e){return!!e.title}function M(e,t,n,r){if(t&&Array.isArray(t)){let r=t;return[r.length>1&&{title:e,depth:n},...t.map((t,i)=>M(r.length>1?String(i+1):e,t,n+1,e)).flat(1)].filter(x)}if(N(t)){let r=t;return[{title:e,depth:n},...Object.keys(t).map(t=>M(String(t),r[t],n+1,e)).flat(1)]}return(e===`__updatedtime__`||e===`__createdtime__`)&&(e=e.replace(/_/g,``).replace(`time`,``)),typeof t==`number`?t>O&&t<Date.now()+k?t=T(Date.now()-t,t):r===`memory`?t=g(t):!e.startsWith(`raw`)&&e.toLowerCase().includes(`load`)&&(t=Math.round(t*10)/10+`%`):typeof t==`boolean`&&(t=t?`Yes`:`No`),[{name:e,value:String(t),depth:n}]}function N(e){return!!e&&typeof e==`object`}var P=e(n(),1),F=i();function I({data:e}){return(0,F.jsx)(`div`,{className:`max-w-96 grid mb-12`,children:(0,P.useMemo)(()=>A(e),[e]).map((e,n)=>j(e)?(0,F.jsx)(`div`,{className:t(`font-semibold text-xl`,n!==0&&`mt-4`),style:{paddingLeft:e.depth*12+`px`},children:e.title},n):(0,F.jsxs)(`div`,{style:{paddingLeft:e.depth*12+`px`},children:[(0,F.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.name,`:`]}),e.value]},n))})}function L({metricConfig:e,startTime:t,endTime:n,instanceParams:r}){return u({queryKey:[`get_analytics`,e.name,e.path,t,n],queryFn:async()=>{let i={operation:`get_analytics`,metric:e.name,start_time:t,end_time:n};e.path&&(i.conditions=[{attribute:`path`,value:e.path}]);let{data:a}=await r.instanceClient.post(`/`,i);return a}})}var R={"persistence-purple":`#403B8A`,"b-tree-green":`#55C58F`,"cyber-grape":`#7A3A87`,"quantum-purple":`#312556`,"cloud-white":`#F5F5F5`,"acid-magenta":`#C63368`,"edge-gray":`#383D40`};function z(e,t,n,r){let i;return i=typeof t==`string`?e[t]??0:t(e),r?E(i,n,r):i}function B({metricConfig:e,startTime:t,endTime:n,instanceParams:r}){let{data:i}=a(L({instanceParams:r,metricConfig:e,startTime:t,endTime:n})),u=(0,P.useMemo)(()=>i?.reduce((e,t)=>{let n={metric:``,node:``,id:0,period:0,count:0,mean:0};for(let e in t)t[e]!==null&&(n[e]=t[e]);return e.push(n),e},[]),[i]),[m,h]=(0,P.useState)(e.units),g=(0,P.useMemo)(()=>{let t={},{dataKey:n,aggregator:r,units:i}=e,a=i;if(u&&u.length>0){a=S(i,Math.max(...u.map(e=>z(e,n,i)))),h(a);for(let e of u){let o=Math.floor(e.id/e.period)*e.period,s=z(e,n,i,a);t[o]?e.node in t[o]?t[o][e.node]=r(t[o][e.node],s):t[o][e.node]=s:t[o]={[e.node]:s}}return Object.keys(t).map(e=>{let n=Number.parseInt(e),r=t[e];return{id:n,...Object.keys(t[e]).reduce((e,t)=>(e[t]=r[t].toFixed(2),e),{})}})}},[u,e]),_=(0,P.useMemo)(()=>Array.from(new Set(u?.map(e=>e.node))),[u]),v=e=>new Date(e).toLocaleDateString(void 0,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,hour12:!1});return g&&g.length>0?(0,F.jsx)(f,{width:`100%`,height:600,className:`mt-8`,children:(0,F.jsxs)(p,{width:600,height:300,data:g,children:[_.map((t,n)=>{let r=e.name;e.path&&(r+=`.`+e.path);let i=r+`.`+t;return(0,F.jsx)(s,{name:t,dataKey:t,stroke:Object.values(R)[n]},i)}),(0,F.jsx)(d,{dataKey:e=>v(e.id)}),(0,F.jsx)(c,{unit:` ${m}`,width:100}),(0,F.jsx)(l,{}),(0,F.jsx)(o,{})]})}):(0,F.jsx)(`div`,{className:`mt-8 h-[600px]`,children:(0,F.jsxs)(`p`,{children:[`No `,e.name,` data for this time period`]})})}var V=typeof window<`u`?P.useLayoutEffect:P.useEffect;function H(e,t){let n=(0,P.useRef)(e);V(()=>{n.current=e},[e]),(0,P.useEffect)(()=>{if(t===null)return;let e=setInterval(()=>{n.current()},t);return()=>{clearInterval(e)}},[t])}var U=[{id:`db-read`,name:`db-read`,dataKey:`count`,aggregator:G,units:`reads`},{id:`db-read-bytes`,label:`db-read-bytes`,name:`db-read`,dataKey:W,aggregator:G,units:`bytes`},{id:`db-write`,name:`db-write`,dataKey:`count`,aggregator:G,units:`writes`},{id:`db-write-bytes`,label:`db-write-bytes`,name:`db-write`,dataKey:W,aggregator:G,units:`bytes`},{id:`db-message`,name:`db-message`,dataKey:`count`,aggregator:G,units:`messages`},{id:`db-message-bytes`,label:`db-message-bytes`,name:`db-message`,dataKey:W,aggregator:G,units:`bytes`},{id:`cpu-usage-user`,name:`cpu-usage`,path:`user`,dataKey:W,aggregator:G,units:`secs`},{id:`cpu-usage-harper`,name:`cpu-usage`,path:`harper`,dataKey:W,aggregator:G,units:`secs`}];function W(e){return e.mean&&e.count?e.mean*e.count:0}function G(e,t){return e+t}var K=[{label:`10 mins`,value:10*6e4},{label:`hour`,value:60*6e4,default:!0},{label:`6 hours`,value:360*6e4},{label:`day`,value:1440*6e4}],q=[{label:`15 secs`,value:15e3},{label:`30 secs`,value:3e4},{label:`minute`,value:6e4,default:!0},{label:`5 mins`,value:5*6e4},{label:`15 mins`,value:15*6e4}];function J({instanceParams:e}){let[t,n]=(0,P.useState)(U[0]),[r,i]=(0,P.useState)(q.find(e=>e.default)),[a,o]=(0,P.useState)(Date.now),[s,c]=(0,P.useState)(K.find(e=>e.default));H(()=>{o(Date.now)},r.value);let l=(0,P.useMemo)(()=>a-s.value,[a,s]);return(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`div`,{className:`flex justify-between`,children:(0,F.jsxs)(`div`,{className:`justify-items-end grid grid-cols-1 lg:grid-cols-3 gap-4`,children:[(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Metric:`}),(0,F.jsxs)(_,{defaultValue:t.id,onValueChange:e=>{n(U.find(t=>t.id===e)||U[0])},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:U.map(e=>{let t=e.label??e.name;return e.path&&(t+=` (${e.path})`),(0,F.jsx)(C,{value:e.id,children:t},e.id)})})})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Show last`}),(0,F.jsxs)(_,{defaultValue:s.value.toString(),onValueChange:e=>{c(K.find(t=>t.value===Number(e)))},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:K.map(e=>(0,F.jsx)(C,{value:e.value.toString(),children:e.label},e.value))})})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Update every`}),(0,F.jsxs)(_,{defaultValue:r.value.toString(),onValueChange:e=>{i(q.find(t=>t.value===Number(e)))},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:q.map(e=>(0,F.jsx)(C,{value:e.value.toString(),children:e.label},e.value))})})]})]})]})}),(0,F.jsx)(B,{metricConfig:t,startTime:l,endTime:a,instanceParams:e})]})}function Y({entityId:e,instanceClient:t}){return u({queryKey:[e,`system_information`],queryFn:async()=>{let{data:e}=await t.post(`/`,{operation:`system_information`,attributes:[`network`,`disk`,`cpu`,`memory`,`system`]});return e}})}function X({instanceParams:e}){let{data:t}=r(Y(e));return(0,F.jsx)(P.Suspense,{fallback:(0,F.jsx)(h,{}),children:(0,F.jsx)(I,{data:t})})}function Z(){let e=m();return(0,F.jsxs)(`div`,{className:`px-4 py-2 flex flex-col`,children:[(0,F.jsx)(`div`,{className:`mb-12`,children:(0,F.jsx)(J,{instanceParams:e})}),(0,F.jsx)(X,{instanceParams:e})]})}export{Z as StatusIndex};
2
- //# sourceMappingURL=status-DKZUoEUd.js.map
1
+ import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{t}from"./cn-BnE9QzQD.js";import"./vendor-core-BY_ZlgBF.js";import{$i as n,Ji as r,Qi as i,Yi as a,a as o,i as s,n as c,o as l,qi as u,r as d,s as f,t as p}from"./vendor-react-DrZSc0Lm.js";import"./vendor-misc-BBL3Mh21.js";import{A as m,_ as h,c as g,d as _,f as v,g as y,h as b,j as x,l as S,m as C,p as w,s as T,u as E,w as D}from"./index-ClD_q6ya.js";var O=new Date(2025,0).getTime(),k=1440*60*1e3;function A(e){let t=[];for(let n in e){let r=e[n];t.push(...M(n,r,0))}return t}function j(e){return!!e.title}function M(e,t,n,r){if(t&&Array.isArray(t)){let r=t;return[r.length>1&&{title:e,depth:n},...t.map((t,i)=>M(r.length>1?String(i+1):e,t,n+1,e)).flat(1)].filter(x)}if(N(t)){let r=t;return[{title:e,depth:n},...Object.keys(t).map(t=>M(String(t),r[t],n+1,e)).flat(1)]}return(e===`__updatedtime__`||e===`__createdtime__`)&&(e=e.replace(/_/g,``).replace(`time`,``)),typeof t==`number`?t>O&&t<Date.now()+k?t=T(Date.now()-t,t):r===`memory`?t=g(t):!e.startsWith(`raw`)&&e.toLowerCase().includes(`load`)&&(t=Math.round(t*10)/10+`%`):typeof t==`boolean`&&(t=t?`Yes`:`No`),[{name:e,value:String(t),depth:n}]}function N(e){return!!e&&typeof e==`object`}var P=e(n(),1),F=i();function I({data:e}){return(0,F.jsx)(`div`,{className:`max-w-96 grid mb-12`,children:(0,P.useMemo)(()=>A(e),[e]).map((e,n)=>j(e)?(0,F.jsx)(`div`,{className:t(`font-semibold text-xl`,n!==0&&`mt-4`),style:{paddingLeft:e.depth*12+`px`},children:e.title},n):(0,F.jsxs)(`div`,{style:{paddingLeft:e.depth*12+`px`},children:[(0,F.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.name,`:`]}),e.value]},n))})}function L({metricConfig:e,startTime:t,endTime:n,instanceParams:r}){return u({queryKey:[`get_analytics`,e.name,e.path,t,n],queryFn:async()=>{let i={operation:`get_analytics`,metric:e.name,start_time:t,end_time:n};e.path&&(i.conditions=[{attribute:`path`,value:e.path}]);let{data:a}=await r.instanceClient.post(`/`,i);return a}})}var R={"persistence-purple":`#403B8A`,"b-tree-green":`#55C58F`,"cyber-grape":`#7A3A87`,"quantum-purple":`#312556`,"cloud-white":`#F5F5F5`,"acid-magenta":`#C63368`,"edge-gray":`#383D40`};function z(e,t,n,r){let i;return i=typeof t==`string`?e[t]??0:t(e),r?E(i,n,r):i}function B({metricConfig:e,startTime:t,endTime:n,instanceParams:r}){let{data:i}=a(L({instanceParams:r,metricConfig:e,startTime:t,endTime:n})),u=(0,P.useMemo)(()=>i?.reduce((e,t)=>{let n={metric:``,node:``,id:0,period:0,count:0,mean:0};for(let e in t)t[e]!==null&&(n[e]=t[e]);return e.push(n),e},[]),[i]),[m,h]=(0,P.useState)(e.units),g=(0,P.useMemo)(()=>{let t={},{dataKey:n,aggregator:r,units:i}=e,a=i;if(u&&u.length>0){a=S(i,Math.max(...u.map(e=>z(e,n,i)))),h(a);for(let e of u){let o=Math.floor(e.id/e.period)*e.period,s=z(e,n,i,a);t[o]?e.node in t[o]?t[o][e.node]=r(t[o][e.node],s):t[o][e.node]=s:t[o]={[e.node]:s}}return Object.keys(t).map(e=>{let n=Number.parseInt(e),r=t[e];return{id:n,...Object.keys(t[e]).reduce((e,t)=>(e[t]=r[t].toFixed(2),e),{})}})}},[u,e]),_=(0,P.useMemo)(()=>Array.from(new Set(u?.map(e=>e.node))),[u]),v=e=>new Date(e).toLocaleDateString(void 0,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,hour12:!1});return g&&g.length>0?(0,F.jsx)(f,{width:`100%`,height:600,className:`mt-8`,children:(0,F.jsxs)(p,{width:600,height:300,data:g,children:[_.map((t,n)=>{let r=e.name;e.path&&(r+=`.`+e.path);let i=r+`.`+t;return(0,F.jsx)(s,{name:t,dataKey:t,stroke:Object.values(R)[n]},i)}),(0,F.jsx)(d,{dataKey:e=>v(e.id)}),(0,F.jsx)(c,{unit:` ${m}`,width:100}),(0,F.jsx)(l,{}),(0,F.jsx)(o,{})]})}):(0,F.jsx)(`div`,{className:`mt-8 h-[600px]`,children:(0,F.jsxs)(`p`,{children:[`No `,e.name,` data for this time period`]})})}var V=typeof window<`u`?P.useLayoutEffect:P.useEffect;function H(e,t){let n=(0,P.useRef)(e);V(()=>{n.current=e},[e]),(0,P.useEffect)(()=>{if(t===null)return;let e=setInterval(()=>{n.current()},t);return()=>{clearInterval(e)}},[t])}var U=[{id:`db-read`,name:`db-read`,dataKey:`count`,aggregator:G,units:`reads`},{id:`db-read-bytes`,label:`db-read-bytes`,name:`db-read`,dataKey:W,aggregator:G,units:`bytes`},{id:`db-write`,name:`db-write`,dataKey:`count`,aggregator:G,units:`writes`},{id:`db-write-bytes`,label:`db-write-bytes`,name:`db-write`,dataKey:W,aggregator:G,units:`bytes`},{id:`db-message`,name:`db-message`,dataKey:`count`,aggregator:G,units:`messages`},{id:`db-message-bytes`,label:`db-message-bytes`,name:`db-message`,dataKey:W,aggregator:G,units:`bytes`},{id:`cpu-usage-user`,name:`cpu-usage`,path:`user`,dataKey:W,aggregator:G,units:`secs`},{id:`cpu-usage-harper`,name:`cpu-usage`,path:`harper`,dataKey:W,aggregator:G,units:`secs`}];function W(e){return e.mean&&e.count?e.mean*e.count:0}function G(e,t){return e+t}var K=[{label:`10 mins`,value:10*6e4},{label:`hour`,value:60*6e4,default:!0},{label:`6 hours`,value:360*6e4},{label:`day`,value:1440*6e4}],q=[{label:`15 secs`,value:15e3},{label:`30 secs`,value:3e4},{label:`minute`,value:6e4,default:!0},{label:`5 mins`,value:5*6e4},{label:`15 mins`,value:15*6e4}];function J({instanceParams:e}){let[t,n]=(0,P.useState)(U[0]),[r,i]=(0,P.useState)(q.find(e=>e.default)),[a,o]=(0,P.useState)(Date.now),[s,c]=(0,P.useState)(K.find(e=>e.default));H(()=>{o(Date.now)},r.value);let l=(0,P.useMemo)(()=>a-s.value,[a,s]);return(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`div`,{className:`flex justify-between`,children:(0,F.jsxs)(`div`,{className:`justify-items-end grid grid-cols-1 lg:grid-cols-3 gap-4`,children:[(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Metric:`}),(0,F.jsxs)(_,{defaultValue:t.id,onValueChange:e=>{n(U.find(t=>t.id===e)||U[0])},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:U.map(e=>{let t=e.label??e.name;return e.path&&(t+=` (${e.path})`),(0,F.jsx)(C,{value:e.id,children:t},e.id)})})})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Show last`}),(0,F.jsxs)(_,{defaultValue:s.value.toString(),onValueChange:e=>{c(K.find(t=>t.value===Number(e)))},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:K.map(e=>(0,F.jsx)(C,{value:e.value.toString(),children:e.label},e.value))})})]})]}),(0,F.jsxs)(`div`,{className:`flex flex-nowrap items-center`,children:[(0,F.jsx)(D,{className:`ml-8 mr-2`,children:`Update every`}),(0,F.jsxs)(_,{defaultValue:r.value.toString(),onValueChange:e=>{i(q.find(t=>t.value===Number(e)))},children:[(0,F.jsx)(b,{className:`inline-flex align-middle w-auto h-auto`,children:(0,F.jsx)(y,{})}),(0,F.jsx)(v,{children:(0,F.jsx)(w,{children:q.map(e=>(0,F.jsx)(C,{value:e.value.toString(),children:e.label},e.value))})})]})]})]})}),(0,F.jsx)(B,{metricConfig:t,startTime:l,endTime:a,instanceParams:e})]})}function Y({entityId:e,instanceClient:t}){return u({queryKey:[e,`system_information`],queryFn:async()=>{let{data:e}=await t.post(`/`,{operation:`system_information`,attributes:[`network`,`disk`,`cpu`,`memory`,`system`]});return e}})}function X({instanceParams:e}){let{data:t}=r(Y(e));return(0,F.jsx)(P.Suspense,{fallback:(0,F.jsx)(h,{}),children:(0,F.jsx)(I,{data:t})})}function Z(){let e=m();return(0,F.jsxs)(`div`,{className:`px-4 py-2 flex flex-col`,children:[(0,F.jsx)(`div`,{className:`mb-12`,children:(0,F.jsx)(J,{instanceParams:e})}),(0,F.jsx)(X,{instanceParams:e})]})}export{Z as StatusIndex};
2
+ //# sourceMappingURL=status-CoGlcjSB.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-DKZUoEUd.js","names":[],"sources":["../../src/features/instance/status/crawlData.ts","../../src/features/instance/status/Status.tsx","../../src/features/instance/status/CloudStatus.tsx","../../src/integrations/api/instance/status/getAnalytics.ts","../../src/lib/colorPalette.ts","../../src/features/instance/status/components/monitoring/MetricVisualization.tsx","../../src/hooks/useIsomorphicLayoutEffect.ts","../../src/hooks/useInterval.ts","../../src/features/instance/status/components/Monitoring.tsx","../../src/integrations/api/instance/status/getSystemInformation.ts","../../src/features/instance/status/LocalStatus.tsx","../../src/features/instance/status/index.tsx"],"sourcesContent":["import { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { humanFileSize } from '@/lib/humanFileSize';\nimport { translateSecondsToAgo } from '@/lib/translateSecondsToAgo';\n\nconst startOf2025 = new Date(2025, 0).getTime();\nconst oneDayInMs = 24 * 60 * 60 * 1000;\n\ninterface TitleItem {\n\ttitle: string;\n\tdepth: number;\n}\n\ninterface NameValuePairItem {\n\tname: string;\n\tvalue: string;\n\tdepth: number;\n}\n\ntype ItemForDisplay = TitleItem | NameValuePairItem;\n\nexport function crawlData(data: Record<string, unknown>): ItemForDisplay[] {\n\tconst sections: ItemForDisplay[] = [];\n\tfor (const key in data) {\n\t\tconst value = data[key];\n\t\tsections.push(...parseValue(key, value, 0));\n\t}\n\treturn sections;\n}\n\nexport function hasTitle(item: ItemForDisplay): item is TitleItem {\n\treturn !!(item as TitleItem).title;\n}\n\nfunction parseValue(name: string, value: unknown, depth: number, parentName?: string): ItemForDisplay[] {\n\tif (value && Array.isArray(value)) {\n\t\tconst array = value;\n\t\treturn [\n\t\t\tarray.length > 1 && { title: name, depth },\n\t\t\t...value.map((item, index) =>\n\t\t\t\tparseValue(\n\t\t\t\t\tarray.length > 1 ? String(index + 1) : name,\n\t\t\t\t\titem,\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tname,\n\t\t\t\t)\n\t\t\t).flat(1),\n\t\t].filter(excludeFalsy);\n\t}\n\tif (isObject(value)) {\n\t\tconst obj = value;\n\t\treturn [\n\t\t\t{ title: name, depth },\n\t\t\t...Object.keys(value).map(subKey =>\n\t\t\t\tparseValue(\n\t\t\t\t\tString(subKey),\n\t\t\t\t\tobj[subKey],\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tname,\n\t\t\t\t)\n\t\t\t).flat(1),\n\t\t];\n\t}\n\tif (name === '__updatedtime__' || name === '__createdtime__') {\n\t\tname = name.replace(/_/g, '').replace('time', '');\n\t}\n\tif (typeof value === 'number') {\n\t\tif (value > startOf2025 && value < Date.now() + oneDayInMs) {\n\t\t\tconst elapsed = Date.now() - value;\n\t\t\tvalue = translateSecondsToAgo(elapsed, value);\n\t\t} else if (parentName === 'memory') {\n\t\t\tvalue = humanFileSize(value);\n\t\t} else if (!name.startsWith('raw') && name.toLowerCase().includes('load')) {\n\t\t\tvalue = Math.round(value * 10) / 10 + '%';\n\t\t}\n\t} else if (typeof value === 'boolean') {\n\t\tvalue = value ? 'Yes' : 'No';\n\t}\n\treturn [\n\t\t{ name, value: String(value), depth },\n\t];\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn !!value && typeof value === 'object';\n}\n","import { crawlData, hasTitle } from '@/features/instance/status/crawlData';\nimport { cn } from '@/lib/cn';\nimport { useMemo } from 'react';\n\nexport function Status({ data }: { data: Record<string, unknown> }) {\n\tconst items = useMemo(() => crawlData(data), [data]);\n\treturn (\n\t\t<div className=\"max-w-96 grid mb-12\">\n\t\t\t{items.map((item, index) =>\n\t\t\t\thasTitle(item)\n\t\t\t\t\t? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\tclassName={cn('font-semibold text-xl', index !== 0 && 'mt-4')}\n\t\t\t\t\t\t\tstyle={{ paddingLeft: item.depth * 12 + 'px' }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{item.title}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<div key={index} style={{ paddingLeft: item.depth * 12 + 'px' }}>\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">{item.name}:</span>\n\t\t\t\t\t\t\t{item.value}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport { Status } from '@/features/instance/status/Status';\nimport { getStatusQueryOptions } from '@/integrations/api/instance/status/getStatus';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Suspense } from 'react';\n\ninterface CloudStatusParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function CloudStatus({ instanceParams }: CloudStatusParams) {\n\tconst { data } = useSuspenseQuery(getStatusQueryOptions(instanceParams));\n\n\treturn (\n\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t<Status data={data} />\n\t\t</Suspense>\n\t);\n}\n","import type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport type { Units } from '@/lib/units';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport type MetricDataKey = string | ((metric: Metric) => number);\nexport type MetricUnits = Units | 'reads' | 'writes' | 'messages';\nexport interface MetricConfig {\n\tid: string;\n\tname: string;\n\tlabel?: string;\n\tdataKey: MetricDataKey;\n\taggregator: (accumulator: number, current: number) => number;\n\tunits: MetricUnits;\n\tpath?: string;\n}\n\ninterface GetAnalyticsParams {\n\tmetricConfig: MetricConfig;\n\tstartTime: number;\n\tendTime: number;\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\ninterface GetAnalyticsRequest {\n\toperation: 'get_analytics';\n\tmetric: string;\n\tstart_time: number;\n\tend_time: number;\n\tconditions?: {\n\t\tattribute: string;\n\t\tvalue: string | number | boolean;\n\t\tcomparator?: string;\n\t}[];\n}\n\nexport interface Metric {\n\tid: number;\n\tmetric: string;\n\tcount: number;\n\tmean: number;\n\tperiod: number;\n\tnode: string;\n\t[key: string]: string | number | boolean | null;\n}\n\ntype GetAnalyticsResponse = Metric[];\n\nexport function getAnalyticsQueryOptions({ metricConfig, startTime, endTime, instanceParams }: GetAnalyticsParams) {\n\treturn queryOptions({\n\t\tqueryKey: ['get_analytics', metricConfig.name, metricConfig.path, startTime, endTime] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst req: GetAnalyticsRequest = {\n\t\t\t\toperation: 'get_analytics',\n\t\t\t\tmetric: metricConfig.name,\n\t\t\t\tstart_time: startTime,\n\t\t\t\tend_time: endTime,\n\t\t\t};\n\t\t\tif (metricConfig.path) {\n\t\t\t\treq.conditions = [{ attribute: 'path', value: metricConfig.path }];\n\t\t\t}\n\t\t\tconst { data } = await instanceParams.instanceClient.post<GetAnalyticsResponse>('/', req);\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","export const harperPalette = {\n\t'persistence-purple': '#403B8A',\n\t'b-tree-green': '#55C58F',\n\t'cyber-grape': '#7A3A87',\n\t'quantum-purple': '#312556',\n\t'cloud-white': '#F5F5F5',\n\t'acid-magenta': '#C63368',\n\t'edge-gray': '#383D40',\n};\n","import type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport {\n\tgetAnalyticsQueryOptions,\n\ttype Metric,\n\ttype MetricConfig,\n\ttype MetricDataKey,\n\ttype MetricUnits,\n} from '@/integrations/api/instance/status/getAnalytics.ts';\nimport { harperPalette } from '@/lib/colorPalette.ts';\nimport { determineUnits, scaleValueToUnits } from '@/lib/units';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo, useState } from 'react';\nimport { Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';\n\ntype MetricValue = string | number | boolean;\ntype NullableMetricValue = MetricValue | null;\ntype NullableMetric = { [key: string]: NullableMetricValue };\ntype NodeMetric = { [node: string]: number };\ntype CoalescedMetrics = { [id: string]: NodeMetric };\ntype FormattedMetric = { [node: string]: string };\n\ninterface MetricVisualizationParams {\n\tmetricConfig: MetricConfig;\n\tstartTime: number;\n\tendTime: number;\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nfunction resolveMetricDataKey(\n\tmetric: Metric,\n\tdataKey: MetricDataKey,\n\tbaseUnits: MetricUnits,\n\tconversionUnits?: string,\n) {\n\tlet baseValue;\n\tif (typeof dataKey === 'string') {\n\t\tbaseValue = metric[dataKey] as number ?? 0;\n\t} else {\n\t\tbaseValue = dataKey(metric);\n\t}\n\n\tif (conversionUnits) {\n\t\treturn scaleValueToUnits(baseValue, baseUnits, conversionUnits);\n\t}\n\n\treturn baseValue;\n}\n\nexport function MetricVisualization({ metricConfig, startTime, endTime, instanceParams }: MetricVisualizationParams) {\n\tconst { data } = useQuery(getAnalyticsQueryOptions({ instanceParams, metricConfig, startTime, endTime }));\n\tconst metrics = useMemo(() => {\n\t\treturn data?.reduce((ms: Metric[], m: NullableMetric) => {\n\t\t\tconst newMetric: Metric = { metric: '', node: '', id: 0, period: 0, count: 0, mean: 0 };\n\t\t\tfor (const k in m) {\n\t\t\t\tif (m[k] !== null) {\n\t\t\t\t\tnewMetric[k] = m[k];\n\t\t\t\t}\n\t\t\t}\n\t\t\tms.push(newMetric);\n\t\t\treturn ms;\n\t\t}, []);\n\t}, [data]);\n\n\tconst [yAxisUnits, setYAxisUnits] = useState<string>(metricConfig.units);\n\n\tconst nodeMetrics = useMemo(() => {\n\t\tconst coalescedMetrics: CoalescedMetrics = {};\n\t\tconst { dataKey, aggregator, units } = metricConfig;\n\t\tlet conversionUnits = units as string;\n\n\t\tif (metrics && metrics.length > 0) {\n\t\t\tconst maxDataValue = Math.max(...metrics.map((m) => resolveMetricDataKey(m, dataKey, units)));\n\t\t\tconversionUnits = determineUnits(units, maxDataValue);\n\t\t\t// We set the y-axis based on the max of the metrics, and we were careful to avoid a circular dependency.\n\t\t\t// So ignoring the set-state-in-render is safe, in this case.\n\t\t\t// eslint-disable-next-line react-hooks/set-state-in-render\n\t\t\tsetYAxisUnits(conversionUnits);\n\n\t\t\tfor (const metric of metrics) {\n\t\t\t\tconst coalescedTime = Math.floor(metric.id / metric.period) * metric.period;\n\t\t\t\tconst resolvedMetric = resolveMetricDataKey(metric, dataKey, units, conversionUnits);\n\n\t\t\t\tif (coalescedMetrics[coalescedTime]) {\n\t\t\t\t\tif (metric.node in coalescedMetrics[coalescedTime]) {\n\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node] = aggregator(\n\t\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node],\n\t\t\t\t\t\t\tresolvedMetric,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node] = resolvedMetric;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcoalescedMetrics[coalescedTime] = { [metric.node]: resolvedMetric };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn Object.keys(coalescedMetrics).map((id: string) => {\n\t\t\t\tconst numericalId = Number.parseInt(id);\n\t\t\t\tconst coalescedMetric = coalescedMetrics[id];\n\t\t\t\tconst formattedMetrics = Object.keys(coalescedMetrics[id]).reduce((metric, node) => {\n\t\t\t\t\tmetric[node] = coalescedMetric[node].toFixed(2);\n\t\t\t\t\treturn metric;\n\t\t\t\t}, {} as FormattedMetric);\n\t\t\t\treturn { id: numericalId, ...formattedMetrics };\n\t\t\t});\n\t\t}\n\t}, [metrics, metricConfig]);\n\n\tconst nodes = useMemo(() => {\n\t\treturn Array.from(new Set<string>(metrics?.map((m) => m.node)));\n\t}, [metrics]);\n\n\tconst formatTime = (ts: number) => {\n\t\tconst date = new Date(ts);\n\t\treturn date.toLocaleDateString(undefined, {\n\t\t\tmonth: '2-digit',\n\t\t\tday: '2-digit',\n\t\t\thour: '2-digit',\n\t\t\tminute: '2-digit',\n\t\t\thour12: false,\n\t\t});\n\t};\n\n\tif (nodeMetrics && nodeMetrics.length > 0) {\n\t\treturn (\n\t\t\t<ResponsiveContainer width=\"100%\" height={600} className=\"mt-8\">\n\t\t\t\t<LineChart width={600} height={300} data={nodeMetrics}>\n\t\t\t\t\t{nodes.map((node, i) => {\n\t\t\t\t\t\tlet metricDifferentiator = metricConfig.name;\n\t\t\t\t\t\tif (metricConfig.path) {\n\t\t\t\t\t\t\tmetricDifferentiator += '.' + metricConfig.path;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst key = metricDifferentiator + '.' + node;\n\t\t\t\t\t\treturn <Line key={key} name={node} dataKey={node} stroke={Object.values(harperPalette)[i]} />;\n\t\t\t\t\t})}\n\t\t\t\t\t<XAxis dataKey={(item) => formatTime(item.id)} />\n\t\t\t\t\t<YAxis unit={` ${yAxisUnits}`} width={100} />\n\t\t\t\t\t<Legend />\n\t\t\t\t\t<Tooltip />\n\t\t\t\t</LineChart>\n\t\t\t</ResponsiveContainer>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"mt-8 h-[600px]\">\n\t\t\t<p>No {metricConfig.name} data for this time period</p>\n\t\t</div>\n\t);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\nexport const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n","import { useIsomorphicLayoutEffect } from '@/hooks/useIsomorphicLayoutEffect';\nimport { useEffect, useRef } from 'react';\n\nexport function useInterval(callback: () => void, delay: number | null) {\n\tconst savedCallback = useRef(callback);\n\n\tuseIsomorphicLayoutEffect(() => {\n\t\tsavedCallback.current = callback;\n\t}, [callback]);\n\n\tuseEffect(() => {\n\t\tif (delay === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst id = setInterval(() => {\n\t\t\tsavedCallback.current();\n\t\t}, delay);\n\n\t\treturn () => {\n\t\t\tclearInterval(id);\n\t\t};\n\t}, [delay]);\n}\n","import { Label } from '@/components/ui/label.tsx';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select.tsx';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport { MetricVisualization } from '@/features/instance/status/components/monitoring/MetricVisualization.tsx';\nimport { useInterval } from '@/hooks/useInterval.ts';\nimport type { Metric, MetricConfig } from '@/integrations/api/instance/status/getAnalytics.ts';\nimport { useMemo, useState } from 'react';\n\nconst metrics: MetricConfig[] = [\n\t{\n\t\tid: 'db-read',\n\t\tname: 'db-read',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'reads',\n\t},\n\t{\n\t\tid: 'db-read-bytes',\n\t\tlabel: 'db-read-bytes',\n\t\tname: 'db-read',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'db-write',\n\t\tname: 'db-write',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'writes',\n\t},\n\t{\n\t\tid: 'db-write-bytes',\n\t\tlabel: 'db-write-bytes',\n\t\tname: 'db-write',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'db-message',\n\t\tname: 'db-message',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'messages',\n\t},\n\t{\n\t\tid: 'db-message-bytes',\n\t\tlabel: 'db-message-bytes',\n\t\tname: 'db-message',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'cpu-usage-user',\n\t\tname: 'cpu-usage',\n\t\tpath: 'user',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'secs',\n\t},\n\t{\n\t\tid: 'cpu-usage-harper',\n\t\tname: 'cpu-usage',\n\t\tpath: 'harper',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'secs',\n\t},\n];\n\nfunction metricSum(metric: Metric) {\n\tif (metric.mean && metric.count) {\n\t\treturn metric.mean * metric.count;\n\t}\n\treturn 0;\n}\n\nfunction aggregateSum(accumulator: number, current: number) {\n\treturn accumulator + current;\n}\n\ninterface TimeSelectOption {\n\tlabel: string;\n\tvalue: number;\n\tdefault?: boolean;\n}\ntype TimeSelectOptions = TimeSelectOption[];\n\nconst windowOptions: TimeSelectOptions = [\n\t{ label: '10 mins', value: 10 * 60_000 },\n\t{ label: 'hour', value: 60 * 60_000, default: true },\n\t{ label: '6 hours', value: 6 * 60 * 60_000 },\n\t{ label: 'day', value: 24 * 60 * 60_000 },\n];\n\nconst intervalOptions: TimeSelectOptions = [\n\t{ label: '15 secs', value: 15_000 },\n\t{ label: '30 secs', value: 30_000 },\n\t{ label: 'minute', value: 60_000, default: true },\n\t{ label: '5 mins', value: 5 * 60_000 },\n\t{ label: '15 mins', value: 15 * 60_000 },\n];\n\ninterface MonitoringParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function Monitoring({ instanceParams }: MonitoringParams) {\n\tconst [selectedMetric, setSelectedMetric] = useState(metrics[0]);\n\n\tconst [updateInterval, setUpdateInterval] = useState(intervalOptions.find((o) => o.default)!);\n\tconst [endTime, setEndTime] = useState(Date.now);\n\n\tconst [timeWindow, setTimeWindow] = useState(windowOptions.find((o) => o.default)!);\n\n\tuseInterval(() => {\n\t\tsetEndTime(Date.now);\n\t}, updateInterval.value);\n\n\tconst startTime = useMemo(() => endTime - timeWindow.value, [endTime, timeWindow]);\n\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"flex justify-between\">\n\t\t\t\t<div className=\"justify-items-end grid grid-cols-1 lg:grid-cols-3 gap-4\">\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Metric:</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={selectedMetric.id}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetSelectedMetric(metrics.find((m) => m.id === value) || metrics[0]);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{metrics.map((m) => {\n\t\t\t\t\t\t\t\t\t\tlet itemLabel = m.label ?? m.name;\n\t\t\t\t\t\t\t\t\t\tif (m.path) {\n\t\t\t\t\t\t\t\t\t\t\titemLabel += ` (${m.path})`;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={m.id} value={m.id}>{itemLabel}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Show last</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={timeWindow.value.toString()}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetTimeWindow(windowOptions.find((o) => o.value === Number(value))!);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{windowOptions.map((o) => {\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={o.value} value={o.value.toString()}>{o.label}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Update every</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={updateInterval.value.toString()}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetUpdateInterval(intervalOptions.find((o) => o.value === Number(value))!);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{intervalOptions.map((o) => {\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={o.value} value={o.value.toString()}>{o.label}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<MetricVisualization\n\t\t\t\tmetricConfig={selectedMetric}\n\t\t\t\tstartTime={startTime}\n\t\t\t\tendTime={endTime}\n\t\t\t\tinstanceParams={instanceParams}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface SystemInformationResponse {\n\tsystem: {\n\t\tplatform: 'darwin' | 'linux' | string;\n\t\tdistro: 'macOS' | 'Debian GNU/Linux' | string;\n\t\trelease: string;\n\t\tcodename: string;\n\t\tkernel: string;\n\t\tarch: 'arm64' | 'x64' | string;\n\t\thostname: string;\n\t\tfqdn: string;\n\t\tnode_version: string;\n\t\tnpm_version: string;\n\t};\n\tcpu: {\n\t\tmanufacturer: 'Apple' | 'AMD' | string;\n\t\tbrand: 'M4' | string;\n\t\tvendor: 'Apple' | 'AMD' | string;\n\t\tspeed: number;\n\t\tspeedMin: number;\n\t\tspeedMax: number;\n\t\tcores: number;\n\t\tphysicalCores: number;\n\t\tperformanceCores: number;\n\t\tefficiencyCores: number;\n\t\tprocessors: number;\n\t\tflags: string;\n\t\tvirtualization: boolean;\n\t\tcpu_speed: {\n\t\t\tmin: number;\n\t\t\tmax: number;\n\t\t\tavg: number;\n\t\t\tcores: number[];\n\t\t};\n\t\tcurrent_load: {\n\t\t\tavgLoad: number;\n\t\t\tcurrentLoad: number;\n\t\t\tcurrentLoadUser: number;\n\t\t\tcurrentLoadSystem: number;\n\t\t\tcurrentLoadNice: number;\n\t\t\tcurrentLoadIdle: number;\n\t\t\tcurrentLoadIrq: number;\n\t\t\tcurrentLoadSteal: number;\n\t\t\tcurrentLoadGuest: number;\n\t\t\trawCurrentLoad: number;\n\t\t\trawCurrentLoadUser: number;\n\t\t\trawCurrentLoadSystem: number;\n\t\t\trawCurrentLoadNice: number;\n\t\t\trawCurrentLoadIdle: number;\n\t\t\trawCurrentLoadIrq: number;\n\t\t\trawCurrentLoadSteal: number;\n\t\t\trawCurrentLoadGuest: number;\n\t\t\tcpus: Array<{\n\t\t\t\tload: number;\n\t\t\t\tloadUser: number;\n\t\t\t\tloadSystem: number;\n\t\t\t\tloadNice: number;\n\t\t\t\tloadIdle: number;\n\t\t\t\tloadIrq: number;\n\t\t\t\tloadSteal: number;\n\t\t\t\tloadGuest: number;\n\t\t\t\trawLoadSteal: number;\n\t\t\t\trawLoadGuest: number;\n\t\t\t}>;\n\t\t};\n\t};\n\tmemory: {\n\t\ttotal: number;\n\t\tfree: number;\n\t\tused: number;\n\t\tactive: number;\n\t\tavailable: number;\n\t\treclaimable: number;\n\t\tswaptotal: number;\n\t\tswapused: number;\n\t\tswapfree: number;\n\t\twriteback: unknown;\n\t\tdirty: unknown;\n\t\trss: number;\n\t\theapTotal: number;\n\t\theapUsed: number;\n\t\texternal: number;\n\t\tarrayBuffers: number;\n\t};\n\tdisk: Record<string, unknown>;\n\tnetwork: {\n\t\tdefault_interface: unknown;\n\t\tlatency: Record<string, unknown>;\n\t\tinterfaces: Array<Record<string, unknown>>;\n\t\tstats: Array<Record<string, unknown>>;\n\t\tconnections: Array<Record<string, unknown>>;\n\t};\n\n\t[key: string]: unknown;\n}\n\nexport function getSystemInformationQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'system_information'] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.post<SystemInformationResponse>('/', {\n\t\t\t\toperation: 'system_information',\n\t\t\t\tattributes: ['network', 'disk', 'cpu', 'memory', 'system'],\n\t\t\t});\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { Status } from '@/features/instance/status/Status';\nimport { getSystemInformationQueryOptions } from '@/integrations/api/instance/status/getSystemInformation';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Suspense } from 'react';\n\ninterface LocalStatusParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function LocalStatus({ instanceParams }: LocalStatusParams) {\n\tconst { data } = useSuspenseQuery(getSystemInformationQueryOptions(instanceParams));\n\n\treturn (\n\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t<Status data={data} />\n\t\t</Suspense>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient.tsx';\nimport { CloudStatus } from '@/features/instance/status/CloudStatus';\nimport { Monitoring } from '@/features/instance/status/components/Monitoring.tsx';\nimport { LocalStatus } from '@/features/instance/status/LocalStatus';\n\nexport function StatusIndex() {\n\tconst instanceParams = useInstanceClientIdParams();\n\n\treturn (\n\t\t<div className=\"px-4 py-2 flex flex-col\">\n\t\t\t<div className=\"mb-12\">\n\t\t\t\t<Monitoring instanceParams={instanceParams} />\n\t\t\t</div>\n\t\t\t{isLocalStudio\n\t\t\t\t? <LocalStatus instanceParams={instanceParams} />\n\t\t\t\t: <CloudStatus instanceParams={instanceParams} />}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"status-CoGlcjSB.js","names":[],"sources":["../../src/features/instance/status/crawlData.ts","../../src/features/instance/status/Status.tsx","../../src/features/instance/status/CloudStatus.tsx","../../src/integrations/api/instance/status/getAnalytics.ts","../../src/lib/colorPalette.ts","../../src/features/instance/status/components/monitoring/MetricVisualization.tsx","../../src/hooks/useIsomorphicLayoutEffect.ts","../../src/hooks/useInterval.ts","../../src/features/instance/status/components/Monitoring.tsx","../../src/integrations/api/instance/status/getSystemInformation.ts","../../src/features/instance/status/LocalStatus.tsx","../../src/features/instance/status/index.tsx"],"sourcesContent":["import { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { humanFileSize } from '@/lib/humanFileSize';\nimport { translateSecondsToAgo } from '@/lib/translateSecondsToAgo';\n\nconst startOf2025 = new Date(2025, 0).getTime();\nconst oneDayInMs = 24 * 60 * 60 * 1000;\n\ninterface TitleItem {\n\ttitle: string;\n\tdepth: number;\n}\n\ninterface NameValuePairItem {\n\tname: string;\n\tvalue: string;\n\tdepth: number;\n}\n\ntype ItemForDisplay = TitleItem | NameValuePairItem;\n\nexport function crawlData(data: Record<string, unknown>): ItemForDisplay[] {\n\tconst sections: ItemForDisplay[] = [];\n\tfor (const key in data) {\n\t\tconst value = data[key];\n\t\tsections.push(...parseValue(key, value, 0));\n\t}\n\treturn sections;\n}\n\nexport function hasTitle(item: ItemForDisplay): item is TitleItem {\n\treturn !!(item as TitleItem).title;\n}\n\nfunction parseValue(name: string, value: unknown, depth: number, parentName?: string): ItemForDisplay[] {\n\tif (value && Array.isArray(value)) {\n\t\tconst array = value;\n\t\treturn [\n\t\t\tarray.length > 1 && { title: name, depth },\n\t\t\t...value.map((item, index) =>\n\t\t\t\tparseValue(\n\t\t\t\t\tarray.length > 1 ? String(index + 1) : name,\n\t\t\t\t\titem,\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tname,\n\t\t\t\t)\n\t\t\t).flat(1),\n\t\t].filter(excludeFalsy);\n\t}\n\tif (isObject(value)) {\n\t\tconst obj = value;\n\t\treturn [\n\t\t\t{ title: name, depth },\n\t\t\t...Object.keys(value).map(subKey =>\n\t\t\t\tparseValue(\n\t\t\t\t\tString(subKey),\n\t\t\t\t\tobj[subKey],\n\t\t\t\t\tdepth + 1,\n\t\t\t\t\tname,\n\t\t\t\t)\n\t\t\t).flat(1),\n\t\t];\n\t}\n\tif (name === '__updatedtime__' || name === '__createdtime__') {\n\t\tname = name.replace(/_/g, '').replace('time', '');\n\t}\n\tif (typeof value === 'number') {\n\t\tif (value > startOf2025 && value < Date.now() + oneDayInMs) {\n\t\t\tconst elapsed = Date.now() - value;\n\t\t\tvalue = translateSecondsToAgo(elapsed, value);\n\t\t} else if (parentName === 'memory') {\n\t\t\tvalue = humanFileSize(value);\n\t\t} else if (!name.startsWith('raw') && name.toLowerCase().includes('load')) {\n\t\t\tvalue = Math.round(value * 10) / 10 + '%';\n\t\t}\n\t} else if (typeof value === 'boolean') {\n\t\tvalue = value ? 'Yes' : 'No';\n\t}\n\treturn [\n\t\t{ name, value: String(value), depth },\n\t];\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn !!value && typeof value === 'object';\n}\n","import { crawlData, hasTitle } from '@/features/instance/status/crawlData';\nimport { cn } from '@/lib/cn';\nimport { useMemo } from 'react';\n\nexport function Status({ data }: { data: Record<string, unknown> }) {\n\tconst items = useMemo(() => crawlData(data), [data]);\n\treturn (\n\t\t<div className=\"max-w-96 grid mb-12\">\n\t\t\t{items.map((item, index) =>\n\t\t\t\thasTitle(item)\n\t\t\t\t\t? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\tclassName={cn('font-semibold text-xl', index !== 0 && 'mt-4')}\n\t\t\t\t\t\t\tstyle={{ paddingLeft: item.depth * 12 + 'px' }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{item.title}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<div key={index} style={{ paddingLeft: item.depth * 12 + 'px' }}>\n\t\t\t\t\t\t\t<span className=\"text-muted-foreground\">{item.name}:</span>\n\t\t\t\t\t\t\t{item.value}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport { Status } from '@/features/instance/status/Status';\nimport { getStatusQueryOptions } from '@/integrations/api/instance/status/getStatus';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Suspense } from 'react';\n\ninterface CloudStatusParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function CloudStatus({ instanceParams }: CloudStatusParams) {\n\tconst { data } = useSuspenseQuery(getStatusQueryOptions(instanceParams));\n\n\treturn (\n\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t<Status data={data} />\n\t\t</Suspense>\n\t);\n}\n","import type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport type { Units } from '@/lib/units';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport type MetricDataKey = string | ((metric: Metric) => number);\nexport type MetricUnits = Units | 'reads' | 'writes' | 'messages';\nexport interface MetricConfig {\n\tid: string;\n\tname: string;\n\tlabel?: string;\n\tdataKey: MetricDataKey;\n\taggregator: (accumulator: number, current: number) => number;\n\tunits: MetricUnits;\n\tpath?: string;\n}\n\ninterface GetAnalyticsParams {\n\tmetricConfig: MetricConfig;\n\tstartTime: number;\n\tendTime: number;\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\ninterface GetAnalyticsRequest {\n\toperation: 'get_analytics';\n\tmetric: string;\n\tstart_time: number;\n\tend_time: number;\n\tconditions?: {\n\t\tattribute: string;\n\t\tvalue: string | number | boolean;\n\t\tcomparator?: string;\n\t}[];\n}\n\nexport interface Metric {\n\tid: number;\n\tmetric: string;\n\tcount: number;\n\tmean: number;\n\tperiod: number;\n\tnode: string;\n\t[key: string]: string | number | boolean | null;\n}\n\ntype GetAnalyticsResponse = Metric[];\n\nexport function getAnalyticsQueryOptions({ metricConfig, startTime, endTime, instanceParams }: GetAnalyticsParams) {\n\treturn queryOptions({\n\t\tqueryKey: ['get_analytics', metricConfig.name, metricConfig.path, startTime, endTime] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst req: GetAnalyticsRequest = {\n\t\t\t\toperation: 'get_analytics',\n\t\t\t\tmetric: metricConfig.name,\n\t\t\t\tstart_time: startTime,\n\t\t\t\tend_time: endTime,\n\t\t\t};\n\t\t\tif (metricConfig.path) {\n\t\t\t\treq.conditions = [{ attribute: 'path', value: metricConfig.path }];\n\t\t\t}\n\t\t\tconst { data } = await instanceParams.instanceClient.post<GetAnalyticsResponse>('/', req);\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","export const harperPalette = {\n\t'persistence-purple': '#403B8A',\n\t'b-tree-green': '#55C58F',\n\t'cyber-grape': '#7A3A87',\n\t'quantum-purple': '#312556',\n\t'cloud-white': '#F5F5F5',\n\t'acid-magenta': '#C63368',\n\t'edge-gray': '#383D40',\n};\n","import type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport {\n\tgetAnalyticsQueryOptions,\n\ttype Metric,\n\ttype MetricConfig,\n\ttype MetricDataKey,\n\ttype MetricUnits,\n} from '@/integrations/api/instance/status/getAnalytics.ts';\nimport { harperPalette } from '@/lib/colorPalette.ts';\nimport { determineUnits, scaleValueToUnits } from '@/lib/units';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMemo, useState } from 'react';\nimport { Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';\n\ntype MetricValue = string | number | boolean;\ntype NullableMetricValue = MetricValue | null;\ntype NullableMetric = { [key: string]: NullableMetricValue };\ntype NodeMetric = { [node: string]: number };\ntype CoalescedMetrics = { [id: string]: NodeMetric };\ntype FormattedMetric = { [node: string]: string };\n\ninterface MetricVisualizationParams {\n\tmetricConfig: MetricConfig;\n\tstartTime: number;\n\tendTime: number;\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nfunction resolveMetricDataKey(\n\tmetric: Metric,\n\tdataKey: MetricDataKey,\n\tbaseUnits: MetricUnits,\n\tconversionUnits?: string,\n) {\n\tlet baseValue;\n\tif (typeof dataKey === 'string') {\n\t\tbaseValue = metric[dataKey] as number ?? 0;\n\t} else {\n\t\tbaseValue = dataKey(metric);\n\t}\n\n\tif (conversionUnits) {\n\t\treturn scaleValueToUnits(baseValue, baseUnits, conversionUnits);\n\t}\n\n\treturn baseValue;\n}\n\nexport function MetricVisualization({ metricConfig, startTime, endTime, instanceParams }: MetricVisualizationParams) {\n\tconst { data } = useQuery(getAnalyticsQueryOptions({ instanceParams, metricConfig, startTime, endTime }));\n\tconst metrics = useMemo(() => {\n\t\treturn data?.reduce((ms: Metric[], m: NullableMetric) => {\n\t\t\tconst newMetric: Metric = { metric: '', node: '', id: 0, period: 0, count: 0, mean: 0 };\n\t\t\tfor (const k in m) {\n\t\t\t\tif (m[k] !== null) {\n\t\t\t\t\tnewMetric[k] = m[k];\n\t\t\t\t}\n\t\t\t}\n\t\t\tms.push(newMetric);\n\t\t\treturn ms;\n\t\t}, []);\n\t}, [data]);\n\n\tconst [yAxisUnits, setYAxisUnits] = useState<string>(metricConfig.units);\n\n\tconst nodeMetrics = useMemo(() => {\n\t\tconst coalescedMetrics: CoalescedMetrics = {};\n\t\tconst { dataKey, aggregator, units } = metricConfig;\n\t\tlet conversionUnits = units as string;\n\n\t\tif (metrics && metrics.length > 0) {\n\t\t\tconst maxDataValue = Math.max(...metrics.map((m) => resolveMetricDataKey(m, dataKey, units)));\n\t\t\tconversionUnits = determineUnits(units, maxDataValue);\n\t\t\t// We set the y-axis based on the max of the metrics, and we were careful to avoid a circular dependency.\n\t\t\t// So ignoring the set-state-in-render is safe, in this case.\n\t\t\t// eslint-disable-next-line react-hooks/set-state-in-render\n\t\t\tsetYAxisUnits(conversionUnits);\n\n\t\t\tfor (const metric of metrics) {\n\t\t\t\tconst coalescedTime = Math.floor(metric.id / metric.period) * metric.period;\n\t\t\t\tconst resolvedMetric = resolveMetricDataKey(metric, dataKey, units, conversionUnits);\n\n\t\t\t\tif (coalescedMetrics[coalescedTime]) {\n\t\t\t\t\tif (metric.node in coalescedMetrics[coalescedTime]) {\n\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node] = aggregator(\n\t\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node],\n\t\t\t\t\t\t\tresolvedMetric,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcoalescedMetrics[coalescedTime][metric.node] = resolvedMetric;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcoalescedMetrics[coalescedTime] = { [metric.node]: resolvedMetric };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn Object.keys(coalescedMetrics).map((id: string) => {\n\t\t\t\tconst numericalId = Number.parseInt(id);\n\t\t\t\tconst coalescedMetric = coalescedMetrics[id];\n\t\t\t\tconst formattedMetrics = Object.keys(coalescedMetrics[id]).reduce((metric, node) => {\n\t\t\t\t\tmetric[node] = coalescedMetric[node].toFixed(2);\n\t\t\t\t\treturn metric;\n\t\t\t\t}, {} as FormattedMetric);\n\t\t\t\treturn { id: numericalId, ...formattedMetrics };\n\t\t\t});\n\t\t}\n\t}, [metrics, metricConfig]);\n\n\tconst nodes = useMemo(() => {\n\t\treturn Array.from(new Set<string>(metrics?.map((m) => m.node)));\n\t}, [metrics]);\n\n\tconst formatTime = (ts: number) => {\n\t\tconst date = new Date(ts);\n\t\treturn date.toLocaleDateString(undefined, {\n\t\t\tmonth: '2-digit',\n\t\t\tday: '2-digit',\n\t\t\thour: '2-digit',\n\t\t\tminute: '2-digit',\n\t\t\thour12: false,\n\t\t});\n\t};\n\n\tif (nodeMetrics && nodeMetrics.length > 0) {\n\t\treturn (\n\t\t\t<ResponsiveContainer width=\"100%\" height={600} className=\"mt-8\">\n\t\t\t\t<LineChart width={600} height={300} data={nodeMetrics}>\n\t\t\t\t\t{nodes.map((node, i) => {\n\t\t\t\t\t\tlet metricDifferentiator = metricConfig.name;\n\t\t\t\t\t\tif (metricConfig.path) {\n\t\t\t\t\t\t\tmetricDifferentiator += '.' + metricConfig.path;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst key = metricDifferentiator + '.' + node;\n\t\t\t\t\t\treturn <Line key={key} name={node} dataKey={node} stroke={Object.values(harperPalette)[i]} />;\n\t\t\t\t\t})}\n\t\t\t\t\t<XAxis dataKey={(item) => formatTime(item.id)} />\n\t\t\t\t\t<YAxis unit={` ${yAxisUnits}`} width={100} />\n\t\t\t\t\t<Legend />\n\t\t\t\t\t<Tooltip />\n\t\t\t\t</LineChart>\n\t\t\t</ResponsiveContainer>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"mt-8 h-[600px]\">\n\t\t\t<p>No {metricConfig.name} data for this time period</p>\n\t\t</div>\n\t);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\nexport const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n","import { useIsomorphicLayoutEffect } from '@/hooks/useIsomorphicLayoutEffect';\nimport { useEffect, useRef } from 'react';\n\nexport function useInterval(callback: () => void, delay: number | null) {\n\tconst savedCallback = useRef(callback);\n\n\tuseIsomorphicLayoutEffect(() => {\n\t\tsavedCallback.current = callback;\n\t}, [callback]);\n\n\tuseEffect(() => {\n\t\tif (delay === null) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst id = setInterval(() => {\n\t\t\tsavedCallback.current();\n\t\t}, delay);\n\n\t\treturn () => {\n\t\t\tclearInterval(id);\n\t\t};\n\t}, [delay]);\n}\n","import { Label } from '@/components/ui/label.tsx';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select.tsx';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig.ts';\nimport { MetricVisualization } from '@/features/instance/status/components/monitoring/MetricVisualization.tsx';\nimport { useInterval } from '@/hooks/useInterval.ts';\nimport type { Metric, MetricConfig } from '@/integrations/api/instance/status/getAnalytics.ts';\nimport { useMemo, useState } from 'react';\n\nconst metrics: MetricConfig[] = [\n\t{\n\t\tid: 'db-read',\n\t\tname: 'db-read',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'reads',\n\t},\n\t{\n\t\tid: 'db-read-bytes',\n\t\tlabel: 'db-read-bytes',\n\t\tname: 'db-read',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'db-write',\n\t\tname: 'db-write',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'writes',\n\t},\n\t{\n\t\tid: 'db-write-bytes',\n\t\tlabel: 'db-write-bytes',\n\t\tname: 'db-write',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'db-message',\n\t\tname: 'db-message',\n\t\tdataKey: 'count',\n\t\taggregator: aggregateSum,\n\t\tunits: 'messages',\n\t},\n\t{\n\t\tid: 'db-message-bytes',\n\t\tlabel: 'db-message-bytes',\n\t\tname: 'db-message',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'bytes',\n\t},\n\t{\n\t\tid: 'cpu-usage-user',\n\t\tname: 'cpu-usage',\n\t\tpath: 'user',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'secs',\n\t},\n\t{\n\t\tid: 'cpu-usage-harper',\n\t\tname: 'cpu-usage',\n\t\tpath: 'harper',\n\t\tdataKey: metricSum,\n\t\taggregator: aggregateSum,\n\t\tunits: 'secs',\n\t},\n];\n\nfunction metricSum(metric: Metric) {\n\tif (metric.mean && metric.count) {\n\t\treturn metric.mean * metric.count;\n\t}\n\treturn 0;\n}\n\nfunction aggregateSum(accumulator: number, current: number) {\n\treturn accumulator + current;\n}\n\ninterface TimeSelectOption {\n\tlabel: string;\n\tvalue: number;\n\tdefault?: boolean;\n}\ntype TimeSelectOptions = TimeSelectOption[];\n\nconst windowOptions: TimeSelectOptions = [\n\t{ label: '10 mins', value: 10 * 60_000 },\n\t{ label: 'hour', value: 60 * 60_000, default: true },\n\t{ label: '6 hours', value: 6 * 60 * 60_000 },\n\t{ label: 'day', value: 24 * 60 * 60_000 },\n];\n\nconst intervalOptions: TimeSelectOptions = [\n\t{ label: '15 secs', value: 15_000 },\n\t{ label: '30 secs', value: 30_000 },\n\t{ label: 'minute', value: 60_000, default: true },\n\t{ label: '5 mins', value: 5 * 60_000 },\n\t{ label: '15 mins', value: 15 * 60_000 },\n];\n\ninterface MonitoringParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function Monitoring({ instanceParams }: MonitoringParams) {\n\tconst [selectedMetric, setSelectedMetric] = useState(metrics[0]);\n\n\tconst [updateInterval, setUpdateInterval] = useState(intervalOptions.find((o) => o.default)!);\n\tconst [endTime, setEndTime] = useState(Date.now);\n\n\tconst [timeWindow, setTimeWindow] = useState(windowOptions.find((o) => o.default)!);\n\n\tuseInterval(() => {\n\t\tsetEndTime(Date.now);\n\t}, updateInterval.value);\n\n\tconst startTime = useMemo(() => endTime - timeWindow.value, [endTime, timeWindow]);\n\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"flex justify-between\">\n\t\t\t\t<div className=\"justify-items-end grid grid-cols-1 lg:grid-cols-3 gap-4\">\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Metric:</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={selectedMetric.id}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetSelectedMetric(metrics.find((m) => m.id === value) || metrics[0]);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{metrics.map((m) => {\n\t\t\t\t\t\t\t\t\t\tlet itemLabel = m.label ?? m.name;\n\t\t\t\t\t\t\t\t\t\tif (m.path) {\n\t\t\t\t\t\t\t\t\t\t\titemLabel += ` (${m.path})`;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={m.id} value={m.id}>{itemLabel}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Show last</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={timeWindow.value.toString()}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetTimeWindow(windowOptions.find((o) => o.value === Number(value))!);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{windowOptions.map((o) => {\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={o.value} value={o.value.toString()}>{o.label}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-nowrap items-center\">\n\t\t\t\t\t\t<Label className=\"ml-8 mr-2\">Update every</Label>\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tdefaultValue={updateInterval.value.toString()}\n\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\tsetUpdateInterval(intervalOptions.find((o) => o.value === Number(value))!);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"inline-flex align-middle w-auto h-auto\">\n\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{intervalOptions.map((o) => {\n\t\t\t\t\t\t\t\t\t\treturn <SelectItem key={o.value} value={o.value.toString()}>{o.label}</SelectItem>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<MetricVisualization\n\t\t\t\tmetricConfig={selectedMetric}\n\t\t\t\tstartTime={startTime}\n\t\t\t\tendTime={endTime}\n\t\t\t\tinstanceParams={instanceParams}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface SystemInformationResponse {\n\tsystem: {\n\t\tplatform: 'darwin' | 'linux' | string;\n\t\tdistro: 'macOS' | 'Debian GNU/Linux' | string;\n\t\trelease: string;\n\t\tcodename: string;\n\t\tkernel: string;\n\t\tarch: 'arm64' | 'x64' | string;\n\t\thostname: string;\n\t\tfqdn: string;\n\t\tnode_version: string;\n\t\tnpm_version: string;\n\t};\n\tcpu: {\n\t\tmanufacturer: 'Apple' | 'AMD' | string;\n\t\tbrand: 'M4' | string;\n\t\tvendor: 'Apple' | 'AMD' | string;\n\t\tspeed: number;\n\t\tspeedMin: number;\n\t\tspeedMax: number;\n\t\tcores: number;\n\t\tphysicalCores: number;\n\t\tperformanceCores: number;\n\t\tefficiencyCores: number;\n\t\tprocessors: number;\n\t\tflags: string;\n\t\tvirtualization: boolean;\n\t\tcpu_speed: {\n\t\t\tmin: number;\n\t\t\tmax: number;\n\t\t\tavg: number;\n\t\t\tcores: number[];\n\t\t};\n\t\tcurrent_load: {\n\t\t\tavgLoad: number;\n\t\t\tcurrentLoad: number;\n\t\t\tcurrentLoadUser: number;\n\t\t\tcurrentLoadSystem: number;\n\t\t\tcurrentLoadNice: number;\n\t\t\tcurrentLoadIdle: number;\n\t\t\tcurrentLoadIrq: number;\n\t\t\tcurrentLoadSteal: number;\n\t\t\tcurrentLoadGuest: number;\n\t\t\trawCurrentLoad: number;\n\t\t\trawCurrentLoadUser: number;\n\t\t\trawCurrentLoadSystem: number;\n\t\t\trawCurrentLoadNice: number;\n\t\t\trawCurrentLoadIdle: number;\n\t\t\trawCurrentLoadIrq: number;\n\t\t\trawCurrentLoadSteal: number;\n\t\t\trawCurrentLoadGuest: number;\n\t\t\tcpus: Array<{\n\t\t\t\tload: number;\n\t\t\t\tloadUser: number;\n\t\t\t\tloadSystem: number;\n\t\t\t\tloadNice: number;\n\t\t\t\tloadIdle: number;\n\t\t\t\tloadIrq: number;\n\t\t\t\tloadSteal: number;\n\t\t\t\tloadGuest: number;\n\t\t\t\trawLoadSteal: number;\n\t\t\t\trawLoadGuest: number;\n\t\t\t}>;\n\t\t};\n\t};\n\tmemory: {\n\t\ttotal: number;\n\t\tfree: number;\n\t\tused: number;\n\t\tactive: number;\n\t\tavailable: number;\n\t\treclaimable: number;\n\t\tswaptotal: number;\n\t\tswapused: number;\n\t\tswapfree: number;\n\t\twriteback: unknown;\n\t\tdirty: unknown;\n\t\trss: number;\n\t\theapTotal: number;\n\t\theapUsed: number;\n\t\texternal: number;\n\t\tarrayBuffers: number;\n\t};\n\tdisk: Record<string, unknown>;\n\tnetwork: {\n\t\tdefault_interface: unknown;\n\t\tlatency: Record<string, unknown>;\n\t\tinterfaces: Array<Record<string, unknown>>;\n\t\tstats: Array<Record<string, unknown>>;\n\t\tconnections: Array<Record<string, unknown>>;\n\t};\n\n\t[key: string]: unknown;\n}\n\nexport function getSystemInformationQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'system_information'] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.post<SystemInformationResponse>('/', {\n\t\t\t\toperation: 'system_information',\n\t\t\t\tattributes: ['network', 'disk', 'cpu', 'memory', 'system'],\n\t\t\t});\n\t\t\treturn data;\n\t\t},\n\t});\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport type { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { Status } from '@/features/instance/status/Status';\nimport { getSystemInformationQueryOptions } from '@/integrations/api/instance/status/getSystemInformation';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Suspense } from 'react';\n\ninterface LocalStatusParams {\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}\n\nexport function LocalStatus({ instanceParams }: LocalStatusParams) {\n\tconst { data } = useSuspenseQuery(getSystemInformationQueryOptions(instanceParams));\n\n\treturn (\n\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t<Status data={data} />\n\t\t</Suspense>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient.tsx';\nimport { CloudStatus } from '@/features/instance/status/CloudStatus';\nimport { Monitoring } from '@/features/instance/status/components/Monitoring.tsx';\nimport { LocalStatus } from '@/features/instance/status/LocalStatus';\n\nexport function StatusIndex() {\n\tconst instanceParams = useInstanceClientIdParams();\n\n\treturn (\n\t\t<div className=\"px-4 py-2 flex flex-col\">\n\t\t\t<div className=\"mb-12\">\n\t\t\t\t<Monitoring instanceParams={instanceParams} />\n\t\t\t</div>\n\t\t\t{isLocalStudio\n\t\t\t\t? <LocalStatus instanceParams={instanceParams} />\n\t\t\t\t: <CloudStatus instanceParams={instanceParams} />}\n\t\t</div>\n\t);\n}\n"],"mappings":"2ZAIA,IAAM,EAAc,IAAI,KAAK,KAAM,EAAE,CAAC,SAAS,CACzC,EAAa,KAAU,GAAK,IAelC,SAAgB,EAAU,EAAiD,CAC1E,IAAM,EAA6B,EAAE,CACrC,IAAK,IAAM,KAAO,EAAM,CACvB,IAAM,EAAQ,EAAK,GACnB,EAAS,KAAK,GAAG,EAAW,EAAK,EAAO,EAAE,CAAC,CAE5C,OAAO,EAGR,SAAgB,EAAS,EAAyC,CACjE,MAAO,CAAC,CAAE,EAAmB,MAG9B,SAAS,EAAW,EAAc,EAAgB,EAAe,EAAuC,CACvG,GAAI,GAAS,MAAM,QAAQ,EAAM,CAAE,CAClC,IAAM,EAAQ,EACd,MAAO,CACN,EAAM,OAAS,GAAK,CAAE,MAAO,EAAM,QAAO,CAC1C,GAAG,EAAM,KAAK,EAAM,IACnB,EACC,EAAM,OAAS,EAAI,OAAO,EAAQ,EAAE,CAAG,EACvC,EACA,EAAQ,EACR,EACA,CACD,CAAC,KAAK,EAAE,CACT,CAAC,OAAO,EAAa,CAEvB,GAAI,EAAS,EAAM,CAAE,CACpB,IAAM,EAAM,EACZ,MAAO,CACN,CAAE,MAAO,EAAM,QAAO,CACtB,GAAG,OAAO,KAAK,EAAM,CAAC,IAAI,GACzB,EACC,OAAO,EAAO,CACd,EAAI,GACJ,EAAQ,EACR,EACA,CACD,CAAC,KAAK,EAAE,CACT,CAiBF,OAfI,IAAS,mBAAqB,IAAS,qBAC1C,EAAO,EAAK,QAAQ,KAAM,GAAG,CAAC,QAAQ,OAAQ,GAAG,EAE9C,OAAO,GAAU,SAChB,EAAQ,GAAe,EAAQ,KAAK,KAAK,CAAG,EAE/C,EAAQ,EADQ,KAAK,KAAK,CAAG,EACU,EAAM,CACnC,IAAe,SACzB,EAAQ,EAAc,EAAM,CAClB,CAAC,EAAK,WAAW,MAAM,EAAI,EAAK,aAAa,CAAC,SAAS,OAAO,GACxE,EAAQ,KAAK,MAAM,EAAQ,GAAG,CAAG,GAAK,KAE7B,OAAO,GAAU,YAC3B,EAAQ,EAAQ,MAAQ,MAElB,CACN,CAAE,OAAM,MAAO,OAAO,EAAM,CAAE,QAAO,CACrC,CAGF,SAAS,EAAS,EAAkD,CACnE,MAAO,CAAC,CAAC,GAAS,OAAO,GAAU,8BC/EpC,SAAgB,EAAO,CAAE,QAA2C,CAEnE,OAAA,EAAA,EAAA,KACE,MAAD,CAAK,UAAU,iDAFY,EAAU,EAAK,CAAE,CAAC,EAAK,CAAC,CAG3C,KAAK,EAAM,IACjB,EAAS,EAAK,EAAA,EAAA,EAAA,KAEX,MAAD,CAEC,UAAW,EAAG,wBAAyB,IAAU,GAAK,OAAO,CAC7D,MAAO,CAAE,YAAa,EAAK,MAAQ,GAAK,KAAM,UAE7C,EAAK,MACD,CALA,EAKA,EAAA,EAAA,EAAA,MAGL,MAAD,CAAiB,MAAO,CAAE,YAAa,EAAK,MAAQ,GAAK,KAAM,UAA/D,EAAA,EAAA,EAAA,MACE,OAAD,CAAM,UAAU,iCAAhB,CAAyC,EAAK,KAAK,IAAQ,GAC1D,EAAK,MACD,EAHI,EAGJ,CAER,CACI,CAAA,CEqBR,SAAgB,EAAyB,CAAE,eAAc,YAAW,UAAS,kBAAsC,CAClH,OAAO,EAAa,CACnB,SAAU,CAAC,gBAAiB,EAAa,KAAM,EAAa,KAAM,EAAW,EAAQ,CACrF,QAAS,SAAY,CACpB,IAAM,EAA2B,CAChC,UAAW,gBACX,OAAQ,EAAa,KACrB,WAAY,EACZ,SAAU,EACV,CACG,EAAa,OAChB,EAAI,WAAa,CAAC,CAAE,UAAW,OAAQ,MAAO,EAAa,KAAM,CAAC,EAEnE,GAAM,CAAE,QAAS,MAAM,EAAe,eAAe,KAA2B,IAAK,EAAI,CACzF,OAAO,GAER,CAAC,CC/DH,IAAa,EAAgB,CAC5B,qBAAsB,UACtB,eAAgB,UAChB,cAAe,UACf,iBAAkB,UAClB,cAAe,UACf,eAAgB,UAChB,YAAa,UACb,CCoBD,SAAS,EACR,EACA,EACA,EACA,EACC,CACD,IAAI,EAWJ,MAVA,CAGC,EAHG,OAAO,GAAY,SACV,EAAO,IAAsB,EAE7B,EAAQ,EAAO,CAGxB,EACI,EAAkB,EAAW,EAAW,EAAgB,CAGzD,EAGR,SAAgB,EAAoB,CAAE,eAAc,YAAW,UAAS,kBAA6C,CACpH,GAAM,CAAE,QAAS,EAAS,EAAyB,CAAE,iBAAgB,eAAc,YAAW,UAAS,CAAC,CAAC,CACnG,GAAA,EAAA,EAAA,aACE,GAAM,QAAQ,EAAc,IAAsB,CACxD,IAAM,EAAoB,CAAE,OAAQ,GAAI,KAAM,GAAI,GAAI,EAAG,OAAQ,EAAG,MAAO,EAAG,KAAM,EAAG,CACvF,IAAK,IAAM,KAAK,EACX,EAAE,KAAO,OACZ,EAAU,GAAK,EAAE,IAInB,OADA,EAAG,KAAK,EAAU,CACX,GACL,EAAE,CAAC,CACJ,CAAC,EAAK,CAAC,CAEJ,CAAC,EAAY,IAAA,EAAA,EAAA,UAAkC,EAAa,MAAM,CAElE,GAAA,EAAA,EAAA,aAA4B,CACjC,IAAM,EAAqC,EAAE,CACvC,CAAE,UAAS,aAAY,SAAU,EACnC,EAAkB,EAEtB,GAAI,GAAW,EAAQ,OAAS,EAAG,CAElC,EAAkB,EAAe,EADZ,KAAK,IAAI,GAAG,EAAQ,IAAK,GAAM,EAAqB,EAAG,EAAS,EAAM,CAAC,CAAC,CACxC,CAIrD,EAAc,EAAgB,CAE9B,IAAK,IAAM,KAAU,EAAS,CAC7B,IAAM,EAAgB,KAAK,MAAM,EAAO,GAAK,EAAO,OAAO,CAAG,EAAO,OAC/D,EAAiB,EAAqB,EAAQ,EAAS,EAAO,EAAgB,CAEhF,EAAiB,GAChB,EAAO,QAAQ,EAAiB,GACnC,EAAiB,GAAe,EAAO,MAAQ,EAC9C,EAAiB,GAAe,EAAO,MACvC,EACA,CAED,EAAiB,GAAe,EAAO,MAAQ,EAGhD,EAAiB,GAAiB,EAAG,EAAO,MAAO,EAAgB,CAIrE,OAAO,OAAO,KAAK,EAAiB,CAAC,IAAK,GAAe,CACxD,IAAM,EAAc,OAAO,SAAS,EAAG,CACjC,EAAkB,EAAiB,GAKzC,MAAO,CAAE,GAAI,EAAa,GAJD,OAAO,KAAK,EAAiB,GAAI,CAAC,QAAQ,EAAQ,KAC1E,EAAO,GAAQ,EAAgB,GAAM,QAAQ,EAAE,CACxC,GACL,EAAE,CAAoB,CACsB,EAC9C,GAED,CAAC,EAAS,EAAa,CAAC,CAErB,GAAA,EAAA,EAAA,aACE,MAAM,KAAK,IAAI,IAAY,GAAS,IAAK,GAAM,EAAE,KAAK,CAAC,CAAC,CAC7D,CAAC,EAAQ,CAAC,CAEP,EAAc,GACN,IAAI,KAAK,EAAG,CACb,mBAAmB,IAAA,GAAW,CACzC,MAAO,UACP,IAAK,UACL,KAAM,UACN,OAAQ,UACR,OAAQ,GACR,CAAC,CAwBH,OArBI,GAAe,EAAY,OAAS,GACvC,EAAA,EAAA,KACE,EAAD,CAAqB,MAAM,OAAO,OAAQ,IAAK,UAAU,2BACvD,EAAD,CAAW,MAAO,IAAK,OAAQ,IAAK,KAAM,WAA1C,CACE,EAAM,KAAK,EAAM,IAAM,CACvB,IAAI,EAAuB,EAAa,KACpC,EAAa,OAChB,GAAwB,IAAM,EAAa,MAE5C,IAAM,EAAM,EAAuB,IAAM,EACzC,OAAA,EAAA,EAAA,KAAQ,EAAD,CAAgB,KAAM,EAAM,QAAS,EAAM,OAAQ,OAAO,OAAO,EAAc,CAAC,GAAM,CAA3E,EAA2E,EAC5F,WACD,EAAD,CAAO,QAAU,GAAS,EAAW,EAAK,GAAG,CAAI,CAAA,WAChD,EAAD,CAAO,KAAM,IAAI,IAAc,MAAO,IAAO,CAAA,WAC5C,EAAD,EAAU,CAAA,WACT,EAAD,EAAW,CAAA,CACA,GACS,CAAA,EAIxB,EAAA,EAAA,KACE,MAAD,CAAK,UAAU,qCACb,IAAD,CAAA,SAAA,CAAG,MAAI,EAAa,KAAK,6BAA8B,CAAA,CAAA,CAClD,CAAA,CCjJR,IAAa,EAA4B,OAAO,OAAW,IAAc,EAAA,gBAAkB,EAAA,UCC3F,SAAgB,EAAY,EAAsB,EAAsB,CACvE,IAAM,GAAA,EAAA,EAAA,QAAuB,EAAS,CAEtC,MAAgC,CAC/B,EAAc,QAAU,GACtB,CAAC,EAAS,CAAC,EAEd,EAAA,EAAA,eAAgB,CACf,GAAI,IAAU,KACb,OAGD,IAAM,EAAK,gBAAkB,CAC5B,EAAc,SAAS,EACrB,EAAM,CAET,UAAa,CACZ,cAAc,EAAG,GAEhB,CAAC,EAAM,CAAC,CCdZ,IAAM,EAA0B,CAC/B,CACC,GAAI,UACJ,KAAM,UACN,QAAS,QACT,WAAY,EACZ,MAAO,QACP,CACD,CACC,GAAI,gBACJ,MAAO,gBACP,KAAM,UACN,QAAS,EACT,WAAY,EACZ,MAAO,QACP,CACD,CACC,GAAI,WACJ,KAAM,WACN,QAAS,QACT,WAAY,EACZ,MAAO,SACP,CACD,CACC,GAAI,iBACJ,MAAO,iBACP,KAAM,WACN,QAAS,EACT,WAAY,EACZ,MAAO,QACP,CACD,CACC,GAAI,aACJ,KAAM,aACN,QAAS,QACT,WAAY,EACZ,MAAO,WACP,CACD,CACC,GAAI,mBACJ,MAAO,mBACP,KAAM,aACN,QAAS,EACT,WAAY,EACZ,MAAO,QACP,CACD,CACC,GAAI,iBACJ,KAAM,YACN,KAAM,OACN,QAAS,EACT,WAAY,EACZ,MAAO,OACP,CACD,CACC,GAAI,mBACJ,KAAM,YACN,KAAM,SACN,QAAS,EACT,WAAY,EACZ,MAAO,OACP,CACD,CAED,SAAS,EAAU,EAAgB,CAIlC,OAHI,EAAO,MAAQ,EAAO,MAClB,EAAO,KAAO,EAAO,MAEtB,EAGR,SAAS,EAAa,EAAqB,EAAiB,CAC3D,OAAO,EAAc,EAUtB,IAAM,EAAmC,CACxC,CAAE,MAAO,UAAW,MAAO,GAAK,IAAQ,CACxC,CAAE,MAAO,OAAQ,MAAO,GAAK,IAAQ,QAAS,GAAM,CACpD,CAAE,MAAO,UAAW,MAAO,IAAS,IAAQ,CAC5C,CAAE,MAAO,MAAO,MAAO,KAAU,IAAQ,CACzC,CAEK,EAAqC,CAC1C,CAAE,MAAO,UAAW,MAAO,KAAQ,CACnC,CAAE,MAAO,UAAW,MAAO,IAAQ,CACnC,CAAE,MAAO,SAAU,MAAO,IAAQ,QAAS,GAAM,CACjD,CAAE,MAAO,SAAU,MAAO,EAAI,IAAQ,CACtC,CAAE,MAAO,UAAW,MAAO,GAAK,IAAQ,CACxC,CAMD,SAAgB,EAAW,CAAE,kBAAoC,CAChE,GAAM,CAAC,EAAgB,IAAA,EAAA,EAAA,UAA8B,EAAQ,GAAG,CAE1D,CAAC,EAAgB,IAAA,EAAA,EAAA,UAA8B,EAAgB,KAAM,GAAM,EAAE,QAAQ,CAAE,CACvF,CAAC,EAAS,IAAA,EAAA,EAAA,UAAuB,KAAK,IAAI,CAE1C,CAAC,EAAY,IAAA,EAAA,EAAA,UAA0B,EAAc,KAAM,GAAM,EAAE,QAAQ,CAAE,CAEnF,MAAkB,CACjB,EAAW,KAAK,IAAI,EAClB,EAAe,MAAM,CAExB,IAAM,GAAA,EAAA,EAAA,aAA0B,EAAU,EAAW,MAAO,CAAC,EAAS,EAAW,CAAC,CAElF,OAAA,EAAA,EAAA,MACE,MAAD,CAAA,SAAA,EAAA,EAAA,EAAA,KACE,MAAD,CAAK,UAAU,2CACb,MAAD,CAAK,UAAU,mEAAf,YACE,MAAD,CAAK,UAAU,yCAAf,EAAA,EAAA,EAAA,KACE,EAAD,CAAO,UAAU,qBAAY,UAAe,CAAA,EAAA,EAAA,EAAA,MAC3C,EAAD,CACC,aAAc,EAAe,GAC7B,cAAgB,GAAU,CACzB,EAAkB,EAAQ,KAAM,GAAM,EAAE,KAAO,EAAM,EAAI,EAAQ,GAAG,WAHtE,EAAA,EAAA,EAAA,KAME,EAAD,CAAe,UAAU,4DACvB,EAAD,EAAe,CAAA,CACA,CAAA,EAAA,EAAA,EAAA,KACf,EAAD,CAAA,UAAA,EAAA,EAAA,KACE,EAAD,CAAA,SACE,EAAQ,IAAK,GAAM,CACnB,IAAI,EAAY,EAAE,OAAS,EAAE,KAI7B,OAHI,EAAE,OACL,GAAa,KAAK,EAAE,KAAK,KAE1B,EAAA,EAAA,KAAQ,EAAD,CAAuB,MAAO,EAAE,YAAK,EAAuB,CAA3C,EAAE,GAAyC,EAClE,CACW,CAAA,CACC,CAAA,CACR,GACJ,cACL,MAAD,CAAK,UAAU,yCAAf,EAAA,EAAA,EAAA,KACE,EAAD,CAAO,UAAU,qBAAY,YAAiB,CAAA,EAAA,EAAA,EAAA,MAC7C,EAAD,CACC,aAAc,EAAW,MAAM,UAAU,CACzC,cAAgB,GAAU,CACzB,EAAc,EAAc,KAAM,GAAM,EAAE,QAAU,OAAO,EAAM,CAAC,CAAE,WAHtE,EAAA,EAAA,EAAA,KAME,EAAD,CAAe,UAAU,4DACvB,EAAD,EAAe,CAAA,CACA,CAAA,EAAA,EAAA,EAAA,KACf,EAAD,CAAA,UAAA,EAAA,EAAA,KACE,EAAD,CAAA,SACE,EAAc,IAAK,IACnB,EAAA,EAAA,KAAQ,EAAD,CAA0B,MAAO,EAAE,MAAM,UAAU,UAAG,EAAE,MAAmB,CAA1D,EAAE,MAAwD,CACjF,CACW,CAAA,CACC,CAAA,CACR,GACJ,cACL,MAAD,CAAK,UAAU,yCAAf,EAAA,EAAA,EAAA,KACE,EAAD,CAAO,UAAU,qBAAY,eAAoB,CAAA,EAAA,EAAA,EAAA,MAChD,EAAD,CACC,aAAc,EAAe,MAAM,UAAU,CAC7C,cAAgB,GAAU,CACzB,EAAkB,EAAgB,KAAM,GAAM,EAAE,QAAU,OAAO,EAAM,CAAC,CAAE,WAH5E,EAAA,EAAA,EAAA,KAME,EAAD,CAAe,UAAU,4DACvB,EAAD,EAAe,CAAA,CACA,CAAA,EAAA,EAAA,EAAA,KACf,EAAD,CAAA,UAAA,EAAA,EAAA,KACE,EAAD,CAAA,SACE,EAAgB,IAAK,IACrB,EAAA,EAAA,KAAQ,EAAD,CAA0B,MAAO,EAAE,MAAM,UAAU,UAAG,EAAE,MAAmB,CAA1D,EAAE,MAAwD,CACjF,CACW,CAAA,CACC,CAAA,CACR,GACJ,GACD,GACD,CAAA,EAAA,EAAA,EAAA,KACL,EAAD,CACC,aAAc,EACH,YACF,UACO,iBACf,CAAA,CACG,CAAA,CAAA,CCrGR,SAAgB,EAAiC,CAAE,WAAU,kBAA0C,CACtG,OAAO,EAAa,CACnB,SAAU,CAAC,EAAU,qBAAqB,CAC1C,QAAS,SAAY,CACpB,GAAM,CAAE,QAAS,MAAM,EAAe,KAAgC,IAAK,CAC1E,UAAW,qBACX,WAAY,CAAC,UAAW,OAAQ,MAAO,SAAU,SAAS,CAC1D,CAAC,CACF,OAAO,GAER,CAAC,CCjGH,SAAgB,EAAY,CAAE,kBAAqC,CAClE,GAAM,CAAE,QAAS,EAAiB,EAAiC,EAAe,CAAC,CAEnF,OAAA,EAAA,EAAA,KACE,EAAA,SAAD,CAAU,UAAA,EAAA,EAAA,KAAW,EAAD,EAAuB,CAAA,oBACzC,EAAD,CAAc,OAAQ,CAAA,CACZ,CAAA,CCXb,SAAgB,GAAc,CAC7B,IAAM,EAAiB,GAA2B,CAElD,OAAA,EAAA,EAAA,MACE,MAAD,CAAK,UAAU,mCAAf,EAAA,EAAA,EAAA,KACE,MAAD,CAAK,UAAU,2BACb,EAAD,CAA4B,iBAAkB,CAAA,CACzC,CAAA,EAAA,EAAA,EAAA,KAEF,EAAD,CAA6B,iBAAkB,CAAA,CAE7C"}
@@ -6,7 +6,7 @@
6
6
  <link rel="icon" type="dynamic-favicon" href="/favicon_purple.png" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>Harper Fabric</title>
9
- <script type="module" crossorigin src="/assets/index-ZhLX9iRh.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-ClD_q6ya.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-datadog-B4t4E5qd.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/vendor-html-C0BzV7Np.js">
@@ -426,6 +426,7 @@ export const LEGACY_CONFIG_PARAMS = {
426
426
  export const CONFIG_PARAMS = {
427
427
  ANALYTICS_AGGREGATEPERIOD: 'analytics_aggregatePeriod',
428
428
  ANALYTICS_REPLICATE: 'analytics_replicate',
429
+ ANALYTICS_STORAGEINTERVAL: 'analytics_storageInterval',
429
430
  AUTHENTICATION_AUTHORIZELOCAL: 'authentication_authorizeLocal',
430
431
  AUTHENTICATION_CACHETTL: 'authentication_cacheTTL',
431
432
  AUTHENTICATION_COOKIE_DOMAINS: 'authentication_cookie_domains',
@@ -82,7 +82,7 @@ function updateLogger(logger, logOptions, name) {
82
82
  logger.logToStdstreams = logOptions.stdStreams ?? false;
83
83
  // if there is a configured tag or if a component is logging to default/main log path, use the component name as the tag
84
84
  // to differentiate it
85
- logger.tag = logOptions.tag ?? (mainLogger.path === logger.path && name);
85
+ logger.tag = logOptions.tag ?? ((mainLogger.path === logger.path || externalLogger.path === logger.path) && name);
86
86
  }
87
87
  // creates a logger where the methods are only defined if they are within the log level.
88
88
  // Using this conditional logger means that every method call must be optional like log.trace?.('message),
@@ -98,6 +98,14 @@ function updateConditional(logger) {
98
98
  conditional.debug = LOG_LEVEL_HIERARCHY.debug >= logger.level ? logger.debug.bind(logger) : undefined;
99
99
  conditional.trace = LOG_LEVEL_HIERARCHY.trace >= logger.level ? logger.trace.bind(logger) : undefined;
100
100
  }
101
+ /**
102
+ * Resolve a config path value against rootPath if it is relative.
103
+ */
104
+ function resolveLogPath(configPath, rootPath) {
105
+ if (!configPath || !rootPath) return configPath;
106
+ if (pathModule.isAbsolute(configPath)) return configPath;
107
+ return pathModule.resolve(rootPath, configPath);
108
+ }
101
109
  async function updateLogSettings() {
102
110
  if (!rootConfig) {
103
111
  // set up the initial watcher
@@ -109,11 +117,23 @@ async function updateLogSettings() {
109
117
  }
110
118
  let rootConfigObject = rootConfig.config;
111
119
  const logOptions = rootConfigObject.logging ?? {};
120
+ // Resolve relative paths against rootPath from the same config
121
+ const rootPath = rootConfigObject.rootPath;
122
+ if (logOptions.root) {
123
+ logOptions.root = resolveLogPath(logOptions.root, rootPath);
124
+ }
125
+ if (logOptions.rotation?.path) {
126
+ logOptions.rotation.path = resolveLogPath(logOptions.rotation.path, rootPath);
127
+ }
112
128
  updateLogger(mainLogger, logOptions);
113
129
  logFilePath = mainLogger.path;
114
130
  logConsole = logOptions.console ?? false;
115
131
  if (logOptions.external) {
116
132
  updateLogger(externalLogger, logOptions.external);
133
+ for (let [name, component] of mainLogger.components) {
134
+ if (!(rootConfigObject[name] && rootConfigObject[name].logging) && component.isExternal)
135
+ updateLogger(component, logOptions.external, name);
136
+ }
117
137
  }
118
138
  for (const name in rootConfigObject) {
119
139
  // we now scan each component to see if it has logging individual configured
@@ -121,7 +141,8 @@ async function updateLogSettings() {
121
141
  if (component.logging) {
122
142
  updateLogger(mainLogger.forComponent(name), component.logging, name);
123
143
  } else if (mainLogger.hasComponent(name)) {
124
- updateLogger(mainLogger.forComponent(name), logOptions, name);
144
+ const componentLogger = mainLogger.forComponent(name);
145
+ updateLogger(componentLogger, (componentLogger.isExternal && logOptions.external) ?? logOptions, name);
125
146
  }
126
147
  }
127
148
  }
@@ -226,7 +247,7 @@ module.exports = {
226
247
  createLogger,
227
248
  logsAtLevel,
228
249
  getLogFilePath: () => logFilePath,
229
- forComponent: (name) => mainLogger.forComponent(name),
250
+ forComponent: (name, isExternal) => mainLogger.forComponent(name, isExternal),
230
251
  setMainLogger,
231
252
  setLogLevel,
232
253
  OUTPUTS,
@@ -273,6 +294,9 @@ module.exports.externalLogger = {
273
294
  loggerWithTag(tag) {
274
295
  return externalLogger.withTag(tag);
275
296
  },
297
+ forComponent(name) {
298
+ return externalLogger.forComponent(name);
299
+ },
276
300
  };
277
301
  _assignPackageExport('logger', module.exports.externalLogger);
278
302
 
@@ -467,7 +491,7 @@ function createLogger({
467
491
  component,
468
492
  }) {
469
493
  if (!logLevel) logLevel = 'info';
470
- let level = LOG_LEVEL_HIERARCHY[logLevel];
494
+ let level = typeof logLevel === 'number' ? logLevel : LOG_LEVEL_HIERARCHY[logLevel];
471
495
  let logger;
472
496
  /**
473
497
  * Log to std out and/or file
@@ -549,25 +573,29 @@ function createLogger({
549
573
  logger.logToStdstreams = logToStdstreams;
550
574
  if (!component) {
551
575
  let components = new Map();
552
- logger.forComponent = function (name) {
576
+ logger.forComponent = function (name, isExternal = false) {
553
577
  let componentLogger = components.get(name);
554
578
  if (!componentLogger) {
579
+ const protoLogger = isExternal ? externalLogger : logger;
555
580
  componentLogger = createLogger({
556
- path: logFilePath,
557
- level: logLevel,
558
- stdStreams: logToStdstreams,
559
- isExternalInstance: name === 'external',
560
- rotation,
581
+ path: protoLogger.path,
582
+ level: protoLogger.level,
583
+ stdStreams: protoLogger.logToStdstreams,
584
+ isExternalInstance: isExternal || name === 'external',
585
+ rotation: protoLogger.rotation,
561
586
  writeToLog,
562
587
  component: true,
563
588
  });
589
+ componentLogger.tag = name;
564
590
  components.set(name, componentLogger);
565
591
  }
592
+ if (isExternal) componentLogger.isExternal = true;
566
593
  return componentLogger;
567
594
  };
568
595
  logger.hasComponent = function (name) {
569
596
  return components.has(name);
570
597
  };
598
+ logger.components = components;
571
599
  }
572
600
  return logger;
573
601
  }
@@ -793,13 +821,18 @@ function getLogConfig(hdbConfigPath) {
793
821
  };
794
822
  }
795
823
  const configDoc = YAML.parseDocument(fs.readFileSync(hdbConfigPath, 'utf8'));
824
+ const rootPath = configDoc.getIn(['rootPath']);
796
825
  const level = configDoc.getIn(['logging', 'level']);
797
- const configLogPath = configDoc.getIn(['logging', 'root']);
826
+ const configLogPath = resolveLogPath(configDoc.getIn(['logging', 'root']), rootPath);
798
827
  const toFile = configDoc.getIn(['logging', 'file']);
799
828
  const toStream = configDoc.getIn(['logging', 'stdStreams']);
800
829
  const logConsole = configDoc.getIn(['logging', 'console']);
801
830
  const colorMode = configDoc.getIn(['logging', 'colors']) ?? true; // default to true
802
831
  const rotation = configDoc.getIn(['logging', 'rotation'])?.toJSON();
832
+ // Resolve rotation path if relative
833
+ if (rotation?.path) {
834
+ rotation.path = resolveLogPath(rotation.path, rootPath);
835
+ }
803
836
 
804
837
  return {
805
838
  level,