@snap/camera-kit 1.2.0 → 1.4.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 +1 -1
- package/dist/environment.js +1 -1
- package/dist/environment.js.map +1 -1
- package/dist/lensCoreWasmVersions.js +3 -3
- package/dist/lensCoreWasmVersions.js.map +1 -1
- package/dist/uri-handlers/internal-handlers/httpValidators.d.ts +1 -1
- package/dist/uri-handlers/internal-handlers/httpValidators.d.ts.map +1 -1
- package/dist/uri-handlers/internal-handlers/httpValidators.js +16 -19
- package/dist/uri-handlers/internal-handlers/httpValidators.js.map +1 -1
- package/dist/uri-handlers/internal-handlers/remoteApiUriHandler.d.ts +3 -0
- package/dist/uri-handlers/internal-handlers/remoteApiUriHandler.d.ts.map +1 -1
- package/dist/uri-handlers/internal-handlers/remoteApiUriHandler.js +45 -42
- package/dist/uri-handlers/internal-handlers/remoteApiUriHandler.js.map +1 -1
- package/docs/html/classes/CameraKit.html +2 -2
- package/docs/html/classes/CameraKitSession.html +2 -2
- package/docs/html/classes/CameraKitSource.html +2 -2
- package/docs/html/classes/LensPerformanceMeasurement.html +2 -2
- package/docs/html/classes/LensPerformanceMetrics.html +2 -2
- package/docs/html/classes/LensRepository.html +2 -2
- package/docs/html/classes/Transform2D.html +2 -2
- package/docs/html/classes/TypedCustomEvent.html +2 -2
- package/docs/html/classes/TypedEventTarget.html +2 -2
- package/docs/html/enums/Lens_CameraFacing.html +2 -2
- package/docs/html/functions/bootstrapCameraKit.html +2 -2
- package/docs/html/functions/createExtension.html +2 -2
- package/docs/html/functions/createImageSource.html +2 -2
- package/docs/html/functions/createMediaStreamSource.html +2 -2
- package/docs/html/functions/createVideoSource.html +2 -2
- package/docs/html/functions/estimateLensPerformance.html +2 -2
- package/docs/html/functions/filePickerFactory.html +2 -2
- package/docs/html/functions/getExtensionRequestContext.html +2 -2
- package/docs/html/functions/lensSourcesFactory.html +2 -2
- package/docs/html/functions/remoteApiServicesFactory.html +1 -1
- package/docs/html/hierarchy.html +1 -1
- package/docs/html/index.html +3 -3
- package/docs/html/interfaces/BitmojiUserInfo.html +2 -2
- package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +2 -2
- package/docs/html/interfaces/CameraKitDeviceOptions.html +2 -2
- package/docs/html/interfaces/CameraKitSourceInfo.html +2 -2
- package/docs/html/interfaces/CameraKitSourceSubscriber.html +2 -2
- package/docs/html/interfaces/ComputedFrameMetrics.html +2 -2
- package/docs/html/interfaces/CreateSessionOptions.html +2 -2
- package/docs/html/interfaces/EstimatedLensPerformance.html +2 -2
- package/docs/html/interfaces/Font.html +2 -2
- package/docs/html/interfaces/FriendUserInfo.html +2 -2
- package/docs/html/interfaces/FunctionSourceOptions.html +2 -2
- package/docs/html/interfaces/Keyboard.html +2 -2
- package/docs/html/interfaces/KeyboardActiveEvent.html +2 -2
- package/docs/html/interfaces/Lens.html +2 -2
- package/docs/html/interfaces/LensCreator.html +2 -2
- package/docs/html/interfaces/LensHttpRequest.html +2 -2
- package/docs/html/interfaces/LensLaunchData.html +2 -2
- package/docs/html/interfaces/LensSource.html +2 -2
- package/docs/html/interfaces/LensUserData.html +2 -2
- package/docs/html/interfaces/LoadAssetRequest.html +2 -2
- package/docs/html/interfaces/MediaStreamSourceOptions.html +2 -2
- package/docs/html/interfaces/Preview.html +2 -2
- package/docs/html/interfaces/RemoteApiRequest.html +2 -2
- package/docs/html/interfaces/RemoteApiResponse.html +2 -2
- package/docs/html/interfaces/RemoteApiService.html +2 -2
- package/docs/html/interfaces/Snapcode.html +2 -2
- package/docs/html/interfaces/UriCancelRequest.html +2 -2
- package/docs/html/interfaces/UriRequest.html +2 -2
- package/docs/html/interfaces/UriResponse.html +2 -2
- package/docs/html/interfaces/VideoSourceOptions.html +2 -2
- package/docs/html/modules.html +1 -1
- package/docs/html/types/ArgumentValidationError.html +2 -2
- package/docs/html/types/AssetLoader.html +2 -2
- package/docs/html/types/AssetResponse.html +1 -1
- package/docs/html/types/AssetTiming.html +2 -2
- package/docs/html/types/BenchmarkError.html +1 -1
- package/docs/html/types/BootstrapError.html +2 -2
- package/docs/html/types/CacheKeyNotFoundError.html +1 -1
- package/docs/html/types/CameraKitSessionEventListener.html +2 -2
- package/docs/html/types/CameraKitSessionEvents.html +2 -2
- package/docs/html/types/CameraKitSourceError.html +1 -1
- package/docs/html/types/ConfigurationError.html +2 -2
- package/docs/html/types/FetchHandler.html +1 -1
- package/docs/html/types/FilePicker.html +2 -2
- package/docs/html/types/FilePickerOptions.html +2 -2
- package/docs/html/types/FilePickerResult.html +2 -2
- package/docs/html/types/KeyboardEventListener.html +2 -2
- package/docs/html/types/KeyboardEvents.html +2 -2
- package/docs/html/types/LegalError.html +1 -1
- package/docs/html/types/LensAbortError.html +2 -2
- package/docs/html/types/LensAssetError.html +2 -2
- package/docs/html/types/LensContentValidationError.html +1 -1
- package/docs/html/types/LensError.html +1 -1
- package/docs/html/types/LensExecutionError.html +2 -2
- package/docs/html/types/LensHttpHandler.html +2 -2
- package/docs/html/types/LensImagePickerError.html +2 -2
- package/docs/html/types/LensLaunchParams.html +2 -2
- package/docs/html/types/LensMetricsEvents.html +2 -2
- package/docs/html/types/LensPerformanceCluster.html +1 -1
- package/docs/html/types/LensView.html +2 -2
- package/docs/html/types/LensWait.html +2 -2
- package/docs/html/types/Matrix.html +2 -2
- package/docs/html/types/PersistentStoreError.html +2 -2
- package/docs/html/types/PlatformNotSupportedError.html +2 -2
- package/docs/html/types/PublicContainer.html +2 -2
- package/docs/html/types/PublicServices.html +2 -2
- package/docs/html/types/RemoteApiCancelRequestHandler.html +2 -2
- package/docs/html/types/RemoteApiRequestHandler.html +2 -2
- package/docs/html/types/RemoteApiServices.html +1 -1
- package/docs/html/types/RemoteApiStatus.html +2 -2
- package/docs/html/types/RenderTarget.html +2 -2
- package/docs/html/types/Uri.html +1 -1
- package/docs/html/types/WebGLError.html +1 -1
- package/docs/html/types/Zodiac.html +1 -1
- package/docs/html/variables/extensionRequestContext.html +2 -2
- package/docs/md/README.md +2 -2
- package/docs/md/classes/CameraKit.md +1 -1
- package/docs/md/classes/CameraKitSession.md +1 -1
- package/docs/md/classes/CameraKitSource.md +1 -1
- package/docs/md/classes/LensPerformanceMeasurement.md +1 -1
- package/docs/md/classes/LensPerformanceMetrics.md +1 -1
- package/docs/md/classes/LensRepository.md +1 -1
- package/docs/md/classes/Transform2D.md +1 -1
- package/docs/md/classes/TypedCustomEvent.md +1 -1
- package/docs/md/classes/TypedEventTarget.md +1 -1
- package/docs/md/enumerations/Lens_CameraFacing.md +1 -1
- package/docs/md/functions/bootstrapCameraKit.md +1 -1
- package/docs/md/functions/createExtension.md +1 -1
- package/docs/md/functions/createImageSource.md +1 -1
- package/docs/md/functions/createMediaStreamSource.md +1 -1
- package/docs/md/functions/createVideoSource.md +1 -1
- package/docs/md/functions/estimateLensPerformance.md +1 -1
- package/docs/md/functions/filePickerFactory.md +1 -1
- package/docs/md/functions/getExtensionRequestContext.md +1 -1
- package/docs/md/functions/lensSourcesFactory.md +1 -1
- package/docs/md/functions/remoteApiServicesFactory.md +1 -1
- package/docs/md/globals.md +2 -2
- package/docs/md/interfaces/BitmojiUserInfo.md +1 -1
- package/docs/md/interfaces/CameraKitBootstrapConfiguration.md +1 -1
- package/docs/md/interfaces/CameraKitDeviceOptions.md +1 -1
- package/docs/md/interfaces/CameraKitSourceInfo.md +1 -1
- package/docs/md/interfaces/CameraKitSourceSubscriber.md +1 -1
- package/docs/md/interfaces/ComputedFrameMetrics.md +1 -1
- package/docs/md/interfaces/CreateSessionOptions.md +1 -1
- package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
- package/docs/md/interfaces/Font.md +1 -1
- package/docs/md/interfaces/FriendUserInfo.md +1 -1
- package/docs/md/interfaces/FunctionSourceOptions.md +1 -1
- package/docs/md/interfaces/Keyboard.md +1 -1
- package/docs/md/interfaces/KeyboardActiveEvent.md +1 -1
- package/docs/md/interfaces/Lens.md +1 -1
- package/docs/md/interfaces/LensCreator.md +1 -1
- package/docs/md/interfaces/LensHttpRequest.md +1 -1
- package/docs/md/interfaces/LensLaunchData.md +1 -1
- package/docs/md/interfaces/LensSource.md +1 -1
- package/docs/md/interfaces/LensUserData.md +1 -1
- package/docs/md/interfaces/LoadAssetRequest.md +1 -1
- package/docs/md/interfaces/MediaStreamSourceOptions.md +1 -1
- package/docs/md/interfaces/Preview.md +1 -1
- package/docs/md/interfaces/RemoteApiRequest.md +1 -1
- package/docs/md/interfaces/RemoteApiResponse.md +1 -1
- package/docs/md/interfaces/RemoteApiService.md +1 -1
- package/docs/md/interfaces/Snapcode.md +1 -1
- package/docs/md/interfaces/UriCancelRequest.md +1 -1
- package/docs/md/interfaces/UriRequest.md +1 -1
- package/docs/md/interfaces/UriResponse.md +1 -1
- package/docs/md/interfaces/VideoSourceOptions.md +1 -1
- package/docs/md/type-aliases/ArgumentValidationError.md +1 -1
- package/docs/md/type-aliases/AssetLoader.md +1 -1
- package/docs/md/type-aliases/AssetResponse.md +1 -1
- package/docs/md/type-aliases/AssetTiming.md +1 -1
- package/docs/md/type-aliases/BenchmarkError.md +1 -1
- package/docs/md/type-aliases/BootstrapError.md +1 -1
- package/docs/md/type-aliases/CacheKeyNotFoundError.md +1 -1
- package/docs/md/type-aliases/CameraKitSessionEventListener.md +1 -1
- package/docs/md/type-aliases/CameraKitSessionEvents.md +1 -1
- package/docs/md/type-aliases/CameraKitSourceError.md +1 -1
- package/docs/md/type-aliases/ConfigurationError.md +1 -1
- package/docs/md/type-aliases/FetchHandler.md +1 -1
- package/docs/md/type-aliases/FilePicker.md +1 -1
- package/docs/md/type-aliases/FilePickerOptions.md +1 -1
- package/docs/md/type-aliases/FilePickerResult.md +1 -1
- package/docs/md/type-aliases/KeyboardEventListener.md +1 -1
- package/docs/md/type-aliases/KeyboardEvents.md +1 -1
- package/docs/md/type-aliases/LegalError.md +1 -1
- package/docs/md/type-aliases/LensAbortError.md +1 -1
- package/docs/md/type-aliases/LensAssetError.md +1 -1
- package/docs/md/type-aliases/LensContentValidationError.md +1 -1
- package/docs/md/type-aliases/LensError.md +1 -1
- package/docs/md/type-aliases/LensExecutionError.md +1 -1
- package/docs/md/type-aliases/LensHttpHandler.md +1 -1
- package/docs/md/type-aliases/LensImagePickerError.md +1 -1
- package/docs/md/type-aliases/LensLaunchParams.md +1 -1
- package/docs/md/type-aliases/LensMetricsEvents.md +1 -1
- package/docs/md/type-aliases/LensPerformanceCluster.md +1 -1
- package/docs/md/type-aliases/LensView.md +1 -1
- package/docs/md/type-aliases/LensWait.md +1 -1
- package/docs/md/type-aliases/Matrix.md +1 -1
- package/docs/md/type-aliases/PersistentStoreError.md +1 -1
- package/docs/md/type-aliases/PlatformNotSupportedError.md +1 -1
- package/docs/md/type-aliases/PublicContainer.md +1 -1
- package/docs/md/type-aliases/PublicServices.md +1 -1
- package/docs/md/type-aliases/RemoteApiCancelRequestHandler.md +1 -1
- package/docs/md/type-aliases/RemoteApiRequestHandler.md +1 -1
- package/docs/md/type-aliases/RemoteApiServices.md +1 -1
- package/docs/md/type-aliases/RemoteApiStatus.md +1 -1
- package/docs/md/type-aliases/RenderTarget.md +1 -1
- package/docs/md/type-aliases/Uri.md +1 -1
- package/docs/md/type-aliases/WebGLError.md +1 -1
- package/docs/md/type-aliases/Zodiac.md +1 -1
- package/docs/md/variables/extensionRequestContext.md +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -181,7 +181,7 @@ session.pause('capture');
|
|
|
181
181
|
|
|
182
182
|
## Error Handling
|
|
183
183
|
|
|
184
|
-
Camera Kit Web SDK methods may throw errors, or return rejected Promises -- these are documented in the [API docs](https://kit.snapchat.com/reference/CameraKit/web/1.
|
|
184
|
+
Camera Kit Web SDK methods may throw errors, or return rejected Promises -- these are documented in the [API docs](https://kit.snapchat.com/reference/CameraKit/web/1.4.0/index.html). It is good practice to handle such cases, to provide a good experience to your users.
|
|
185
185
|
|
|
186
186
|
Errors may also occur during Lens rendering. For example, Lenses contain their own scripting, which could throw an error. A rendering error could also occur if a Lens attempts to use a feature that is not supported by Camera Kit Web SDK.
|
|
187
187
|
|
package/dist/environment.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export default { PACKAGE_VERSION: "1.
|
|
1
|
+
export default { PACKAGE_VERSION: "1.4.0" };
|
|
2
2
|
//# sourceMappingURL=environment.js.map
|
package/dist/environment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC","sourcesContent":["export default { PACKAGE_VERSION: \"1.
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC","sourcesContent":["export default { PACKAGE_VERSION: \"1.4.0\" };\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
version: "
|
|
3
|
-
buildNumber: "
|
|
4
|
-
baseUrl: "https://cf-st.sc-cdn.net/d/
|
|
2
|
+
version: "305",
|
|
3
|
+
buildNumber: "574",
|
|
4
|
+
baseUrl: "https://cf-st.sc-cdn.net/d/mJaVaSIsblEzSy0An5Tei?go=IgsKCTIBBEgBUFxgAQ%3D%3D&uc=92",
|
|
5
5
|
};
|
|
6
6
|
//# sourceMappingURL=lensCoreWasmVersions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lensCoreWasmVersions.js","sourceRoot":"","sources":["../src/lensCoreWasmVersions.ts"],"names":[],"mappings":"AAAA,eAAe;IACX,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,OAAO,EAAE,oFAAoF;CAChG,CAAC","sourcesContent":["export default {\n version: \"
|
|
1
|
+
{"version":3,"file":"lensCoreWasmVersions.js","sourceRoot":"","sources":["../src/lensCoreWasmVersions.ts"],"names":[],"mappings":"AAAA,eAAe;IACX,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,OAAO,EAAE,oFAAoF;CAChG,CAAC","sourcesContent":["export default {\n version: \"305\",\n buildNumber: \"574\",\n baseUrl: \"https://cf-st.sc-cdn.net/d/mJaVaSIsblEzSy0An5Tei?go=IgsKCTIBBEgBUFxgAQ%3D%3D&uc=92\",\n};\n"]}
|
|
@@ -5,5 +5,5 @@ export declare const requestValidationError: (message: string, cause?: unknown)
|
|
|
5
5
|
export declare function validateRequest(request: UriRequest, specs: RemoteApiSpec[]): void;
|
|
6
6
|
export declare function validatePath(path: string, parameters: RemoteParameter[]): void;
|
|
7
7
|
export declare function validateHeaders(headers: Record<string, string>, parameters: RemoteParameter[]): void;
|
|
8
|
-
export declare function validateQuery(
|
|
8
|
+
export declare function validateQuery(queryParams: URLSearchParams, parameters: RemoteParameter[]): void;
|
|
9
9
|
//# sourceMappingURL=httpValidators.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpValidators.d.ts","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/httpValidators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,+DAA+D,CAAC;AAIpH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,eAAO,MAAM,sBAAsB,6CAAyC,CAAC;AAE7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"httpValidators.d.ts","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/httpValidators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,+DAA+D,CAAC;AAIpH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,eAAO,MAAM,sBAAsB,6CAAyC,CAAC;AAE7E,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,QA8B1E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,QAqDvE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,eAAe,EAAE,QAuB7F;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,QAwBxF"}
|
|
@@ -5,22 +5,23 @@ import { namedError } from "../../namedErrors";
|
|
|
5
5
|
export const requestValidationErrorName = "RequestValidationError";
|
|
6
6
|
export const requestValidationError = namedError(requestValidationErrorName);
|
|
7
7
|
export function validateRequest(request, specs) {
|
|
8
|
-
var _a
|
|
8
|
+
var _a;
|
|
9
|
+
const url = new URL(request.uri);
|
|
9
10
|
for (const spec of specs) {
|
|
10
|
-
|
|
11
|
-
if (!request.uri.startsWith(url))
|
|
11
|
+
if (url.host !== spec.host || url.protocol !== (spec.tlsRequired ? "https:" : "http:")) {
|
|
12
12
|
continue;
|
|
13
|
-
|
|
13
|
+
}
|
|
14
|
+
const path = url.pathname.replace(/^\/|\/$/g, "");
|
|
14
15
|
for (const endpoint of spec.endpoints) {
|
|
15
|
-
const endpointPath = endpoint.path.replace(
|
|
16
|
+
const endpointPath = endpoint.path.replace(/^\/|\/$/g, "");
|
|
16
17
|
if (!path.startsWith(endpointPath))
|
|
17
18
|
continue;
|
|
18
|
-
const method = (
|
|
19
|
+
const method = (_a = RemoteEndpoint_HttpRequestMethod[request.method]) !== null && _a !== void 0 ? _a : RemoteEndpoint_HttpRequestMethod.UNRECOGNIZED;
|
|
19
20
|
if (!endpoint.methods.includes(method))
|
|
20
21
|
continue;
|
|
21
|
-
validatePath(
|
|
22
|
+
validatePath(path.split(endpointPath)[1], endpoint.parameters);
|
|
22
23
|
validateHeaders(request.metadata, endpoint.parameters);
|
|
23
|
-
validateQuery(
|
|
24
|
+
validateQuery(url.searchParams, endpoint.parameters);
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
@@ -45,7 +46,12 @@ export function validatePath(path, parameters) {
|
|
|
45
46
|
}
|
|
46
47
|
else if (param.optional) {
|
|
47
48
|
if (paramNameComponent === param.name) {
|
|
48
|
-
|
|
49
|
+
if (paramValueComponent !== undefined) {
|
|
50
|
+
paramIndex += 2;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
paramIndex += 1;
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
57
|
else {
|
|
@@ -75,9 +81,6 @@ export function validateHeaders(headers, parameters) {
|
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
else if (param.optional) {
|
|
78
|
-
if (headerValue != undefined && isEmptyString(headerValue)) {
|
|
79
|
-
throw requestValidationError(`Header '${param.name}' is present but empty. If provided, it should not be empty.`);
|
|
80
|
-
}
|
|
81
84
|
}
|
|
82
85
|
else {
|
|
83
86
|
if (headerValue == undefined || isEmptyString(headerValue)) {
|
|
@@ -86,9 +89,7 @@ export function validateHeaders(headers, parameters) {
|
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
|
-
export function validateQuery(
|
|
90
|
-
const url = new URL(uri);
|
|
91
|
-
const queryParams = new URLSearchParams(url.search);
|
|
92
|
+
export function validateQuery(queryParams, parameters) {
|
|
92
93
|
for (const param of parameters) {
|
|
93
94
|
if (param.location !== RemoteParameter_ParameterLocation.QUERY)
|
|
94
95
|
continue;
|
|
@@ -100,10 +101,6 @@ export function validateQuery(uri, parameters) {
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
else if (param.optional) {
|
|
103
|
-
if (paramValue != undefined && isEmptyString(paramValue)) {
|
|
104
|
-
throw requestValidationError(`Optional query parameter '${param.name}' is present but empty. ` +
|
|
105
|
-
`If provided, it should not be empty.`);
|
|
106
|
-
}
|
|
107
104
|
}
|
|
108
105
|
else {
|
|
109
106
|
if (paramValue == undefined || isEmptyString(paramValue)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpValidators.js","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/httpValidators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,gCAAgC,EAAE,MAAM,+DAA+D,CAAC;AACjH,OAAO,EAAE,iCAAiC,EAAE,MAAM,+DAA+D,CAAC;AAClH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,MAAM,CAAC,MAAM,0BAA0B,GAAG,wBAAwB,CAAC;AACnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,UAAU,CAAC,0BAA0B,CAAC,CAAC;AAE7E,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE,KAAsB;;IAEvE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACtB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAEvE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAG3C,MAAM,IAAI,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,mCAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;YACnC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAE7C,MAAM,MAAM,GACR,MAAA,gCAAgC,CAAC,OAAO,CAAC,MAAM,CAAC,mCAAI,gCAAgC,CAAC,YAAY,CAAC;YACtG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,SAAS;YAEjD,YAAY,CAAC,MAAA,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,mCAAI,EAAE,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrE,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YACvD,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YAEhD,OAAO;SACV;KACJ;IAGD,MAAM,sBAAsB,CAAC,kEAAkE,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,UAA6B;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEvD,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;QAC5B,IAAI,KAAK,CAAC,QAAQ,KAAK,iCAAiC,CAAC,IAAI;YAAE,SAAS;QAExE,MAAM,kBAAkB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,mBAAmB,GAAG,cAAc,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAE3D,IAAI,KAAK,CAAC,QAAQ,EAAE;YAEhB,IAAI,kBAAkB,KAAK,KAAK,CAAC,IAAI,IAAI,mBAAmB,KAAK,KAAK,CAAC,YAAY,EAAE;gBACjF,UAAU,IAAI,CAAC,CAAC;aACnB;iBAAM;gBACH,MAAM,sBAAsB,CACxB,gCAAgC,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,YAAY,IAAI;oBAC7E,eAAe,UAAU,gBAAgB,kBAAkB,UAAU,mBAAmB,IAAI,CACnG,CAAC;aACL;SACJ;aAAM,IAAI,KAAK,CAAC,QAAQ,EAAE;YACvB,IAAI,kBAAkB,KAAK,KAAK,CAAC,IAAI,EAAE;gBACnC,UAAU,IAAI,CAAC,CAAC;aACnB;SAEJ;aAAM;YAEH,IAAI,kBAAkB,KAAK,KAAK,CAAC,IAAI,IAAI,mBAAmB,KAAK,SAAS,EAAE;gBACxE,UAAU,IAAI,CAAC,CAAC;aACnB;iBAAM;gBACH,MAAM,sBAAsB,CACxB,uBAAuB,KAAK,CAAC,IAAI,8BAA8B,UAAU,IAAI;oBACzE,cAAc,kBAAkB,UAAU,mBAAmB,IAAI,CACxE,CAAC;aACL;SACJ;KACJ;IAGD,IAAI,UAAU,KAAK,cAAc,CAAC,MAAM,EAAE;QACtC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/D,MAAM,sBAAsB,CACxB,yDAAyD,UAAU,MAAM,WAAW,IAAI,CAC3F,CAAC;KACL;AACL,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA+B,EAAE,UAA6B;IAC1F,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;QAC5B,IAAI,KAAK,CAAC,QAAQ,KAAK,iCAAiC,CAAC,MAAM;YAAE,SAAS;QAE1E,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,KAAK,CAAC,QAAQ,EAAE;YAEhB,IAAI,WAAW,KAAK,KAAK,CAAC,YAAY,EAAE;gBACpC,MAAM,sBAAsB,CACxB,6BAA6B,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,YAAY,KAAK;oBAC3E,cAAc,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,WAAW,IAAI,CACnD,CAAC;aACL;SACJ;aAAM,IAAI,KAAK,CAAC,QAAQ,EAAE;YAEvB,IAAI,WAAW,IAAI,SAAS,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE;gBACxD,MAAM,sBAAsB,CACxB,WAAW,KAAK,CAAC,IAAI,8DAA8D,CACtF,CAAC;aACL;SACJ;aAAM;YAEH,IAAI,WAAW,IAAI,SAAS,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE;gBACxD,MAAM,sBAAsB,CAAC,oBAAoB,KAAK,CAAC,IAAI,wBAAwB,CAAC,CAAC;aACxF;SACJ;KACJ;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,UAA6B;IACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;QAC5B,IAAI,KAAK,CAAC,QAAQ,KAAK,iCAAiC,CAAC,KAAK;YAAE,SAAS;QAEzE,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,IAAI,KAAK,CAAC,QAAQ,EAAE;YAEhB,IAAI,UAAU,KAAK,KAAK,CAAC,YAAY,EAAE;gBACnC,MAAM,sBAAsB,CACxB,sCAAsC,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,YAAY,KAAK;oBACpF,cAAc,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,WAAW,IAAI,CAClD,CAAC;aACL;SACJ;aAAM,IAAI,KAAK,CAAC,QAAQ,EAAE;YAEvB,IAAI,UAAU,IAAI,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE;gBACtD,MAAM,sBAAsB,CACxB,6BAA6B,KAAK,CAAC,IAAI,0BAA0B;oBAC7D,sCAAsC,CAC7C,CAAC;aACL;SACJ;aAAM;YAEH,IAAI,UAAU,IAAI,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE;gBACtD,MAAM,sBAAsB,CAAC,6BAA6B,KAAK,CAAC,IAAI,wBAAwB,CAAC,CAAC;aACjG;SACJ;KACJ;AAEL,CAAC","sourcesContent":["import { isEmptyString } from \"../../common/typeguards\";\nimport type { RemoteApiSpec, RemoteParameter } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { RemoteEndpoint_HttpRequestMethod } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { RemoteParameter_ParameterLocation } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { namedError } from \"../../namedErrors\";\nimport type { UriRequest } from \"../UriHandlers\";\n\nexport const requestValidationErrorName = \"RequestValidationError\";\nexport const requestValidationError = namedError(requestValidationErrorName);\n\nexport function validateRequest(request: UriRequest, specs: RemoteApiSpec[]) {\n // 1. Given url, method and headers and spec:\n for (const spec of specs) {\n const url = `${spec.tlsRequired ? \"https://\" : \"http://\"}${spec.host}`;\n // 2. Check url starts with schema + the host. If yes trim that part and split by /\n if (!request.uri.startsWith(url)) continue;\n\n // 3. Split the rest by / and go for each part together with the path parameters.\n const path = (request.uri.split(url)[1] ?? \"\").replace(/^\\//, \"\").replace(/\\/$/, \"\");\n for (const endpoint of spec.endpoints) {\n const endpointPath = endpoint.path.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n if (!path.startsWith(endpointPath)) continue;\n\n const method =\n RemoteEndpoint_HttpRequestMethod[request.method] ?? RemoteEndpoint_HttpRequestMethod.UNRECOGNIZED;\n if (!endpoint.methods.includes(method)) continue;\n\n validatePath(path.split(endpointPath)[1] ?? \"\", endpoint.parameters);\n validateHeaders(request.metadata, endpoint.parameters);\n validateQuery(request.uri, endpoint.parameters);\n // The request matches the current endpoint\n return;\n }\n }\n\n // The request does not match any of the endpoints\n throw requestValidationError(\"The request does not match any of the Remote API specifications.\");\n}\n\nexport function validatePath(path: string, parameters: RemoteParameter[]) {\n const pathComponents = path.split(\"/\").filter(Boolean);\n\n let paramIndex = 0;\n\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.PATH) continue;\n\n const paramNameComponent = pathComponents[paramIndex];\n const paramValueComponent = pathComponents[paramIndex + 1];\n\n if (param.constant) {\n // For constant parameters, the value must match the defaultValue\n if (paramNameComponent === param.name && paramValueComponent === param.defaultValue) {\n paramIndex += 2; // Move to the next parameter pair\n } else {\n throw requestValidationError(\n `Expected constant parameter '${param.name}' with value '${param.defaultValue}' ` +\n `at position ${paramIndex}, but found '${paramNameComponent}' and '${paramValueComponent}'.`\n );\n }\n } else if (param.optional) {\n if (paramNameComponent === param.name) {\n paramIndex += 2; // Move to the next parameter pair if optional parameter exists\n }\n // If optional and not present, continue without incrementing paramIndex\n } else {\n // For regular parameters, we just need to ensure a name/value pair exists\n if (paramNameComponent === param.name && paramValueComponent !== undefined) {\n paramIndex += 2; // Move to the next parameter pair\n } else {\n throw requestValidationError(\n `Expected parameter '${param.name}' with a value at position ${paramIndex}, ` +\n `but found '${paramNameComponent}' and '${paramValueComponent}'.`\n );\n }\n }\n }\n\n // After processing all parameters, there should be no extra path components\n if (paramIndex !== pathComponents.length) {\n const invalidPath = pathComponents.slice(paramIndex).join(\"/\");\n throw requestValidationError(\n `Unexpected extra path components starting at position ${paramIndex}: '${invalidPath}'.`\n );\n }\n}\n\nexport function validateHeaders(headers: Record<string, string>, parameters: RemoteParameter[]) {\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.HEADER) continue;\n\n const headerValue = headers[param.name];\n\n if (param.constant) {\n // For constant parameters, the header must exist and match defaultValue\n if (headerValue !== param.defaultValue) {\n throw requestValidationError(\n `Expected constant header '${param.name}' with value '${param.defaultValue}', ` +\n `but found '${headerValue ?? \"undefined\"}'.`\n );\n }\n } else if (param.optional) {\n // If optional, we only validate if the header exists\n if (headerValue != undefined && isEmptyString(headerValue)) {\n throw requestValidationError(\n `Header '${param.name}' is present but empty. If provided, it should not be empty.`\n );\n }\n } else {\n // For regular parameters, the header must exist and have a non-empty value\n if (headerValue == undefined || isEmptyString(headerValue)) {\n throw requestValidationError(`Required header '${param.name}' is missing or empty.`);\n }\n }\n }\n}\n\nexport function validateQuery(uri: string, parameters: RemoteParameter[]) {\n const url = new URL(uri);\n const queryParams = new URLSearchParams(url.search);\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.QUERY) continue;\n\n const paramValue = queryParams.get(param.name);\n\n if (param.constant) {\n // For constant parameters, the query parameter must exist and match defaultValue\n if (paramValue !== param.defaultValue) {\n throw requestValidationError(\n `Expected constant query parameter '${param.name}' with value '${param.defaultValue}', ` +\n `but found '${paramValue ?? \"undefined\"}'.`\n );\n }\n } else if (param.optional) {\n // If optional, validate only if the query parameter exists\n if (paramValue != undefined && isEmptyString(paramValue)) {\n throw requestValidationError(\n `Optional query parameter '${param.name}' is present but empty. ` +\n `If provided, it should not be empty.`\n );\n }\n } else {\n // For regular parameters, the query parameter must exist and have a non-empty value\n if (paramValue == undefined || isEmptyString(paramValue)) {\n throw requestValidationError(`Required query parameter '${param.name}' is missing or empty.`);\n }\n }\n }\n // All query parameters are valid\n}\n"]}
|
|
1
|
+
{"version":3,"file":"httpValidators.js","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/httpValidators.ts"],"names":[],"mappings":"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","sourcesContent":["import { isEmptyString } from \"../../common/typeguards\";\nimport type { RemoteApiSpec, RemoteParameter } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { RemoteEndpoint_HttpRequestMethod } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { RemoteParameter_ParameterLocation } from \"../../generated-proto/pb_schema/camera_kit/v3/remote_api_spec\";\nimport { namedError } from \"../../namedErrors\";\nimport type { UriRequest } from \"../UriHandlers\";\n\nexport const requestValidationErrorName = \"RequestValidationError\";\nexport const requestValidationError = namedError(requestValidationErrorName);\n\nexport function validateRequest(request: UriRequest, specs: RemoteApiSpec[]) {\n const url = new URL(request.uri);\n\n // 1. Given url, method and headers and spec:\n for (const spec of specs) {\n // 2. Check protocol and host.\n if (url.host !== spec.host || url.protocol !== (spec.tlsRequired ? \"https:\" : \"http:\")) {\n continue;\n }\n\n // 3. Go for each part together with the path parameters.\n const path = url.pathname.replace(/^\\/|\\/$/g, \"\");\n for (const endpoint of spec.endpoints) {\n const endpointPath = endpoint.path.replace(/^\\/|\\/$/g, \"\");\n if (!path.startsWith(endpointPath)) continue;\n\n const method =\n RemoteEndpoint_HttpRequestMethod[request.method] ?? RemoteEndpoint_HttpRequestMethod.UNRECOGNIZED;\n if (!endpoint.methods.includes(method)) continue;\n\n validatePath(path.split(endpointPath)[1], endpoint.parameters);\n validateHeaders(request.metadata, endpoint.parameters);\n validateQuery(url.searchParams, endpoint.parameters);\n // The request matches the current endpoint\n return;\n }\n }\n\n // The request does not match any of the endpoints\n throw requestValidationError(\"The request does not match any of the Remote API specifications.\");\n}\n\nexport function validatePath(path: string, parameters: RemoteParameter[]) {\n const pathComponents = path.split(\"/\").filter(Boolean);\n\n let paramIndex = 0;\n\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.PATH) continue;\n\n const paramNameComponent = pathComponents[paramIndex];\n const paramValueComponent = pathComponents[paramIndex + 1];\n\n if (param.constant) {\n // For constant parameters, the value must match the defaultValue\n if (paramNameComponent === param.name && paramValueComponent === param.defaultValue) {\n paramIndex += 2; // Move to the next parameter pair\n } else {\n throw requestValidationError(\n `Expected constant parameter '${param.name}' with value '${param.defaultValue}' ` +\n `at position ${paramIndex}, but found '${paramNameComponent}' and '${paramValueComponent}'.`\n );\n }\n } else if (param.optional) {\n if (paramNameComponent === param.name) {\n // Check if there's another component for its value\n if (paramValueComponent !== undefined) {\n // Optional param with a value\n paramIndex += 2;\n } else {\n // Optional param without a value\n paramIndex += 1;\n }\n }\n // If optional and not present, continue without incrementing paramIndex\n } else {\n // For regular parameters, we just need to ensure a name/value pair exists\n if (paramNameComponent === param.name && paramValueComponent !== undefined) {\n paramIndex += 2; // Move to the next parameter pair\n } else {\n throw requestValidationError(\n `Expected parameter '${param.name}' with a value at position ${paramIndex}, ` +\n `but found '${paramNameComponent}' and '${paramValueComponent}'.`\n );\n }\n }\n }\n\n // After processing all parameters, there should be no extra path components\n if (paramIndex !== pathComponents.length) {\n const invalidPath = pathComponents.slice(paramIndex).join(\"/\");\n throw requestValidationError(\n `Unexpected extra path components starting at position ${paramIndex}: '${invalidPath}'.`\n );\n }\n}\n\nexport function validateHeaders(headers: Record<string, string>, parameters: RemoteParameter[]) {\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.HEADER) continue;\n\n const headerValue = headers[param.name];\n\n if (param.constant) {\n // For constant parameters, the header must exist and match defaultValue\n if (headerValue !== param.defaultValue) {\n throw requestValidationError(\n `Expected constant header '${param.name}' with value '${param.defaultValue}', ` +\n `but found '${headerValue ?? \"undefined\"}'.`\n );\n }\n } else if (param.optional) {\n // If optional, missing or present value is OK\n } else {\n // For required parameters, the header must exist and have a non-empty value\n if (headerValue == undefined || isEmptyString(headerValue)) {\n throw requestValidationError(`Required header '${param.name}' is missing or empty.`);\n }\n }\n }\n}\n\nexport function validateQuery(queryParams: URLSearchParams, parameters: RemoteParameter[]) {\n for (const param of parameters) {\n if (param.location !== RemoteParameter_ParameterLocation.QUERY) continue;\n\n const paramValue = queryParams.get(param.name);\n\n if (param.constant) {\n // For constant parameters, the query parameter must exist and match defaultValue\n if (paramValue !== param.defaultValue) {\n throw requestValidationError(\n `Expected constant query parameter '${param.name}' with value '${param.defaultValue}', ` +\n `but found '${paramValue ?? \"undefined\"}'.`\n );\n }\n } else if (param.optional) {\n // If optional, missing or present value is OK\n } else {\n // For required parameters, the query parameter must exist and have a non-empty value\n if (paramValue == undefined || isEmptyString(paramValue)) {\n throw requestValidationError(`Required query parameter '${param.name}' is missing or empty.`);\n }\n }\n }\n // All query parameters are valid\n}\n"]}
|
|
@@ -80,6 +80,9 @@ export declare const remoteApiServicesFactory: {
|
|
|
80
80
|
token: "remoteApiServices";
|
|
81
81
|
dependencies: [];
|
|
82
82
|
};
|
|
83
|
+
declare global {
|
|
84
|
+
var __snap_camkit_ra_1: string | undefined;
|
|
85
|
+
}
|
|
83
86
|
/**
|
|
84
87
|
* Provides a URI handler that searches for a match within the provided services to handle Remote API requests,
|
|
85
88
|
* i.e., those whose URI starts with 'app://remote-api/performApiRequest'.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteApiUriHandler.d.ts","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/remoteApiUriHandler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,gBAAgB,CAAC;AAyC9D;;GAEG;AACH,MAAM,MAAM,eAAe,GACrB,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,aAAa,GACb,WAAW,GACX,YAAY,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,MAAM,EAAE,eAAe,CAAC;IACxB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,MAAM,IAAI,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,KAC3C,6BAA6B,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,uBAAuB,GAAG,SAAS,CAAC;CACjG;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,CAAC;AAEnD,eAAO,MAAM,wBAAwB;;;;CAGnC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,yBAAyB,CACrC,kBAAkB,EAAE,gBAAgB,EAAE,EACtC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,aAAa,GACvB,UAAU,
|
|
1
|
+
{"version":3,"file":"remoteApiUriHandler.d.ts","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/remoteApiUriHandler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,gBAAgB,CAAC;AAyC9D;;GAEG;AACH,MAAM,MAAM,eAAe,GACrB,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,aAAa,GACb,WAAW,GACX,YAAY,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,MAAM,EAAE,eAAe,CAAC;IACxB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,MAAM,IAAI,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAClC,KAAK,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,KAC3C,6BAA6B,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,uBAAuB,GAAG,SAAS,CAAC;CACjG;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,CAAC;AAEnD,eAAO,MAAM,wBAAwB;;;;CAGnC,CAAC;AAEH,OAAO,CAAC,MAAM,CAAC;IAEX,IAAI,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAgBD;;;GAGG;AACH,wBAAgB,yBAAyB,CACrC,kBAAkB,EAAE,gBAAgB,EAAE,EACtC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,aAAa,GACvB,UAAU,CA2GZ"}
|
|
@@ -28,6 +28,17 @@ export const remoteApiServicesFactory = Injectable("remoteApiServices", () => {
|
|
|
28
28
|
const remoteApiServices = [];
|
|
29
29
|
return remoteApiServices;
|
|
30
30
|
});
|
|
31
|
+
function getFirstRequestHandler(services, remoteApiRequest, lens) {
|
|
32
|
+
for (const service of services) {
|
|
33
|
+
try {
|
|
34
|
+
return service.getRequestHandler(remoteApiRequest, lens);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
logger.warn("Client's Remote API request handler factory threw an error.", error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
31
42
|
export function createRemoteApiUriHandler(registeredServices, sessionState, lensState, lensRepository, metrics) {
|
|
32
43
|
const registeredServiceMap = new Map();
|
|
33
44
|
for (const service of registeredServices) {
|
|
@@ -50,66 +61,58 @@ export function createRemoteApiUriHandler(registeredServices, sessionState, lens
|
|
|
50
61
|
};
|
|
51
62
|
},
|
|
52
63
|
processRequest({ request, reply, lens, setCancellationHandler, state }) {
|
|
53
|
-
var _a;
|
|
64
|
+
var _a, _b;
|
|
54
65
|
const { route } = extractSchemeAndRoute(request.uri);
|
|
55
66
|
const [specId, endpointIdWithQuery] = route.split("/").slice(2);
|
|
56
67
|
const [endpointId] = endpointIdWithQuery.split("?");
|
|
57
|
-
if (!(state === null || state === void 0 ? void 0 : state.supportedSpecIds.has(specId)))
|
|
58
|
-
return;
|
|
59
|
-
if (!registeredServiceMap.has(specId))
|
|
60
|
-
return;
|
|
61
68
|
const dimensions = { specId };
|
|
62
69
|
const reportSingleCount = (name) => {
|
|
63
70
|
metrics.setOperationalMetrics(Count.count(joinMetricNames(["lens", "remote-api", name]), 1, dimensions));
|
|
64
71
|
};
|
|
65
72
|
reportSingleCount("requests");
|
|
73
|
+
if (!(state === null || state === void 0 ? void 0 : state.supportedSpecIds.has(specId)))
|
|
74
|
+
return;
|
|
66
75
|
const remoteApiRequest = {
|
|
67
76
|
apiSpecId: specId,
|
|
68
77
|
body: request.data,
|
|
69
78
|
endpointId,
|
|
70
79
|
parameters: request.metadata,
|
|
71
80
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
let requestHandler = getFirstRequestHandler((_a = registeredServiceMap.get(specId)) !== null && _a !== void 0 ? _a : [], remoteApiRequest, lens);
|
|
82
|
+
if (!requestHandler && globalThis.__snap_camkit_ra_1) {
|
|
83
|
+
requestHandler = getFirstRequestHandler((_b = registeredServiceMap.get(globalThis.__snap_camkit_ra_1)) !== null && _b !== void 0 ? _b : [], remoteApiRequest, lens);
|
|
84
|
+
}
|
|
85
|
+
if (!requestHandler)
|
|
86
|
+
return;
|
|
87
|
+
reportSingleCount("handled-requests");
|
|
88
|
+
let cancellationHandler = undefined;
|
|
89
|
+
try {
|
|
90
|
+
cancellationHandler = requestHandler((response) => {
|
|
91
|
+
var _a;
|
|
92
|
+
reportSingleCount("responses");
|
|
93
|
+
const responseCode = (_a = statusToResponseCodeMap[response.status]) !== null && _a !== void 0 ? _a : ResponseCode.UNRECOGNIZED;
|
|
94
|
+
const uriResponse = {
|
|
95
|
+
code: uriResponseOkCode,
|
|
96
|
+
description: "",
|
|
97
|
+
contentType: apiBinaryContentType,
|
|
98
|
+
data: response.body,
|
|
99
|
+
metadata: Object.assign(Object.assign({}, response.metadata), { [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString() }),
|
|
100
|
+
};
|
|
101
|
+
reply(uriResponse);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
logger.warn("Client's Remote API request handler threw an error.", error);
|
|
106
|
+
}
|
|
107
|
+
if (typeof cancellationHandler === "function") {
|
|
108
|
+
setCancellationHandler(() => {
|
|
83
109
|
try {
|
|
84
|
-
cancellationHandler
|
|
85
|
-
var _a;
|
|
86
|
-
reportSingleCount("responses");
|
|
87
|
-
const responseCode = (_a = statusToResponseCodeMap[response.status]) !== null && _a !== void 0 ? _a : ResponseCode.UNRECOGNIZED;
|
|
88
|
-
const uriResponse = {
|
|
89
|
-
code: uriResponseOkCode,
|
|
90
|
-
description: "",
|
|
91
|
-
contentType: apiBinaryContentType,
|
|
92
|
-
data: response.body,
|
|
93
|
-
metadata: Object.assign(Object.assign({}, response.metadata), { [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString() }),
|
|
94
|
-
};
|
|
95
|
-
reply(uriResponse);
|
|
96
|
-
});
|
|
110
|
+
cancellationHandler();
|
|
97
111
|
}
|
|
98
112
|
catch (error) {
|
|
99
|
-
logger.warn("Client's Remote API request handler threw an error.", error);
|
|
100
|
-
}
|
|
101
|
-
if (typeof cancellationHandler === "function") {
|
|
102
|
-
setCancellationHandler(() => {
|
|
103
|
-
try {
|
|
104
|
-
cancellationHandler();
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
logger.warn("Client's Remote API request cancellation handler threw an error.", error);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
113
|
+
logger.warn("Client's Remote API request cancellation handler threw an error.", error);
|
|
110
114
|
}
|
|
111
|
-
|
|
112
|
-
}
|
|
115
|
+
});
|
|
113
116
|
}
|
|
114
117
|
},
|
|
115
118
|
processInternalError(error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteApiUriHandler.js","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/remoteApiUriHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from \"@snap/ts-inject\";\nimport { RemoteApiInfo } from \"../../generated-proto/pb_schema/camera_kit/v3/features/remote_api_info\";\nimport {\n ResponseCode,\n responseCodeToNumber,\n} from \"../../generated-proto/pb_schema/lenses/remote_api/remote_api_service\";\nimport type { LensRepository } from \"../../lens/LensRepository\";\nimport type { Lens } from \"../../lens/Lens\";\nimport type { LensState } from \"../../session/lensState\";\nimport type { SessionState } from \"../../session/sessionState\";\nimport { getLogger } from \"../../logger/logger\";\nimport type { EnumToPublicStringLiteralMap, ExcludeKeys } from \"../../common/types\";\nimport type { MetricsClient } from \"../../clients/metricsClient\";\nimport { Count } from \"../../metrics/operational/Count\";\nimport { joinMetricNames } from \"../../metrics/operational/Metric\";\nimport { createUriRequestProcessor } from \"../uriRequestProcessor\";\nimport type { UriHandler, UriResponse } from \"../UriHandlers\";\nimport { extractSchemeAndRoute } from \"../UriHandlers\";\n\n// NOTE: There's potential for overloads when reporting metrics if reporting is triggered on each frame,\n// (i.e., when the lens sends Remote API requests every frame).\n// As of now, this isn't a concern because src/metrics/operational/operationalMetricsReporter.ts aggregates\n// \"count\" metrics into a single metric within a batch, and the Remote API service currently\n// reports only \"count\" metrics. For instance, if 30 metrics with the same name are generated per second,\n// given the current bundle size of 100 operational metrics, there will be one metrics report approximately\n// every 3.3 seconds.\n// In the future, if we opt to report \"histogram\" or other metric types, they must be approached with caution:\n// either the operationalMetricsReporter should be enhanced to aggregate such metrics,\n// or the Remote API service should manage it directly.\n// Mobiles ticket: https://jira.sc-corp.net/browse/CAMKIT-3092\n\nconst logger = getLogger(\"RemoteApiServices\");\n\nconst uriResponseOkCode = 200;\nconst apiResponseStatusHeader = \":sc_lens_api_status\";\nconst apiBinaryContentType = \"application/octet-stream\";\nconst remoteApiInfoProtobufTypeUrl = \"type.googleapis.com/com.snap.camerakit.v3.features.RemoteApiInfo\";\nconst remoteApiUploadImageSpecId = \"af3f69c8-2e62-441f-8b1c-d3956f7b336c\";\n\nconst statusToResponseCodeMap: ExcludeKeys<\n EnumToPublicStringLiteralMap<typeof ResponseCode>,\n \"responseCodeUnset\" | \"unrecognized\"\n> = {\n success: ResponseCode.SUCCESS,\n redirected: ResponseCode.REDIRECTED,\n badRequest: ResponseCode.BAD_REQUEST,\n accessDenied: ResponseCode.ACCESS_DENIED,\n notFound: ResponseCode.NOT_FOUND,\n timeout: ResponseCode.TIMEOUT,\n requestTooLarge: ResponseCode.REQUEST_TOO_LARGE,\n serverError: ResponseCode.SERVER_ERROR,\n cancelled: ResponseCode.CANCELLED,\n proxyError: ResponseCode.PROXY_ERROR,\n // NOTE: This rule helps keep the public-facing RemoteApiStatus type consistent with the proto.\n // We prefer using a separate type for TypeDoc purposes.\n} satisfies Record<RemoteApiStatus, ResponseCode>;\n\n/**\n * Status of a Remote API response.\n */\nexport type RemoteApiStatus =\n | \"success\"\n | \"redirected\"\n | \"badRequest\"\n | \"accessDenied\"\n | \"notFound\"\n | \"timeout\"\n | \"requestTooLarge\"\n | \"serverError\"\n | \"cancelled\"\n | \"proxyError\";\n\n/**\n * Remote API request sent by a lens.\n */\nexport interface RemoteApiRequest {\n /**\n * Unique id of the remote API service specification.\n */\n apiSpecId: string;\n /**\n * Unique id of the remote API service endpoint requested by this request.\n */\n endpointId: string;\n /**\n * A map of named parameters associated with the request.\n */\n parameters: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Remote API response to a request sent by a lens.\n */\nexport interface RemoteApiResponse {\n /**\n * Status of the response\n */\n status: RemoteApiStatus;\n /**\n * A map of named metadata associated with the response.\n */\n metadata: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Represents a Remote API request cancellation handler function.\n */\nexport type RemoteApiCancelRequestHandler = () => void;\n\n/**\n * Represents a Remote API request handler function.\n * It is provided with a reply callback that must be invoked to send a response back to the lens.\n * The reply callback can be invoked multiple times if needed.\n * Additionally, the handler can return a cancellation callback, which is triggered when the lens cancels the request.\n */\nexport type RemoteApiRequestHandler = (\n reply: (response: RemoteApiResponse) => void\n) => RemoteApiCancelRequestHandler | void;\n\n/**\n * Service to handle a lens Remote API request.\n */\nexport interface RemoteApiService {\n /**\n * Remote API spec ID(s).\n */\n apiSpecId: string;\n\n /**\n * This method is called by Camera Kit when a lens triggers a Remote API request with a corresponding spec ID.\n * If the service can handle the request, the method returns a request handler; otherwise, it returns nothing.\n * @param request Remote API request object.\n * @param lens Lens that triggers the request.\n * @returns A request handler if applicable.\n */\n getRequestHandler(request: RemoteApiRequest, lens: Lens): RemoteApiRequestHandler | undefined;\n}\n\nexport type RemoteApiServices = RemoteApiService[];\n\nexport const remoteApiServicesFactory = Injectable(\"remoteApiServices\", () => {\n const remoteApiServices: RemoteApiServices = [];\n return remoteApiServices;\n});\n\n/**\n * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,\n * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.\n */\nexport function createRemoteApiUriHandler(\n registeredServices: RemoteApiService[],\n sessionState: SessionState,\n lensState: LensState,\n lensRepository: LensRepository,\n metrics: MetricsClient\n): UriHandler {\n // Groups services by spec ID for faster lookups.\n const registeredServiceMap = new Map<string, RemoteApiService[]>();\n for (const service of registeredServices) {\n const existingServices = registeredServiceMap.get(service.apiSpecId) || [];\n registeredServiceMap.set(service.apiSpecId, [...existingServices, service]);\n }\n\n return createUriRequestProcessor({\n uri: \"app://remote-api/performApiRequest\",\n lensState,\n sessionState,\n createLensRequestState(_request, lens) {\n return {\n supportedSpecIds: new Set([\n // Parse lens metadata to obtain supported Remote API specs.\n ...(lensRepository.getLensMetadata(lens.id)?.featureMetadata ?? [])\n .filter((feature) => feature.typeUrl === remoteApiInfoProtobufTypeUrl)\n .flatMap((any) => RemoteApiInfo.decode(any.value).apiSpecIds),\n // Also add remoteApiUploadImageSpecId as this spec should be available for all lenses.\n // See https://jira.sc-corp.net/browse/CAMKIT-6245.\n remoteApiUploadImageSpecId,\n ]),\n };\n },\n processRequest({ request, reply, lens, setCancellationHandler, state }) {\n // Extracts the spec ID and endpoint ID from the provided Remote API request URI.\n // The given URI is expected to conform to the following specification:\n // eslint-disable-next-line max-len\n // https://docs.google.com/document/d/18fbGYDhD2N_aMTe4ZLY4QKeCSoMeJuklG28TutDzLZc/edit#bookmark=id.p2y39gwgbm4g\n const { route } = extractSchemeAndRoute(request.uri);\n const [specId, endpointIdWithQuery] = route.split(\"/\").slice(2);\n const [endpointId] = endpointIdWithQuery.split(\"?\");\n\n // only handle requests for API spec ID that current lens supports\n if (!state?.supportedSpecIds.has(specId)) return;\n\n // only handle requests if we have a registered service for it\n if (!registeredServiceMap.has(specId)) return;\n\n const dimensions = { specId };\n const reportSingleCount = (name: string) => {\n metrics.setOperationalMetrics(\n Count.count(joinMetricNames([\"lens\", \"remote-api\", name]), 1, dimensions)\n );\n };\n\n reportSingleCount(\"requests\");\n\n const remoteApiRequest: RemoteApiRequest = {\n apiSpecId: specId,\n body: request.data,\n endpointId,\n parameters: request.metadata,\n };\n\n // Looks for the first Remote API request handler.\n for (const service of registeredServiceMap.get(specId) ?? []) {\n let requestHandler: RemoteApiRequestHandler | undefined = undefined;\n try {\n requestHandler = service.getRequestHandler(remoteApiRequest, lens);\n } catch (error) {\n logger.warn(\"Client's Remote API request handler factory threw an error.\", error);\n }\n\n if (requestHandler) {\n reportSingleCount(\"handled-requests\");\n\n let cancellationHandler: RemoteApiCancelRequestHandler | void = undefined;\n try {\n // Calls client's Remote API handler to process the request.\n cancellationHandler = requestHandler((response) => {\n reportSingleCount(\"responses\");\n\n const responseCode = statusToResponseCodeMap[response.status] ?? ResponseCode.UNRECOGNIZED;\n const uriResponse: UriResponse = {\n code: uriResponseOkCode,\n description: \"\",\n contentType: apiBinaryContentType,\n data: response.body,\n metadata: {\n ...response.metadata,\n [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString(),\n },\n };\n reply(uriResponse);\n });\n } catch (error) {\n logger.warn(\"Client's Remote API request handler threw an error.\", error);\n }\n\n if (typeof cancellationHandler === \"function\") {\n setCancellationHandler(() => {\n try {\n cancellationHandler!();\n } catch (error) {\n logger.warn(\"Client's Remote API request cancellation handler threw an error.\", error);\n }\n });\n }\n\n break;\n }\n }\n },\n processInternalError(error) {\n // The expectation is that if an error occurs, it happens in our own implementation,\n // because app callbacks are wrapped with try..catch blocks.\n // Therefore, we would like to report this error.\n logger.error(error);\n metrics.setOperationalMetrics(Count.count(joinMetricNames([\"lens\", \"remote-api\", \"errors\"]), 1));\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteApiUriHandler.js","sourceRoot":"","sources":["../../../src/uri-handlers/internal-handlers/remoteApiUriHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from \"@snap/ts-inject\";\nimport { RemoteApiInfo } from \"../../generated-proto/pb_schema/camera_kit/v3/features/remote_api_info\";\nimport {\n ResponseCode,\n responseCodeToNumber,\n} from \"../../generated-proto/pb_schema/lenses/remote_api/remote_api_service\";\nimport type { LensRepository } from \"../../lens/LensRepository\";\nimport type { Lens } from \"../../lens/Lens\";\nimport type { LensState } from \"../../session/lensState\";\nimport type { SessionState } from \"../../session/sessionState\";\nimport { getLogger } from \"../../logger/logger\";\nimport type { EnumToPublicStringLiteralMap, ExcludeKeys } from \"../../common/types\";\nimport type { MetricsClient } from \"../../clients/metricsClient\";\nimport { Count } from \"../../metrics/operational/Count\";\nimport { joinMetricNames } from \"../../metrics/operational/Metric\";\nimport { createUriRequestProcessor } from \"../uriRequestProcessor\";\nimport type { UriHandler, UriResponse } from \"../UriHandlers\";\nimport { extractSchemeAndRoute } from \"../UriHandlers\";\n\n// NOTE: There's potential for overloads when reporting metrics if reporting is triggered on each frame,\n// (i.e., when the lens sends Remote API requests every frame).\n// As of now, this isn't a concern because src/metrics/operational/operationalMetricsReporter.ts aggregates\n// \"count\" metrics into a single metric within a batch, and the Remote API service currently\n// reports only \"count\" metrics. For instance, if 30 metrics with the same name are generated per second,\n// given the current bundle size of 100 operational metrics, there will be one metrics report approximately\n// every 3.3 seconds.\n// In the future, if we opt to report \"histogram\" or other metric types, they must be approached with caution:\n// either the operationalMetricsReporter should be enhanced to aggregate such metrics,\n// or the Remote API service should manage it directly.\n// Mobiles ticket: https://jira.sc-corp.net/browse/CAMKIT-3092\n\nconst logger = getLogger(\"RemoteApiServices\");\n\nconst uriResponseOkCode = 200;\nconst apiResponseStatusHeader = \":sc_lens_api_status\";\nconst apiBinaryContentType = \"application/octet-stream\";\nconst remoteApiInfoProtobufTypeUrl = \"type.googleapis.com/com.snap.camerakit.v3.features.RemoteApiInfo\";\nconst remoteApiUploadImageSpecId = \"af3f69c8-2e62-441f-8b1c-d3956f7b336c\";\n\nconst statusToResponseCodeMap: ExcludeKeys<\n EnumToPublicStringLiteralMap<typeof ResponseCode>,\n \"responseCodeUnset\" | \"unrecognized\"\n> = {\n success: ResponseCode.SUCCESS,\n redirected: ResponseCode.REDIRECTED,\n badRequest: ResponseCode.BAD_REQUEST,\n accessDenied: ResponseCode.ACCESS_DENIED,\n notFound: ResponseCode.NOT_FOUND,\n timeout: ResponseCode.TIMEOUT,\n requestTooLarge: ResponseCode.REQUEST_TOO_LARGE,\n serverError: ResponseCode.SERVER_ERROR,\n cancelled: ResponseCode.CANCELLED,\n proxyError: ResponseCode.PROXY_ERROR,\n // NOTE: This rule helps keep the public-facing RemoteApiStatus type consistent with the proto.\n // We prefer using a separate type for TypeDoc purposes.\n} satisfies Record<RemoteApiStatus, ResponseCode>;\n\n/**\n * Status of a Remote API response.\n */\nexport type RemoteApiStatus =\n | \"success\"\n | \"redirected\"\n | \"badRequest\"\n | \"accessDenied\"\n | \"notFound\"\n | \"timeout\"\n | \"requestTooLarge\"\n | \"serverError\"\n | \"cancelled\"\n | \"proxyError\";\n\n/**\n * Remote API request sent by a lens.\n */\nexport interface RemoteApiRequest {\n /**\n * Unique id of the remote API service specification.\n */\n apiSpecId: string;\n /**\n * Unique id of the remote API service endpoint requested by this request.\n */\n endpointId: string;\n /**\n * A map of named parameters associated with the request.\n */\n parameters: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Remote API response to a request sent by a lens.\n */\nexport interface RemoteApiResponse {\n /**\n * Status of the response\n */\n status: RemoteApiStatus;\n /**\n * A map of named metadata associated with the response.\n */\n metadata: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Represents a Remote API request cancellation handler function.\n */\nexport type RemoteApiCancelRequestHandler = () => void;\n\n/**\n * Represents a Remote API request handler function.\n * It is provided with a reply callback that must be invoked to send a response back to the lens.\n * The reply callback can be invoked multiple times if needed.\n * Additionally, the handler can return a cancellation callback, which is triggered when the lens cancels the request.\n */\nexport type RemoteApiRequestHandler = (\n reply: (response: RemoteApiResponse) => void\n) => RemoteApiCancelRequestHandler | void;\n\n/**\n * Service to handle a lens Remote API request.\n */\nexport interface RemoteApiService {\n /**\n * Remote API spec ID(s).\n */\n apiSpecId: string;\n\n /**\n * This method is called by Camera Kit when a lens triggers a Remote API request with a corresponding spec ID.\n * If the service can handle the request, the method returns a request handler; otherwise, it returns nothing.\n * @param request Remote API request object.\n * @param lens Lens that triggers the request.\n * @returns A request handler if applicable.\n */\n getRequestHandler(request: RemoteApiRequest, lens: Lens): RemoteApiRequestHandler | undefined;\n}\n\nexport type RemoteApiServices = RemoteApiService[];\n\nexport const remoteApiServicesFactory = Injectable(\"remoteApiServices\", () => {\n const remoteApiServices: RemoteApiServices = [];\n return remoteApiServices;\n});\n\ndeclare global {\n // See internal-packages/camera-kit-extensions for the meaning of the field.\n var __snap_camkit_ra_1: string | undefined;\n}\n\n/**\n * Goes over provided services and returns the first request handler that is able to handle the request.\n */\nfunction getFirstRequestHandler(services: RemoteApiService[], remoteApiRequest: RemoteApiRequest, lens: Lens) {\n for (const service of services) {\n try {\n return service.getRequestHandler(remoteApiRequest, lens);\n } catch (error) {\n logger.warn(\"Client's Remote API request handler factory threw an error.\", error);\n }\n }\n return undefined;\n}\n\n/**\n * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,\n * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.\n */\nexport function createRemoteApiUriHandler(\n registeredServices: RemoteApiService[],\n sessionState: SessionState,\n lensState: LensState,\n lensRepository: LensRepository,\n metrics: MetricsClient\n): UriHandler {\n // Groups services by spec ID for faster lookups.\n const registeredServiceMap = new Map<string, RemoteApiService[]>();\n for (const service of registeredServices) {\n const existingServices = registeredServiceMap.get(service.apiSpecId) || [];\n registeredServiceMap.set(service.apiSpecId, [...existingServices, service]);\n }\n\n return createUriRequestProcessor({\n uri: \"app://remote-api/performApiRequest\",\n lensState,\n sessionState,\n createLensRequestState(_request, lens) {\n return {\n supportedSpecIds: new Set([\n // Parse lens metadata to obtain supported Remote API specs.\n ...(lensRepository.getLensMetadata(lens.id)?.featureMetadata ?? [])\n .filter((feature) => feature.typeUrl === remoteApiInfoProtobufTypeUrl)\n .flatMap((any) => RemoteApiInfo.decode(any.value).apiSpecIds),\n // Also add remoteApiUploadImageSpecId as this spec should be available for all lenses.\n // See https://jira.sc-corp.net/browse/CAMKIT-6245.\n remoteApiUploadImageSpecId,\n ]),\n };\n },\n processRequest({ request, reply, lens, setCancellationHandler, state }) {\n // Extracts the spec ID and endpoint ID from the provided Remote API request URI.\n // The given URI is expected to conform to the following specification:\n // eslint-disable-next-line max-len\n // https://docs.google.com/document/d/18fbGYDhD2N_aMTe4ZLY4QKeCSoMeJuklG28TutDzLZc/edit#bookmark=id.p2y39gwgbm4g\n const { route } = extractSchemeAndRoute(request.uri);\n const [specId, endpointIdWithQuery] = route.split(\"/\").slice(2);\n const [endpointId] = endpointIdWithQuery.split(\"?\");\n\n const dimensions = { specId };\n const reportSingleCount = (name: string) => {\n metrics.setOperationalMetrics(\n Count.count(joinMetricNames([\"lens\", \"remote-api\", name]), 1, dimensions)\n );\n };\n reportSingleCount(\"requests\");\n\n // Only handle requests for API spec ID that current lens supports.\n if (!state?.supportedSpecIds.has(specId)) return;\n\n const remoteApiRequest: RemoteApiRequest = {\n apiSpecId: specId,\n body: request.data,\n endpointId,\n parameters: request.metadata,\n };\n\n let requestHandler = getFirstRequestHandler(registeredServiceMap.get(specId) ?? [], remoteApiRequest, lens);\n\n // Check maybe there is an internal catch-all handler.\n if (!requestHandler && globalThis.__snap_camkit_ra_1) {\n requestHandler = getFirstRequestHandler(\n registeredServiceMap.get(globalThis.__snap_camkit_ra_1) ?? [],\n remoteApiRequest,\n lens\n );\n }\n if (!requestHandler) return;\n\n reportSingleCount(\"handled-requests\");\n\n let cancellationHandler: RemoteApiCancelRequestHandler | void = undefined;\n try {\n // Calls client's Remote API handler to process the request.\n cancellationHandler = requestHandler((response) => {\n reportSingleCount(\"responses\");\n\n const responseCode = statusToResponseCodeMap[response.status] ?? ResponseCode.UNRECOGNIZED;\n const uriResponse: UriResponse = {\n code: uriResponseOkCode,\n description: \"\",\n contentType: apiBinaryContentType,\n data: response.body,\n metadata: {\n ...response.metadata,\n [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString(),\n },\n };\n reply(uriResponse);\n });\n } catch (error) {\n logger.warn(\"Client's Remote API request handler threw an error.\", error);\n }\n\n if (typeof cancellationHandler === \"function\") {\n setCancellationHandler(() => {\n try {\n cancellationHandler!();\n } catch (error) {\n logger.warn(\"Client's Remote API request cancellation handler threw an error.\", error);\n }\n });\n }\n },\n processInternalError(error) {\n // The expectation is that if an error occurs, it happens in our own implementation,\n // because app callbacks are wrapped with try..catch blocks.\n // Therefore, we would like to report this error.\n logger.error(error);\n metrics.setOperationalMetrics(Count.count(joinMetricNames([\"lens\", \"remote-api\", \"errors\"]), 1));\n },\n });\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>CameraKit | CameraKit Web SDK - v1.
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>CameraKit | CameraKit Web SDK - v1.4.0</title><meta name="description" content="Documentation for CameraKit Web SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CameraKit Web SDK - v1.4.0</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CameraKit Web SDK</a></li><li><a href="CameraKit.html">CameraKit</a></li></ul><h1>Class CameraKit</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>The entry point to the CameraKit SDK's API. Most of CameraKit's features are accessed via this class.</p>
|
|
2
2
|
<p>Applications obtain an instance of CameraKit by calling <a href="../functions/bootstrapCameraKit.html" class="tsd-kind-function">bootstrapCameraKit</a>.</p>
|
|
3
3
|
</div><div class="tsd-comment tsd-typography"><div class="tsd-tag-example"><h4 class="tsd-anchor-link"><a id="example" class="tsd-anchor"></a>Example<a href="#example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-6">cameraKit</span><span class="hl-1"> = </span><span class="hl-2">await</span><span class="hl-1"> </span><span class="hl-5">bootstrapCameraKit</span><span class="hl-1">(</span><span class="hl-0">config</span><span class="hl-1">)</span>
|
|
4
4
|
</code><button type="button">Copy</button></pre>
|
|
@@ -25,4 +25,4 @@ to Lens rendering.</p>
|
|
|
25
25
|
</code><button type="button">Copy</button></pre>
|
|
26
26
|
|
|
27
27
|
</div></div></li></ul></section><section class="tsd-panel tsd-member"><a id="destroy" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>destroy</span><a href="#destroy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="destroy-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">destroy</span><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span><a href="#destroy-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Destroys all sessions and frees all resources.</p>
|
|
28
|
-
</div><h4 class="tsd-returns-title">Returns <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><div class="tsd-comment tsd-typography"></div></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#lenses" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>lenses</span></a><a href="#metrics" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>metrics</span></a><a href="#lensrepository" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>lens<wbr/>Repository</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#createsession" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>create<wbr/>Session</span></a><a href="#destroy" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>destroy</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CameraKit Web SDK - v1.
|
|
28
|
+
</div><h4 class="tsd-returns-title">Returns <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><div class="tsd-comment tsd-typography"></div></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#lenses" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>lenses</span></a><a href="#metrics" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>metrics</span></a><a href="#lensrepository" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>lens<wbr/>Repository</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#createsession" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>create<wbr/>Session</span></a><a href="#destroy" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>destroy</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CameraKit Web SDK - v1.4.0</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>CameraKitSession | CameraKit Web SDK - v1.
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>CameraKitSession | CameraKit Web SDK - v1.4.0</title><meta name="description" content="Documentation for CameraKit Web SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">CameraKit Web SDK - v1.4.0</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">CameraKit Web SDK</a></li><li><a href="CameraKitSession.html">CameraKitSession</a></li></ul><h1>Class CameraKitSession</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>A CameraKitSession represents a single rendering pipeline connecting an input media source to output <code><canvas></code>
|
|
2
2
|
elements. When a Lens is applied to the session, CameraKit uses the Lens to transform the input media into rendered
|
|
3
3
|
output.</p>
|
|
4
4
|
<p>CameraKitSession is the primary object that applications interact with when integrating the CameraKit SDK.</p>
|
|
@@ -149,4 +149,4 @@ alternatives.</p>
|
|
|
149
149
|
</div><div class="tsd-comment tsd-typography"></div></li></ul></div><h4 class="tsd-returns-title">Returns <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><p>Promise is resolved when the limit is successfully set.</p>
|
|
150
150
|
<div class="tsd-comment tsd-typography"></div></li></ul></section><section class="tsd-panel tsd-member"><a id="destroy" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>destroy</span><a href="#destroy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="destroy-1" class="tsd-anchor"></a><span class="tsd-kind-call-signature">destroy</span><span class="tsd-signature-symbol">()</span><span class="tsd-signature-symbol">:</span> <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span><a href="#destroy-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Destroy the session.</p>
|
|
151
151
|
<p>The session will become inoperable. Frame processing stops, and any session-scoped graphical resources are freed.</p>
|
|
152
|
-
</div><h4 class="tsd-returns-title">Returns <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><div class="tsd-comment tsd-typography"></div></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#output" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>output</span></a><a href="#playing" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>playing</span></a><a href="#events" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>events</span></a><a href="#metrics" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>metrics</span></a><a href="#keyboard" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>keyboard</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#applylens" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>apply<wbr/>Lens</span></a><a href="#removelens" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>remove<wbr/>Lens</span></a><a href="#play" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>play</span></a><a href="#pause" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>pause</span></a><a href="#mute" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>mute</span></a><a href="#unmute" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>unmute</span></a><a href="#setsource" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>set<wbr/>Source</span></a><a href="#setfpslimit" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>setFPSLimit</span></a><a href="#destroy" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>destroy</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CameraKit Web SDK - v1.
|
|
152
|
+
</div><h4 class="tsd-returns-title">Returns <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise" class="tsd-signature-type external" target="_blank">Promise</a><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">void</span><span class="tsd-signature-symbol">></span></h4><div class="tsd-comment tsd-typography"></div></li></ul></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#output" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>output</span></a><a href="#playing" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>playing</span></a><a href="#events" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>events</span></a><a href="#metrics" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>metrics</span></a><a href="#keyboard" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>keyboard</span></a></div></details><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Methods"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Methods</summary><div><a href="#applylens" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>apply<wbr/>Lens</span></a><a href="#removelens" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>remove<wbr/>Lens</span></a><a href="#play" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>play</span></a><a href="#pause" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>pause</span></a><a href="#mute" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>mute</span></a><a href="#unmute" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>unmute</span></a><a href="#setsource" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>set<wbr/>Source</span></a><a href="#setfpslimit" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>setFPSLimit</span></a><a href="#destroy" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-2048"></use></svg><span>destroy</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">CameraKit Web SDK - v1.4.0</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
|