@zodic/shared 0.0.115 → 0.0.117

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/api/index.ts CHANGED
@@ -16,9 +16,7 @@ import {
16
16
  HouseCuspsReport,
17
17
  LeonardoGenerateImageParams,
18
18
  LeonardoGenerateImageResponse,
19
- LeonardoGeneratePresignedUrlParams,
20
19
  LeonardoRequestBody,
21
- LeonardoUploadImageParams,
22
20
  NatalHouseCuspReport,
23
21
  TimezoneResponse,
24
22
  } from '../../types/scopes/legacy';
@@ -236,13 +234,24 @@ export const Api = (env: BackendBindings) => ({
236
234
  num_images: quantity,
237
235
  };
238
236
 
237
+ // ✅ Dynamically add `controlNets` based on available settings
239
238
  if (controlNets.length > 0) {
240
- body['controlnets'] = controlNets.map((net) => ({
241
- initImageId: net.initImageId,
242
- initImageType: net.initImageType,
243
- preprocessorId: net.preprocessorId,
244
- strengthType: net.strengthType,
245
- }));
239
+ // @ts-expect-error
240
+ body['controlnets'] = controlNets.map((net) => {
241
+ const baseNet = {
242
+ initImageId: net.initImageId,
243
+ initImageType: net.initImageType,
244
+ preprocessorId: net.preprocessorId,
245
+ };
246
+
247
+ if (net.preprocessorId === 100) {
248
+ return { ...baseNet, strengthType: net.strengthType };
249
+ } else if (net.preprocessorId === 19) {
250
+ return { ...baseNet, weight: net.weight };
251
+ }
252
+
253
+ return baseNet;
254
+ });
246
255
  }
247
256
 
248
257
  if (initImageId) {
@@ -259,123 +268,18 @@ export const Api = (env: BackendBindings) => ({
259
268
 
260
269
  if (!response.ok) {
261
270
  const error = await response.json();
262
- console.error('Error from Leonardo API:', error);
271
+ console.error('Error from Leonardo API:', error);
263
272
  throw new Error(`Leonardo API Error: ${response.status}`);
264
273
  }
265
274
 
266
275
  const data = (await response.json()) as LeonardoGenerateImageResponse;
267
276
  return data;
268
277
  } catch (err: any) {
269
- console.error('Error calling Leonardo API:', err.message);
278
+ console.error('Error calling Leonardo API:', err.message);
270
279
  throw err;
271
280
  }
272
281
  },
273
- generatePresignedUrl: async ({
274
- extension,
275
- }: LeonardoGeneratePresignedUrlParams): Promise<{
276
- url: string;
277
- fields: string;
278
- id: string;
279
- key: string;
280
- }> => {
281
- console.log('Generating presigned URL with extension:', extension);
282
-
283
- const endpoint = 'https://cloud.leonardo.ai/api/rest/v1/init-image';
284
- const headers = {
285
- Authorization: `Bearer ${env.LEONARDO_API_KEY}`,
286
- 'Content-Type': 'application/json',
287
- };
288
-
289
- if (!extension) {
290
- throw new Error('Invalid MIME type');
291
- }
292
-
293
- const body = JSON.stringify({
294
- extension,
295
- });
296
-
297
- try {
298
- const response = await fetch(endpoint, {
299
- method: 'POST',
300
- headers,
301
- body,
302
- });
303
-
304
- if (!response.ok) {
305
- const error = await response.text();
306
- console.error('Leonardo API error:', error);
307
- throw new Error(
308
- `Presigned URL generation failed: ${response.status}`
309
- );
310
- }
311
-
312
- const rawResponse = (await response.json()) as any;
313
- console.log('Presigned URL response:', rawResponse);
314
-
315
- if (
316
- !rawResponse.uploadInitImage ||
317
- !rawResponse.uploadInitImage.url ||
318
- !rawResponse.uploadInitImage.fields
319
- ) {
320
- throw new Error('Invalid presigned URL response');
321
- }
322
-
323
- return rawResponse.uploadInitImage;
324
- } catch (error: any) {
325
- console.error('Error generating presigned URL:', error.message);
326
- throw error;
327
- }
328
- },
329
- uploadImage: async ({
330
- presignedUrl,
331
- fields,
332
- file,
333
- }: LeonardoUploadImageParams) => {
334
- console.log('Starting image upload to:', presignedUrl);
335
-
336
- if (!(file instanceof Blob)) {
337
- throw new Error('Invalid file type for upload');
338
- }
339
-
340
- try {
341
- console.log('Parsing fields...');
342
- const parsedFields = JSON.parse(fields);
343
-
344
- if (!parsedFields || typeof parsedFields !== 'object') {
345
- throw new Error('Invalid fields format');
346
- }
347
-
348
- console.log('Parsed fields:', parsedFields);
349
-
350
- const formData = new FormData();
351
-
352
- Object.entries(parsedFields).forEach(([key, value]) => {
353
- formData.append(key, value as string);
354
- });
355
-
356
- formData.append('file', file);
357
-
358
- console.log('Uploading with FormData:', Array.from(formData.entries()));
359
-
360
- const response = await fetch(presignedUrl, {
361
- method: 'POST',
362
- body: formData,
363
- });
364
-
365
- if (!response.ok) {
366
- const errorDetails = await response.text();
367
- console.error('Upload failed:', errorDetails);
368
- throw new Error(`Image upload failed: ${response.status}`);
369
- }
370
-
371
- console.log('Image uploaded successfully');
372
- } catch (error: any) {
373
- console.error('Error during uploadImage:', error.message);
374
- throw error;
375
- }
376
- },
377
282
  },
378
-
379
283
  callImageDescriber: async (imageUrl: string): Promise<string> => {
380
284
  const mimeType = 'image/png';
381
285
  const endpoint =
@@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify';
3
3
  import 'reflect-metadata';
4
4
  import { v4 as uuidv4 } from 'uuid';
5
5
  import { schema } from '../..';
6
- import { Concept, Languages } from '../../types';
6
+ import { Concept, ControlNetConfig, Languages } from '../../types';
7
7
  import { KVConcept, sizes } from '../../types/scopes/legacy';
8
8
  import { leonardoInitImages } from '../../utils/initImages';
9
9
  import { buildConceptKVKey } from '../../utils/KVKeysBuilders';
@@ -214,7 +214,6 @@ export class ConceptService {
214
214
  `🔹 Extracted planet signs: ${planet1} -> ${planet1Sign}, ${planet2} -> ${planet2Sign}, ${planet3} -> ${planet3Sign}`
215
215
  );
216
216
 
217
- // 🔍 Ensure Concept Combination exists
218
217
  let [conceptCombination] = await drizzle
219
218
  .select({ id: conceptCombinations.id })
220
219
  .from(conceptCombinations)
@@ -253,25 +252,25 @@ export class ConceptService {
253
252
 
254
253
  console.log(`🎨 Requesting Leonardo AI image generation...`);
255
254
 
256
- // 🔍 Check if there is a valid init image
257
- const initImageId = leonardoInitImages.concepts[conceptSlug]?.imageId;
258
- const controlNets = initImageId
259
- ? ([
260
- {
261
- initImageId,
262
- initImageType: 'UPLOADED',
263
- preprocessorId: 100, // Content reference
264
- strengthType: 'Low',
265
- },
266
- ] as Array<{
267
- initImageId: string;
268
- initImageType: 'UPLOADED' | 'GENERATED';
269
- preprocessorId: number;
270
- strengthType: 'Low' | 'Mid' | 'High';
271
- }>)
255
+ const initImage = leonardoInitImages.concepts[conceptSlug];
256
+ const controlNets: ControlNetConfig[] = initImage.imageId
257
+ ? [
258
+ initImage.preprocessorId === 100
259
+ ? {
260
+ initImageId: initImage.imageId,
261
+ initImageType: 'UPLOADED',
262
+ preprocessorId: 100,
263
+ strengthType: initImage.strengthType!,
264
+ }
265
+ : {
266
+ initImageId: initImage.imageId,
267
+ initImageType: 'UPLOADED',
268
+ preprocessorId: 19,
269
+ weight: initImage.weight!,
270
+ },
271
+ ]
272
272
  : [];
273
273
 
274
- // 🎨 Call Leonardo with or without ControlNet
275
274
  const leonardoResponse = await this.context
276
275
  .api()
277
276
  .callLeonardo.generateImage({
@@ -279,7 +278,7 @@ export class ConceptService {
279
278
  width,
280
279
  height,
281
280
  ...(controlNets.length > 0 ? { controlNets } : {}),
282
- negPrompt: 'person, hands, face, body parts, people, animals, fingers'
281
+ negPrompt: 'person, hands, face, body parts, people, animals, fingers',
283
282
  });
284
283
 
285
284
  const generationId = leonardoResponse?.sdGenerationJob?.generationId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.115",
3
+ "version": "0.0.117",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -148,7 +148,7 @@ export type Concept =
148
148
  | 'lantern'
149
149
  | 'orb'
150
150
  | 'ring';
151
-
151
+
152
152
  export type Concepts = ['crown', 'scepter', 'amulet', 'lantern', 'orb', 'ring'];
153
153
  export type ConceptQueueMessage = {
154
154
  conceptSlug: Concept;
@@ -296,4 +296,22 @@ export interface JWK {
296
296
 
297
297
  export interface JWKS {
298
298
  keys: JWK[];
299
- }
299
+ }
300
+
301
+ export type ControlNetStrenghtType = 'Low' | 'Mid' | 'High';
302
+
303
+ export type ControlNetPreprocessorId = 100 | 19;
304
+
305
+ export type ControlNetConfig =
306
+ | {
307
+ initImageId: string;
308
+ initImageType: 'UPLOADED' | 'GENERATED';
309
+ preprocessorId: 100; // Content Reference
310
+ strengthType: ControlNetStrenghtType;
311
+ }
312
+ | {
313
+ initImageId: string;
314
+ initImageType: 'UPLOADED' | 'GENERATED';
315
+ preprocessorId: 19; // Edge to Image
316
+ weight: string;
317
+ };
@@ -1,5 +1,5 @@
1
1
  import { BackendBindings } from './cloudflare';
2
- import { Gender } from './generic';
2
+ import { ControlNetConfig, Gender } from './generic';
3
3
 
4
4
  export const zodiacSigns = [
5
5
  'Aries',
@@ -25,12 +25,7 @@ export interface LeonardoGenerateImageParams {
25
25
  prompt: string;
26
26
  width: number;
27
27
  height: number;
28
- controlNets?: Array<{
29
- initImageId: string;
30
- initImageType: 'UPLOADED' | 'GENERATED';
31
- preprocessorId: number;
32
- strengthType: 'Low' | 'Mid' | 'High';
33
- }>;
28
+ controlNets?: Array<ControlNetConfig>;
34
29
  quantity?: number;
35
30
  negPrompt?: string | null;
36
31
  }
@@ -162,12 +157,7 @@ export interface LeonardoRequestBody {
162
157
  modelId: string;
163
158
  presetStyle: string;
164
159
  alchemy: boolean;
165
- controlnets?: Array<{
166
- initImageId: string;
167
- initImageType: string;
168
- preprocessorId: number;
169
- strengthType: string;
170
- }>;
160
+ controlnets?: Array<ControlNetConfig>;
171
161
  init_generation_image_id?: string;
172
162
  init_strength?: number;
173
163
  }
@@ -6,11 +6,15 @@ export const leonardoInitImages: LeonardoInitImages = {
6
6
  imageId: '450076a1-c6bb-4877-8a0b-c0d3ba72fca7',
7
7
  imageUrl:
8
8
  'https://cdn.leonardo.ai/users/b117a933-e5c9-45b2-96aa-4b619c2d74ba/initImages/450076a1-c6bb-4877-8a0b-c0d3ba72fca7.jpg',
9
+ preprocessorId: 100,
10
+ strengthType: 'Low',
9
11
  },
10
12
  scepter: {
11
13
  imageId: '744169ef-3db4-416d-86dd-9bd814e33432',
12
14
  imageUrl:
13
15
  'https://cdn.leonardo.ai/users/b117a933-e5c9-45b2-96aa-4b619c2d74ba/initImages/744169ef-3db4-416d-86dd-9bd814e33432.jpg',
16
+ preprocessorId: 100,
17
+ strengthType: 'Low',
14
18
  },
15
19
  amulet: {
16
20
  imageId: null,
@@ -21,8 +25,11 @@ export const leonardoInitImages: LeonardoInitImages = {
21
25
  imageUrl: null,
22
26
  },
23
27
  orb: {
24
- imageId: null,
25
- imageUrl: null,
28
+ imageId: 'c489e496-00c4-4958-8bcd-4460a43a43bf',
29
+ imageUrl:
30
+ 'https://cdn.leonardo.ai/users/b117a933-e5c9-45b2-96aa-4b619c2d74ba/initImages/c489e496-00c4-4958-8bcd-4460a43a43bf.jpg',
31
+ preprocessorId: 19,
32
+ weight: '0.3',
26
33
  },
27
34
  ring: {
28
35
  imageId: null,
@@ -31,10 +38,30 @@ export const leonardoInitImages: LeonardoInitImages = {
31
38
  },
32
39
  };
33
40
 
34
- type ConceptsInitImages = Record<
35
- Concept,
36
- { imageId: string | null; imageUrl: string | null }
37
- >;
41
+ type ConceptsInitImages = Record<Concept, ControlNetSettings>;
42
+
43
+ type ControlNetSettings =
44
+ | {
45
+ imageId: string;
46
+ imageUrl: string;
47
+ preprocessorId: 100;
48
+ strengthType: 'Low' | 'Mid' | 'High';
49
+ weight?: null;
50
+ }
51
+ | {
52
+ imageId: string;
53
+ imageUrl: string;
54
+ preprocessorId: 19;
55
+ weight: string;
56
+ strengthType?: null;
57
+ }
58
+ | {
59
+ imageId: null;
60
+ imageUrl: null;
61
+ preprocessorId?: undefined;
62
+ strengthType?: undefined;
63
+ weight?: undefined;
64
+ };
38
65
 
39
66
  type LeonardoInitImages = {
40
67
  concepts: ConceptsInitImages;