@veltrixsecops/app-sdk 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,6 +92,48 @@ Two rules for app pages:
92
92
  - Only import third-party client libraries if you accept them being compiled into your
93
93
  bundle; keep pages lean.
94
94
 
95
+ ### UI components
96
+
97
+ Build page bodies from the platform's design-system kit instead of hand-rolling raw
98
+ HTML. Import from `@veltrixsecops/app-sdk/ui`:
99
+
100
+ ```tsx
101
+ import { Button, Card, CardHeader, CardBody, Tabs, DataTable } from '@veltrixsecops/app-sdk/ui'
102
+
103
+ function Configs() {
104
+ return (
105
+ <Card>
106
+ <CardHeader actions={<Button variant="primary">New</Button>}>Configurations</CardHeader>
107
+ <CardBody>
108
+ <Tabs
109
+ tabs={[
110
+ { key: 'indexes', label: 'Indexes', content: <p>…</p> },
111
+ { key: 'roles', label: 'Roles', content: <p>…</p> },
112
+ ]}
113
+ />
114
+ </CardBody>
115
+ </Card>
116
+ )
117
+ }
118
+ ```
119
+
120
+ These render in the platform design system and pick up the tenant theme (light/dark) and
121
+ your app's branding automatically via the platform's CSS-token bridge — no styling needed.
122
+ The bundler shims `@veltrixsecops/app-sdk/ui` to the host's real components, so they share
123
+ the single host React instance.
124
+
125
+ Available components: `Button`, `Input`, `Textarea`, `Checkbox`, `Select`, `Card` (+
126
+ `CardHeader`/`CardBody`/`CardFooter`), `Badge`, `Tooltip`, `EmptyState`, `Skeleton` (+
127
+ `SkeletonText`/`SkeletonCard`), `DataTable`, `StatsCard`, `FormDialog`, `FormField`, `Tabs`,
128
+ `Spinner`. Hooks: `useToast`, `useConfirmDialog`. All prop types are exported alongside the
129
+ components.
130
+
131
+ `useToast` / `useConfirmDialog` are backed by providers the platform mounts around every app
132
+ page, so they work with no extra wiring inside Veltrix. Every export is usable outside the
133
+ platform too (local dev, tests): components render a minimal, unstyled, accessible fallback,
134
+ `useToast` logs to the console, and `useConfirmDialog().confirm()` resolves to `false`
135
+ (fails closed) — so nothing crashes, it just runs without platform theming.
136
+
95
137
  ## Branding
96
138
 
97
139
  Declare your vendor identity in the manifest and the platform applies it in defined
@@ -137,11 +179,17 @@ conventionalPaths('indexes').handlers.deploy // 'config-types/indexes/deploy'
137
179
 
138
180
  ## Package layout
139
181
 
182
+ > **2.0.0 (breaking):** the root entry no longer re-exports the React hooks — import them from
183
+ > `@veltrixsecops/app-sdk/hooks`. Pipeline handlers run in a bare Node child process, so the contract
184
+ > they import must never pull in React.
185
+
140
186
  | Entry point | Contents |
141
187
  |---|---|
142
- | `@veltrixsecops/app-sdk` | All types: handler contexts/results, manifest, platform refs, hook contexts |
188
+ | `@veltrixsecops/app-sdk` | **React-free.** All types (handler contexts/results, manifest, platform refs, hook contexts), `APP_LAYOUT`/`HANDLER_NAMES`/`conventionalPaths()` — safe to load in a bare Node process, which is what the sandbox runner does |
143
189
  | `@veltrixsecops/app-sdk/pipeline` | `defineValidator`, `defineDeployer`, `defineRollbackHandler`, `defineHealthChecker`, `defineDriftDetector` |
144
190
  | `@veltrixsecops/app-sdk/hooks` | React hooks for app client pages (requires `react`) |
191
+ | `@veltrixsecops/app-sdk/client` | Browser client contract: `authFetch`, `getHostRuntime`, `AppClientModule` |
192
+ | `@veltrixsecops/app-sdk/ui` | Platform design-system components + hooks for app client pages (requires `react`; renders richly inside the platform, degrades to a minimal accessible fallback outside it) |
145
193
 
146
194
  ## Building an app
147
195
 
@@ -25,4 +25,4 @@ export {
25
25
  requireHostRuntime,
26
26
  authFetch
27
27
  };
28
- //# sourceMappingURL=chunk-PJN3ATPH.js.map
28
+ //# sourceMappingURL=chunk-GC3FJ5Q2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":";AAuBO,IAAM,sBAAsB;AA8B5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAGO,SAAS,qBAAyC;AACvD,QAAM,UAAU,eAAe;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,qHAC0C,mBAAmB;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;","names":[]}
1
+ {"version":3,"sources":["../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n /**\n * The platform's design-system components and hooks, host-owned so they\n * share the single host React instance. Keyed by the exact component/hook\n * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,\n * DataTable, useToast, ...). Present only inside the platform.\n */\n ui?: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":";AAuBO,IAAM,sBAAsB;AAqC5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAGO,SAAS,qBAAyC;AACvD,QAAM,UAAU,eAAe;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,qHAC0C,mBAAmB;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBO,IAAM,sBAAsB;AA8B5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAGO,SAAS,qBAAyC;AACvD,QAAM,UAAU,eAAe;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,qHAC0C,mBAAmB;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;","names":[]}
1
+ {"version":3,"sources":["../../src/client/index.ts"],"sourcesContent":["// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n /**\n * The platform's design-system components and hooks, host-owned so they\n * share the single host React instance. Keyed by the exact component/hook\n * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,\n * DataTable, useToast, ...). Present only inside the platform.\n */\n ui?: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBO,IAAM,sBAAsB;AAqC5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAGO,SAAS,qBAAyC;AACvD,QAAM,UAAU,eAAe;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,qHAC0C,mBAAmB;AAAA,IAC/D;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { ComponentType, LazyExoticComponent, Context } from 'react';
2
- import { A as AppContextValue } from '../use-app-context-DdrtEPeb.cjs';
3
- export { a as AppBrandingDeclaration } from '../use-app-context-DdrtEPeb.cjs';
2
+ import { A as AppContextValue } from '../use-app-context-Be10sZyq.cjs';
3
+ export { a as AppBrandingDeclaration } from '../use-app-context-Be10sZyq.cjs';
4
4
 
5
5
  /** Name of the global the platform installs before loading app bundles. */
6
6
  declare const HOST_RUNTIME_GLOBAL = "__VELTRIX_APP_RUNTIME__";
@@ -29,6 +29,13 @@ interface VeltrixHostRuntime {
29
29
  * usePipelineStatus, authFetch, getHostRuntime, ...).
30
30
  */
31
31
  sdk: Record<string, unknown>;
32
+ /**
33
+ * The platform's design-system components and hooks, host-owned so they
34
+ * share the single host React instance. Keyed by the exact component/hook
35
+ * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,
36
+ * DataTable, useToast, ...). Present only inside the platform.
37
+ */
38
+ ui?: Record<string, unknown>;
32
39
  }
33
40
  /** Read the host runtime, or null outside the platform (tests, storybook). */
34
41
  declare function getHostRuntime(): VeltrixHostRuntime | null;
@@ -1,6 +1,6 @@
1
1
  import { ComponentType, LazyExoticComponent, Context } from 'react';
2
- import { A as AppContextValue } from '../use-app-context-DdrtEPeb.js';
3
- export { a as AppBrandingDeclaration } from '../use-app-context-DdrtEPeb.js';
2
+ import { A as AppContextValue } from '../use-app-context-Be10sZyq.js';
3
+ export { a as AppBrandingDeclaration } from '../use-app-context-Be10sZyq.js';
4
4
 
5
5
  /** Name of the global the platform installs before loading app bundles. */
6
6
  declare const HOST_RUNTIME_GLOBAL = "__VELTRIX_APP_RUNTIME__";
@@ -29,6 +29,13 @@ interface VeltrixHostRuntime {
29
29
  * usePipelineStatus, authFetch, getHostRuntime, ...).
30
30
  */
31
31
  sdk: Record<string, unknown>;
32
+ /**
33
+ * The platform's design-system components and hooks, host-owned so they
34
+ * share the single host React instance. Keyed by the exact component/hook
35
+ * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,
36
+ * DataTable, useToast, ...). Present only inside the platform.
37
+ */
38
+ ui?: Record<string, unknown>;
32
39
  }
33
40
  /** Read the host runtime, or null outside the platform (tests, storybook). */
34
41
  declare function getHostRuntime(): VeltrixHostRuntime | null;
@@ -3,7 +3,7 @@ import {
3
3
  authFetch,
4
4
  getHostRuntime,
5
5
  requireHostRuntime
6
- } from "../chunk-PJN3ATPH.js";
6
+ } from "../chunk-GC3FJ5Q2.js";
7
7
  export {
8
8
  HOST_RUNTIME_GLOBAL,
9
9
  authFetch,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/index.ts","../../src/hooks/use-app-context.ts","../../src/hooks/use-pipeline-status.ts","../../src/client/index.ts","../../src/hooks/use-app-branding.ts"],"sourcesContent":["export { useAppContext, AppContext, type AppContextValue } from './use-app-context'\nexport { usePipelineStatus, type PipelineStatusData } from './use-pipeline-status'\nexport { useAppBranding } from './use-app-branding'\n","// ========================================================================\n// React hooks for app developers\n// These provide access to platform data and pipeline state\n// ========================================================================\n\nimport { createContext, useContext, type Context } from 'react'\nimport type { Component, Credential, Tag, User, Customer } from '../types/platform'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\nexport interface AppContextValue {\n appId: string\n customerId: string\n user: User | null\n customer: Customer | null\n\n // Platform data accessors\n getComponents: () => Promise<Component[]>\n getCredentials: () => Promise<Credential[]>\n getTags: () => Promise<Tag[]>\n\n // App settings\n settings: Record<string, unknown>\n\n /** The app's manifest branding, resolved by the platform (null when unset). */\n branding?: AppBrandingDeclaration | null\n}\n\n// Anchor the context on the host runtime when running inside the platform,\n// so a bundle that inlined its own SDK copy still shares the host's context\n// (two createContext objects never match, even with identical shapes).\nconst hostContext = (\n (globalThis as Record<string, unknown>).__VELTRIX_APP_RUNTIME__ as\n | { AppContext?: Context<AppContextValue | null> }\n | undefined\n)?.AppContext\n\nexport const AppContext: Context<AppContextValue | null> =\n hostContext ?? createContext<AppContextValue | null>(null)\n\n/**\n * Access the app context in any app component.\n *\n * @example\n * ```tsx\n * import { useAppContext } from '@veltrixsecops/app-sdk/hooks'\n *\n * function MyComponent() {\n * const { appId, settings, getComponents } = useAppContext()\n * // ...\n * }\n * ```\n */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContext)\n if (!ctx) {\n throw new Error('useAppContext must be used within an AppContextProvider')\n }\n return ctx\n}\n","import { useState, useEffect, useCallback } from 'react'\nimport { authFetch } from '../client'\n\nexport interface PipelineStatusData {\n pendingApprovals: number\n activeDeployments: number\n failedDeployments: number\n unresolvedDrifts: number\n recentDeployments: Array<{\n id: string\n canvasName: string\n environment: string\n status: string\n startedAt: string\n completedAt?: string\n }>\n}\n\n/**\n * Hook to access pipeline status for the current app/customer.\n *\n * @example\n * ```tsx\n * import { usePipelineStatus } from '@veltrixsecops/app-sdk/hooks'\n *\n * function Dashboard() {\n * const { data, isLoading } = usePipelineStatus('my-app')\n * if (isLoading) return <Spinner />\n * return <div>{data.activeDeployments} active deployments</div>\n * }\n * ```\n */\nexport function usePipelineStatus(appId: string) {\n const [data, setData] = useState<PipelineStatusData | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const refresh = useCallback(async () => {\n try {\n setIsLoading(true)\n // Platform APIs are bearer-token protected — plain fetch would 401\n const response = await authFetch(`/api/pipeline/summary?appId=${appId}`)\n if (!response.ok) throw new Error(`Failed to fetch pipeline status`)\n const result = await response.json()\n setData(result)\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Unknown error'))\n } finally {\n setIsLoading(false)\n }\n }, [appId])\n\n useEffect(() => {\n refresh()\n }, [refresh])\n\n return { data, isLoading, error, refresh }\n}\n","// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n","import { useAppContext } from './use-app-context'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\n/**\n * The app's brand identity as declared in manifest.yaml `branding`.\n *\n * The platform already applies it in the defined slots (the app navbar and\n * the scoped CSS variables --veltrix-app-primary / --veltrix-app-accent on\n * the app page container). Use this hook only when a page needs the values\n * programmatically — prefer the CSS variables for styling:\n *\n * @example\n * ```tsx\n * <span style={{ color: 'var(--veltrix-app-primary)' }}>12 detections</span>\n * ```\n */\nexport function useAppBranding(): AppBrandingDeclaration | null {\n return useAppContext().branding ?? null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,mBAAwD;AAyBxD,IAAM,cACH,WAAuC,yBAGvC;AAEI,IAAM,aACX,mBAAe,4BAAsC,IAAI;AAepD,SAAS,gBAAiC;AAC/C,QAAM,UAAM,yBAAW,UAAU;AACjC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,SAAO;AACT;;;AC1DA,IAAAA,gBAAiD;;;ACuB1C,IAAM,sBAAsB;AA8B5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAmBO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;;;AD/CO,SAAS,kBAAkB,OAAe;AAC/C,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAoC,IAAI;AAChE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,IAAI;AAC/C,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAuB,IAAI;AAErD,QAAM,cAAU,2BAAY,YAAY;AACtC,QAAI;AACF,mBAAa,IAAI;AAEjB,YAAM,WAAW,MAAM,UAAU,+BAA+B,KAAK,EAAE;AACvE,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,iCAAiC;AACnE,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC,cAAQ,MAAM;AACd,eAAS,IAAI;AAAA,IACf,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,eAAe,CAAC;AAAA,IAClE,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,+BAAU,MAAM;AACd,YAAQ;AAAA,EACV,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,MAAM,WAAW,OAAO,QAAQ;AAC3C;;;AE1CO,SAAS,iBAAgD;AAC9D,SAAO,cAAc,EAAE,YAAY;AACrC;","names":["import_react"]}
1
+ {"version":3,"sources":["../../src/hooks/index.ts","../../src/hooks/use-app-context.ts","../../src/hooks/use-pipeline-status.ts","../../src/client/index.ts","../../src/hooks/use-app-branding.ts"],"sourcesContent":["export { useAppContext, AppContext, type AppContextValue } from './use-app-context'\nexport { usePipelineStatus, type PipelineStatusData } from './use-pipeline-status'\nexport { useAppBranding } from './use-app-branding'\n","// ========================================================================\n// React hooks for app developers\n// These provide access to platform data and pipeline state\n// ========================================================================\n\nimport { createContext, useContext, type Context } from 'react'\nimport type { Component, Credential, Tag, User, Customer } from '../types/platform'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\nexport interface AppContextValue {\n appId: string\n customerId: string\n user: User | null\n customer: Customer | null\n\n // Platform data accessors\n getComponents: () => Promise<Component[]>\n getCredentials: () => Promise<Credential[]>\n getTags: () => Promise<Tag[]>\n\n // App settings\n settings: Record<string, unknown>\n\n /** The app's manifest branding, resolved by the platform (null when unset). */\n branding?: AppBrandingDeclaration | null\n}\n\n// Anchor the context on the host runtime when running inside the platform,\n// so a bundle that inlined its own SDK copy still shares the host's context\n// (two createContext objects never match, even with identical shapes).\nconst hostContext = (\n (globalThis as Record<string, unknown>).__VELTRIX_APP_RUNTIME__ as\n | { AppContext?: Context<AppContextValue | null> }\n | undefined\n)?.AppContext\n\nexport const AppContext: Context<AppContextValue | null> =\n hostContext ?? createContext<AppContextValue | null>(null)\n\n/**\n * Access the app context in any app component.\n *\n * @example\n * ```tsx\n * import { useAppContext } from '@veltrixsecops/app-sdk/hooks'\n *\n * function MyComponent() {\n * const { appId, settings, getComponents } = useAppContext()\n * // ...\n * }\n * ```\n */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContext)\n if (!ctx) {\n throw new Error('useAppContext must be used within an AppContextProvider')\n }\n return ctx\n}\n","import { useState, useEffect, useCallback } from 'react'\nimport { authFetch } from '../client'\n\nexport interface PipelineStatusData {\n pendingApprovals: number\n activeDeployments: number\n failedDeployments: number\n unresolvedDrifts: number\n recentDeployments: Array<{\n id: string\n canvasName: string\n environment: string\n status: string\n startedAt: string\n completedAt?: string\n }>\n}\n\n/**\n * Hook to access pipeline status for the current app/customer.\n *\n * @example\n * ```tsx\n * import { usePipelineStatus } from '@veltrixsecops/app-sdk/hooks'\n *\n * function Dashboard() {\n * const { data, isLoading } = usePipelineStatus('my-app')\n * if (isLoading) return <Spinner />\n * return <div>{data.activeDeployments} active deployments</div>\n * }\n * ```\n */\nexport function usePipelineStatus(appId: string) {\n const [data, setData] = useState<PipelineStatusData | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const refresh = useCallback(async () => {\n try {\n setIsLoading(true)\n // Platform APIs are bearer-token protected — plain fetch would 401\n const response = await authFetch(`/api/pipeline/summary?appId=${appId}`)\n if (!response.ok) throw new Error(`Failed to fetch pipeline status`)\n const result = await response.json()\n setData(result)\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Unknown error'))\n } finally {\n setIsLoading(false)\n }\n }, [appId])\n\n useEffect(() => {\n refresh()\n }, [refresh])\n\n return { data, isLoading, error, refresh }\n}\n","// ========================================================================\n// Client runtime contract — how app client bundles talk to the host.\n//\n// App client code is packaged as a hermetic ESM bundle in which `react`,\n// `react-dom`, `react/jsx-runtime`, and every `@veltrixsecops/app-sdk`\n// subpath are compile-time shims that read the host-provided runtime from\n// `globalThis.__VELTRIX_APP_RUNTIME__`. The platform installs that global\n// (with ITS React instance, the shared AppContext, and an authenticated\n// fetch) before dynamically importing any app bundle, so app components\n// render inside the host React tree with working hooks and context.\n//\n// App authors: import from '@veltrixsecops/app-sdk/client' (and /hooks) —\n// never bundle your own copy of react. Use `authFetch` for calls to your\n// app's server routes (/api/apps/<app-id>/...): plain fetch() lacks the\n// platform's Authorization header and will receive 401s.\n// ========================================================================\n\nimport type { ComponentType, Context, LazyExoticComponent } from 'react'\nimport type { AppContextValue } from '../hooks/use-app-context'\n\nexport type { AppBrandingDeclaration } from '../types/manifest'\n\n/** Name of the global the platform installs before loading app bundles. */\nexport const HOST_RUNTIME_GLOBAL = '__VELTRIX_APP_RUNTIME__'\n\n/**\n * The runtime surface the platform exposes to app client bundles.\n * The react/reactDom/jsxRuntime members are the host's own module objects —\n * app bundles are compiled with shims that re-export them, guaranteeing a\n * single React instance per page.\n */\nexport interface VeltrixHostRuntime {\n /** The host's `react` module object. */\n react: unknown\n /** The host's `react-dom` module object. */\n reactDom: unknown\n /** The host's `react-dom/client` module object. */\n reactDomClient?: unknown\n /** The host's `react/jsx-runtime` module object. */\n jsxRuntime: unknown\n /** Shared app context — the host wraps app pages in its Provider. */\n AppContext: Context<AppContextValue | null>\n /** fetch() with the platform's Authorization header attached. */\n authFetch: (input: string, init?: RequestInit) => Promise<Response>\n /**\n * The SDK surface app bundles receive for `@veltrixsecops/app-sdk`,\n * `.../hooks`, and `.../client` imports (useAppContext, AppContext,\n * usePipelineStatus, authFetch, getHostRuntime, ...).\n */\n sdk: Record<string, unknown>\n /**\n * The platform's design-system components and hooks, host-owned so they\n * share the single host React instance. Keyed by the exact component/hook\n * names re-exported from `@veltrixsecops/app-sdk/ui` (Button, Input, Card,\n * DataTable, useToast, ...). Present only inside the platform.\n */\n ui?: Record<string, unknown>\n}\n\n/** Read the host runtime, or null outside the platform (tests, storybook). */\nexport function getHostRuntime(): VeltrixHostRuntime | null {\n const runtime = (globalThis as Record<string, unknown>)[HOST_RUNTIME_GLOBAL]\n return (runtime as VeltrixHostRuntime) ?? null\n}\n\n/** Read the host runtime, throwing a diagnosable error when absent. */\nexport function requireHostRuntime(): VeltrixHostRuntime {\n const runtime = getHostRuntime()\n if (!runtime) {\n throw new Error(\n 'Veltrix host runtime not found — app client bundles only run inside the ' +\n `Veltrix platform (missing globalThis.${HOST_RUNTIME_GLOBAL})`,\n )\n }\n return runtime\n}\n\n/**\n * fetch() that carries the platform's Authorization header. Required for an\n * app page to call its own server routes (/api/apps/<app-id>/...), which are\n * bearer-token protected. Falls back to plain fetch outside the platform.\n */\nexport function authFetch(input: string, init?: RequestInit): Promise<Response> {\n const runtime = getHostRuntime()\n if (runtime) return runtime.authFetch(input, init)\n return fetch(input, init)\n}\n\n/** A sidebar entry contributed by the app's client entry module. */\nexport interface AppSidebarItem {\n path: string\n label: string\n icon?: string\n}\n\n/**\n * Shape of the default export of an app's `client/index.tsx`.\n * `pages` keys must match `manifest.client.pages[].component`.\n */\nexport interface AppClientModule {\n id: string\n pages: Record<string, ComponentType | LazyExoticComponent<ComponentType>>\n sidebarItems?: AppSidebarItem[]\n}\n","import { useAppContext } from './use-app-context'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\n/**\n * The app's brand identity as declared in manifest.yaml `branding`.\n *\n * The platform already applies it in the defined slots (the app navbar and\n * the scoped CSS variables --veltrix-app-primary / --veltrix-app-accent on\n * the app page container). Use this hook only when a page needs the values\n * programmatically — prefer the CSS variables for styling:\n *\n * @example\n * ```tsx\n * <span style={{ color: 'var(--veltrix-app-primary)' }}>12 detections</span>\n * ```\n */\nexport function useAppBranding(): AppBrandingDeclaration | null {\n return useAppContext().branding ?? null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,mBAAwD;AAyBxD,IAAM,cACH,WAAuC,yBAGvC;AAEI,IAAM,aACX,mBAAe,4BAAsC,IAAI;AAepD,SAAS,gBAAiC;AAC/C,QAAM,UAAM,yBAAW,UAAU;AACjC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,SAAO;AACT;;;AC1DA,IAAAA,gBAAiD;;;ACuB1C,IAAM,sBAAsB;AAqC5B,SAAS,iBAA4C;AAC1D,QAAM,UAAW,WAAuC,mBAAmB;AAC3E,SAAQ,WAAkC;AAC5C;AAmBO,SAAS,UAAU,OAAe,MAAuC;AAC9E,QAAM,UAAU,eAAe;AAC/B,MAAI,QAAS,QAAO,QAAQ,UAAU,OAAO,IAAI;AACjD,SAAO,MAAM,OAAO,IAAI;AAC1B;;;ADtDO,SAAS,kBAAkB,OAAe;AAC/C,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAoC,IAAI;AAChE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,IAAI;AAC/C,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAuB,IAAI;AAErD,QAAM,cAAU,2BAAY,YAAY;AACtC,QAAI;AACF,mBAAa,IAAI;AAEjB,YAAM,WAAW,MAAM,UAAU,+BAA+B,KAAK,EAAE;AACvE,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,iCAAiC;AACnE,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC,cAAQ,MAAM;AACd,eAAS,IAAI;AAAA,IACf,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,eAAe,CAAC;AAAA,IAClE,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,+BAAU,MAAM;AACd,YAAQ;AAAA,EACV,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,MAAM,WAAW,OAAO,QAAQ;AAC3C;;;AE1CO,SAAS,iBAAgD;AAC9D,SAAO,cAAc,EAAE,YAAY;AACrC;","names":["import_react"]}
@@ -1,42 +1,8 @@
1
- import { a as AppBrandingDeclaration } from '../use-app-context-DdrtEPeb.cjs';
2
- export { e as AppContext, A as AppContextValue, x as useAppContext } from '../use-app-context-DdrtEPeb.cjs';
1
+ import { a as AppBrandingDeclaration } from '../use-app-context-Be10sZyq.cjs';
2
+ export { b as AppContext, A as AppContextValue, u as useAppContext } from '../use-app-context-Be10sZyq.cjs';
3
+ export { P as PipelineStatusData, u as usePipelineStatus } from '../use-pipeline-status-CCSQ9Neh.cjs';
3
4
  import 'react';
4
5
 
5
- interface PipelineStatusData {
6
- pendingApprovals: number;
7
- activeDeployments: number;
8
- failedDeployments: number;
9
- unresolvedDrifts: number;
10
- recentDeployments: Array<{
11
- id: string;
12
- canvasName: string;
13
- environment: string;
14
- status: string;
15
- startedAt: string;
16
- completedAt?: string;
17
- }>;
18
- }
19
- /**
20
- * Hook to access pipeline status for the current app/customer.
21
- *
22
- * @example
23
- * ```tsx
24
- * import { usePipelineStatus } from '@veltrixsecops/app-sdk/hooks'
25
- *
26
- * function Dashboard() {
27
- * const { data, isLoading } = usePipelineStatus('my-app')
28
- * if (isLoading) return <Spinner />
29
- * return <div>{data.activeDeployments} active deployments</div>
30
- * }
31
- * ```
32
- */
33
- declare function usePipelineStatus(appId: string): {
34
- data: PipelineStatusData | null;
35
- isLoading: boolean;
36
- error: Error | null;
37
- refresh: () => Promise<void>;
38
- };
39
-
40
6
  /**
41
7
  * The app's brand identity as declared in manifest.yaml `branding`.
42
8
  *
@@ -52,4 +18,4 @@ declare function usePipelineStatus(appId: string): {
52
18
  */
53
19
  declare function useAppBranding(): AppBrandingDeclaration | null;
54
20
 
55
- export { type PipelineStatusData, useAppBranding, usePipelineStatus };
21
+ export { useAppBranding };
@@ -1,42 +1,8 @@
1
- import { a as AppBrandingDeclaration } from '../use-app-context-DdrtEPeb.js';
2
- export { e as AppContext, A as AppContextValue, x as useAppContext } from '../use-app-context-DdrtEPeb.js';
1
+ import { a as AppBrandingDeclaration } from '../use-app-context-Be10sZyq.js';
2
+ export { b as AppContext, A as AppContextValue, u as useAppContext } from '../use-app-context-Be10sZyq.js';
3
+ export { P as PipelineStatusData, u as usePipelineStatus } from '../use-pipeline-status-CCSQ9Neh.js';
3
4
  import 'react';
4
5
 
5
- interface PipelineStatusData {
6
- pendingApprovals: number;
7
- activeDeployments: number;
8
- failedDeployments: number;
9
- unresolvedDrifts: number;
10
- recentDeployments: Array<{
11
- id: string;
12
- canvasName: string;
13
- environment: string;
14
- status: string;
15
- startedAt: string;
16
- completedAt?: string;
17
- }>;
18
- }
19
- /**
20
- * Hook to access pipeline status for the current app/customer.
21
- *
22
- * @example
23
- * ```tsx
24
- * import { usePipelineStatus } from '@veltrixsecops/app-sdk/hooks'
25
- *
26
- * function Dashboard() {
27
- * const { data, isLoading } = usePipelineStatus('my-app')
28
- * if (isLoading) return <Spinner />
29
- * return <div>{data.activeDeployments} active deployments</div>
30
- * }
31
- * ```
32
- */
33
- declare function usePipelineStatus(appId: string): {
34
- data: PipelineStatusData | null;
35
- isLoading: boolean;
36
- error: Error | null;
37
- refresh: () => Promise<void>;
38
- };
39
-
40
6
  /**
41
7
  * The app's brand identity as declared in manifest.yaml `branding`.
42
8
  *
@@ -52,4 +18,4 @@ declare function usePipelineStatus(appId: string): {
52
18
  */
53
19
  declare function useAppBranding(): AppBrandingDeclaration | null;
54
20
 
55
- export { type PipelineStatusData, useAppBranding, usePipelineStatus };
21
+ export { useAppBranding };
@@ -1,10 +1,49 @@
1
1
  import {
2
- AppContext,
3
- useAppBranding,
4
- useAppContext,
5
- usePipelineStatus
6
- } from "../chunk-JOJTOQZQ.js";
7
- import "../chunk-PJN3ATPH.js";
2
+ authFetch
3
+ } from "../chunk-GC3FJ5Q2.js";
4
+
5
+ // src/hooks/use-app-context.ts
6
+ import { createContext, useContext } from "react";
7
+ var hostContext = globalThis.__VELTRIX_APP_RUNTIME__?.AppContext;
8
+ var AppContext = hostContext ?? createContext(null);
9
+ function useAppContext() {
10
+ const ctx = useContext(AppContext);
11
+ if (!ctx) {
12
+ throw new Error("useAppContext must be used within an AppContextProvider");
13
+ }
14
+ return ctx;
15
+ }
16
+
17
+ // src/hooks/use-pipeline-status.ts
18
+ import { useState, useEffect, useCallback } from "react";
19
+ function usePipelineStatus(appId) {
20
+ const [data, setData] = useState(null);
21
+ const [isLoading, setIsLoading] = useState(true);
22
+ const [error, setError] = useState(null);
23
+ const refresh = useCallback(async () => {
24
+ try {
25
+ setIsLoading(true);
26
+ const response = await authFetch(`/api/pipeline/summary?appId=${appId}`);
27
+ if (!response.ok) throw new Error(`Failed to fetch pipeline status`);
28
+ const result = await response.json();
29
+ setData(result);
30
+ setError(null);
31
+ } catch (err) {
32
+ setError(err instanceof Error ? err : new Error("Unknown error"));
33
+ } finally {
34
+ setIsLoading(false);
35
+ }
36
+ }, [appId]);
37
+ useEffect(() => {
38
+ refresh();
39
+ }, [refresh]);
40
+ return { data, isLoading, error, refresh };
41
+ }
42
+
43
+ // src/hooks/use-app-branding.ts
44
+ function useAppBranding() {
45
+ return useAppContext().branding ?? null;
46
+ }
8
47
  export {
9
48
  AppContext,
10
49
  useAppBranding,
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../../src/hooks/use-app-context.ts","../../src/hooks/use-pipeline-status.ts","../../src/hooks/use-app-branding.ts"],"sourcesContent":["// ========================================================================\n// React hooks for app developers\n// These provide access to platform data and pipeline state\n// ========================================================================\n\nimport { createContext, useContext, type Context } from 'react'\nimport type { Component, Credential, Tag, User, Customer } from '../types/platform'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\nexport interface AppContextValue {\n appId: string\n customerId: string\n user: User | null\n customer: Customer | null\n\n // Platform data accessors\n getComponents: () => Promise<Component[]>\n getCredentials: () => Promise<Credential[]>\n getTags: () => Promise<Tag[]>\n\n // App settings\n settings: Record<string, unknown>\n\n /** The app's manifest branding, resolved by the platform (null when unset). */\n branding?: AppBrandingDeclaration | null\n}\n\n// Anchor the context on the host runtime when running inside the platform,\n// so a bundle that inlined its own SDK copy still shares the host's context\n// (two createContext objects never match, even with identical shapes).\nconst hostContext = (\n (globalThis as Record<string, unknown>).__VELTRIX_APP_RUNTIME__ as\n | { AppContext?: Context<AppContextValue | null> }\n | undefined\n)?.AppContext\n\nexport const AppContext: Context<AppContextValue | null> =\n hostContext ?? createContext<AppContextValue | null>(null)\n\n/**\n * Access the app context in any app component.\n *\n * @example\n * ```tsx\n * import { useAppContext } from '@veltrixsecops/app-sdk/hooks'\n *\n * function MyComponent() {\n * const { appId, settings, getComponents } = useAppContext()\n * // ...\n * }\n * ```\n */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContext)\n if (!ctx) {\n throw new Error('useAppContext must be used within an AppContextProvider')\n }\n return ctx\n}\n","import { useState, useEffect, useCallback } from 'react'\nimport { authFetch } from '../client'\n\nexport interface PipelineStatusData {\n pendingApprovals: number\n activeDeployments: number\n failedDeployments: number\n unresolvedDrifts: number\n recentDeployments: Array<{\n id: string\n canvasName: string\n environment: string\n status: string\n startedAt: string\n completedAt?: string\n }>\n}\n\n/**\n * Hook to access pipeline status for the current app/customer.\n *\n * @example\n * ```tsx\n * import { usePipelineStatus } from '@veltrixsecops/app-sdk/hooks'\n *\n * function Dashboard() {\n * const { data, isLoading } = usePipelineStatus('my-app')\n * if (isLoading) return <Spinner />\n * return <div>{data.activeDeployments} active deployments</div>\n * }\n * ```\n */\nexport function usePipelineStatus(appId: string) {\n const [data, setData] = useState<PipelineStatusData | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n const refresh = useCallback(async () => {\n try {\n setIsLoading(true)\n // Platform APIs are bearer-token protected — plain fetch would 401\n const response = await authFetch(`/api/pipeline/summary?appId=${appId}`)\n if (!response.ok) throw new Error(`Failed to fetch pipeline status`)\n const result = await response.json()\n setData(result)\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Unknown error'))\n } finally {\n setIsLoading(false)\n }\n }, [appId])\n\n useEffect(() => {\n refresh()\n }, [refresh])\n\n return { data, isLoading, error, refresh }\n}\n","import { useAppContext } from './use-app-context'\nimport type { AppBrandingDeclaration } from '../types/manifest'\n\n/**\n * The app's brand identity as declared in manifest.yaml `branding`.\n *\n * The platform already applies it in the defined slots (the app navbar and\n * the scoped CSS variables --veltrix-app-primary / --veltrix-app-accent on\n * the app page container). Use this hook only when a page needs the values\n * programmatically — prefer the CSS variables for styling:\n *\n * @example\n * ```tsx\n * <span style={{ color: 'var(--veltrix-app-primary)' }}>12 detections</span>\n * ```\n */\nexport function useAppBranding(): AppBrandingDeclaration | null {\n return useAppContext().branding ?? null\n}\n"],"mappings":";;;;;AAKA,SAAS,eAAe,kBAAgC;AAyBxD,IAAM,cACH,WAAuC,yBAGvC;AAEI,IAAM,aACX,eAAe,cAAsC,IAAI;AAepD,SAAS,gBAAiC;AAC/C,QAAM,MAAM,WAAW,UAAU;AACjC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,SAAO;AACT;;;AC1DA,SAAS,UAAU,WAAW,mBAAmB;AAgC1C,SAAS,kBAAkB,OAAe;AAC/C,QAAM,CAAC,MAAM,OAAO,IAAI,SAAoC,IAAI;AAChE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAC/C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AAErD,QAAM,UAAU,YAAY,YAAY;AACtC,QAAI;AACF,mBAAa,IAAI;AAEjB,YAAM,WAAW,MAAM,UAAU,+BAA+B,KAAK,EAAE;AACvE,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,iCAAiC;AACnE,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC,cAAQ,MAAM;AACd,eAAS,IAAI;AAAA,IACf,SAAS,KAAK;AACZ,eAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,eAAe,CAAC;AAAA,IAClE,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,YAAU,MAAM;AACd,YAAQ;AAAA,EACV,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO,EAAE,MAAM,WAAW,OAAO,QAAQ;AAC3C;;;AC1CO,SAAS,iBAAgD;AAC9D,SAAO,cAAc,EAAE,YAAY;AACrC;","names":[]}
package/dist/index.cjs CHANGED
@@ -23,17 +23,13 @@ __export(src_exports, {
23
23
  APP_LAYOUT: () => APP_LAYOUT,
24
24
  APP_PAGE_LAYOUTS: () => APP_PAGE_LAYOUTS,
25
25
  APP_PAGE_NAV: () => APP_PAGE_NAV,
26
- AppContext: () => AppContext,
27
26
  HANDLER_NAMES: () => HANDLER_NAMES,
28
27
  conventionalPaths: () => conventionalPaths,
29
28
  defineDeployer: () => defineDeployer,
30
29
  defineDriftDetector: () => defineDriftDetector,
31
30
  defineHealthChecker: () => defineHealthChecker,
32
31
  defineRollbackHandler: () => defineRollbackHandler,
33
- defineValidator: () => defineValidator,
34
- useAppBranding: () => useAppBranding,
35
- useAppContext: () => useAppContext,
36
- usePipelineStatus: () => usePipelineStatus
32
+ defineValidator: () => defineValidator
37
33
  });
38
34
  module.exports = __toCommonJS(src_exports);
39
35
 
@@ -62,63 +58,6 @@ function defineDriftDetector(handler) {
62
58
  return handler;
63
59
  }
64
60
 
65
- // src/hooks/use-app-context.ts
66
- var import_react = require("react");
67
- var hostContext = globalThis.__VELTRIX_APP_RUNTIME__?.AppContext;
68
- var AppContext = hostContext ?? (0, import_react.createContext)(null);
69
- function useAppContext() {
70
- const ctx = (0, import_react.useContext)(AppContext);
71
- if (!ctx) {
72
- throw new Error("useAppContext must be used within an AppContextProvider");
73
- }
74
- return ctx;
75
- }
76
-
77
- // src/hooks/use-pipeline-status.ts
78
- var import_react2 = require("react");
79
-
80
- // src/client/index.ts
81
- var HOST_RUNTIME_GLOBAL = "__VELTRIX_APP_RUNTIME__";
82
- function getHostRuntime() {
83
- const runtime = globalThis[HOST_RUNTIME_GLOBAL];
84
- return runtime ?? null;
85
- }
86
- function authFetch(input, init) {
87
- const runtime = getHostRuntime();
88
- if (runtime) return runtime.authFetch(input, init);
89
- return fetch(input, init);
90
- }
91
-
92
- // src/hooks/use-pipeline-status.ts
93
- function usePipelineStatus(appId) {
94
- const [data, setData] = (0, import_react2.useState)(null);
95
- const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
96
- const [error, setError] = (0, import_react2.useState)(null);
97
- const refresh = (0, import_react2.useCallback)(async () => {
98
- try {
99
- setIsLoading(true);
100
- const response = await authFetch(`/api/pipeline/summary?appId=${appId}`);
101
- if (!response.ok) throw new Error(`Failed to fetch pipeline status`);
102
- const result = await response.json();
103
- setData(result);
104
- setError(null);
105
- } catch (err) {
106
- setError(err instanceof Error ? err : new Error("Unknown error"));
107
- } finally {
108
- setIsLoading(false);
109
- }
110
- }, [appId]);
111
- (0, import_react2.useEffect)(() => {
112
- refresh();
113
- }, [refresh]);
114
- return { data, isLoading, error, refresh };
115
- }
116
-
117
- // src/hooks/use-app-branding.ts
118
- function useAppBranding() {
119
- return useAppContext().branding ?? null;
120
- }
121
-
122
61
  // src/types/manifest.ts
123
62
  var APP_PAGE_LAYOUTS = ["standard", "full-bleed", "canvas"];
124
63
  var APP_PAGE_NAV = ["sidebar", "tab", "hidden"];
@@ -177,16 +116,12 @@ function conventionalPaths(configTypeId) {
177
116
  APP_LAYOUT,
178
117
  APP_PAGE_LAYOUTS,
179
118
  APP_PAGE_NAV,
180
- AppContext,
181
119
  HANDLER_NAMES,
182
120
  conventionalPaths,
183
121
  defineDeployer,
184
122
  defineDriftDetector,
185
123
  defineHealthChecker,
186
124
  defineRollbackHandler,
187
- defineValidator,
188
- useAppBranding,
189
- useAppContext,
190
- usePipelineStatus
125
+ defineValidator
191
126
  });
192
127
  //# sourceMappingURL=index.cjs.map