@rohitaryal/whisk-api 4.0.0 → 4.0.1

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/Project.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Media } from "./Media.js";
2
- import type { MediaReference, PromptConfig } from "./Types.js";
2
+ import type { ImageInput, MediaReference, PromptConfig } from "./Types.js";
3
3
  import { Account } from "./Whisk.js";
4
4
  export declare class Project {
5
5
  readonly account: Account;
@@ -11,21 +11,29 @@ export declare class Project {
11
11
  /**
12
12
  * Uploads a custom image and adds it as a subject reference
13
13
  *
14
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
14
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
15
15
  */
16
- addSubject(rawBytes: string): Promise<void>;
16
+ addSubject(input: ImageInput): Promise<MediaReference>;
17
17
  /**
18
18
  * Uploads a custom image and adds it as a scene reference
19
19
  *
20
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
20
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
21
21
  */
22
- addScene(rawBytes: string): Promise<void>;
22
+ addScene(input: ImageInput): Promise<MediaReference>;
23
23
  /**
24
24
  * Uploads a custom image and adds it as a style reference
25
25
  *
26
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
26
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
27
27
  */
28
- addStyle(rawBytes: string): Promise<void>;
28
+ addStyle(input: ImageInput): Promise<MediaReference>;
29
+ addSubjectById(mediaGenerationId: string, prompt: string): void;
30
+ addSceneById(mediaGenerationId: string, prompt: string): void;
31
+ addStyleById(mediaGenerationId: string, prompt: string): void;
32
+ removeSubject(mediaGenerationId: string): MediaReference;
33
+ removeScene(mediaGenerationId: string): MediaReference;
34
+ removeStyle(mediaGenerationId: string): MediaReference;
35
+ private addById;
36
+ private removeById;
29
37
  private addReference;
30
38
  generateImage(input: string | PromptConfig): Promise<Media>;
31
39
  /**
package/dist/Project.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ImageGenerationModel, MediaCategory } from "./Constants.js";
2
2
  import { Media } from "./Media.js";
3
- import { request } from "./Utils.js";
3
+ import { request, resolveImageInput } from "./Utils.js";
4
4
  import { Account, Whisk } from "./Whisk.js";
5
5
  export class Project {
6
6
  account;
@@ -24,28 +24,69 @@ export class Project {
24
24
  /**
25
25
  * Uploads a custom image and adds it as a subject reference
26
26
  *
27
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
27
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
28
28
  */
29
- async addSubject(rawBytes) {
30
- await this.addReference(rawBytes, MediaCategory.SUBJECT, this.subjects);
29
+ async addSubject(input) {
30
+ return this.addReference(input, MediaCategory.SUBJECT, this.subjects);
31
31
  }
32
32
  /**
33
33
  * Uploads a custom image and adds it as a scene reference
34
34
  *
35
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
35
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
36
36
  */
37
- async addScene(rawBytes) {
38
- await this.addReference(rawBytes, MediaCategory.SCENE, this.scenes);
37
+ async addScene(input) {
38
+ return this.addReference(input, MediaCategory.SCENE, this.scenes);
39
39
  }
40
40
  /**
41
41
  * Uploads a custom image and adds it as a style reference
42
42
  *
43
- * @param rawBytes Base64 encoded image (with or without data URI prefix)
43
+ * @param input Image as { file: string }, { url: string }, or { base64: string }
44
44
  */
45
- async addStyle(rawBytes) {
46
- await this.addReference(rawBytes, MediaCategory.STYLE, this.styles);
45
+ async addStyle(input) {
46
+ return this.addReference(input, MediaCategory.STYLE, this.styles);
47
47
  }
48
- async addReference(rawBytes, category, target) {
48
+ addSubjectById(mediaGenerationId, prompt) {
49
+ this.addById(mediaGenerationId, prompt, this.subjects);
50
+ }
51
+ addSceneById(mediaGenerationId, prompt) {
52
+ this.addById(mediaGenerationId, prompt, this.scenes);
53
+ }
54
+ addStyleById(mediaGenerationId, prompt) {
55
+ this.addById(mediaGenerationId, prompt, this.styles);
56
+ }
57
+ removeSubject(mediaGenerationId) {
58
+ return this.removeById(mediaGenerationId, this.subjects);
59
+ }
60
+ removeScene(mediaGenerationId) {
61
+ return this.removeById(mediaGenerationId, this.scenes);
62
+ }
63
+ removeStyle(mediaGenerationId) {
64
+ return this.removeById(mediaGenerationId, this.styles);
65
+ }
66
+ addById(mediaGenerationId, prompt, target) {
67
+ if (typeof mediaGenerationId !== "string" || !mediaGenerationId.trim()) {
68
+ throw new Error("media generation id is required");
69
+ }
70
+ if (typeof prompt !== "string" || !prompt.trim()) {
71
+ throw new Error("prompt is required");
72
+ }
73
+ if (target.some(ref => ref.mediaGenerationId === mediaGenerationId)) {
74
+ throw new Error(`'${mediaGenerationId}': reference already exists`);
75
+ }
76
+ target.push({ prompt, mediaGenerationId });
77
+ }
78
+ removeById(mediaGenerationId, target) {
79
+ if (typeof mediaGenerationId !== "string" || !mediaGenerationId.trim()) {
80
+ throw new Error("media generation id is required");
81
+ }
82
+ const index = target.findIndex(ref => ref.mediaGenerationId === mediaGenerationId);
83
+ if (index === -1) {
84
+ throw new Error(`'${mediaGenerationId}': reference not found`);
85
+ }
86
+ return target.splice(index, 1)[0];
87
+ }
88
+ async addReference(input, category, target) {
89
+ const rawBytes = await resolveImageInput(input);
49
90
  if (!(rawBytes?.trim?.())) {
50
91
  throw new Error("image data is required");
51
92
  }
@@ -68,7 +109,9 @@ export class Project {
68
109
  });
69
110
  const caption = captions.candidates[0].output;
70
111
  const uploadMediaGenerationId = await Whisk.uploadImage(rawBytes, caption, category, this.projectId, this.account);
71
- target.push({ prompt: caption, mediaGenerationId: uploadMediaGenerationId });
112
+ const ref = { prompt: caption, mediaGenerationId: uploadMediaGenerationId };
113
+ target.push(ref);
114
+ return ref;
72
115
  }
73
116
  async generateImage(input) {
74
117
  if (typeof input === "string") {
package/dist/Types.d.ts CHANGED
@@ -29,3 +29,10 @@ export interface MediaReference {
29
29
  prompt: string;
30
30
  mediaGenerationId: string;
31
31
  }
32
+ export type ImageInput = {
33
+ file: string;
34
+ } | {
35
+ url: string;
36
+ } | {
37
+ base64: string;
38
+ };
package/dist/Utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ImageExtensionTypes } from "./Types.js";
1
+ import type { ImageInput } from "./Types.js";
2
2
  /**
3
3
  * Make a request, thats all
4
4
  *
@@ -12,10 +12,5 @@ export declare function request<T>(input: RequestInfo | URL, init?: RequestInit)
12
12
  * @param url URL of the image to fetch
13
13
  */
14
14
  export declare function imageFromUrl(url: string): Promise<string>;
15
- /**
16
- * Returns base64 encoded image
17
- *
18
- * @param imagePath Path to image file
19
- * @param imageType Extension of image (if that matters)
20
- */
21
- export declare function imageToBase64(imagePath: string, imageType?: ImageExtensionTypes): Promise<string>;
15
+ export declare function resolveImageInput(input: ImageInput): Promise<string>;
16
+ export declare function imageToBase64(imagePath: string): Promise<string>;
package/dist/Utils.js CHANGED
@@ -32,27 +32,28 @@ export async function imageFromUrl(url) {
32
32
  if (!response.ok) {
33
33
  throw new Error(`Failed to fetch image (${response.status}): ${url}`);
34
34
  }
35
- const contentType = response.headers.get("content-type") || "image/png";
35
+ const contentType = response.headers.get("content-type") || "";
36
+ const imageType = contentType.split("/")[1]?.split(";")[0];
37
+ if (!Object.values(ImageExtension).includes(imageType)) {
38
+ throw new Error(`'${url}': unsupported image type '${contentType}'`);
39
+ }
36
40
  const buffer = Buffer.from(await response.arrayBuffer());
37
- return `data:${contentType};base64,${buffer.toString("base64")}`;
41
+ return `data:image/${imageType};base64,${buffer.toString("base64")}`;
38
42
  }
39
- /**
40
- * Returns base64 encoded image
41
- *
42
- * @param imagePath Path to image file
43
- * @param imageType Extension of image (if that matters)
44
- */
45
- export async function imageToBase64(imagePath, imageType) {
43
+ export async function resolveImageInput(input) {
44
+ if ("file" in input)
45
+ return await imageToBase64(input.file);
46
+ if ("url" in input)
47
+ return await imageFromUrl(input.url);
48
+ return input.base64;
49
+ }
50
+ export async function imageToBase64(imagePath) {
46
51
  if (!(imagePath?.trim?.()) || !fs.existsSync(imagePath)) {
47
52
  throw new Error(`'${imagePath}': image not found`);
48
53
  }
49
- // Try to figure out image type from its extension
50
- if (!(imageType?.trim?.())) {
51
- imageType = path.extname(imagePath).slice(1);
52
- }
53
- // If extension not in valid extension list throw error
54
+ const imageType = path.extname(imagePath).slice(1);
54
55
  if (!Object.values(ImageExtension).includes(imageType)) {
55
- throw new Error(`'${imagePath}': couldn't identify image type, please specify 'imageType'`);
56
+ throw new Error(`'${imagePath}': unsupported image type '${imageType}'`);
56
57
  }
57
58
  const base64Header = `data:image/${imageType};base64,`;
58
59
  return new Promise((resolve, reject) => {
package/dist/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export { Whisk } from "./Whisk.js";
3
3
  export { Media } from "./Media.js";
4
4
  export { Project } from "./Project.js";
5
5
  export * from "./Types.js";
6
+ export * from "./Constants.js";
7
+ export { imageToBase64, imageFromUrl } from "./Utils.js";
package/dist/index.js CHANGED
@@ -3,3 +3,5 @@ export { Whisk } from "./Whisk.js";
3
3
  export { Media } from "./Media.js";
4
4
  export { Project } from "./Project.js";
5
5
  export * from "./Types.js";
6
+ export * from "./Constants.js";
7
+ export { imageToBase64, imageFromUrl } from "./Utils.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rohitaryal/whisk-api",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",