@mediaviz/sdk 1.7.0 → 1.8.0-dev.101

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/dist/sdk.d.cts CHANGED
@@ -60,6 +60,79 @@ export class ServerError extends ApiError {
60
60
 
61
61
  export function handleResponse(response: Response): Promise<any>;
62
62
 
63
+ export type WebhookAck = 'handled' | 'duplicate' | 'bad_signature';
64
+
65
+ export interface WebhookDeliveryEvent {
66
+ event_id: string;
67
+ event_type: string;
68
+ schema_version?: string;
69
+ subscription_id: string;
70
+ project_table_name: string;
71
+ photo_id: number;
72
+ target: string;
73
+ completed_at?: string;
74
+ result_location?: string;
75
+ [key: string]: any;
76
+ }
77
+
78
+ export interface WebhookStoreLike {
79
+ markSeen(eventId: string, ttlS: number): boolean;
80
+ unmarkSeen(eventId: string): void;
81
+ saveSecret(subscriptionId: string, secret: string): void;
82
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
83
+ getSecrets(subscriptionId: string): [string | null, string | null];
84
+ getCursor(subscriptionId: string): string | null;
85
+ setCursor(subscriptionId: string, cursor: string): void;
86
+ }
87
+
88
+ export class InMemoryWebhookStore implements WebhookStoreLike {
89
+ markSeen(eventId: string, ttlS: number): boolean;
90
+ unmarkSeen(eventId: string): void;
91
+ saveSecret(subscriptionId: string, secret: string): void;
92
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
93
+ getSecrets(subscriptionId: string): [string | null, string | null];
94
+ getCursor(subscriptionId: string): string | null;
95
+ setCursor(subscriptionId: string, cursor: string): void;
96
+ }
97
+
98
+ export class WebhookConsumer {
99
+ constructor(ctx: any, subscriptionApi: any, options?: {
100
+ store?: WebhookStoreLike;
101
+ onEvent?: (event: WebhookDeliveryEvent) => void | Promise<void>;
102
+ skewToleranceS?: number;
103
+ rotationWindowS?: number;
104
+ dedupeTtlS?: number;
105
+ pageLimit?: number;
106
+ });
107
+ store: WebhookStoreLike;
108
+ skewToleranceS: number;
109
+ rotationWindowS: number;
110
+ dedupeTtlS: number;
111
+ pageLimit: number;
112
+ onEvent(fn: (event: WebhookDeliveryEvent) => void | Promise<void>): (event: WebhookDeliveryEvent) => void | Promise<void>;
113
+ useStore(store: WebhookStoreLike): void;
114
+ classifyMessage(body: any): 'verification' | 'delivery' | 'unknown';
115
+ handleChallenge(body: any): { challenge: string };
116
+ handleDelivery(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<WebhookAck>;
117
+ handleRequest(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<{ status: number; body: any }>;
118
+ register(projectTableName: string, callbackUrl: string, targets: string[]): Promise<any>;
119
+ confirm(subscriptionId: string): Promise<any>;
120
+ rotateSecret(subscriptionId: string): Promise<string>;
121
+ updateCallback(subscriptionId: string, callbackUrl: string): Promise<any>;
122
+ disable(subscriptionId: string): Promise<any>;
123
+ listSubscriptions(): Promise<any>;
124
+ pullEvents(subscriptionId: string, options?: { since?: string; limit?: number }): Promise<any>;
125
+ reconcile(subscriptionId: string, projectTableName: string): Promise<{ pulled: number; dispatched: number }>;
126
+ fetchResult(event: WebhookDeliveryEvent): Promise<{ photo: any; selected: Record<string, any> | null }>;
127
+ saveSecret(subscriptionId: string, secret: string): void;
128
+ }
129
+
130
+ export function signWebhookPayload(secret: string, timestamp: string, rawBody: string | Uint8Array | ArrayBuffer): Promise<string>;
131
+ export function verifyWebhookSignature(secretCurrent: string | null, secretPrevious: string | null, headers: any, rawBody: string | Uint8Array | ArrayBuffer, options?: { skewToleranceS?: number; now?: number }): Promise<boolean>;
132
+ export function selectResultColumns(photo: any, target: string): Record<string, any> | null;
133
+ export const WEBHOOK_MODEL_COLUMNS: Record<string, string[]>;
134
+ export const WEBHOOK_OUTCOME_MODELS: Record<string, string[]>;
135
+
63
136
  // ── response schemas ──
64
137
  export interface AlbumDisplay {
65
138
  name?: string;
@@ -107,6 +180,11 @@ export interface CuratedAlbumDisplay {
107
180
  confidence_value?: number;
108
181
  }
109
182
 
183
+ export interface EventPage {
184
+ events: PullEvent[];
185
+ next_cursor?: string;
186
+ }
187
+
110
188
  export interface HealthCheck {
111
189
  status?: string;
112
190
  timestamp?: string;
@@ -190,6 +268,15 @@ export interface PhotoDisplay {
190
268
  hue_values?: number[];
191
269
  light_values?: number[];
192
270
  saturation_values?: number[];
271
+ aesthetic_appeal?: number;
272
+ lighting?: number;
273
+ subject_significance?: number;
274
+ emotional_intensity?: number;
275
+ positive_emotion?: number;
276
+ universal_relatability?: number;
277
+ memorability?: number;
278
+ composition?: number;
279
+ judgment_overall_score?: number;
193
280
  user_id: number;
194
281
  company_id: number;
195
282
  id: number;
@@ -248,7 +335,7 @@ export interface PhotoPersonWithS3Link {
248
335
  export interface ProjectRunDisplay {
249
336
  name: string;
250
337
  private?: boolean;
251
- type?: number;
338
+ type: number;
252
339
  description?: string;
253
340
  directory?: string;
254
341
  photo_upload_vector?: number;
@@ -278,11 +365,20 @@ export interface ProjectRunDisplay {
278
365
  image_comparison_model?: boolean;
279
366
  image_describe_model?: boolean;
280
367
  ocr_model?: boolean;
368
+ judgment_model?: boolean;
281
369
  similarity_model?: boolean;
282
370
  personhood_model?: boolean;
283
371
  evidence_model?: boolean;
284
372
  insights_model?: boolean;
285
373
  normalize?: boolean;
374
+ is_continuous_upload?: boolean;
375
+ }
376
+
377
+ export interface PullEvent {
378
+ event_id: string;
379
+ photo_id: number;
380
+ target: string;
381
+ completed_at: string;
286
382
  }
287
383
 
288
384
  export interface SearchDisplay {
@@ -305,6 +401,24 @@ export interface SearchDisplay {
305
401
  curated_album_id?: number;
306
402
  }
307
403
 
404
+ export interface SubscriptionActivated {
405
+ subscription_id: string;
406
+ status: string;
407
+ signing_secret: string;
408
+ }
409
+
410
+ export interface SubscriptionDisplay {
411
+ id: string;
412
+ project_table_name: string;
413
+ callback_url: string;
414
+ targets: string[];
415
+ status: string;
416
+ consecutive_failures: number;
417
+ last_delivery_at?: string;
418
+ last_status_code?: number;
419
+ created_at: string;
420
+ }
421
+
308
422
  export interface UserDisplay {
309
423
  id: number;
310
424
  company_id: number;
@@ -397,7 +511,7 @@ export class OauthAuthorization {
397
511
  export class OauthToken {
398
512
  token(body: { grantType: string, code: string, redirectUri: string, clientId: string, codeVerifier: string, refreshToken: string, clientSecret: string }): Promise<Record<string, any>>;
399
513
  adminRevokeUserTokens(userId: number): Promise<Record<string, any>>;
400
- revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<any>;
514
+ revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<Record<string, any>>;
401
515
  }
402
516
 
403
517
  export class OauthLogin {
@@ -407,12 +521,14 @@ export class OauthLogin {
407
521
 
408
522
  export class Person {
409
523
  updatePerson(projectTableName: string, personId: string, options?: { personName?: string | string[] }): Promise<any>;
524
+ removePersonName(projectTableName: string, personId: string): Promise<PhotoPersonLight>;
410
525
  combinePersons(projectTableName: string, destinationPersonId: string, oldPersonId: string): Promise<PhotoPersonLight>;
411
526
  splitPersons(projectTableName: string, id: number, options?: { newName?: string | string[], destinationPersonId?: string | string[] }): Promise<PhotoPersonLight>;
412
527
  getAllPersonsFromProject(projectTableName: string): Promise<PhotoPersonWithS3Link[]>;
413
528
  getAllPersonNamesFromProject(projectTableName: string): Promise<any>;
414
529
  getPhotoIdsByPersons(projectTableName: string, options?: { personId?: string[] | string[][] }): Promise<any>;
415
530
  getAllPersonsFromPhoto(projectTableName: string, photoId: number): Promise<PhotoPersonLight[]>;
531
+ removePerson(projectTableName: string, personId: string): Promise<Record<string, any>>;
416
532
  }
417
533
 
418
534
  export class Photoupload {
@@ -432,7 +548,7 @@ export class Photos {
432
548
  }
433
549
 
434
550
  export class Projects {
435
- createProjectAndRun(name: string, private_?: boolean, type?: number, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
551
+ createProjectAndRun(name: string, type: number, private_?: boolean, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
436
552
  markProjectUploadComplete(projectTableName: string, options?: { skippedFileCount?: number | number[] }): Promise<any>;
437
553
  checkProjectStatus(projectTableName: string): Promise<any>;
438
554
  getProjectPrelimModelRequestTemplate(projectTableName: string): Promise<Record<string, any>>;
@@ -464,6 +580,16 @@ export class Search {
464
580
  deleteSavedSearchById(searchId: number): Promise<Record<string, any>>;
465
581
  }
466
582
 
583
+ export class Subscription {
584
+ createSubscription(projectTableName: string, callbackUrl: string, targets: string[]): Promise<SubscriptionActivated>;
585
+ verifySubscription(subscriptionId: string): Promise<SubscriptionActivated>;
586
+ listSubscriptions(): Promise<SubscriptionDisplay[]>;
587
+ listSubscriptionEvents(subscriptionId: string, options?: { since?: string | string[], limit?: number | number[] }): Promise<EventPage>;
588
+ updateSubscription(subscriptionId: string, body?: { callbackUrl?: string, targets?: string[] }): Promise<SubscriptionDisplay>;
589
+ deleteSubscription(subscriptionId: string): Promise<Record<string, any>>;
590
+ rotateSubscriptionSecret(subscriptionId: string): Promise<SubscriptionActivated>;
591
+ }
592
+
467
593
  export class Users {
468
594
  createUser(name: string, email: string, accountType: number, companyId?: number, profilePicture?: string, paymentPlanType?: string): Promise<UserDisplay>;
469
595
  createUserAndCompany(name: string, email: string, password: string, companyId?: number, profilePicture?: string, paymentPlanType?: string, companyName?: string, credits?: number, options?: { inviteToken?: string | string[] }): Promise<UserDisplay>;
@@ -499,6 +625,8 @@ export class MediaViz {
499
625
  readonly photos: Photos;
500
626
  readonly projects: Projects;
501
627
  readonly search: Search;
628
+ readonly subscription: Subscription;
502
629
  readonly users: Users;
630
+ readonly webhooks: WebhookConsumer;
503
631
  }
504
632
 
package/dist/sdk.d.ts CHANGED
@@ -60,6 +60,79 @@ export class ServerError extends ApiError {
60
60
 
61
61
  export function handleResponse(response: Response): Promise<any>;
62
62
 
63
+ export type WebhookAck = 'handled' | 'duplicate' | 'bad_signature';
64
+
65
+ export interface WebhookDeliveryEvent {
66
+ event_id: string;
67
+ event_type: string;
68
+ schema_version?: string;
69
+ subscription_id: string;
70
+ project_table_name: string;
71
+ photo_id: number;
72
+ target: string;
73
+ completed_at?: string;
74
+ result_location?: string;
75
+ [key: string]: any;
76
+ }
77
+
78
+ export interface WebhookStoreLike {
79
+ markSeen(eventId: string, ttlS: number): boolean;
80
+ unmarkSeen(eventId: string): void;
81
+ saveSecret(subscriptionId: string, secret: string): void;
82
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
83
+ getSecrets(subscriptionId: string): [string | null, string | null];
84
+ getCursor(subscriptionId: string): string | null;
85
+ setCursor(subscriptionId: string, cursor: string): void;
86
+ }
87
+
88
+ export class InMemoryWebhookStore implements WebhookStoreLike {
89
+ markSeen(eventId: string, ttlS: number): boolean;
90
+ unmarkSeen(eventId: string): void;
91
+ saveSecret(subscriptionId: string, secret: string): void;
92
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
93
+ getSecrets(subscriptionId: string): [string | null, string | null];
94
+ getCursor(subscriptionId: string): string | null;
95
+ setCursor(subscriptionId: string, cursor: string): void;
96
+ }
97
+
98
+ export class WebhookConsumer {
99
+ constructor(ctx: any, subscriptionApi: any, options?: {
100
+ store?: WebhookStoreLike;
101
+ onEvent?: (event: WebhookDeliveryEvent) => void | Promise<void>;
102
+ skewToleranceS?: number;
103
+ rotationWindowS?: number;
104
+ dedupeTtlS?: number;
105
+ pageLimit?: number;
106
+ });
107
+ store: WebhookStoreLike;
108
+ skewToleranceS: number;
109
+ rotationWindowS: number;
110
+ dedupeTtlS: number;
111
+ pageLimit: number;
112
+ onEvent(fn: (event: WebhookDeliveryEvent) => void | Promise<void>): (event: WebhookDeliveryEvent) => void | Promise<void>;
113
+ useStore(store: WebhookStoreLike): void;
114
+ classifyMessage(body: any): 'verification' | 'delivery' | 'unknown';
115
+ handleChallenge(body: any): { challenge: string };
116
+ handleDelivery(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<WebhookAck>;
117
+ handleRequest(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<{ status: number; body: any }>;
118
+ register(projectTableName: string, callbackUrl: string, targets: string[]): Promise<any>;
119
+ confirm(subscriptionId: string): Promise<any>;
120
+ rotateSecret(subscriptionId: string): Promise<string>;
121
+ updateCallback(subscriptionId: string, callbackUrl: string): Promise<any>;
122
+ disable(subscriptionId: string): Promise<any>;
123
+ listSubscriptions(): Promise<any>;
124
+ pullEvents(subscriptionId: string, options?: { since?: string; limit?: number }): Promise<any>;
125
+ reconcile(subscriptionId: string, projectTableName: string): Promise<{ pulled: number; dispatched: number }>;
126
+ fetchResult(event: WebhookDeliveryEvent): Promise<{ photo: any; selected: Record<string, any> | null }>;
127
+ saveSecret(subscriptionId: string, secret: string): void;
128
+ }
129
+
130
+ export function signWebhookPayload(secret: string, timestamp: string, rawBody: string | Uint8Array | ArrayBuffer): Promise<string>;
131
+ export function verifyWebhookSignature(secretCurrent: string | null, secretPrevious: string | null, headers: any, rawBody: string | Uint8Array | ArrayBuffer, options?: { skewToleranceS?: number; now?: number }): Promise<boolean>;
132
+ export function selectResultColumns(photo: any, target: string): Record<string, any> | null;
133
+ export const WEBHOOK_MODEL_COLUMNS: Record<string, string[]>;
134
+ export const WEBHOOK_OUTCOME_MODELS: Record<string, string[]>;
135
+
63
136
  // ── response schemas ──
64
137
  export interface AlbumDisplay {
65
138
  name?: string;
@@ -107,6 +180,11 @@ export interface CuratedAlbumDisplay {
107
180
  confidence_value?: number;
108
181
  }
109
182
 
183
+ export interface EventPage {
184
+ events: PullEvent[];
185
+ next_cursor?: string;
186
+ }
187
+
110
188
  export interface HealthCheck {
111
189
  status?: string;
112
190
  timestamp?: string;
@@ -190,6 +268,15 @@ export interface PhotoDisplay {
190
268
  hue_values?: number[];
191
269
  light_values?: number[];
192
270
  saturation_values?: number[];
271
+ aesthetic_appeal?: number;
272
+ lighting?: number;
273
+ subject_significance?: number;
274
+ emotional_intensity?: number;
275
+ positive_emotion?: number;
276
+ universal_relatability?: number;
277
+ memorability?: number;
278
+ composition?: number;
279
+ judgment_overall_score?: number;
193
280
  user_id: number;
194
281
  company_id: number;
195
282
  id: number;
@@ -248,7 +335,7 @@ export interface PhotoPersonWithS3Link {
248
335
  export interface ProjectRunDisplay {
249
336
  name: string;
250
337
  private?: boolean;
251
- type?: number;
338
+ type: number;
252
339
  description?: string;
253
340
  directory?: string;
254
341
  photo_upload_vector?: number;
@@ -278,11 +365,20 @@ export interface ProjectRunDisplay {
278
365
  image_comparison_model?: boolean;
279
366
  image_describe_model?: boolean;
280
367
  ocr_model?: boolean;
368
+ judgment_model?: boolean;
281
369
  similarity_model?: boolean;
282
370
  personhood_model?: boolean;
283
371
  evidence_model?: boolean;
284
372
  insights_model?: boolean;
285
373
  normalize?: boolean;
374
+ is_continuous_upload?: boolean;
375
+ }
376
+
377
+ export interface PullEvent {
378
+ event_id: string;
379
+ photo_id: number;
380
+ target: string;
381
+ completed_at: string;
286
382
  }
287
383
 
288
384
  export interface SearchDisplay {
@@ -305,6 +401,24 @@ export interface SearchDisplay {
305
401
  curated_album_id?: number;
306
402
  }
307
403
 
404
+ export interface SubscriptionActivated {
405
+ subscription_id: string;
406
+ status: string;
407
+ signing_secret: string;
408
+ }
409
+
410
+ export interface SubscriptionDisplay {
411
+ id: string;
412
+ project_table_name: string;
413
+ callback_url: string;
414
+ targets: string[];
415
+ status: string;
416
+ consecutive_failures: number;
417
+ last_delivery_at?: string;
418
+ last_status_code?: number;
419
+ created_at: string;
420
+ }
421
+
308
422
  export interface UserDisplay {
309
423
  id: number;
310
424
  company_id: number;
@@ -397,7 +511,7 @@ export class OauthAuthorization {
397
511
  export class OauthToken {
398
512
  token(body: { grantType: string, code: string, redirectUri: string, clientId: string, codeVerifier: string, refreshToken: string, clientSecret: string }): Promise<Record<string, any>>;
399
513
  adminRevokeUserTokens(userId: number): Promise<Record<string, any>>;
400
- revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<any>;
514
+ revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<Record<string, any>>;
401
515
  }
402
516
 
403
517
  export class OauthLogin {
@@ -407,12 +521,14 @@ export class OauthLogin {
407
521
 
408
522
  export class Person {
409
523
  updatePerson(projectTableName: string, personId: string, options?: { personName?: string | string[] }): Promise<any>;
524
+ removePersonName(projectTableName: string, personId: string): Promise<PhotoPersonLight>;
410
525
  combinePersons(projectTableName: string, destinationPersonId: string, oldPersonId: string): Promise<PhotoPersonLight>;
411
526
  splitPersons(projectTableName: string, id: number, options?: { newName?: string | string[], destinationPersonId?: string | string[] }): Promise<PhotoPersonLight>;
412
527
  getAllPersonsFromProject(projectTableName: string): Promise<PhotoPersonWithS3Link[]>;
413
528
  getAllPersonNamesFromProject(projectTableName: string): Promise<any>;
414
529
  getPhotoIdsByPersons(projectTableName: string, options?: { personId?: string[] | string[][] }): Promise<any>;
415
530
  getAllPersonsFromPhoto(projectTableName: string, photoId: number): Promise<PhotoPersonLight[]>;
531
+ removePerson(projectTableName: string, personId: string): Promise<Record<string, any>>;
416
532
  }
417
533
 
418
534
  export class Photoupload {
@@ -432,7 +548,7 @@ export class Photos {
432
548
  }
433
549
 
434
550
  export class Projects {
435
- createProjectAndRun(name: string, private_?: boolean, type?: number, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
551
+ createProjectAndRun(name: string, type: number, private_?: boolean, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
436
552
  markProjectUploadComplete(projectTableName: string, options?: { skippedFileCount?: number | number[] }): Promise<any>;
437
553
  checkProjectStatus(projectTableName: string): Promise<any>;
438
554
  getProjectPrelimModelRequestTemplate(projectTableName: string): Promise<Record<string, any>>;
@@ -464,6 +580,16 @@ export class Search {
464
580
  deleteSavedSearchById(searchId: number): Promise<Record<string, any>>;
465
581
  }
466
582
 
583
+ export class Subscription {
584
+ createSubscription(projectTableName: string, callbackUrl: string, targets: string[]): Promise<SubscriptionActivated>;
585
+ verifySubscription(subscriptionId: string): Promise<SubscriptionActivated>;
586
+ listSubscriptions(): Promise<SubscriptionDisplay[]>;
587
+ listSubscriptionEvents(subscriptionId: string, options?: { since?: string | string[], limit?: number | number[] }): Promise<EventPage>;
588
+ updateSubscription(subscriptionId: string, body?: { callbackUrl?: string, targets?: string[] }): Promise<SubscriptionDisplay>;
589
+ deleteSubscription(subscriptionId: string): Promise<Record<string, any>>;
590
+ rotateSubscriptionSecret(subscriptionId: string): Promise<SubscriptionActivated>;
591
+ }
592
+
467
593
  export class Users {
468
594
  createUser(name: string, email: string, accountType: number, companyId?: number, profilePicture?: string, paymentPlanType?: string): Promise<UserDisplay>;
469
595
  createUserAndCompany(name: string, email: string, password: string, companyId?: number, profilePicture?: string, paymentPlanType?: string, companyName?: string, credits?: number, options?: { inviteToken?: string | string[] }): Promise<UserDisplay>;
@@ -499,6 +625,8 @@ export class MediaViz {
499
625
  readonly photos: Photos;
500
626
  readonly projects: Projects;
501
627
  readonly search: Search;
628
+ readonly subscription: Subscription;
502
629
  readonly users: Users;
630
+ readonly webhooks: WebhookConsumer;
503
631
  }
504
632
 
package/dist/sdk.esm.d.ts CHANGED
@@ -60,6 +60,79 @@ export class ServerError extends ApiError {
60
60
 
61
61
  export function handleResponse(response: Response): Promise<any>;
62
62
 
63
+ export type WebhookAck = 'handled' | 'duplicate' | 'bad_signature';
64
+
65
+ export interface WebhookDeliveryEvent {
66
+ event_id: string;
67
+ event_type: string;
68
+ schema_version?: string;
69
+ subscription_id: string;
70
+ project_table_name: string;
71
+ photo_id: number;
72
+ target: string;
73
+ completed_at?: string;
74
+ result_location?: string;
75
+ [key: string]: any;
76
+ }
77
+
78
+ export interface WebhookStoreLike {
79
+ markSeen(eventId: string, ttlS: number): boolean;
80
+ unmarkSeen(eventId: string): void;
81
+ saveSecret(subscriptionId: string, secret: string): void;
82
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
83
+ getSecrets(subscriptionId: string): [string | null, string | null];
84
+ getCursor(subscriptionId: string): string | null;
85
+ setCursor(subscriptionId: string, cursor: string): void;
86
+ }
87
+
88
+ export class InMemoryWebhookStore implements WebhookStoreLike {
89
+ markSeen(eventId: string, ttlS: number): boolean;
90
+ unmarkSeen(eventId: string): void;
91
+ saveSecret(subscriptionId: string, secret: string): void;
92
+ rotateSecret(subscriptionId: string, newSecret: string, windowS: number): void;
93
+ getSecrets(subscriptionId: string): [string | null, string | null];
94
+ getCursor(subscriptionId: string): string | null;
95
+ setCursor(subscriptionId: string, cursor: string): void;
96
+ }
97
+
98
+ export class WebhookConsumer {
99
+ constructor(ctx: any, subscriptionApi: any, options?: {
100
+ store?: WebhookStoreLike;
101
+ onEvent?: (event: WebhookDeliveryEvent) => void | Promise<void>;
102
+ skewToleranceS?: number;
103
+ rotationWindowS?: number;
104
+ dedupeTtlS?: number;
105
+ pageLimit?: number;
106
+ });
107
+ store: WebhookStoreLike;
108
+ skewToleranceS: number;
109
+ rotationWindowS: number;
110
+ dedupeTtlS: number;
111
+ pageLimit: number;
112
+ onEvent(fn: (event: WebhookDeliveryEvent) => void | Promise<void>): (event: WebhookDeliveryEvent) => void | Promise<void>;
113
+ useStore(store: WebhookStoreLike): void;
114
+ classifyMessage(body: any): 'verification' | 'delivery' | 'unknown';
115
+ handleChallenge(body: any): { challenge: string };
116
+ handleDelivery(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<WebhookAck>;
117
+ handleRequest(headers: any, rawBody: string | Uint8Array | ArrayBuffer): Promise<{ status: number; body: any }>;
118
+ register(projectTableName: string, callbackUrl: string, targets: string[]): Promise<any>;
119
+ confirm(subscriptionId: string): Promise<any>;
120
+ rotateSecret(subscriptionId: string): Promise<string>;
121
+ updateCallback(subscriptionId: string, callbackUrl: string): Promise<any>;
122
+ disable(subscriptionId: string): Promise<any>;
123
+ listSubscriptions(): Promise<any>;
124
+ pullEvents(subscriptionId: string, options?: { since?: string; limit?: number }): Promise<any>;
125
+ reconcile(subscriptionId: string, projectTableName: string): Promise<{ pulled: number; dispatched: number }>;
126
+ fetchResult(event: WebhookDeliveryEvent): Promise<{ photo: any; selected: Record<string, any> | null }>;
127
+ saveSecret(subscriptionId: string, secret: string): void;
128
+ }
129
+
130
+ export function signWebhookPayload(secret: string, timestamp: string, rawBody: string | Uint8Array | ArrayBuffer): Promise<string>;
131
+ export function verifyWebhookSignature(secretCurrent: string | null, secretPrevious: string | null, headers: any, rawBody: string | Uint8Array | ArrayBuffer, options?: { skewToleranceS?: number; now?: number }): Promise<boolean>;
132
+ export function selectResultColumns(photo: any, target: string): Record<string, any> | null;
133
+ export const WEBHOOK_MODEL_COLUMNS: Record<string, string[]>;
134
+ export const WEBHOOK_OUTCOME_MODELS: Record<string, string[]>;
135
+
63
136
  // ── response schemas ──
64
137
  export interface AlbumDisplay {
65
138
  name?: string;
@@ -107,6 +180,11 @@ export interface CuratedAlbumDisplay {
107
180
  confidence_value?: number;
108
181
  }
109
182
 
183
+ export interface EventPage {
184
+ events: PullEvent[];
185
+ next_cursor?: string;
186
+ }
187
+
110
188
  export interface HealthCheck {
111
189
  status?: string;
112
190
  timestamp?: string;
@@ -190,6 +268,15 @@ export interface PhotoDisplay {
190
268
  hue_values?: number[];
191
269
  light_values?: number[];
192
270
  saturation_values?: number[];
271
+ aesthetic_appeal?: number;
272
+ lighting?: number;
273
+ subject_significance?: number;
274
+ emotional_intensity?: number;
275
+ positive_emotion?: number;
276
+ universal_relatability?: number;
277
+ memorability?: number;
278
+ composition?: number;
279
+ judgment_overall_score?: number;
193
280
  user_id: number;
194
281
  company_id: number;
195
282
  id: number;
@@ -248,7 +335,7 @@ export interface PhotoPersonWithS3Link {
248
335
  export interface ProjectRunDisplay {
249
336
  name: string;
250
337
  private?: boolean;
251
- type?: number;
338
+ type: number;
252
339
  description?: string;
253
340
  directory?: string;
254
341
  photo_upload_vector?: number;
@@ -278,11 +365,20 @@ export interface ProjectRunDisplay {
278
365
  image_comparison_model?: boolean;
279
366
  image_describe_model?: boolean;
280
367
  ocr_model?: boolean;
368
+ judgment_model?: boolean;
281
369
  similarity_model?: boolean;
282
370
  personhood_model?: boolean;
283
371
  evidence_model?: boolean;
284
372
  insights_model?: boolean;
285
373
  normalize?: boolean;
374
+ is_continuous_upload?: boolean;
375
+ }
376
+
377
+ export interface PullEvent {
378
+ event_id: string;
379
+ photo_id: number;
380
+ target: string;
381
+ completed_at: string;
286
382
  }
287
383
 
288
384
  export interface SearchDisplay {
@@ -305,6 +401,24 @@ export interface SearchDisplay {
305
401
  curated_album_id?: number;
306
402
  }
307
403
 
404
+ export interface SubscriptionActivated {
405
+ subscription_id: string;
406
+ status: string;
407
+ signing_secret: string;
408
+ }
409
+
410
+ export interface SubscriptionDisplay {
411
+ id: string;
412
+ project_table_name: string;
413
+ callback_url: string;
414
+ targets: string[];
415
+ status: string;
416
+ consecutive_failures: number;
417
+ last_delivery_at?: string;
418
+ last_status_code?: number;
419
+ created_at: string;
420
+ }
421
+
308
422
  export interface UserDisplay {
309
423
  id: number;
310
424
  company_id: number;
@@ -397,7 +511,7 @@ export class OauthAuthorization {
397
511
  export class OauthToken {
398
512
  token(body: { grantType: string, code: string, redirectUri: string, clientId: string, codeVerifier: string, refreshToken: string, clientSecret: string }): Promise<Record<string, any>>;
399
513
  adminRevokeUserTokens(userId: number): Promise<Record<string, any>>;
400
- revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<any>;
514
+ revoke(body: { token: string, tokenTypeHint: string, clientId: string }): Promise<Record<string, any>>;
401
515
  }
402
516
 
403
517
  export class OauthLogin {
@@ -407,12 +521,14 @@ export class OauthLogin {
407
521
 
408
522
  export class Person {
409
523
  updatePerson(projectTableName: string, personId: string, options?: { personName?: string | string[] }): Promise<any>;
524
+ removePersonName(projectTableName: string, personId: string): Promise<PhotoPersonLight>;
410
525
  combinePersons(projectTableName: string, destinationPersonId: string, oldPersonId: string): Promise<PhotoPersonLight>;
411
526
  splitPersons(projectTableName: string, id: number, options?: { newName?: string | string[], destinationPersonId?: string | string[] }): Promise<PhotoPersonLight>;
412
527
  getAllPersonsFromProject(projectTableName: string): Promise<PhotoPersonWithS3Link[]>;
413
528
  getAllPersonNamesFromProject(projectTableName: string): Promise<any>;
414
529
  getPhotoIdsByPersons(projectTableName: string, options?: { personId?: string[] | string[][] }): Promise<any>;
415
530
  getAllPersonsFromPhoto(projectTableName: string, photoId: number): Promise<PhotoPersonLight[]>;
531
+ removePerson(projectTableName: string, personId: string): Promise<Record<string, any>>;
416
532
  }
417
533
 
418
534
  export class Photoupload {
@@ -432,7 +548,7 @@ export class Photos {
432
548
  }
433
549
 
434
550
  export class Projects {
435
- createProjectAndRun(name: string, private_?: boolean, type?: number, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
551
+ createProjectAndRun(name: string, type: number, private_?: boolean, description?: string, directory?: string, photoUploadVector?: number, thumbnail?: string, runName?: string, options?: { outcomes?: any, models?: any }): Promise<ProjectRunDisplay>;
436
552
  markProjectUploadComplete(projectTableName: string, options?: { skippedFileCount?: number | number[] }): Promise<any>;
437
553
  checkProjectStatus(projectTableName: string): Promise<any>;
438
554
  getProjectPrelimModelRequestTemplate(projectTableName: string): Promise<Record<string, any>>;
@@ -464,6 +580,16 @@ export class Search {
464
580
  deleteSavedSearchById(searchId: number): Promise<Record<string, any>>;
465
581
  }
466
582
 
583
+ export class Subscription {
584
+ createSubscription(projectTableName: string, callbackUrl: string, targets: string[]): Promise<SubscriptionActivated>;
585
+ verifySubscription(subscriptionId: string): Promise<SubscriptionActivated>;
586
+ listSubscriptions(): Promise<SubscriptionDisplay[]>;
587
+ listSubscriptionEvents(subscriptionId: string, options?: { since?: string | string[], limit?: number | number[] }): Promise<EventPage>;
588
+ updateSubscription(subscriptionId: string, body?: { callbackUrl?: string, targets?: string[] }): Promise<SubscriptionDisplay>;
589
+ deleteSubscription(subscriptionId: string): Promise<Record<string, any>>;
590
+ rotateSubscriptionSecret(subscriptionId: string): Promise<SubscriptionActivated>;
591
+ }
592
+
467
593
  export class Users {
468
594
  createUser(name: string, email: string, accountType: number, companyId?: number, profilePicture?: string, paymentPlanType?: string): Promise<UserDisplay>;
469
595
  createUserAndCompany(name: string, email: string, password: string, companyId?: number, profilePicture?: string, paymentPlanType?: string, companyName?: string, credits?: number, options?: { inviteToken?: string | string[] }): Promise<UserDisplay>;
@@ -499,6 +625,8 @@ export class MediaViz {
499
625
  readonly photos: Photos;
500
626
  readonly projects: Projects;
501
627
  readonly search: Search;
628
+ readonly subscription: Subscription;
502
629
  readonly users: Users;
630
+ readonly webhooks: WebhookConsumer;
503
631
  }
504
632