@golpoai/sdk 0.1.9 → 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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/Golpo.ts
2
2
  import axios from "axios";
3
- import { createReadStream } from "fs";
3
+ import { createReadStream, promises as fs } from "fs";
4
4
  import { basename, resolve } from "path";
5
5
  import { lookup as mimeLookup } from "mime-types";
6
6
  import pLimit from "p-limit";
@@ -20,33 +20,55 @@ var Golpo = class {
20
20
  async createPodcastJob(prompt, opts = {}) {
21
21
  const {
22
22
  uploads,
23
- concurrency = 8,
24
- addMusic = false,
25
23
  voiceInstructions,
26
- personality1,
27
- personality2,
28
- doResearch = false,
29
- ttsModel = "accurate",
30
24
  language,
31
- style = "conversational",
25
+ style = "solo-female-3",
32
26
  bgMusic,
33
- outputVolume = 1,
34
- no_voice_chunking = false
27
+ // Extended params
28
+ newScript,
29
+ timing = 1
30
+ // timing in minutes – default 1 if not provided
35
31
  } = opts;
32
+ const concurrency = 8;
36
33
  const fields = [
37
34
  ["prompt", prompt],
38
- ["add_music", String(addMusic)],
39
- ["do_research", String(doResearch)],
40
- ["tts_model", ttsModel],
41
- ["style", style],
42
- ["output_volume", String(outputVolume)]
35
+ ["style", style]
43
36
  ];
44
37
  if (voiceInstructions) fields.push(["voice_instructions", voiceInstructions]);
45
- if (personality1) fields.push(["personality_1", personality1]);
46
- if (personality2) fields.push(["personality_2", personality2]);
47
38
  if (language) fields.push(["language", language]);
48
39
  if (bgMusic) fields.push(["bg_music", bgMusic]);
49
- if (no_voice_chunking) fields.push(["no_voice_chunking", String(no_voice_chunking)]);
40
+ if (newScript != null) fields.push(["new_script", newScript]);
41
+ fields.push(["timing", String(timing)]);
42
+ fields.push(["video_type", "null"]);
43
+ const hasUploads = (() => {
44
+ if (!uploads) return false;
45
+ if (typeof uploads === "string") return uploads.trim().length > 0;
46
+ const iterator = uploads[Symbol.iterator]();
47
+ const first = iterator.next();
48
+ return !first.done;
49
+ })();
50
+ const request_payload = {
51
+ prompt,
52
+ video_voice: style,
53
+ video_duration: String(timing),
54
+ video_type: "null",
55
+ language,
56
+ voice_instructions: voiceInstructions,
57
+ new_script: newScript,
58
+ bg_music: bgMusic,
59
+ attached_documents: uploads,
60
+ source: "node-sdk"
61
+ };
62
+ try {
63
+ const result = await this.createVideoRecord({
64
+ topic: prompt,
65
+ requestPayload: request_payload
66
+ });
67
+ if (result && result.videoId) {
68
+ fields.push(["video_id", result.videoId]);
69
+ }
70
+ } catch (error) {
71
+ }
50
72
  const formData = await this.createFormData(fields, uploads, concurrency);
51
73
  const { data } = await this.http.post("/generate", formData, {
52
74
  timeout: 24e4,
@@ -73,63 +95,210 @@ var Golpo = class {
73
95
  async createPodcast(prompt, opts = {}) {
74
96
  const { pollIntervalMs = 2e3, ...jobOpts } = opts;
75
97
  const jobId = await this.createPodcastJob(prompt, jobOpts);
76
- return this.pollUntilComplete(
98
+ const r = await this.pollUntilComplete(
77
99
  jobId,
78
100
  pollIntervalMs
79
- ).then((r) => ({
80
- podcastUrl: r.podcast_url,
81
- podcastScript: r.podcast_script
82
- }));
101
+ );
102
+ return { url: r.podcast_url, script: r.podcast_script, videoId: jobId };
83
103
  }
84
104
  async createVideo(prompt, opts = {}) {
85
105
  const {
86
106
  uploads,
87
107
  pollIntervalMs = 2e3,
88
- concurrency = 8,
89
108
  voiceInstructions,
90
- personality1,
91
- doResearch = false,
92
- ttsModel = "accurate",
93
109
  language,
94
- style = "solo-female",
110
+ style = "solo-female-3",
95
111
  bgMusic = "engaging",
96
- bgVolume = 1.4,
97
- outputVolume = 1,
98
112
  videoType = "long",
99
- includeWatermark = true,
113
+ includeWatermark = false,
100
114
  logo,
101
- timing = "1"
115
+ timing = 1,
116
+ useColor = true,
117
+ // newly added backend parameters
118
+ newScript,
119
+ logoPlacement,
120
+ videoInstructions,
121
+ useLineart2Style,
122
+ audioClip,
123
+ isPublic,
124
+ useAsIs,
125
+ skipAnimation,
126
+ userImages,
127
+ userImagesDescriptions,
128
+ userVideos,
129
+ userVideosDescription,
130
+ userAudioInVideo,
131
+ use2Style,
132
+ // specificAnimation, // not yet supported by the Golpo 2.0 pipeline
133
+ imageStyle,
134
+ inputImages,
135
+ penStyle,
136
+ showPencilCursor,
137
+ pacing,
138
+ justReturnScript
102
139
  } = opts;
140
+ const concurrency = 8;
141
+ const request_payload = {
142
+ prompt,
143
+ video_voice: style,
144
+ video_duration: String(timing),
145
+ video_type: videoType,
146
+ language,
147
+ voice_instructions: voiceInstructions,
148
+ bg_music: bgMusic,
149
+ use_color: useColor,
150
+ direct_script: newScript,
151
+ script_mode: newScript ? true : false,
152
+ logo_placement: logoPlacement,
153
+ video_instructions: videoInstructions,
154
+ use_lineart_2_style: useLineart2Style,
155
+ audio_clip: audioClip,
156
+ is_public: isPublic,
157
+ use_as_is: useAsIs,
158
+ skip_animation: skipAnimation,
159
+ user_images: userImages,
160
+ user_images_descriptions: userImagesDescriptions,
161
+ user_videos: userVideos,
162
+ user_videos_description: userVideosDescription,
163
+ user_audio_in_video: userAudioInVideo,
164
+ use_2_0_style: use2Style,
165
+ // specific_animation: specificAnimation, // not yet supported by the pipeline
166
+ image_style: imageStyle,
167
+ input_images: inputImages,
168
+ pen_style: penStyle,
169
+ show_pencil_cursor: penStyle ? true : showPencilCursor ?? false,
170
+ pacing,
171
+ own_narration_video_mode: null,
172
+ own_narration_pip_position: null,
173
+ just_return_script: justReturnScript,
174
+ attached_documents: uploads,
175
+ source: "node-sdk"
176
+ };
103
177
  const fields = [
104
178
  ["prompt", prompt],
105
- ["do_research", String(doResearch)],
106
- ["tts_model", ttsModel],
107
- ["bg_volume", String(bgVolume)],
108
- ["output_volume", String(outputVolume)],
109
179
  ["style", style],
110
180
  ["video_type", videoType],
111
181
  ["include_watermark", String(includeWatermark)],
112
- ["timing", timing]
182
+ ["timing", String(timing)],
183
+ ["use_color", String(useColor)]
113
184
  ];
114
185
  if (language) fields.push(["language", language]);
115
186
  if (voiceInstructions) fields.push(["voice_instructions", voiceInstructions]);
116
- if (personality1) fields.push(["personality_1", personality1]);
117
187
  if (bgMusic) fields.push(["bg_music", bgMusic]);
188
+ try {
189
+ const result = await this.createVideoRecord({
190
+ topic: prompt,
191
+ requestPayload: request_payload
192
+ });
193
+ if (result && result.videoId) {
194
+ fields.push(["video_id", result.videoId]);
195
+ }
196
+ } catch (error) {
197
+ }
198
+ if (newScript) fields.push(["new_script", newScript]);
199
+ if (logoPlacement) fields.push(["logo_placement", logoPlacement]);
200
+ if (videoInstructions) fields.push(["video_instructions", videoInstructions]);
201
+ if (useLineart2Style) fields.push(["use_lineart_2_style", useLineart2Style]);
202
+ if (isPublic != null) fields.push(["is_public", String(isPublic)]);
203
+ if (useAsIs) {
204
+ const value = Array.isArray(useAsIs) ? JSON.stringify(useAsIs) : useAsIs;
205
+ fields.push(["use_as_is", value]);
206
+ }
207
+ if (skipAnimation) {
208
+ const value = Array.isArray(skipAnimation) ? JSON.stringify(skipAnimation) : skipAnimation;
209
+ fields.push(["skip_animation", value]);
210
+ }
211
+ if (userImagesDescriptions) {
212
+ const value = Array.isArray(userImagesDescriptions) ? JSON.stringify(userImagesDescriptions) : userImagesDescriptions;
213
+ fields.push(["user_images_descriptions", value]);
214
+ }
215
+ if (userVideosDescription) {
216
+ const value = Array.isArray(userVideosDescription) ? JSON.stringify(userVideosDescription) : userVideosDescription;
217
+ fields.push(["user_videos_description", value]);
218
+ }
219
+ if (userAudioInVideo) {
220
+ fields.push(["user_audio_in_video", userAudioInVideo]);
221
+ } else if (userVideos) {
222
+ fields.push(["user_audio_in_video", "[]"]);
223
+ }
224
+ if (use2Style != null) fields.push(["use_2_0_style", String(use2Style)]);
225
+ if (imageStyle) fields.push(["image_style", imageStyle]);
226
+ if (penStyle) fields.push(["pen_style", penStyle]);
227
+ const effectiveShowPencilCursor = penStyle ? true : showPencilCursor ?? false;
228
+ fields.push(["show_pencil_cursor", String(effectiveShowPencilCursor)]);
229
+ if (pacing) fields.push(["pacing", pacing]);
230
+ if (justReturnScript != null) fields.push(["just_return_script", String(justReturnScript)]);
118
231
  if (logo) {
119
232
  fields.push(["logo_path", logo]);
120
233
  }
121
- const formData = await this.createFormData(fields, uploads, concurrency, logo);
234
+ const formData = await this.createFormData(
235
+ fields,
236
+ uploads,
237
+ concurrency,
238
+ logo,
239
+ audioClip,
240
+ userImages,
241
+ userVideos,
242
+ inputImages
243
+ );
122
244
  const { data } = await this.http.post("/generate", formData, {
123
245
  timeout: 24e4,
124
246
  headers: formData.getHeaders()
125
247
  });
126
- return this.pollUntilComplete(
248
+ if (justReturnScript) {
249
+ const r2 = await this.pollUntilComplete(
250
+ data.job_id,
251
+ pollIntervalMs,
252
+ "/script-status"
253
+ );
254
+ return { url: "", script: r2.podcast_script, videoId: data.job_id };
255
+ }
256
+ const r = await this.pollUntilComplete(
127
257
  data.job_id,
128
258
  pollIntervalMs
129
- ).then((r) => ({
130
- videoUrl: r.podcast_url,
131
- videoScript: r.podcast_script
132
- }));
259
+ );
260
+ return { url: r.podcast_url, script: r.podcast_script, videoId: data.job_id };
261
+ }
262
+ /**
263
+ * Private helper: Get user email from API key
264
+ * Backend resolves: api_key -> user_id -> user_credits.email
265
+ */
266
+ async getUserEmailFromApiKey() {
267
+ try {
268
+ const { data } = await this.http.get("/api/resolve-email-from-api-key");
269
+ return data.email || null;
270
+ } catch (error) {
271
+ return null;
272
+ }
273
+ }
274
+ async createVideoRecord(opts) {
275
+ const {
276
+ topic,
277
+ context = "",
278
+ scenes = 6,
279
+ pipeline = "color",
280
+ shareDocuments = false,
281
+ logoPlacement = null,
282
+ audioClipUrl = null,
283
+ requestPayload
284
+ } = opts;
285
+ const emailFromApiKey = await this.getUserEmailFromApiKey();
286
+ if (!emailFromApiKey) {
287
+ throw new Error("Email not found");
288
+ }
289
+ const body = {
290
+ topic,
291
+ context,
292
+ scenes,
293
+ pipeline,
294
+ user_email: emailFromApiKey,
295
+ share_documents: shareDocuments,
296
+ logo_placement: logoPlacement,
297
+ audio_clip_url: audioClipUrl,
298
+ request_payload: requestPayload ? JSON.stringify(requestPayload) : null
299
+ };
300
+ const { data } = await this.http.post("/api/create-video-record", body);
301
+ return { videoId: data.video_id };
133
302
  }
134
303
  /**
135
304
  * Edit specific frames of a video and regenerate the video.
@@ -176,11 +345,11 @@ var Golpo = class {
176
345
  try {
177
346
  const frameVersions = await this.getFrameVersions(videoId);
178
347
  let frameAnimations = frameVersions.frame_animations ? { ...frameVersions.frame_animations } : {};
179
- frameIds.forEach(async (frameId) => {
348
+ for (const frameId of frameIds) {
180
349
  await this.setFrameVersion(videoId, frameId, editResult);
181
350
  const updatedVersions = await this.getFrameVersions(videoId);
182
351
  frameAnimations = updatedVersions.frame_animations || {};
183
- });
352
+ }
184
353
  const mp4Urls = Object.entries(frameAnimations).sort(([a], [b]) => parseInt(a) - parseInt(b)).map(([_, url]) => url);
185
354
  if (mp4Urls.length === 0) {
186
355
  throw new Error("No frame animations found to combine");
@@ -190,17 +359,11 @@ var Golpo = class {
190
359
  pollIntervalMs,
191
360
  videoUrl
192
361
  };
193
- const combinedUrl = await this.combineVideos(combineOptions);
194
- return {
195
- videoUrl: combinedUrl,
196
- jobId
197
- };
362
+ const combined = await this.combineVideos(combineOptions);
363
+ return { videoUrl: combined.url, jobId };
198
364
  } catch (error) {
199
365
  console.warn("Failed to auto-combine videos, returning edit result:", error);
200
- return {
201
- videoUrl: editResult,
202
- jobId
203
- };
366
+ return { videoUrl: editResult, jobId };
204
367
  }
205
368
  }
206
369
  /**
@@ -354,19 +517,25 @@ var Golpo = class {
354
517
  if (!combineJobId) {
355
518
  throw new Error("No job ID received from combine-videos API");
356
519
  }
357
- return this.pollEditStatus(combineJobId, pollIntervalMs);
520
+ const url = await this.pollEditStatus(combineJobId, pollIntervalMs);
521
+ return { url };
358
522
  }
359
523
  /* ------------------------------------------------------------ *
360
524
  * INTERNAL HELPERS
361
525
  * ------------------------------------------------------------ */
362
- async pollUntilComplete(jobId, interval) {
526
+ async pollUntilComplete(jobId, interval, statusPath = "/status") {
363
527
  while (true) {
528
+ let data;
364
529
  try {
365
- const { data } = await this.http.get(`/status/${jobId}`);
366
- if (data.status === "completed") return data;
530
+ const res = await this.http.get(`${statusPath}/${jobId}`);
531
+ data = res.data;
367
532
  } catch (error) {
368
533
  console.warn(`Status check failed for job ${jobId}, retrying in ${interval}ms:`, error instanceof Error ? error.message : error);
369
534
  }
535
+ if (data?.status === "completed") return data;
536
+ if (data?.status === "failed") {
537
+ throw new Error(`Job ${jobId} failed: ${data.error || data.message || "unknown error"}`);
538
+ }
370
539
  await new Promise((r) => setTimeout(r, interval));
371
540
  }
372
541
  }
@@ -416,7 +585,50 @@ var Golpo = class {
416
585
  attempts++;
417
586
  }
418
587
  }
419
- async createFormData(fields, uploads, concurrency, logo) {
588
+ /**
589
+ * Upload a file using /upload-url endpoint and return the final URL.
590
+ * Replicates the _presign_and_upload_one logic from the backend.
591
+ */
592
+ async uploadFileAndGetUrl(filePath) {
593
+ const absPath = resolve(filePath.trim().replace(/^<|>$/g, ""));
594
+ try {
595
+ await fs.access(absPath);
596
+ } catch (error) {
597
+ throw new Error(`File not found: ${absPath}. Original path: ${filePath}`);
598
+ }
599
+ const fileName = basename(absPath);
600
+ const fileData = await fs.readFile(absPath);
601
+ const mimeType = mimeLookup(absPath) || "application/octet-stream";
602
+ const { data: presignInfo } = await this.http.post(
603
+ "/upload-url",
604
+ { filename: fileName },
605
+ { headers: { "Content-Type": "application/x-www-form-urlencoded" } }
606
+ );
607
+ let finalUrl;
608
+ if (presignInfo.url && presignInfo.fields) {
609
+ const uploadFormData = new FormData();
610
+ Object.entries(presignInfo.fields).forEach(([key, value]) => {
611
+ uploadFormData.append(key, value);
612
+ });
613
+ uploadFormData.append("file", fileData, { filename: fileName });
614
+ await axios.post(presignInfo.url, uploadFormData, {
615
+ headers: uploadFormData.getHeaders(),
616
+ timeout: 3e4
617
+ });
618
+ finalUrl = presignInfo.final_url || presignInfo.url.split("?")[0];
619
+ } else if (presignInfo.upload_url || presignInfo.url) {
620
+ const uploadUrl = presignInfo.upload_url || presignInfo.url;
621
+ await axios.put(uploadUrl, fileData, {
622
+ headers: { "Content-Type": mimeType },
623
+ timeout: 3e4
624
+ });
625
+ finalUrl = presignInfo.final_url || uploadUrl.split("?")[0];
626
+ } else {
627
+ throw new Error(`Unrecognized presign response: ${JSON.stringify(presignInfo)}`);
628
+ }
629
+ return finalUrl;
630
+ }
631
+ async createFormData(fields, uploads, concurrency, logo, audioClip, userImages, userVideos, inputImages) {
420
632
  const formData = new FormData();
421
633
  fields.forEach(([key, value]) => {
422
634
  if (key !== "logo_path") {
@@ -425,16 +637,147 @@ var Golpo = class {
425
637
  });
426
638
  if (logo) {
427
639
  const logoPath = logo.trim().replace(/^<|>$/g, "");
640
+ let logoUrl;
428
641
  if (URL_RE.test(logoPath)) {
429
- throw new Error("URL uploads not supported for logo - only local file paths are accepted");
642
+ logoUrl = logoPath;
643
+ } else {
644
+ logoUrl = await this.uploadFileAndGetUrl(logoPath);
645
+ }
646
+ formData.append("logo", logoUrl);
647
+ }
648
+ if (audioClip) {
649
+ const audioList = Array.isArray(audioClip) ? audioClip : [audioClip];
650
+ const audioLocalFiles = [];
651
+ const audioUrls = [];
652
+ audioList.forEach((item) => {
653
+ const path = String(item).trim().replace(/^<|>$/g, "");
654
+ if (URL_RE.test(path)) {
655
+ audioUrls.push(path);
656
+ } else {
657
+ audioLocalFiles.push(path);
658
+ }
659
+ });
660
+ if (audioLocalFiles.length > 0) {
661
+ const limit = pLimit(concurrency);
662
+ const uploadedUrls = await Promise.all(
663
+ audioLocalFiles.map(
664
+ (filePath) => limit(() => this.uploadFileAndGetUrl(filePath))
665
+ )
666
+ );
667
+ audioUrls.push(...uploadedUrls);
668
+ }
669
+ if (audioUrls.length > 0) {
670
+ formData.append("audio_clip", audioUrls[0]);
671
+ }
672
+ }
673
+ if (userImages) {
674
+ const imagesList = Array.isArray(userImages) ? userImages : [userImages];
675
+ const imageLocalFiles = [];
676
+ const imageUrls = [];
677
+ console.log("[SDK] Processing userImages:", imagesList);
678
+ imagesList.forEach((item) => {
679
+ const path = String(item).trim().replace(/^<|>$/g, "");
680
+ if (URL_RE.test(path)) {
681
+ console.log("[SDK] userImages item is URL:", path);
682
+ imageUrls.push(path);
683
+ } else {
684
+ console.log("[SDK] userImages item is local file:", path);
685
+ imageLocalFiles.push(path);
686
+ }
687
+ });
688
+ if (imageLocalFiles.length > 0) {
689
+ console.log("[SDK] Uploading", imageLocalFiles.length, "image file(s)");
690
+ const limit = pLimit(concurrency);
691
+ try {
692
+ const uploadedUrls = await Promise.all(
693
+ imageLocalFiles.map(
694
+ (filePath) => limit(async () => {
695
+ try {
696
+ console.log("[SDK] Uploading image file:", filePath);
697
+ const url = await this.uploadFileAndGetUrl(filePath);
698
+ console.log("[SDK] Image uploaded, got URL:", url);
699
+ return url;
700
+ } catch (error) {
701
+ console.error(`[SDK] Failed to upload image file ${filePath}:`, error);
702
+ throw error;
703
+ }
704
+ })
705
+ )
706
+ );
707
+ imageUrls.push(...uploadedUrls);
708
+ console.log("[SDK] All images uploaded, total URLs:", imageUrls.length);
709
+ } catch (error) {
710
+ console.error("[SDK] Error uploading image files:", error);
711
+ throw error;
712
+ }
713
+ }
714
+ if (imageUrls.length > 0) {
715
+ const jsonArray = JSON.stringify(imageUrls);
716
+ console.log("[SDK] Sending user_images as JSON:", jsonArray);
717
+ formData.append("user_images", jsonArray);
718
+ } else {
719
+ console.log("[SDK] No image URLs to send");
720
+ }
721
+ }
722
+ if (userVideos) {
723
+ const videosList = Array.isArray(userVideos) ? userVideos : [userVideos];
724
+ const videoLocalFiles = [];
725
+ const videoUrls = [];
726
+ videosList.forEach((item) => {
727
+ const path = String(item).trim().replace(/^<|>$/g, "");
728
+ if (URL_RE.test(path)) {
729
+ videoUrls.push(path);
730
+ } else {
731
+ videoLocalFiles.push(path);
732
+ }
733
+ });
734
+ if (videoLocalFiles.length > 0) {
735
+ const limit = pLimit(concurrency);
736
+ try {
737
+ const uploadedUrls = await Promise.all(
738
+ videoLocalFiles.map(
739
+ (filePath) => limit(async () => {
740
+ try {
741
+ return await this.uploadFileAndGetUrl(filePath);
742
+ } catch (error) {
743
+ console.error(`Failed to upload video file ${filePath}:`, error);
744
+ throw error;
745
+ }
746
+ })
747
+ )
748
+ );
749
+ videoUrls.push(...uploadedUrls);
750
+ } catch (error) {
751
+ console.error("Error uploading video files:", error);
752
+ throw error;
753
+ }
754
+ }
755
+ if (videoUrls.length > 0) {
756
+ formData.append("user_videos", JSON.stringify(videoUrls));
430
757
  }
431
- const absLogoPath = resolve(logoPath);
432
- const logoFileName = basename(absLogoPath);
433
- const logoMimeType = mimeLookup(absLogoPath) || "application/octet-stream";
434
- formData.append("logo", createReadStream(absLogoPath), {
435
- filename: logoFileName,
436
- contentType: logoMimeType
758
+ }
759
+ if (inputImages) {
760
+ const imagesList = Array.isArray(inputImages) ? inputImages : [inputImages];
761
+ const localFiles = [];
762
+ const imageUrls = [];
763
+ imagesList.forEach((item) => {
764
+ const path = String(item).trim().replace(/^<|>$/g, "");
765
+ if (URL_RE.test(path)) {
766
+ imageUrls.push(path);
767
+ } else {
768
+ localFiles.push(path);
769
+ }
437
770
  });
771
+ if (localFiles.length > 0) {
772
+ const limit = pLimit(concurrency);
773
+ const uploadedUrls = await Promise.all(
774
+ localFiles.map((filePath) => limit(() => this.uploadFileAndGetUrl(filePath)))
775
+ );
776
+ imageUrls.push(...uploadedUrls);
777
+ }
778
+ if (imageUrls.length > 0) {
779
+ formData.append("input_images", JSON.stringify(imageUrls));
780
+ }
438
781
  }
439
782
  if (uploads) {
440
783
  const list = typeof uploads === "string" ? [uploads] : [...uploads];
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@golpoai/sdk",
3
- "version": "0.1.9",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
- "exports": "./dist/index.js",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs"
10
+ }
11
+ },
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
6
14
  "types": "./dist/index.d.ts",
7
15
  "files": [
8
16
  "dist/**/*"