@sparkvault/sdk 1.1.6 → 1.8.2

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Upload API
3
+ *
4
+ * API client for vault upload operations.
5
+ */
6
+ import type { ResolvedConfig } from '../../config';
7
+ import type { VaultUploadConfig } from './types';
8
+ import { SparkVaultError } from '../../errors';
9
+ /**
10
+ * Error class for upload API errors.
11
+ */
12
+ export declare class UploadApiError extends SparkVaultError {
13
+ readonly httpStatus: number;
14
+ constructor(message: string, code: string, httpStatus: number);
15
+ }
16
+ export declare class UploadApi {
17
+ private readonly config;
18
+ private readonly timeoutMs;
19
+ constructor(config: ResolvedConfig);
20
+ /**
21
+ * Get vault upload info (public endpoint).
22
+ */
23
+ getVaultUploadInfo(vaultId: string): Promise<VaultUploadConfig>;
24
+ /**
25
+ * Initiate an upload to get Forge URL and ingot ID.
26
+ */
27
+ initiateUpload(vaultId: string, filename: string, sizeBytes: number, contentType: string): Promise<{
28
+ forgeUrl: string;
29
+ ingotId: string;
30
+ }>;
31
+ /**
32
+ * Internal request method with timeout handling and error context.
33
+ */
34
+ private request;
35
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Upload Container Interface
3
+ *
4
+ * Abstract interface for upload UI containers.
5
+ * Allows switching between modal (popup) and inline rendering modes
6
+ * while reusing all view logic, state management, and handlers.
7
+ */
8
+ import type { UploadBranding } from './types';
9
+ /**
10
+ * Container options for initialization.
11
+ */
12
+ export interface UploadContainerOptions {
13
+ branding?: UploadBranding;
14
+ /** Enable backdrop blur (modal only) */
15
+ backdropBlur?: boolean;
16
+ }
17
+ /**
18
+ * Container interface that both ModalContainer and InlineContainer implement.
19
+ * The renderer interacts with containers through this interface.
20
+ */
21
+ export interface UploadContainer {
22
+ /**
23
+ * Create the container with loading state.
24
+ * Called immediately when upload flow starts.
25
+ */
26
+ createLoading(options: {
27
+ backdropBlur?: boolean;
28
+ }, onClose: () => void): void;
29
+ /**
30
+ * Update branding after vault config loads.
31
+ */
32
+ updateBranding(branding: UploadBranding): void;
33
+ /**
34
+ * Update backdrop blur setting (may be no-op for inline container).
35
+ */
36
+ updateBackdropBlur(enabled: boolean): void;
37
+ /**
38
+ * Get the body element where views are rendered.
39
+ */
40
+ getBody(): HTMLDivElement | null;
41
+ /**
42
+ * Get the sidebar element for security info (optional).
43
+ */
44
+ getSidebar(): HTMLDivElement | null;
45
+ /**
46
+ * Show or hide the security sidebar.
47
+ */
48
+ toggleSidebar(show: boolean): void;
49
+ /**
50
+ * Check if the container is currently active.
51
+ */
52
+ isOpen(): boolean;
53
+ /**
54
+ * Destroy the container and clean up event listeners.
55
+ */
56
+ destroy(): void;
57
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Vault Upload Module
3
+ *
4
+ * Embedded upload widget for vaults with public upload enabled.
5
+ *
6
+ * @example Dialog mode (immediate)
7
+ * const result = await sv.vaults.upload({ vaultId: 'vlt_abc123' });
8
+ *
9
+ * @example Dialog mode (attached to clicks)
10
+ * sv.vaults.upload.attach('.upload-btn', { vaultId: 'vlt_abc123' });
11
+ *
12
+ * @example Inline mode
13
+ * const result = await sv.vaults.upload({
14
+ * vaultId: 'vlt_abc123',
15
+ * target: '#upload-container'
16
+ * });
17
+ */
18
+ import type { ResolvedConfig } from '../../config';
19
+ import type { UploadOptions, UploadAttachOptions, UploadResult } from './types';
20
+ export declare class VaultUploadModule {
21
+ private readonly config;
22
+ private readonly api;
23
+ private renderer;
24
+ private attachedElements;
25
+ constructor(config: ResolvedConfig);
26
+ /**
27
+ * Upload a file to a vault.
28
+ *
29
+ * - Without `target`: Opens a dialog (modal)
30
+ * - With `target`: Renders inline into the specified element
31
+ *
32
+ * @example Dialog mode
33
+ * const result = await sv.vaults.upload({ vaultId: 'vlt_abc123' });
34
+ * console.log('Uploaded:', result.ingotId);
35
+ *
36
+ * @example Inline mode
37
+ * const result = await sv.vaults.upload({
38
+ * vaultId: 'vlt_abc123',
39
+ * target: '#upload-container'
40
+ * });
41
+ */
42
+ upload(options: UploadOptions): Promise<UploadResult>;
43
+ /**
44
+ * Attach upload functionality to element clicks.
45
+ * When any matching element is clicked, opens the upload dialog.
46
+ *
47
+ * @param selector - CSS selector for elements to attach to
48
+ * @param options - Upload options including vaultId and callbacks
49
+ * @returns Cleanup function to remove event listeners
50
+ *
51
+ * @example
52
+ * const cleanup = sv.vaults.upload.attach('.upload-btn', {
53
+ * vaultId: 'vlt_abc123',
54
+ * onSuccess: (result) => console.log('Uploaded:', result.ingotId)
55
+ * });
56
+ *
57
+ * // Later, remove listeners
58
+ * cleanup();
59
+ */
60
+ attach(selector: string, options: UploadAttachOptions): () => void;
61
+ /**
62
+ * Close the upload dialog/inline UI if open.
63
+ */
64
+ close(): void;
65
+ /**
66
+ * Resolve target to an HTMLElement and create inline container.
67
+ */
68
+ private createInlineContainer;
69
+ /**
70
+ * @deprecated Use `upload()` instead. Will be removed in v2.0.
71
+ */
72
+ pop(options: UploadOptions): Promise<UploadResult>;
73
+ /**
74
+ * @deprecated Use `upload({ target })` instead. Will be removed in v2.0.
75
+ */
76
+ render(options: UploadOptions): Promise<UploadResult>;
77
+ }
78
+ export type { UploadOptions, UploadAttachOptions, UploadResult, UploadProgress, VaultUploadConfig, UploadBranding, EncryptionInfo, UploadPopOptions, UploadRenderOptions, } from './types';
79
+ export { UploadApiError } from './api';
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Inline Upload Container
3
+ *
4
+ * Renders upload UI inline within a target element.
5
+ * Unlike UploadModalContainer which creates an overlay popup, this embeds
6
+ * directly into the customer's page where render() was called.
7
+ *
8
+ * Implements the UploadContainer interface for use with UploadRenderer.
9
+ */
10
+ import type { UploadContainer } from './container';
11
+ import type { UploadBranding } from './types';
12
+ export interface InlineContainerOptions {
13
+ /** Show header with branding and optional close button */
14
+ showHeader?: boolean;
15
+ /** Show close button in header (requires showHeader) */
16
+ showCloseButton?: boolean;
17
+ /** Show footer with SparkVault branding */
18
+ showFooter?: boolean;
19
+ }
20
+ export declare class UploadInlineContainer implements UploadContainer {
21
+ private readonly targetElement;
22
+ private readonly containerOptions;
23
+ private container;
24
+ private header;
25
+ private body;
26
+ private footer;
27
+ private sidebar;
28
+ private closeBtn;
29
+ private onCloseCallback;
30
+ private closeBtnClickHandler;
31
+ private isDarkMode;
32
+ private branding;
33
+ constructor(targetElement: HTMLElement, options?: InlineContainerOptions);
34
+ /**
35
+ * Create the inline container with loading state.
36
+ */
37
+ createLoading(_options: {
38
+ backdropBlur?: boolean;
39
+ }, onClose: () => void): void;
40
+ /**
41
+ * Update branding after vault config loads.
42
+ */
43
+ updateBranding(branding: UploadBranding): void;
44
+ /**
45
+ * Update backdrop blur setting (no-op for inline container).
46
+ */
47
+ updateBackdropBlur(_enabled: boolean): void;
48
+ /**
49
+ * Set dark mode for uploading/ceremony states.
50
+ */
51
+ setDarkMode(enabled: boolean): void;
52
+ /**
53
+ * Show or hide the security sidebar.
54
+ */
55
+ toggleSidebar(show: boolean): void;
56
+ /**
57
+ * Get the body element for content rendering.
58
+ */
59
+ getBody(): HTMLDivElement | null;
60
+ /**
61
+ * Get the sidebar element.
62
+ */
63
+ getSidebar(): HTMLDivElement | null;
64
+ /**
65
+ * Check if the container is currently active.
66
+ */
67
+ isOpen(): boolean;
68
+ /**
69
+ * Destroy the container and clean up.
70
+ */
71
+ destroy(): void;
72
+ private createHeader;
73
+ private createSecuritySidebar;
74
+ private handleClose;
75
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Upload Modal Container
3
+ *
4
+ * Single responsibility: DOM modal container lifecycle.
5
+ * Creates, shows, hides, and destroys the modal overlay and container.
6
+ * Does NOT handle content rendering - that's the Renderer's job.
7
+ */
8
+ import type { UploadBranding } from './types';
9
+ import type { UploadContainer } from './container';
10
+ export interface UploadModalOptions {
11
+ branding?: UploadBranding;
12
+ backdropBlur?: boolean;
13
+ }
14
+ export interface ModalContainerElements {
15
+ overlay: HTMLDivElement;
16
+ modal: HTMLDivElement;
17
+ main: HTMLDivElement;
18
+ header: HTMLDivElement;
19
+ body: HTMLDivElement;
20
+ footer: HTMLDivElement;
21
+ sidebar: HTMLDivElement | null;
22
+ }
23
+ export declare class UploadModalContainer implements UploadContainer {
24
+ private elements;
25
+ private onCloseCallback;
26
+ private keydownHandler;
27
+ private overlayClickHandler;
28
+ private closeBtnClickHandler;
29
+ private closeBtn;
30
+ private backdropBlur;
31
+ private isDarkMode;
32
+ private headerElement;
33
+ private branding;
34
+ /**
35
+ * Create and show the modal immediately with loading state.
36
+ */
37
+ createLoading(options: {
38
+ backdropBlur?: boolean;
39
+ }, onClose: () => void): void;
40
+ /**
41
+ * Create and show the modal container.
42
+ */
43
+ private create;
44
+ private createHeader;
45
+ /**
46
+ * Update branding after vault config loads.
47
+ */
48
+ updateBranding(branding: UploadBranding): void;
49
+ /**
50
+ * Update backdrop blur setting.
51
+ */
52
+ updateBackdropBlur(enabled: boolean): void;
53
+ /**
54
+ * Set dark mode for uploading/ceremony states.
55
+ */
56
+ setDarkMode(enabled: boolean): void;
57
+ /**
58
+ * Show or hide the security sidebar.
59
+ */
60
+ toggleSidebar(show: boolean): void;
61
+ private createSecuritySidebar;
62
+ private handleClose;
63
+ /**
64
+ * Get the modal body element for content rendering.
65
+ */
66
+ getBody(): HTMLDivElement | null;
67
+ /**
68
+ * Get the sidebar element.
69
+ */
70
+ getSidebar(): HTMLDivElement | null;
71
+ /**
72
+ * Check if the modal is currently open.
73
+ */
74
+ isOpen(): boolean;
75
+ /**
76
+ * Destroy the modal and clean up all event listeners.
77
+ */
78
+ destroy(): void;
79
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Upload Renderer
3
+ *
4
+ * Orchestrates view state and rendering for vault upload flows.
5
+ * Manages the complete upload lifecycle: form, uploading, ceremony, completion.
6
+ */
7
+ import type { UploadOptions, UploadResult, UploadProgress } from './types';
8
+ import type { UploadContainer } from './container';
9
+ import { UploadApi } from './api';
10
+ interface RendererCallbacks {
11
+ onSuccess: (result: UploadResult) => void;
12
+ onError: (error: Error) => void;
13
+ onCancel: () => void;
14
+ onProgress?: (progress: UploadProgress) => void;
15
+ }
16
+ export declare class UploadRenderer {
17
+ private readonly api;
18
+ private readonly container;
19
+ private readonly options;
20
+ private readonly callbacks;
21
+ private viewState;
22
+ private config;
23
+ private selectedFile;
24
+ private fileInputElement;
25
+ constructor(container: UploadContainer, api: UploadApi, options: UploadOptions, callbacks: RendererCallbacks);
26
+ /**
27
+ * Start the upload flow.
28
+ */
29
+ start(): Promise<void>;
30
+ /**
31
+ * Close the upload flow.
32
+ */
33
+ close(): void;
34
+ private handleClose;
35
+ private setState;
36
+ private render;
37
+ private renderLoading;
38
+ private renderForm;
39
+ private renderUploading;
40
+ private renderCeremony;
41
+ private renderComplete;
42
+ private renderError;
43
+ private handleFileSelect;
44
+ private openFileSelector;
45
+ private cleanupFileInput;
46
+ private pasteHandler;
47
+ private setupPasteHandler;
48
+ private cleanupPasteHandler;
49
+ private startUpload;
50
+ private uploadWithTus;
51
+ private runCeremony;
52
+ private handleApiError;
53
+ private escapeHtml;
54
+ }
55
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Upload Widget Styles
3
+ *
4
+ * Enterprise-grade styling for the vault upload widget.
5
+ * Follows the same design principles as the identity modal.
6
+ */
7
+ import type { UploadBranding } from './types';
8
+ export interface UploadStyleOptions {
9
+ branding?: UploadBranding;
10
+ backdropBlur?: boolean;
11
+ theme?: 'light' | 'dark';
12
+ }
13
+ /**
14
+ * Inject upload widget styles into the document head.
15
+ */
16
+ export declare function injectUploadStyles(options: UploadStyleOptions): void;
17
+ /**
18
+ * Remove upload widget styles.
19
+ */
20
+ export declare function removeUploadStyles(): void;
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Vault Upload Module Types
3
+ *
4
+ * Types for the embedded vault upload widget.
5
+ */
6
+ /**
7
+ * Branding configuration from vault upload info.
8
+ */
9
+ export interface UploadBranding {
10
+ /** Organization name */
11
+ organizationName: string;
12
+ /** Light theme logo URL */
13
+ logoLightUrl: string | null;
14
+ /** Dark theme logo URL */
15
+ logoDarkUrl: string | null;
16
+ }
17
+ /**
18
+ * Encryption information for the vault.
19
+ */
20
+ export interface EncryptionInfo {
21
+ /** Encryption algorithm (e.g., 'AES-256-GCM') */
22
+ algorithm: string;
23
+ /** Key derivation method (e.g., 'Triple Zero-Trust') */
24
+ keyDerivation: string;
25
+ /** Post-quantum protection status */
26
+ postQuantum: string;
27
+ }
28
+ /**
29
+ * Vault upload configuration from API.
30
+ */
31
+ export interface VaultUploadConfig {
32
+ /** Vault ID */
33
+ vaultId: string;
34
+ /** Vault name */
35
+ vaultName: string;
36
+ /** Maximum upload size in bytes */
37
+ maxSizeBytes: number;
38
+ /** Branding information */
39
+ branding: UploadBranding;
40
+ /** Encryption details */
41
+ encryption: EncryptionInfo;
42
+ /** Forge status */
43
+ forgeStatus: 'active' | 'inactive';
44
+ }
45
+ /**
46
+ * Options for upload().
47
+ * - Without `target`: Opens a dialog (modal)
48
+ * - With `target`: Renders inline into the specified element
49
+ */
50
+ export interface UploadOptions {
51
+ /** Vault ID to upload to */
52
+ vaultId: string;
53
+ /**
54
+ * Target element for inline rendering. Can be:
55
+ * - A CSS selector string (e.g., "#upload-container")
56
+ * - An HTMLElement reference
57
+ * - Omitted for dialog mode (default)
58
+ */
59
+ target?: string | HTMLElement;
60
+ /** Override backdrop blur for this dialog (uses global config if omitted) */
61
+ backdropBlur?: boolean;
62
+ /** Callback when upload completes successfully (if omitted, uses server-configured redirect) */
63
+ onSuccess?: (result: UploadResult) => void;
64
+ /** Callback when an error occurs (if omitted, uses server-configured redirect) */
65
+ onError?: (error: Error) => void;
66
+ /** Callback when user cancels (if omitted, uses server-configured redirect) */
67
+ onCancel?: () => void;
68
+ /** Callback for upload progress */
69
+ onProgress?: (progress: UploadProgress) => void;
70
+ }
71
+ /** Options for attach() - binds upload to element clicks */
72
+ export interface UploadAttachOptions {
73
+ /** Vault ID to upload to */
74
+ vaultId: string;
75
+ /** Callback when upload completes successfully */
76
+ onSuccess?: (result: UploadResult) => void;
77
+ /** Callback when an error occurs */
78
+ onError?: (error: Error) => void;
79
+ /** Callback when user cancels */
80
+ onCancel?: () => void;
81
+ /** Callback for upload progress */
82
+ onProgress?: (progress: UploadProgress) => void;
83
+ }
84
+ /** @deprecated Use UploadOptions instead */
85
+ export type UploadPopOptions = UploadOptions;
86
+ /** @deprecated Use UploadOptions instead */
87
+ export type UploadRenderOptions = UploadOptions;
88
+ /**
89
+ * Upload progress information.
90
+ */
91
+ export interface UploadProgress {
92
+ /** Bytes uploaded */
93
+ bytesUploaded: number;
94
+ /** Total bytes */
95
+ bytesTotal: number;
96
+ /** Percentage (0-100) */
97
+ percentage: number;
98
+ /** Current phase */
99
+ phase: 'uploading' | 'ceremony' | 'complete';
100
+ }
101
+ /**
102
+ * Successful upload result.
103
+ */
104
+ export interface UploadResult {
105
+ /** Ingot ID */
106
+ ingotId: string;
107
+ /** Vault ID */
108
+ vaultId: string;
109
+ /** Original filename */
110
+ filename: string;
111
+ /** File size in bytes */
112
+ sizeBytes: number;
113
+ /** Upload timestamp (ISO 8601) */
114
+ uploadTime: string;
115
+ }
116
+ /**
117
+ * Upload view states.
118
+ */
119
+ export type UploadViewState = {
120
+ view: 'loading';
121
+ } | {
122
+ view: 'form';
123
+ config: VaultUploadConfig;
124
+ error?: string;
125
+ } | {
126
+ view: 'uploading';
127
+ file: File;
128
+ ingotId: string;
129
+ requestId: string;
130
+ progress: number;
131
+ bytesUploaded: number;
132
+ } | {
133
+ view: 'ceremony';
134
+ file: File;
135
+ ingotId: string;
136
+ requestId: string;
137
+ step: number;
138
+ complete: boolean;
139
+ } | {
140
+ view: 'complete';
141
+ result: UploadResult;
142
+ config: VaultUploadConfig;
143
+ } | {
144
+ view: 'error';
145
+ message: string;
146
+ code: string;
147
+ httpStatus?: number;
148
+ };
149
+ /**
150
+ * API response for vault upload info.
151
+ */
152
+ export interface VaultUploadInfoResponse {
153
+ vault_id: string;
154
+ vault_name: string;
155
+ max_size_bytes: number;
156
+ branding: {
157
+ organization_name: string;
158
+ logo_light_url: string | null;
159
+ logo_dark_url: string | null;
160
+ };
161
+ encryption: {
162
+ algorithm: string;
163
+ key_derivation: string;
164
+ post_quantum: string;
165
+ };
166
+ forge_status: 'active' | 'inactive';
167
+ }
168
+ /**
169
+ * API response for initiating upload.
170
+ */
171
+ export interface InitiateUploadResponse {
172
+ forge_url: string;
173
+ ingot_id: string;
174
+ }
175
+ /**
176
+ * Ceremony step definition.
177
+ */
178
+ export interface CeremonyStep {
179
+ /** Display text */
180
+ text: string;
181
+ /** Duration in milliseconds */
182
+ duration: number;
183
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sparkvault/sdk",
3
- "version": "1.1.6",
4
- "description": "SparkVault JavaScript SDK - Identity, Sparks, Vaults, and RNG",
3
+ "version": "1.8.2",
4
+ "description": "SparkVault JavaScript SDK - Identity Verification and Encrypted Vaults",
5
5
  "type": "module",
6
6
  "main": "dist/sparkvault.cjs.js",
7
7
  "module": "dist/sparkvault.esm.js",
@@ -16,8 +16,7 @@
16
16
  "typecheck": "tsc --noEmit",
17
17
  "lint": "eslint src --ext .ts",
18
18
  "test": "vitest run",
19
- "test:watch": "vitest",
20
- "prepublishOnly": "npm run build"
19
+ "test:watch": "vitest"
21
20
  },
22
21
  "keywords": [
23
22
  "sparkvault",
@@ -28,14 +27,14 @@
28
27
  "passkey",
29
28
  "webauthn",
30
29
  "totp",
31
- "vault",
32
- "rng"
30
+ "vault"
33
31
  ],
34
32
  "author": "SparkVault",
35
33
  "license": "MIT",
36
34
  "repository": {
37
35
  "type": "git",
38
- "url": "https://github.com/Spark-Vault/sdk-js.git"
36
+ "url": "git+https://github.com/Spark-Vault/platform.git",
37
+ "directory": "packages/sdk-js"
39
38
  },
40
39
  "homepage": "https://sparkvault.com/api/docs/sdk",
41
40
  "devDependencies": {
@@ -1,54 +0,0 @@
1
- /**
2
- * RNG Module
3
- *
4
- * Generate cryptographically secure random numbers.
5
- * Uses hybrid entropy from AWS KMS HSM + local CSPRNG.
6
- */
7
- import { HttpClient } from '../http';
8
- import type { GenerateOptions, RandomResult } from './types';
9
- export declare class RNGModule {
10
- private readonly http;
11
- constructor(http: HttpClient);
12
- /**
13
- * Generate cryptographically secure random bytes.
14
- *
15
- * @example
16
- * const result = await sv.rng.generate({ bytes: 32, format: 'hex' });
17
- * console.log(result.value);
18
- */
19
- generate(options: GenerateOptions): Promise<RandomResult>;
20
- /**
21
- * Generate a random UUID v4.
22
- *
23
- * @example
24
- * const uuid = await sv.rng.uuid();
25
- * console.log(uuid); // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
26
- */
27
- uuid(): Promise<string>;
28
- /**
29
- * Generate a random hex string.
30
- *
31
- * @example
32
- * const hex = await sv.rng.hex(16);
33
- * console.log(hex); // '1a2b3c4d5e6f7890...'
34
- */
35
- hex(bytes: number): Promise<string>;
36
- /**
37
- * Generate a random alphanumeric string.
38
- *
39
- * @example
40
- * const code = await sv.rng.alphanumeric(8);
41
- * console.log(code); // 'A1B2C3D4'
42
- */
43
- alphanumeric(bytes: number): Promise<string>;
44
- /**
45
- * Generate a random password with special characters.
46
- *
47
- * @example
48
- * const password = await sv.rng.password(16);
49
- * console.log(password); // 'aB3$xY7!mN9@pQ2#'
50
- */
51
- password(bytes: number): Promise<string>;
52
- private validateOptions;
53
- }
54
- export type { GenerateOptions, RandomResult, RNGFormat } from './types';