@capturly/capture-sdk 2.10.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.
- package/CHANGELOG.md +1 -0
- package/LICENSE +23 -0
- package/README.md +144 -0
- package/dist/CaptureClient.d.ts +47 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4556 -0
- package/dist/transport.d.ts +40 -0
- package/dist/types.d.ts +76 -0
- package/package.json +67 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type CaptureAccess } from './types.js';
|
|
2
|
+
export interface UploadTarget {
|
|
3
|
+
objectName: string;
|
|
4
|
+
url: string;
|
|
5
|
+
method: string;
|
|
6
|
+
/** Covered by the URL signature. Storage rejects a PUT that omits them. */
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/** Request an upload target. The size is signed in, so it must be the real
|
|
10
|
+
* byte count of what gets uploaded. */
|
|
11
|
+
export declare function requestUpload(args: {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
access: CaptureAccess;
|
|
14
|
+
sizeBytes: number;
|
|
15
|
+
}): Promise<UploadTarget>;
|
|
16
|
+
/**
|
|
17
|
+
* Send the bytes. XHR rather than fetch only for `upload.onprogress`; fetch
|
|
18
|
+
* still has no upload progress in browsers.
|
|
19
|
+
*/
|
|
20
|
+
export declare function uploadBlob(args: {
|
|
21
|
+
target: UploadTarget;
|
|
22
|
+
blob: Blob;
|
|
23
|
+
onProgress?: (fraction: number) => void;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Confirm the upload and record the submission. Idempotent on the object
|
|
27
|
+
* name, so a retry after a lost response resolves to the same submission.
|
|
28
|
+
*/
|
|
29
|
+
export declare function finalizeSubmission(args: {
|
|
30
|
+
baseUrl: string;
|
|
31
|
+
access: CaptureAccess;
|
|
32
|
+
objectName: string;
|
|
33
|
+
durationSec: number;
|
|
34
|
+
displayName?: string | undefined;
|
|
35
|
+
releaseAccepted: boolean;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
submissionId: string;
|
|
38
|
+
submittedAt: string;
|
|
39
|
+
replaced: boolean;
|
|
40
|
+
}>;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The capability this browser records under.
|
|
3
|
+
*
|
|
4
|
+
* Not an API key — a secret key grants your whole organization and must stay
|
|
5
|
+
* on your server. Your backend mints one of these per person from
|
|
6
|
+
* `POST /v1/capture-requests/{id}/contacts` (the id and `k` from the returned
|
|
7
|
+
* URL), or uses the request's `openLink.url` for a link anyone can use.
|
|
8
|
+
*/
|
|
9
|
+
export type CaptureAccess = {
|
|
10
|
+
mode: 'contact';
|
|
11
|
+
contactId: string;
|
|
12
|
+
key: string;
|
|
13
|
+
} | {
|
|
14
|
+
mode: 'open';
|
|
15
|
+
campaignId: string;
|
|
16
|
+
key: string;
|
|
17
|
+
};
|
|
18
|
+
export interface CaptureClientOptions {
|
|
19
|
+
access: CaptureAccess;
|
|
20
|
+
/** Defaults to the production API. Set it for staging or self-hosted. */
|
|
21
|
+
baseUrl?: string;
|
|
22
|
+
/** Non-fatal problems, such as a preview that could not be read. Failures
|
|
23
|
+
* that stop something are thrown. */
|
|
24
|
+
onWarning?: (message: string, cause?: unknown) => void;
|
|
25
|
+
}
|
|
26
|
+
export type CaptureState = 'idle' | 'starting' | 'recording' | 'stopping' | 'stopped';
|
|
27
|
+
export interface CaptureDevice {
|
|
28
|
+
deviceId: string;
|
|
29
|
+
label: string;
|
|
30
|
+
kind: 'audioinput' | 'videoinput';
|
|
31
|
+
}
|
|
32
|
+
export interface PreviewOptions {
|
|
33
|
+
audioDeviceId?: string;
|
|
34
|
+
videoDeviceId?: string;
|
|
35
|
+
/** Skip the camera and record audio only. */
|
|
36
|
+
audioOnly?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface CaptureTake {
|
|
39
|
+
durationSec: number;
|
|
40
|
+
/** For local playback before submitting. `discard()` revokes it, or call
|
|
41
|
+
* `URL.revokeObjectURL` yourself. */
|
|
42
|
+
previewUrl: string | null;
|
|
43
|
+
sizeBytes: number;
|
|
44
|
+
}
|
|
45
|
+
export interface SubmitOptions {
|
|
46
|
+
/** Required for an open link. Ignored for a contact link, which already has
|
|
47
|
+
* the roster name. */
|
|
48
|
+
displayName?: string;
|
|
49
|
+
/** Whether the person accepted the request's release text. Read that text
|
|
50
|
+
* from the API and show it — this writes a consent record either way. */
|
|
51
|
+
releaseAccepted: boolean;
|
|
52
|
+
/** 0–1, as the bytes move. */
|
|
53
|
+
onProgress?: (fraction: number) => void;
|
|
54
|
+
}
|
|
55
|
+
export interface SubmitResult {
|
|
56
|
+
submissionId: string;
|
|
57
|
+
submittedAt: string;
|
|
58
|
+
/** This take replaced an earlier one from the same person, and the previous
|
|
59
|
+
* recording is gone. Key your own records on the request and the person,
|
|
60
|
+
* not on a submission id. */
|
|
61
|
+
replaced: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Why something failed.
|
|
65
|
+
*
|
|
66
|
+
* `unsupported_browser`, `permission_denied` and `no_devices` are the person's
|
|
67
|
+
* to fix. `link_expired`, `request_closed` and `quota_exceeded` are yours, so
|
|
68
|
+
* a retry for those loops forever. `network` and `upload_failed` are worth
|
|
69
|
+
* retrying as-is.
|
|
70
|
+
*/
|
|
71
|
+
export type CaptureErrorCode = 'unsupported_browser' | 'permission_denied' | 'no_devices' | 'not_recording' | 'nothing_to_submit' | 'link_expired' | 'request_closed' | 'quota_exceeded' | 'upload_failed' | 'network' | 'unknown';
|
|
72
|
+
export declare class CaptureError extends Error {
|
|
73
|
+
readonly code: CaptureErrorCode;
|
|
74
|
+
readonly cause?: unknown;
|
|
75
|
+
constructor(code: CaptureErrorCode, message: string, cause?: unknown);
|
|
76
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capturly/capture-sdk",
|
|
3
|
+
"version": "2.10.2",
|
|
4
|
+
"description": "Record full-quality audio and video on your user's own device, from your own product.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"recording",
|
|
7
|
+
"video",
|
|
8
|
+
"capture",
|
|
9
|
+
"testimonials",
|
|
10
|
+
"capturly"
|
|
11
|
+
],
|
|
12
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Corey Alan LLC",
|
|
15
|
+
"url": "https://capturly.app"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://capturly.app/platform",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/Corey-Alan-Consulting/capturly.app.git",
|
|
21
|
+
"directory": "packages/capture-sdk"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/Corey-Alan-Consulting/capturly.app/issues"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=20"
|
|
28
|
+
},
|
|
29
|
+
"type": "module",
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./package.json": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"README.md",
|
|
44
|
+
"CHANGELOG.md"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "node build.mjs && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"test:watch": "vitest",
|
|
53
|
+
"lint": "eslint src --ext .ts",
|
|
54
|
+
"type-check": "tsc --noEmit",
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"prepublishOnly": "pnpm clean && pnpm type-check && pnpm test && pnpm build"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@capturly/eslint-config": "workspace:*",
|
|
61
|
+
"@capturly/recording-engine": "workspace:*",
|
|
62
|
+
"@capturly/tsconfig": "workspace:*",
|
|
63
|
+
"esbuild": "^0.25.0",
|
|
64
|
+
"typescript": "^5.4.0",
|
|
65
|
+
"vitest": "^4.1.7"
|
|
66
|
+
}
|
|
67
|
+
}
|