@arkyc/face-match 1.0.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.
@@ -0,0 +1,17 @@
1
+ import { FaceMatchConfig, FaceMatchDriver, FaceMatchRequest } from "../types.mjs";
2
+ import { FaceMatchResultData } from "@arkyc/types";
3
+
4
+ //#region src/drivers/external.d.ts
5
+ /**
6
+ * Generic HTTP face-match driver: POSTs both base64 images to a configured
7
+ * endpoint and expects a {@link FaceMatchResultData}-shaped JSON response.
8
+ */
9
+ declare class ExternalFaceMatchDriver implements FaceMatchDriver {
10
+ private readonly config;
11
+ readonly name = "external";
12
+ constructor(config: FaceMatchConfig);
13
+ compare(request: FaceMatchRequest): Promise<FaceMatchResultData>;
14
+ }
15
+ //#endregion
16
+ export { ExternalFaceMatchDriver };
17
+ //# sourceMappingURL=external.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external.d.mts","names":[],"sources":["../../src/drivers/external.ts"],"mappings":";;;;;;AAOA;;cAAa,uBAAA,YAAmC,eAAA;EAAA,iBAGjB,MAAA;EAAA,SAFpB,IAAA;cAEoB,MAAA,EAAQ,eAAA;EAI/B,OAAA,CAAQ,OAAA,EAAS,gBAAA,GAAmB,OAAA,CAAQ,mBAAA;AAAA"}
@@ -0,0 +1,32 @@
1
+ //#region src/drivers/external.ts
2
+ /**
3
+ * Generic HTTP face-match driver: POSTs both base64 images to a configured
4
+ * endpoint and expects a {@link FaceMatchResultData}-shaped JSON response.
5
+ */
6
+ var ExternalFaceMatchDriver = class {
7
+ config;
8
+ name = "external";
9
+ constructor(config) {
10
+ this.config = config;
11
+ if (!config.endpoint) throw new Error("ExternalFaceMatchDriver requires config.endpoint");
12
+ }
13
+ async compare(request) {
14
+ const res = await fetch(this.config.endpoint, {
15
+ method: "POST",
16
+ headers: {
17
+ "content-type": "application/json",
18
+ ...this.config.apiKey ? { authorization: `Bearer ${this.config.apiKey}` } : {}
19
+ },
20
+ body: JSON.stringify({
21
+ documentPortrait: Buffer.from(request.documentPortrait).toString("base64"),
22
+ selfie: Buffer.from(request.selfie).toString("base64")
23
+ })
24
+ });
25
+ if (!res.ok) throw new Error(`ExternalFaceMatchDriver request failed with status ${res.status}`);
26
+ return await res.json();
27
+ }
28
+ };
29
+ //#endregion
30
+ export { ExternalFaceMatchDriver };
31
+
32
+ //# sourceMappingURL=external.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external.mjs","names":[],"sources":["../../src/drivers/external.ts"],"sourcesContent":["import type { FaceMatchResultData } from '@arkyc/types'\nimport type { FaceMatchConfig, FaceMatchDriver, FaceMatchRequest } from '../types'\n\n/**\n * Generic HTTP face-match driver: POSTs both base64 images to a configured\n * endpoint and expects a {@link FaceMatchResultData}-shaped JSON response.\n */\nexport class ExternalFaceMatchDriver implements FaceMatchDriver {\n readonly name = 'external'\n\n constructor(private readonly config: FaceMatchConfig) {\n if (!config.endpoint) throw new Error('ExternalFaceMatchDriver requires config.endpoint')\n }\n\n async compare(request: FaceMatchRequest): Promise<FaceMatchResultData> {\n const res = await fetch(this.config.endpoint as string, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...(this.config.apiKey ? { authorization: `Bearer ${this.config.apiKey}` } : {}),\n },\n body: JSON.stringify({\n documentPortrait: Buffer.from(request.documentPortrait).toString('base64'),\n selfie: Buffer.from(request.selfie).toString('base64'),\n }),\n })\n\n if (!res.ok) {\n throw new Error(`ExternalFaceMatchDriver request failed with status ${res.status}`)\n }\n\n return (await res.json()) as FaceMatchResultData\n }\n}\n"],"mappings":";;;;;AAOA,IAAa,0BAAb,MAAgE;CAGjC;CAF7B,OAAgB;CAEhB,YAAY,QAA0C;EAAzB,KAAA,SAAA;EAC3B,IAAI,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,kDAAkD;CAC1F;CAEA,MAAM,QAAQ,SAAyD;EACrE,MAAM,MAAM,MAAM,MAAM,KAAK,OAAO,UAAoB;GACtD,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,GAAI,KAAK,OAAO,SAAS,EAAE,eAAe,UAAU,KAAK,OAAO,SAAS,IAAI,CAAC;GAChF;GACA,MAAM,KAAK,UAAU;IACnB,kBAAkB,OAAO,KAAK,QAAQ,gBAAgB,CAAC,CAAC,SAAS,QAAQ;IACzE,QAAQ,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,SAAS,QAAQ;GACvD,CAAC;EACH,CAAC;EAED,IAAI,CAAC,IAAI,IACP,MAAM,IAAI,MAAM,sDAAsD,IAAI,QAAQ;EAGpF,OAAQ,MAAM,IAAI,KAAK;CACzB;AACF"}
@@ -0,0 +1,15 @@
1
+ import { FaceMatchDriver, FaceMatchRequest } from "../types.mjs";
2
+ import { FaceMatchResultData } from "@arkyc/types";
3
+
4
+ //#region src/drivers/mock.d.ts
5
+ /**
6
+ * Deterministic face-match driver for development + tests. Passes by default;
7
+ * `hints` steer the similarity score and verdict.
8
+ */
9
+ declare class MockFaceMatchDriver implements FaceMatchDriver {
10
+ readonly name = "mock";
11
+ compare(request: FaceMatchRequest): Promise<FaceMatchResultData>;
12
+ }
13
+ //#endregion
14
+ export { MockFaceMatchDriver };
15
+ //# sourceMappingURL=mock.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock.d.mts","names":[],"sources":["../../src/drivers/mock.ts"],"mappings":";;;;;;AASA;;cAAa,mBAAA,YAA+B,eAAA;EAAA,SACjC,IAAA;EAEH,OAAA,CAAQ,OAAA,EAAS,gBAAA,GAAmB,OAAA,CAAQ,mBAAA;AAAA"}
@@ -0,0 +1,25 @@
1
+ //#region src/drivers/mock.ts
2
+ const clamp01 = (n) => Math.min(1, Math.max(0, n));
3
+ /**
4
+ * Deterministic face-match driver for development + tests. Passes by default;
5
+ * `hints` steer the similarity score and verdict.
6
+ */
7
+ var MockFaceMatchDriver = class {
8
+ name = "mock";
9
+ async compare(request) {
10
+ const similarityScore = clamp01(request.hints?.similarityScore ?? .9);
11
+ return {
12
+ passed: request.hints?.passed ?? similarityScore >= .5,
13
+ similarityScore,
14
+ confidence: .93,
15
+ raw: {
16
+ provider: "mock",
17
+ similarityScore
18
+ }
19
+ };
20
+ }
21
+ };
22
+ //#endregion
23
+ export { MockFaceMatchDriver };
24
+
25
+ //# sourceMappingURL=mock.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock.mjs","names":[],"sources":["../../src/drivers/mock.ts"],"sourcesContent":["import type { FaceMatchResultData } from '@arkyc/types'\nimport type { FaceMatchDriver, FaceMatchRequest } from '../types'\n\nconst clamp01 = (n: number): number => Math.min(1, Math.max(0, n))\n\n/**\n * Deterministic face-match driver for development + tests. Passes by default;\n * `hints` steer the similarity score and verdict.\n */\nexport class MockFaceMatchDriver implements FaceMatchDriver {\n readonly name = 'mock'\n\n async compare(request: FaceMatchRequest): Promise<FaceMatchResultData> {\n const similarityScore = clamp01(request.hints?.similarityScore ?? 0.9)\n const passed = request.hints?.passed ?? similarityScore >= 0.5\n\n return {\n passed,\n similarityScore,\n confidence: 0.93,\n raw: { provider: 'mock', similarityScore },\n }\n }\n}\n"],"mappings":";AAGA,MAAM,WAAW,MAAsB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;;;;;AAMjE,IAAa,sBAAb,MAA4D;CAC1D,OAAgB;CAEhB,MAAM,QAAQ,SAAyD;EACrE,MAAM,kBAAkB,QAAQ,QAAQ,OAAO,mBAAmB,EAAG;EAGrE,OAAO;GACL,QAHa,QAAQ,OAAO,UAAU,mBAAmB;GAIzD;GACA,YAAY;GACZ,KAAK;IAAE,UAAU;IAAQ;GAAgB;EAC3C;CACF;AACF"}
@@ -0,0 +1,5 @@
1
+ import { FaceMatchConfig, FaceMatchDriver, FaceMatchDriverName, FaceMatchRequest } from "./types.mjs";
2
+ import { FaceMatchDriverFactory } from "./registry.mjs";
3
+ import { MockFaceMatchDriver } from "./drivers/mock.mjs";
4
+ import { ExternalFaceMatchDriver } from "./drivers/external.mjs";
5
+ export { ExternalFaceMatchDriver, FaceMatchConfig, FaceMatchDriver, FaceMatchDriverFactory, FaceMatchDriverName, FaceMatchRequest, MockFaceMatchDriver };
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import { ExternalFaceMatchDriver } from "./drivers/external.mjs";
2
+ import { MockFaceMatchDriver } from "./drivers/mock.mjs";
3
+ import { FaceMatchDriverFactory } from "./registry.mjs";
4
+ export { ExternalFaceMatchDriver, FaceMatchDriverFactory, MockFaceMatchDriver };
@@ -0,0 +1,16 @@
1
+ import { FaceMatchConfig, FaceMatchDriver } from "./types.mjs";
2
+
3
+ //#region src/registry.d.ts
4
+ /** Selects a face-match driver from config. */
5
+ declare class FaceMatchDriverFactory {
6
+ /**'
7
+ * Resolve the face-match driver named by `config`.
8
+ *
9
+ * @param config
10
+ * @returns
11
+ */
12
+ static create(config: FaceMatchConfig): FaceMatchDriver;
13
+ }
14
+ //#endregion
15
+ export { FaceMatchDriverFactory };
16
+ //# sourceMappingURL=registry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.mts","names":[],"sources":["../src/registry.ts"],"mappings":";;;;cAMa,sBAAA;EAAA;;;;;;EAAA,OAOJ,MAAA,CAAO,MAAA,EAAQ,eAAA,GAAkB,eAAe;AAAA"}
@@ -0,0 +1,23 @@
1
+ import { ExternalFaceMatchDriver } from "./drivers/external.mjs";
2
+ import { MockFaceMatchDriver } from "./drivers/mock.mjs";
3
+ //#region src/registry.ts
4
+ /** Selects a face-match driver from config. */
5
+ var FaceMatchDriverFactory = class {
6
+ /**'
7
+ * Resolve the face-match driver named by `config`.
8
+ *
9
+ * @param config
10
+ * @returns
11
+ */
12
+ static create(config) {
13
+ switch (config.driver) {
14
+ case "mock": return new MockFaceMatchDriver();
15
+ case "external": return new ExternalFaceMatchDriver(config);
16
+ default: throw new Error(`Unknown face-match driver: ${config.driver}`);
17
+ }
18
+ }
19
+ };
20
+ //#endregion
21
+ export { FaceMatchDriverFactory };
22
+
23
+ //# sourceMappingURL=registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../src/registry.ts"],"sourcesContent":["import type { FaceMatchConfig, FaceMatchDriver } from './types'\n\nimport { ExternalFaceMatchDriver } from './drivers/external'\nimport { MockFaceMatchDriver } from './drivers/mock'\n\n/** Selects a face-match driver from config. */\nexport class FaceMatchDriverFactory {\n /**'\n * Resolve the face-match driver named by `config`.\n *\n * @param config\n * @returns\n */\n static create(config: FaceMatchConfig): FaceMatchDriver {\n switch (config.driver) {\n case 'mock':\n return new MockFaceMatchDriver()\n case 'external':\n return new ExternalFaceMatchDriver(config)\n default:\n throw new Error(`Unknown face-match driver: ${(config as FaceMatchConfig).driver}`)\n }\n }\n}\n"],"mappings":";;;;AAMA,IAAa,yBAAb,MAAoC;;;;;;;CAOlC,OAAO,OAAO,QAA0C;EACtD,QAAQ,OAAO,QAAf;GACE,KAAK,QACH,OAAO,IAAI,oBAAoB;GACjC,KAAK,YACH,OAAO,IAAI,wBAAwB,MAAM;GAC3C,SACE,MAAM,IAAI,MAAM,8BAA+B,OAA2B,QAAQ;EACtF;CACF;AACF"}
@@ -0,0 +1,34 @@
1
+ import { FaceMatchResultData } from "@arkyc/types";
2
+
3
+ //#region src/types.d.ts
4
+ /** The two images compared by a face-match driver. */
5
+ interface FaceMatchRequest {
6
+ /** Portrait extracted from the identity document. */
7
+ documentPortrait: Uint8Array;
8
+ /** Selfie captured during liveness. */
9
+ selfie: Uint8Array;
10
+ /**
11
+ * Optional deterministic signals (used by the `mock` driver and tests to
12
+ * steer the similarity / verdict). Ignored by real drivers.
13
+ */
14
+ hints?: {
15
+ similarityScore?: number;
16
+ passed?: boolean;
17
+ };
18
+ }
19
+ /** A pluggable face-match provider. */
20
+ interface FaceMatchDriver {
21
+ readonly name: string;
22
+ compare(request: FaceMatchRequest): Promise<FaceMatchResultData>;
23
+ }
24
+ /** Identifier for a registered face-match driver. */
25
+ type FaceMatchDriverName = 'mock' | 'external';
26
+ /** Configuration selecting + parameterising the active face-match driver. */
27
+ interface FaceMatchConfig {
28
+ driver: FaceMatchDriverName;
29
+ endpoint?: string;
30
+ apiKey?: string;
31
+ }
32
+ //#endregion
33
+ export { FaceMatchConfig, FaceMatchDriver, FaceMatchDriverName, FaceMatchRequest };
34
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;UAGiB,gBAAA;EAAA;EAEf,gBAAA,EAAkB,UAAA;;EAElB,MAAA,EAAQ,UAAU;EAFlB;;;;EAOA,KAAA;IAAU,eAAA;IAA0B,MAAA;EAAA;AAAA;AAItC;AAAA,UAAiB,eAAA;EAAA,SACN,IAAA;EACT,OAAA,CAAQ,OAAA,EAAS,gBAAA,GAAmB,OAAA,CAAQ,mBAAA;AAAA;;KAIlC,mBAAA;;UAGK,eAAA;EACf,MAAA,EAAQ,mBAAmB;EAC3B,QAAA;EACA,MAAA;AAAA"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@arkyc/face-match",
3
+ "version": "1.0.0",
4
+ "description": "Driver-based face matching",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.mjs",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.mts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.mts",
13
+ "import": "./dist/index.mjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {
20
+ "@arkyc/types": "^1.0.0"
21
+ },
22
+ "scripts": {
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run",
25
+ "lint": "eslint src",
26
+ "clean": "rm -rf dist"
27
+ }
28
+ }