issue-sticker 0.11.0 → 0.13.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/headless.d.ts CHANGED
@@ -101,6 +101,27 @@ export interface IssueStickerSummary {
101
101
  readonly color: string;
102
102
  readonly label: string | null;
103
103
  } | null;
104
+ /** 영상 URL. 업로드 중이거나 영상이 없으면 `null` 입니다. */
105
+ video?: string | null;
106
+ /**
107
+ * 영상 업로드 상태. `submitDraft()` 직후에는 `'uploading'` 이고, 업로드가 끝나면
108
+ * `snapshot.issues` 의 같은 이슈가 `'ready'` 로 바뀝니다. 영상 URL 은 `openIssue()` 로 연
109
+ * `snapshot.activeIssue.video` 에서 확인합니다. 업로드를 끝내 포기하면 `'failed'` 입니다.
110
+ * 영상이 없으면 `null`.
111
+ */
112
+ video_status?: 'uploading' | 'ready' | 'failed' | null;
113
+ /**
114
+ * 영상 업로드를 끝내 포기한 이유. `video_status` 가 `'failed'` 이고 이유를 알 때만 있습니다.
115
+ * 업로드하는 동안 프로젝트 마스킹 정책이 화면 녹화를 막으면 `'masking_video_excluded'` 이고,
116
+ * 이슈는 영상 없이 남습니다.
117
+ */
118
+ video_failure_reason?: 'masking_video_excluded' | null;
119
+ /**
120
+ * 세션 리플레이 업로드 상태. 리플레이가 있는 이슈는 `submitDraft()`·`createIssue()` 직후
121
+ * `'uploading'` 이고, 업로드가 끝나면 `snapshot.issues` 의 같은 이슈가 `'ready'` 로 바뀝니다.
122
+ * 업로드를 끝내 포기하면 `'failed'` 이고 그 이슈에는 리플레이가 없습니다. 리플레이가 없으면 `null`.
123
+ */
124
+ replay_status?: 'uploading' | 'ready' | 'failed' | null;
104
125
  }
105
126
 
106
127
  /** 상세 조회한 이슈. */
@@ -162,7 +183,15 @@ export type HeadlessErrorCode =
162
183
  | 'NETWORK_ERROR'
163
184
  | 'CAPTURE_FAILED'
164
185
  | 'VALIDATION_ERROR'
165
- | 'PAYLOAD_TOO_LARGE';
186
+ | 'PAYLOAD_TOO_LARGE'
187
+ /** 워크스페이스 마스킹 정책을 불러오지 못해 이슈를 만들지 않았다. 네트워크를 확인한 뒤 다시 제출한다. */
188
+ | 'MASKING_POLICY_UNAVAILABLE'
189
+ /** 제출 중 프로젝트의 화면 마스킹 규칙이 바뀌었다. 스크린샷·세션 리플레이를 새로 만든 뒤 제출한다. */
190
+ | 'MASKING_POLICY_CHANGED'
191
+ /** 화면 마스킹 규칙의 선택자를 이 브라우저에서 적용할 수 없다. 다시 시도해도 같으므로 워크스페이스 관리자에게 문의한다. */
192
+ | 'MASKING_SELECTOR_UNSUPPORTED'
193
+ /** `createIssue()` 호출 한도(60초에 5건)를 넘었다. 한도 구간이 지난 뒤 다시 호출한다. */
194
+ | 'RATE_LIMITED';
166
195
 
167
196
  export type HeadlessAuthMode = 'public' | 'member';
168
197
  export type HeadlessCaptureMediaMode = 'screenshot' | 'video';
@@ -257,6 +286,28 @@ export interface HeadlessSessionReplayState {
257
286
  readonly error: string | null;
258
287
  }
259
288
 
289
+ /** 뒤에서 올리는 영상 하나의 상태. 업로드가 끝나면 목록에서 빠집니다. */
290
+ export interface HeadlessVideoUpload {
291
+ readonly issueId: string;
292
+ /** `failed` 는 네트워크 재시도를 모두 쓴 상태입니다. `retryVideoUpload()` 로 이어 올립니다. */
293
+ readonly status: 'queued' | 'uploading' | 'failed';
294
+ /** 0~1 */
295
+ readonly progress: number;
296
+ }
297
+
298
+ /** 뒤에서 올리는 세션 리플레이·웹소켓 로그 하나의 상태. 업로드가 끝나면 목록에서 빠집니다. */
299
+ export interface HeadlessAttachmentUpload {
300
+ readonly issueId: string;
301
+ readonly kind: 'replay' | 'socket';
302
+ /**
303
+ * `failed` 는 네트워크 재시도를 모두 쓴 상태입니다. 연결이 돌아오거나 다음에 초기화할 때,
304
+ * 또는 `retryVideoUpload(issueId)` 를 부르면 다시 올립니다.
305
+ */
306
+ readonly status: 'queued' | 'uploading' | 'failed';
307
+ /** 0~1 */
308
+ readonly progress: number;
309
+ }
310
+
260
311
  export interface HeadlessSnapshot {
261
312
  readonly phase: HeadlessPhase;
262
313
  readonly auth: HeadlessAuthState;
@@ -265,6 +316,8 @@ export interface HeadlessSnapshot {
265
316
  readonly draft: HeadlessIssueDraft | null;
266
317
  readonly videoCapture: HeadlessVideoCaptureState;
267
318
  readonly sessionReplay: HeadlessSessionReplayState;
319
+ readonly videoUploads: readonly HeadlessVideoUpload[];
320
+ readonly attachmentUploads: readonly HeadlessAttachmentUpload[];
268
321
  readonly formSchema: IssueFormSchema | null;
269
322
  readonly filterSchema: IssueFilterSchema | null;
270
323
  readonly error: IssueStickerHeadlessError | null;
@@ -313,6 +366,11 @@ export interface CreateIssueInput extends SubmitDraftInput {
313
366
  readonly target?: HTMLElement;
314
367
  /** 기본 `'screenshot'`. `'none'`이면 캡처를 건너뛰고 즉시 전송합니다. */
315
368
  readonly media?: 'screenshot' | 'none';
369
+ /**
370
+ * 이슈를 생성하지 않고 `null`로 끝날 때 한 번 호출됩니다. `code`는 `submitDraft()`가 던지는
371
+ * 코드와 같습니다. 이 콜백에서 던진 예외는 `createIssue()` 밖으로 전달되지 않습니다.
372
+ */
373
+ readonly onError?: (error: IssueStickerHeadlessError) => void;
316
374
  }
317
375
 
318
376
  export interface HeadlessClient {
@@ -329,18 +387,36 @@ export interface HeadlessClient {
329
387
  stopVideoCapture(): Promise<void>;
330
388
  setSessionReplayEnabled(enabled: boolean): void;
331
389
  cancelIssueCapture(): void;
332
- submitDraft(input: SubmitDraftInput): Promise<Issue>;
390
+ /**
391
+ * 이슈를 생성하고 바로 돌려줍니다. 녹화 영상·세션 리플레이·웹소켓 로그는 이슈가 생성된 뒤
392
+ * 따로 업로드되며, 진행은 `snapshot.videoUploads`·`snapshot.attachmentUploads` 로 확인합니다.
393
+ *
394
+ * 프로젝트 마스킹 정책이 화면 녹화를 금지하면 영상 없이 이슈를 생성하고 `videoExcluded: true` 를
395
+ * 함께 돌려줍니다. 마스킹 정책을 적용하지 못해 스크린샷을 한 장이라도 첨부하지 않았으면
396
+ * `screenshotExcluded: true` 를 함께 돌려줍니다.
397
+ */
398
+ submitDraft(
399
+ input: SubmitDraftInput
400
+ ): Promise<Issue & { readonly videoExcluded?: boolean; readonly screenshotExcluded?: boolean }>;
401
+ /** 이슈의 실패한 업로드(영상·세션 리플레이·웹소켓 로그)를 다시 올립니다. */
402
+ retryVideoUpload(issueId: string): void;
333
403
  /**
334
404
  * 유저 액션 없이 코드에서 이슈를 만듭니다. 캡처 단계를 거치지 않으므로 `phase`와
335
405
  * `draft`를 건드리지 않고, 사용자가 이슈를 작성하는 중에도 호출할 수 있습니다.
336
406
  *
337
407
  * 실패해도 예외를 던지지 않고 `null`을 돌려줍니다. 이미 오류를 처리하는 자리에서
338
408
  * 부르는 메서드라, 이슈 생성만을 위한 try/catch 를 한 겹 더 쓰지 않아도 됩니다.
339
- * 실패 사유는 콘솔 경고로 남습니다.
409
+ * 실패 사유는 콘솔 경고로 남고, `input.onError`가 있으면 그 에러로 호출됩니다.
340
410
  *
341
411
  * 호출 조건이 잘못 잡히면 이슈가 무한히 쌓이므로 SDK가 60초 5건으로 제한합니다.
412
+ * 넘어선 호출은 `RATE_LIMITED`로 끝납니다.
413
+ *
414
+ * 마스킹 정책을 적용하지 못해 스크린샷을 한 장이라도 첨부하지 않았으면 `screenshotExcluded: true` 를
415
+ * 함께 돌려줍니다.
342
416
  */
343
- createIssue(input: CreateIssueInput): Promise<Issue | null>;
417
+ createIssue(
418
+ input: CreateIssueInput
419
+ ): Promise<(Issue & { readonly screenshotExcluded?: boolean }) | null>;
344
420
  loginAsMember(): Promise<void>;
345
421
  logoutMember(): Promise<void>;
346
422
  destroy(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "issue-sticker",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "IssueSticker SDK - Visual bug tracking widget for web applications",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",