@veltdev/sdk-staging 5.0.2-beta.7 → 5.0.2-beta.70
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/app/client/snippyly.model.d.ts +21 -2
- package/app/models/data/activity-resolver.data.model.d.ts +27 -0
- package/app/models/data/activity.data.model.d.ts +179 -0
- package/app/models/data/attachment-resolver.data.model.d.ts +2 -2
- package/app/models/data/attachment.model.d.ts +1 -0
- package/app/models/data/autocomplete.data.model.d.ts +4 -3
- package/app/models/data/base-metadata.data.model.d.ts +3 -0
- package/app/models/data/comment-actions.data.model.d.ts +4 -0
- package/app/models/data/comment-annotation.data.model.d.ts +18 -2
- package/app/models/data/comment-events.data.model.d.ts +11 -2
- package/app/models/data/comment-resolver.data.model.d.ts +3 -3
- package/app/models/data/comment-sidebar-config.model.d.ts +2 -0
- package/app/models/data/config.data.model.d.ts +26 -0
- package/app/models/data/core-events.data.model.d.ts +74 -1
- package/app/models/data/crdt.data.model.d.ts +51 -0
- package/app/models/data/document.data.model.d.ts +2 -0
- package/app/models/data/live-state-events.data.model.d.ts +6 -0
- package/app/models/data/notification-resolver.data.model.d.ts +39 -0
- package/app/models/data/notification.model.d.ts +4 -0
- package/app/models/data/presence-user.data.model.d.ts +5 -0
- package/app/models/data/provider.data.model.d.ts +8 -1
- package/app/models/data/reaction-resolver.data.model.d.ts +3 -3
- package/app/models/data/recorder-annotation.data.model.d.ts +11 -0
- package/app/models/data/recorder-events.data.model.d.ts +3 -0
- package/app/models/data/recorder-resolver.data.model.d.ts +58 -0
- package/app/models/data/resolver.data.model.d.ts +1 -0
- package/app/models/data/rewriter-events.data.model.d.ts +44 -0
- package/app/models/data/suggestion-events.data.model.d.ts +57 -0
- package/app/models/data/suggestion.data.model.d.ts +267 -0
- package/app/models/data/user-resolver.data.model.d.ts +17 -1
- package/app/models/data/user.data.model.d.ts +3 -0
- package/app/models/element/activity-element.model.d.ts +33 -0
- package/app/models/element/comment-element.model.d.ts +48 -8
- package/app/models/element/crdt-element.model.d.ts +88 -1
- package/app/models/element/presence-element.model.d.ts +25 -0
- package/app/models/element/rewriter-element.model.d.ts +20 -0
- package/app/models/element/suggestion-element.model.d.ts +180 -0
- package/app/utils/constants.d.ts +224 -0
- package/app/utils/enums.d.ts +36 -3
- package/models.d.ts +7 -0
- package/package.json +1 -1
- package/types.d.ts +2 -0
- package/velt.css +1 -1
- package/velt.js +131 -143
|
@@ -16,6 +16,8 @@ export interface SetDocumentsRequestOptions {
|
|
|
16
16
|
locationId?: string;
|
|
17
17
|
rootDocumentId?: string;
|
|
18
18
|
context?: SetDocumentsContext;
|
|
19
|
+
debounceTime?: number;
|
|
20
|
+
optimisticPermissions?: boolean;
|
|
19
21
|
}
|
|
20
22
|
export interface UpdateDocumentsRequest<T = unknown> {
|
|
21
23
|
organizationId?: string;
|
|
@@ -5,12 +5,18 @@ export interface AccessRequestEvent {
|
|
|
5
5
|
editor?: User;
|
|
6
6
|
timestamp?: number;
|
|
7
7
|
status?: string;
|
|
8
|
+
totalUsers?: number;
|
|
9
|
+
presenceSnippylyUserIds?: string[];
|
|
10
|
+
presenceClientUserIds?: string[];
|
|
8
11
|
}
|
|
9
12
|
export interface SEMEvent {
|
|
10
13
|
viewer?: User;
|
|
11
14
|
editor?: User;
|
|
12
15
|
timestamp?: number;
|
|
13
16
|
role?: string;
|
|
17
|
+
totalUsers?: number;
|
|
18
|
+
presenceSnippylyUserIds?: string[];
|
|
19
|
+
presenceClientUserIds?: string[];
|
|
14
20
|
}
|
|
15
21
|
export type LiveStateEventTypesMap = {
|
|
16
22
|
[LiveStateSyncEventTypes.ACCESS_REQUESTED]: AccessRequestEvent;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ResolverEndpointConfig, ResolverResponse, RetryConfig } from "./resolver.data.model";
|
|
2
|
+
import { User } from "./user.data.model";
|
|
3
|
+
export interface NotificationDataProvider {
|
|
4
|
+
get?: (request: GetNotificationResolverRequest) => Promise<ResolverResponse<Record<string, PartialNotification>>>;
|
|
5
|
+
delete?: (request: DeleteNotificationResolverRequest) => Promise<ResolverResponse<undefined>>;
|
|
6
|
+
config?: NotificationResolverConfig;
|
|
7
|
+
}
|
|
8
|
+
export interface NotificationResolverConfig {
|
|
9
|
+
resolveTimeout?: number;
|
|
10
|
+
getRetryConfig?: RetryConfig;
|
|
11
|
+
deleteRetryConfig?: RetryConfig;
|
|
12
|
+
getConfig?: ResolverEndpointConfig;
|
|
13
|
+
deleteConfig?: ResolverEndpointConfig;
|
|
14
|
+
}
|
|
15
|
+
export interface GetNotificationResolverRequest {
|
|
16
|
+
organizationId: string;
|
|
17
|
+
notificationIds: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface DeleteNotificationResolverRequest {
|
|
20
|
+
notificationId: string;
|
|
21
|
+
organizationId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PartialNotification {
|
|
24
|
+
notificationId: string;
|
|
25
|
+
displayHeadlineMessageTemplate?: string;
|
|
26
|
+
displayHeadlineMessageTemplateData?: {
|
|
27
|
+
actionUser?: User;
|
|
28
|
+
recipientUser?: User;
|
|
29
|
+
actionMessage?: string;
|
|
30
|
+
[key: string]: any;
|
|
31
|
+
};
|
|
32
|
+
displayBodyMessage?: string;
|
|
33
|
+
displayBodyMessageTemplate?: string;
|
|
34
|
+
displayBodyMessageTemplateData?: {
|
|
35
|
+
[key: string]: any;
|
|
36
|
+
};
|
|
37
|
+
notificationSourceData?: any;
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
}
|
|
@@ -137,6 +137,10 @@ export declare class Notification {
|
|
|
137
137
|
* Is comment text available
|
|
138
138
|
*/
|
|
139
139
|
isCommentResolverUsed?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Is notification resolver used
|
|
142
|
+
*/
|
|
143
|
+
isNotificationResolverUsed?: boolean;
|
|
140
144
|
/**
|
|
141
145
|
* Display body message template
|
|
142
146
|
*/
|
|
@@ -83,4 +83,9 @@ export declare class PresenceUser {
|
|
|
83
83
|
initial?: string;
|
|
84
84
|
isTabAway?: boolean;
|
|
85
85
|
isUserIdle?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Whether this custom user is local-only (not persisted to DB).
|
|
88
|
+
* Only applicable to users added via addUser API.
|
|
89
|
+
*/
|
|
90
|
+
localOnly?: boolean;
|
|
86
91
|
}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import { ActivityAnnotationDataProvider } from "./activity-resolver.data.model";
|
|
1
2
|
import { CommentAnnotationDataProvider } from "./comment-resolver.data.model";
|
|
2
3
|
import { AttachmentDataProvider } from "./attachment-resolver.data.model";
|
|
4
|
+
import { NotificationDataProvider } from "./notification-resolver.data.model";
|
|
3
5
|
import { ReactionAnnotationDataProvider } from "./reaction-resolver.data.model";
|
|
4
|
-
import {
|
|
6
|
+
import { RecorderAnnotationDataProvider } from "./recorder-resolver.data.model";
|
|
7
|
+
import { AnonymousUserDataProvider, UserDataProvider } from "./user-resolver.data.model";
|
|
5
8
|
export interface VeltDataProvider {
|
|
6
9
|
comment?: CommentAnnotationDataProvider;
|
|
7
10
|
user?: UserDataProvider;
|
|
8
11
|
reaction?: ReactionAnnotationDataProvider;
|
|
9
12
|
attachment?: AttachmentDataProvider;
|
|
13
|
+
anonymousUser?: AnonymousUserDataProvider;
|
|
14
|
+
recorder?: RecorderAnnotationDataProvider;
|
|
15
|
+
notification?: NotificationDataProvider;
|
|
16
|
+
activity?: ActivityAnnotationDataProvider;
|
|
10
17
|
}
|
|
@@ -4,9 +4,9 @@ import { PartialUser } from "./comment-resolver.data.model";
|
|
|
4
4
|
import { ReactionAnnotation } from "./reaction-annotation.data.model";
|
|
5
5
|
import { ResolverConfig, ResolverResponse } from "./resolver.data.model";
|
|
6
6
|
export interface ReactionAnnotationDataProvider {
|
|
7
|
-
get
|
|
8
|
-
save
|
|
9
|
-
delete
|
|
7
|
+
get?: (request: GetReactionResolverRequest) => Promise<ResolverResponse<Record<string, PartialReactionAnnotation>>>;
|
|
8
|
+
save?: (request: SaveReactionResolverRequest) => Promise<ResolverResponse<undefined>>;
|
|
9
|
+
delete?: (request: DeleteReactionResolverRequest) => Promise<ResolverResponse<undefined>>;
|
|
10
10
|
config?: ResolverConfig;
|
|
11
11
|
}
|
|
12
12
|
export interface GetReactionResolverRequest {
|
|
@@ -150,6 +150,17 @@ export declare class RecorderAnnotation {
|
|
|
150
150
|
chunkUrls?: {
|
|
151
151
|
[key: number]: string;
|
|
152
152
|
};
|
|
153
|
+
/**
|
|
154
|
+
* Whether the recorder resolver is used for this annotation.
|
|
155
|
+
* Used by UI components to show loading states while resolver data is being fetched.
|
|
156
|
+
*/
|
|
157
|
+
isRecorderResolverUsed?: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the real recording URL is available.
|
|
160
|
+
* Set to false when the annotation is first saved (URL is still a local blob),
|
|
161
|
+
* and true once the actual URL from storage is available after the async upload completes.
|
|
162
|
+
*/
|
|
163
|
+
isUrlAvailable?: boolean;
|
|
153
164
|
}
|
|
154
165
|
export interface RecorderAnnotationEditVersion {
|
|
155
166
|
from?: User;
|
|
@@ -4,6 +4,8 @@ export interface TranscriptionDoneEvent extends RecorderData {
|
|
|
4
4
|
}
|
|
5
5
|
export interface RecordingDoneEvent extends RecorderData {
|
|
6
6
|
}
|
|
7
|
+
export interface RecordingDoneLocalEvent extends RecorderData {
|
|
8
|
+
}
|
|
7
9
|
export interface RecordingDeleteEvent extends RecorderData {
|
|
8
10
|
}
|
|
9
11
|
export interface RecordingEditDoneEvent extends RecorderData {
|
|
@@ -35,6 +37,7 @@ export interface RecordingSaveInitiatedEvent {
|
|
|
35
37
|
export type RecorderEventTypesMap = {
|
|
36
38
|
[RecorderEventTypes.TRANSCRIPTION_DONE]: TranscriptionDoneEvent;
|
|
37
39
|
[RecorderEventTypes.RECORDING_DONE]: RecordingDoneEvent;
|
|
40
|
+
[RecorderEventTypes.RECORDING_DONE_LOCAL]: RecordingDoneLocalEvent;
|
|
38
41
|
[RecorderEventTypes.RECORDING_EDIT_DONE]: RecordingEditDoneEvent;
|
|
39
42
|
[RecorderEventTypes.DELETE_RECORDING]: RecordingDeleteEvent;
|
|
40
43
|
[RecorderEventTypes.RECORDING_STARTED]: RecordingStartedEvent;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ResolverActions } from "../../utils/enums";
|
|
2
|
+
import { AttachmentDataProvider } from "./attachment-resolver.data.model";
|
|
3
|
+
import { BaseMetadata } from "./base-metadata.data.model";
|
|
4
|
+
import { RecorderAnnotation } from "./recorder-annotation.data.model";
|
|
5
|
+
import { ResolverConfig, ResolverResponse } from "./resolver.data.model";
|
|
6
|
+
import { Attachment } from "./attachment.model";
|
|
7
|
+
import { Transcription } from "./transcription.data.model";
|
|
8
|
+
import { User } from "./user.data.model";
|
|
9
|
+
export interface RecorderAnnotationDataProvider {
|
|
10
|
+
get?: (request: GetRecorderResolverRequest) => Promise<ResolverResponse<Record<string, PartialRecorderAnnotation>>>;
|
|
11
|
+
save?: (request: SaveRecorderResolverRequest) => Promise<ResolverResponse<SaveRecorderResolverData | undefined>>;
|
|
12
|
+
delete?: (request: DeleteRecorderResolverRequest) => Promise<ResolverResponse<undefined>>;
|
|
13
|
+
config?: ResolverConfig;
|
|
14
|
+
uploadChunks?: boolean;
|
|
15
|
+
storage?: AttachmentDataProvider;
|
|
16
|
+
}
|
|
17
|
+
export interface GetRecorderResolverRequest {
|
|
18
|
+
organizationId: string;
|
|
19
|
+
recorderAnnotationIds?: string[];
|
|
20
|
+
documentIds?: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface SaveRecorderResolverRequest {
|
|
23
|
+
recorderAnnotation: Record<string, PartialRecorderAnnotation>;
|
|
24
|
+
event?: ResolverActions;
|
|
25
|
+
metadata?: BaseMetadata;
|
|
26
|
+
}
|
|
27
|
+
export interface SaveRecorderResolverData {
|
|
28
|
+
transcription?: Transcription;
|
|
29
|
+
attachment?: Attachment | null;
|
|
30
|
+
attachments?: Attachment[];
|
|
31
|
+
}
|
|
32
|
+
export interface DeleteRecorderResolverRequest {
|
|
33
|
+
recorderAnnotationId: string;
|
|
34
|
+
metadata?: BaseMetadata;
|
|
35
|
+
event?: ResolverActions;
|
|
36
|
+
}
|
|
37
|
+
export interface PartialRecorderAnnotation {
|
|
38
|
+
annotationId: string;
|
|
39
|
+
metadata?: BaseMetadata;
|
|
40
|
+
from?: User;
|
|
41
|
+
transcription?: Transcription;
|
|
42
|
+
attachment?: Attachment | null;
|
|
43
|
+
attachments?: Attachment[];
|
|
44
|
+
chunkUrls?: Record<number, string>;
|
|
45
|
+
recordingEditVersions?: Record<number, PartialRecorderAnnotationEditVersion>;
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
}
|
|
48
|
+
export interface PartialRecorderAnnotationEditVersion {
|
|
49
|
+
from?: User;
|
|
50
|
+
attachment?: Attachment | null;
|
|
51
|
+
attachments?: Attachment[];
|
|
52
|
+
transcription?: Transcription;
|
|
53
|
+
}
|
|
54
|
+
export interface PartialRecorderAnnotationResult {
|
|
55
|
+
strippedData: Record<string, PartialRecorderAnnotation> | null;
|
|
56
|
+
originalData: RecorderAnnotation | null;
|
|
57
|
+
eventType?: ResolverActions;
|
|
58
|
+
}
|
|
@@ -9,6 +9,7 @@ export interface ResolverConfig {
|
|
|
9
9
|
getRetryConfig?: RetryConfig;
|
|
10
10
|
resolveUsersConfig?: ResolveUsersConfig;
|
|
11
11
|
fieldsToRemove?: string[];
|
|
12
|
+
additionalFields?: string[];
|
|
12
13
|
getConfig?: ResolverEndpointConfig;
|
|
13
14
|
saveConfig?: ResolverEndpointConfig;
|
|
14
15
|
deleteConfig?: ResolverEndpointConfig;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { TargetTextRange } from './target-text-range.data.model';
|
|
2
|
+
import { RewriterEventTypes } from '../../utils/enums';
|
|
3
|
+
export type OpenAiModel = 'gpt-5.4' | 'gpt-5.4-pro' | 'gpt-5.4-mini' | 'gpt-5.4-nano' | 'gpt-5-mini' | 'gpt-5-nano' | 'gpt-5' | 'gpt-4.1' | 'gpt-4o' | 'gpt-4o-mini' | 'gpt-4-turbo' | 'o3-pro' | 'o3' | 'o3-mini' | 'o4-mini';
|
|
4
|
+
export type AnthropicModel = 'claude-opus-4-6' | 'claude-sonnet-4-6' | 'claude-haiku-4-5' | 'claude-sonnet-4-5' | 'claude-opus-4-5' | 'claude-opus-4-1' | 'claude-sonnet-4-0' | 'claude-opus-4-0';
|
|
5
|
+
export type GeminiModel = 'gemini-3.1-pro-preview' | 'gemini-3-flash-preview' | 'gemini-3.1-flash-lite-preview' | 'gemini-2.5-flash' | 'gemini-2.5-flash-lite' | 'gemini-2.5-pro';
|
|
6
|
+
export type AiModel = OpenAiModel | AnthropicModel | GeminiModel | (string & NonNullable<unknown>);
|
|
7
|
+
export interface TextSelectedEvent {
|
|
8
|
+
selectionId: string;
|
|
9
|
+
text: string;
|
|
10
|
+
targetTextRange: TargetTextRange;
|
|
11
|
+
}
|
|
12
|
+
export interface RewriterAskAiRequest {
|
|
13
|
+
model: AiModel;
|
|
14
|
+
prompt: string;
|
|
15
|
+
selectedText: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RewriterReplaceTextRequest {
|
|
18
|
+
text: string;
|
|
19
|
+
event: TextSelectedEvent;
|
|
20
|
+
}
|
|
21
|
+
export interface RewriterAddCommentRequest {
|
|
22
|
+
text: string;
|
|
23
|
+
event: TextSelectedEvent;
|
|
24
|
+
}
|
|
25
|
+
export interface RewriterAskAiResponse {
|
|
26
|
+
text: string;
|
|
27
|
+
success: boolean;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface RewriterReplaceTextResponse {
|
|
31
|
+
success: boolean;
|
|
32
|
+
originalText: string;
|
|
33
|
+
replacedText: string;
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface RewriterAddCommentResponse {
|
|
37
|
+
success: boolean;
|
|
38
|
+
annotationId?: string;
|
|
39
|
+
commentText?: string;
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
export type RewriterEventTypesMap = {
|
|
43
|
+
[RewriterEventTypes.TEXT_SELECTED]: TextSelectedEvent;
|
|
44
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { SuggestionEventTypes } from '../../utils/enums';
|
|
2
|
+
import { ApprovedSuggestion, PendingSuggestion, RejectedSuggestion, StaleSuggestion, TargetEditCommitBuilder, TargetEditDetails } from './suggestion.data.model';
|
|
3
|
+
/**
|
|
4
|
+
* Public payload types for the v1 Suggestions feature. Mirrors the layout of
|
|
5
|
+
* `comment-events.data.model.ts` and `recorder-events.data.model.ts`:
|
|
6
|
+
*
|
|
7
|
+
* - One named interface per event payload.
|
|
8
|
+
* - One `SuggestionEventTypesMap` keyed by `SuggestionEventTypes` enum values.
|
|
9
|
+
*
|
|
10
|
+
* Customers pass an event-name string (or the enum constant — they're
|
|
11
|
+
* equivalent) to `velt.getSuggestionElement().on(...)` and receive an
|
|
12
|
+
* `Observable<SuggestionEventTypesMap[T]>`.
|
|
13
|
+
*
|
|
14
|
+
* No separate `actor`/`user` field on the payloads: the user info is on
|
|
15
|
+
* `suggestion.createdBy` (for created) and `suggestion.resolvedBy` (for
|
|
16
|
+
* approved/rejected/stale). Matches the comment-event shape.
|
|
17
|
+
*/
|
|
18
|
+
export interface SuggestionCreatedEvent {
|
|
19
|
+
suggestion: PendingSuggestion;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}
|
|
22
|
+
export interface SuggestionApprovedEvent {
|
|
23
|
+
suggestion: ApprovedSuggestion;
|
|
24
|
+
timestamp: number;
|
|
25
|
+
}
|
|
26
|
+
export interface SuggestionRejectedEvent {
|
|
27
|
+
suggestion: RejectedSuggestion;
|
|
28
|
+
timestamp: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SuggestionStaleEvent {
|
|
31
|
+
suggestion: StaleSuggestion;
|
|
32
|
+
timestamp: number;
|
|
33
|
+
}
|
|
34
|
+
export interface TargetEditStartEvent {
|
|
35
|
+
details: TargetEditDetails;
|
|
36
|
+
timestamp: number;
|
|
37
|
+
}
|
|
38
|
+
export interface TargetEditCommitEvent {
|
|
39
|
+
details: TargetEditDetails;
|
|
40
|
+
/**
|
|
41
|
+
* Pre-bound builder. Calling it commits the suggestion using the SDK's
|
|
42
|
+
* default summary/metadata, optionally overridden by `result`. If the
|
|
43
|
+
* customer's `onTargetEditCommit` handler already returned a non-null
|
|
44
|
+
* result for this edit, this builder is a no-op so subscribers can't
|
|
45
|
+
* double-commit.
|
|
46
|
+
*/
|
|
47
|
+
commitSuggestion: TargetEditCommitBuilder;
|
|
48
|
+
timestamp: number;
|
|
49
|
+
}
|
|
50
|
+
export type SuggestionEventTypesMap = {
|
|
51
|
+
[SuggestionEventTypes.SUGGESTION_CREATED]: SuggestionCreatedEvent;
|
|
52
|
+
[SuggestionEventTypes.SUGGESTION_APPROVED]: SuggestionApprovedEvent;
|
|
53
|
+
[SuggestionEventTypes.SUGGESTION_REJECTED]: SuggestionRejectedEvent;
|
|
54
|
+
[SuggestionEventTypes.SUGGESTION_STALE]: SuggestionStaleEvent;
|
|
55
|
+
[SuggestionEventTypes.TARGET_EDIT_START]: TargetEditStartEvent;
|
|
56
|
+
[SuggestionEventTypes.TARGET_EDIT_COMMIT]: TargetEditCommitEvent;
|
|
57
|
+
};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suggestions feature — public type surface for v1.
|
|
3
|
+
*
|
|
4
|
+
* Source contract: docs/suggestions-api-contract.md
|
|
5
|
+
* Source flows: docs/suggestions-implementation-flows.md
|
|
6
|
+
*
|
|
7
|
+
* Types are exported from the SDK's public barrel. Customer code interacts
|
|
8
|
+
* with these via Snippyly.getSuggestionElement(); the SDK constructs all
|
|
9
|
+
* Suggestion objects internally and customers do not build them directly.
|
|
10
|
+
*/
|
|
11
|
+
import { User } from './user.data.model';
|
|
12
|
+
/**
|
|
13
|
+
* Lifecycle state machine for a Suggestion.
|
|
14
|
+
*
|
|
15
|
+
* - pending: Just created, awaiting owner action.
|
|
16
|
+
* - approved: Owner clicked Approve. Customer apply handler ran successfully.
|
|
17
|
+
* - rejected: Owner clicked Reject (with optional reason).
|
|
18
|
+
* - stale: Target was unresolvable at approve time. Owner can dismiss.
|
|
19
|
+
* - apply_failed: Customer apply handler threw during a suggestionApproved event.
|
|
20
|
+
* Status set by the SDK after the throw was caught.
|
|
21
|
+
*/
|
|
22
|
+
export type SuggestionStatus = 'pending' | 'approved' | 'rejected' | 'stale' | 'apply_failed';
|
|
23
|
+
/**
|
|
24
|
+
* Global per-user-per-session suggestion mode. Not persisted; reload returns to 'editing'.
|
|
25
|
+
*/
|
|
26
|
+
export type SuggestionMode = 'editing' | 'suggesting';
|
|
27
|
+
/**
|
|
28
|
+
* Discriminator for the substrate that produced a suggestion. v1: always 'custom'.
|
|
29
|
+
* Wrapper libraries (e.g. tiptap-velt-comments) widen this union when they integrate.
|
|
30
|
+
*
|
|
31
|
+
* Customers should treat unknown values as opaque; the field exists so customer code
|
|
32
|
+
* can differentiate substrate when domain-specific rendering matters.
|
|
33
|
+
*/
|
|
34
|
+
export type SuggestionTargetType = 'custom';
|
|
35
|
+
/**
|
|
36
|
+
* Single-arg config passed to `SuggestionElement.registerTarget(config)`.
|
|
37
|
+
* Carrying both `targetId` and `getter` in one object so the API can grow
|
|
38
|
+
* (e.g., metadata, target-specific options) without breaking customers.
|
|
39
|
+
*/
|
|
40
|
+
export interface RegisterTargetConfig<T = unknown> {
|
|
41
|
+
targetId: string;
|
|
42
|
+
getter: TargetGetter<T>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Function the customer registers via SuggestionElement.registerTarget(config).
|
|
46
|
+
* Required for any non-primitive (wrapper) target.
|
|
47
|
+
*
|
|
48
|
+
* The SDK calls this getter twice in a typical edit cycle:
|
|
49
|
+
* 1. On focus of the tagged element — to snapshot the pre-edit value.
|
|
50
|
+
* 2. On commit (focusout / change) — to read the current value for the diff.
|
|
51
|
+
*
|
|
52
|
+
* IMPORTANT — edit-time state, not persisted state: the getter must reflect
|
|
53
|
+
* what the user is currently editing, not what's persisted in the customer's
|
|
54
|
+
* app store. If the customer's state is only updated on commit/approve (as
|
|
55
|
+
* is typical when suggesting mode is on), reading from that state would
|
|
56
|
+
* return the snapshot value at commit time, the diff check would short-
|
|
57
|
+
* circuit, and no suggestion would ever fire.
|
|
58
|
+
*
|
|
59
|
+
* Recommended: read from the DOM (controlled or uncontrolled inputs) so the
|
|
60
|
+
* getter always returns what's visible to the user.
|
|
61
|
+
*
|
|
62
|
+
* el.registerTarget('row.123', () => ({
|
|
63
|
+
* qty: parseInt(qtyInput.value, 10),
|
|
64
|
+
* price: parseInt(priceInput.value, 10),
|
|
65
|
+
* }));
|
|
66
|
+
*
|
|
67
|
+
* For controlled inputs (state updates on every keystroke), reading from
|
|
68
|
+
* the customer state is fine: `() => myState.row123`. The contract is
|
|
69
|
+
* "edit-time state" — whichever source of truth has it.
|
|
70
|
+
*/
|
|
71
|
+
export type TargetGetter<T = unknown> = () => T;
|
|
72
|
+
/**
|
|
73
|
+
* Returned from SuggestionElement.on(...). Calling it removes the handler.
|
|
74
|
+
*/
|
|
75
|
+
export type Unsubscribe = () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Details about a target edit, passed to the customer's resolver handler and
|
|
78
|
+
* to subscribers of `targetEditStart` / `targetEditCommit` events.
|
|
79
|
+
*
|
|
80
|
+
* `element` is the DOM element that produced the edit. It's the tagged
|
|
81
|
+
* descendant — or, for wrappers that nest interactive controls inside a
|
|
82
|
+
* tagged container, the inner element that actually fired the event. In
|
|
83
|
+
* either case the SDK walks up to the nearest ancestor carrying
|
|
84
|
+
* `data-velt-suggestion-target` to resolve `targetId`.
|
|
85
|
+
*
|
|
86
|
+
* `element` is provided for read access only — customers should not retain
|
|
87
|
+
* the reference past the synchronous handler call.
|
|
88
|
+
*/
|
|
89
|
+
export interface TargetEditDetails<T = unknown> {
|
|
90
|
+
targetId: string;
|
|
91
|
+
oldValue: T;
|
|
92
|
+
newValue: T;
|
|
93
|
+
element: Element | null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return type of `onTargetEditCommit`. Returning a value auto-commits the
|
|
97
|
+
* suggestion using the (optional) overrides; returning null skips the
|
|
98
|
+
* auto-commit so a subscriber to `targetEditCommit` can drive it explicitly.
|
|
99
|
+
*/
|
|
100
|
+
export interface TargetEditCommitResult {
|
|
101
|
+
/** Override the SDK's default `${targetId}: ${old} → ${new}` summary. */
|
|
102
|
+
summary?: string;
|
|
103
|
+
/** Customer metadata persisted on the resulting Suggestion. */
|
|
104
|
+
metadata?: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Return type of `onTargetEditStart`. Reserved for future fields; v1 has
|
|
108
|
+
* no behavior-bearing return values, so customers may omit a return.
|
|
109
|
+
*
|
|
110
|
+
* Roadmap: future versions may accept `{ oldValue }` here so customers can
|
|
111
|
+
* override the SDK's auto-snapshot with a domain-canonical value.
|
|
112
|
+
*/
|
|
113
|
+
export interface TargetEditStartResult {
|
|
114
|
+
}
|
|
115
|
+
export type TargetEditStartHandler<T = unknown> = (details: TargetEditDetails<T>) => TargetEditStartResult | void | null;
|
|
116
|
+
export type TargetEditCommitHandler<T = unknown> = (details: TargetEditDetails<T>) => TargetEditCommitResult | null;
|
|
117
|
+
/**
|
|
118
|
+
* Config passed to `SuggestionElement.enableSuggestionMode(config?)`.
|
|
119
|
+
* Both callbacks are optional. If `onTargetEditCommit` is omitted, customers
|
|
120
|
+
* can still drive auto-commit by subscribing to the `targetEditCommit` event
|
|
121
|
+
* and calling the pre-bound `commitSuggestion` builder on the payload.
|
|
122
|
+
*/
|
|
123
|
+
export interface EnableSuggestionModeConfig {
|
|
124
|
+
/**
|
|
125
|
+
* Invoked on focus of a tagged element, after the SDK captures the
|
|
126
|
+
* snapshot. v1: informational — return value is reserved for future
|
|
127
|
+
* use (e.g. `{ oldValue }` to override the SDK's auto-snapshot).
|
|
128
|
+
*/
|
|
129
|
+
onTargetEditStart?: TargetEditStartHandler;
|
|
130
|
+
/**
|
|
131
|
+
* Invoked once per detected commit (on `change` for atomic inputs, on
|
|
132
|
+
* `focusout` for text-like inputs). Returning a `TargetEditCommitResult`
|
|
133
|
+
* auto-commits with the supplied summary/metadata; returning null defers
|
|
134
|
+
* to event subscribers.
|
|
135
|
+
*/
|
|
136
|
+
onTargetEditCommit?: TargetEditCommitHandler;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* SDK-managed suggestion data persisted on a CommentAnnotation.
|
|
140
|
+
* Present iff annotation.type === 'suggestion'.
|
|
141
|
+
*
|
|
142
|
+
* Customer code must not write to this directly — use the SuggestionElement API.
|
|
143
|
+
*/
|
|
144
|
+
export interface SuggestionData {
|
|
145
|
+
/** Lifecycle state machine. */
|
|
146
|
+
status: SuggestionStatus;
|
|
147
|
+
/** Stable, customer-owned target identifier. */
|
|
148
|
+
targetId: string;
|
|
149
|
+
/** v1: always 'custom'. Wrappers widen later. */
|
|
150
|
+
targetType: SuggestionTargetType;
|
|
151
|
+
/** Snapshot taken at startSuggestion / focus time. Frozen via structuredClone. */
|
|
152
|
+
oldValue: any;
|
|
153
|
+
/** Value submitted via commitSuggestion. */
|
|
154
|
+
newValue: any;
|
|
155
|
+
/** Optional human-readable description for logs / notifications. */
|
|
156
|
+
summary: string | null;
|
|
157
|
+
/**
|
|
158
|
+
* True if the live value at approve time differed from oldValue.
|
|
159
|
+
* v1 records flag only; v1.1 will surface a confirmation prompt.
|
|
160
|
+
*/
|
|
161
|
+
driftDetected: boolean;
|
|
162
|
+
/** Populated only when status === 'rejected'. */
|
|
163
|
+
rejectReason: string | null;
|
|
164
|
+
/**
|
|
165
|
+
* Full User snapshot of the resolver, populated when status moves to
|
|
166
|
+
* approved | rejected | stale | apply_failed. Snapshot rather than userId
|
|
167
|
+
* so customer code can render name/email/photoUrl without an extra lookup,
|
|
168
|
+
* and so historical suggestions retain their resolver record even if the
|
|
169
|
+
* user later updates their profile.
|
|
170
|
+
*/
|
|
171
|
+
resolvedBy: User | null;
|
|
172
|
+
resolvedAt: number | null;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Fields shared across every Suggestion regardless of status.
|
|
176
|
+
* Internal — used to build the per-status discriminated types below.
|
|
177
|
+
*/
|
|
178
|
+
interface SuggestionBase<T = unknown> {
|
|
179
|
+
/** Annotation document id (same as the underlying CommentAnnotation.annotationId). */
|
|
180
|
+
annotationId: string;
|
|
181
|
+
/** Stable, customer-owned target identifier. */
|
|
182
|
+
targetId: string;
|
|
183
|
+
/** v1: always 'custom'. */
|
|
184
|
+
targetType: SuggestionTargetType;
|
|
185
|
+
/** Snapshot taken at startSuggestion / focus time. */
|
|
186
|
+
oldValue: T;
|
|
187
|
+
/** Value submitted via commitSuggestion. */
|
|
188
|
+
newValue: T;
|
|
189
|
+
/** Optional human-readable description. */
|
|
190
|
+
summary: string | null;
|
|
191
|
+
/** Customer-defined metadata supplied via CommitSuggestionConfig.metadata. */
|
|
192
|
+
metadata: Record<string, any>;
|
|
193
|
+
/** True iff the live value at approve time differed from oldValue. */
|
|
194
|
+
driftDetected: boolean;
|
|
195
|
+
/**
|
|
196
|
+
* User of the suggestion's creator (sourced from annotation.from).
|
|
197
|
+
*/
|
|
198
|
+
createdBy?: User;
|
|
199
|
+
createdAt: number;
|
|
200
|
+
}
|
|
201
|
+
/** A suggestion in the 'pending' state — newly created, no owner action yet. */
|
|
202
|
+
export interface PendingSuggestion<T = unknown> extends SuggestionBase<T> {
|
|
203
|
+
status: 'pending';
|
|
204
|
+
rejectReason: null;
|
|
205
|
+
resolvedBy: null;
|
|
206
|
+
resolvedAt: null;
|
|
207
|
+
}
|
|
208
|
+
/** A suggestion that has been approved (apply handler success or pending invocation). */
|
|
209
|
+
export interface ApprovedSuggestion<T = unknown> extends SuggestionBase<T> {
|
|
210
|
+
status: 'approved' | 'apply_failed';
|
|
211
|
+
rejectReason: null;
|
|
212
|
+
resolvedBy: User;
|
|
213
|
+
resolvedAt: number;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* A suggestion that has been rejected. `rejectReason` may be null when the
|
|
217
|
+
* rejecter dismissed without supplying a reason — matches the persisted
|
|
218
|
+
* `SuggestionData.rejectReason: string | null` shape.
|
|
219
|
+
*/
|
|
220
|
+
export interface RejectedSuggestion<T = unknown> extends SuggestionBase<T> {
|
|
221
|
+
status: 'rejected';
|
|
222
|
+
rejectReason: string | null;
|
|
223
|
+
resolvedBy: User;
|
|
224
|
+
resolvedAt: number;
|
|
225
|
+
}
|
|
226
|
+
/** A suggestion whose target was unresolvable at approve time. */
|
|
227
|
+
export interface StaleSuggestion<T = unknown> extends SuggestionBase<T> {
|
|
228
|
+
status: 'stale';
|
|
229
|
+
rejectReason: null;
|
|
230
|
+
resolvedBy: User | null;
|
|
231
|
+
resolvedAt: number | null;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Public Suggestion — discriminated union keyed by `status`. TypeScript narrows
|
|
235
|
+
* field types per status (e.g. `resolvedBy: User` is non-null on approved/rejected,
|
|
236
|
+
* `rejectReason: string | null` on rejected since one-click reject without a reason
|
|
237
|
+
* is supported).
|
|
238
|
+
*/
|
|
239
|
+
export type Suggestion<T = unknown> = PendingSuggestion<T> | ApprovedSuggestion<T> | RejectedSuggestion<T> | StaleSuggestion<T>;
|
|
240
|
+
export interface CommitSuggestionConfig<T = unknown> {
|
|
241
|
+
/**
|
|
242
|
+
* Must be registered (via data-velt-target attribute or registerTarget call)
|
|
243
|
+
* before commit, otherwise the suggestion is rejected with a dev-mode warning.
|
|
244
|
+
*/
|
|
245
|
+
targetId: string;
|
|
246
|
+
/** Any JSON-serializable value. Customer's apply handler interprets it. */
|
|
247
|
+
newValue: T;
|
|
248
|
+
/** Optional human-readable string for logs and notifications. */
|
|
249
|
+
summary?: string;
|
|
250
|
+
/** Optional customer-defined metadata. Stored on Suggestion.metadata. */
|
|
251
|
+
metadata?: Record<string, unknown>;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Pre-bound builder attached to `targetEditCommit` payloads. Calling it
|
|
255
|
+
* commits the suggestion with the SDK's default summary/metadata, optionally
|
|
256
|
+
* overridden by `result`. If the customer's `onTargetEditCommit` handler
|
|
257
|
+
* already returned a non-null result for this edit, this builder is a no-op
|
|
258
|
+
* (resolves immediately) so subscribers can't double-commit.
|
|
259
|
+
*/
|
|
260
|
+
export type TargetEditCommitBuilder = (result?: TargetEditCommitResult) => Promise<{
|
|
261
|
+
id: string;
|
|
262
|
+
} | null>;
|
|
263
|
+
export interface SuggestionGetSuggestionsFilter {
|
|
264
|
+
targetId?: string;
|
|
265
|
+
status?: SuggestionStatus | SuggestionStatus[];
|
|
266
|
+
}
|
|
267
|
+
export {};
|
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import { ResolverConfig } from "./resolver.data.model";
|
|
1
|
+
import { ResolverConfig, ResolverResponse, RetryConfig } from "./resolver.data.model";
|
|
2
2
|
import { User } from "./user.data.model";
|
|
3
3
|
export interface UserDataProvider {
|
|
4
4
|
get(userIds: string[]): Promise<Record<string, User>>;
|
|
5
5
|
config?: ResolverConfig;
|
|
6
6
|
resolveTimeout?: number;
|
|
7
7
|
}
|
|
8
|
+
export interface AnonymousUserDataProvider {
|
|
9
|
+
resolveUserIdsByEmail(request: ResolveUserIdsByEmailRequest): Promise<ResolverResponse<Record<string, string>>>;
|
|
10
|
+
config?: AnonymousUserDataProviderConfig;
|
|
11
|
+
}
|
|
12
|
+
export interface AnonymousUserDataProviderConfig {
|
|
13
|
+
resolveTimeout?: number;
|
|
14
|
+
getRetryConfig?: RetryConfig;
|
|
15
|
+
}
|
|
16
|
+
export interface ResolveUserIdsByEmailRequest {
|
|
17
|
+
organizationId: string;
|
|
18
|
+
documentId?: string;
|
|
19
|
+
folderId?: string;
|
|
20
|
+
emails: string[];
|
|
21
|
+
}
|
|
8
22
|
export interface GetUserResolverRequest {
|
|
9
23
|
organizationId: string;
|
|
10
24
|
userIds: string[];
|
|
@@ -19,6 +33,7 @@ export interface GetUserPermissionsResponse {
|
|
|
19
33
|
folders?: {
|
|
20
34
|
[folderId: string]: {
|
|
21
35
|
accessRole?: UserPermissionAccessRole;
|
|
36
|
+
accessType?: string;
|
|
22
37
|
expiresAt?: number;
|
|
23
38
|
error?: string;
|
|
24
39
|
errorCode?: UserPermissionAccessRoleResult;
|
|
@@ -35,6 +50,7 @@ export interface GetUserPermissionsResponse {
|
|
|
35
50
|
documents?: {
|
|
36
51
|
[documentId: string]: {
|
|
37
52
|
accessRole?: UserPermissionAccessRole;
|
|
53
|
+
accessType?: string;
|
|
38
54
|
expiresAt?: number;
|
|
39
55
|
error?: string;
|
|
40
56
|
errorCode?: UserPermissionAccessRoleResult;
|
|
@@ -12,6 +12,8 @@ export declare class User {
|
|
|
12
12
|
* Default: Random avatar name.
|
|
13
13
|
*/
|
|
14
14
|
name?: string;
|
|
15
|
+
email_lowercase?: string;
|
|
16
|
+
name_lowercase?: string;
|
|
15
17
|
clientUserName?: string;
|
|
16
18
|
/**
|
|
17
19
|
* Your user's display picture URL.
|
|
@@ -158,6 +160,7 @@ export interface PermissionQuery {
|
|
|
158
160
|
source: PermissionSource;
|
|
159
161
|
organizationId: string;
|
|
160
162
|
context?: Context | SetDocumentsContext;
|
|
163
|
+
parentFolderId?: string;
|
|
161
164
|
};
|
|
162
165
|
}
|
|
163
166
|
export interface PermissionResult {
|