@zodic/shared 0.0.37 → 0.0.38
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/api/astrology/index.ts +37 -0
- package/api/index.ts +702 -0
- package/base/AppContext.ts +93 -0
- package/base/index.ts +0 -0
- package/db/schema.ts +2 -2
- package/package.json +3 -2
- package/services/ConceptService.ts +207 -0
- package/tsconfig.json +2 -0
- package/types/scopes/generic.ts +14 -0
- package/types/scopes/legacy.ts +255 -0
- package/utils/buildMessages.ts +134 -0
- package/utils/conceptPrompts.ts +49 -0
- package/workflow/ConceptWorkflow.ts +58 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { drizzle } from 'drizzle-orm/d1';
|
|
2
|
+
import { Api } from '../api';
|
|
3
|
+
import * as schema from '../db/schema';
|
|
4
|
+
import { BackendBindings } from '../types';
|
|
5
|
+
import { buildChatGPTMessages } from '../utils/buildMessages';
|
|
6
|
+
|
|
7
|
+
export class AppContext {
|
|
8
|
+
private _drizzle?: ReturnType<typeof drizzle>;
|
|
9
|
+
|
|
10
|
+
constructor(public env: BackendBindings) {}
|
|
11
|
+
|
|
12
|
+
buildChatGPTMessages() {
|
|
13
|
+
return buildChatGPTMessages(this.env);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
kvCosmicMirrorArchetypesStore() {
|
|
17
|
+
if (!this.env.KV_COSMIC_MIRROR_ARCHETYPES) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'KV_COSMIC_MIRROR_ARCHETYPES is not defined in the environment.'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return this.env.KV_COSMIC_MIRROR_ARCHETYPES;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
kvConceptsStore() {
|
|
26
|
+
if (!this.env.KV_CONCEPTS) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'KV_COSMIC_MIRROR_ARCHETYPES is not defined in the environment.'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return this.env.KV_CONCEPTS;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
kvGenerationStore() {
|
|
35
|
+
if (!this.env.KV_GENERATION_MANAGEMENT) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
'KV_GENERATION_MANAGEMENT is not defined in the environment.'
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return this.env.KV_GENERATION_MANAGEMENT;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
kvUserGenerationStore() {
|
|
44
|
+
if (!this.env.KV_USER_GENERATIONS) {
|
|
45
|
+
throw new Error('KV_USER_GENERATIONS is not defined in the environment.');
|
|
46
|
+
}
|
|
47
|
+
return this.env.KV_GENERATION_MANAGEMENT;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
kvPromptsStore() {
|
|
51
|
+
if (!this.env.KV_LEONARDO_PROMPTS) {
|
|
52
|
+
throw new Error('KV_LEONARDO_PROMPTS is not defined in the environment.');
|
|
53
|
+
}
|
|
54
|
+
return this.env.KV_LEONARDO_PROMPTS;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
kvUserProductStatus() {
|
|
58
|
+
if (!this.env.KV_USER_PRODUCT_STATUS) {
|
|
59
|
+
throw new Error('KV_LEONARDO_PROMPTS is not defined in the environment.');
|
|
60
|
+
}
|
|
61
|
+
return this.env.KV_USER_PRODUCT_STATUS;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
api() {
|
|
65
|
+
return Api(this.env);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
drizzle() {
|
|
69
|
+
if (!this._drizzle) {
|
|
70
|
+
if (!this.env.DB) {
|
|
71
|
+
throw new Error('Database binding (DB) is not defined.');
|
|
72
|
+
}
|
|
73
|
+
this._drizzle = drizzle(this.env.DB, { schema });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return this._drizzle;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get queues() {
|
|
80
|
+
return {
|
|
81
|
+
conceptGenerationQueue: this.conceptGenerationQueue(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private conceptGenerationQueue() {
|
|
86
|
+
if (!this.env.CONCEPT_GENERATION_QUEUE) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
'CONCEPT_GENERATION_QUEUE is not defined in the environment.'
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
return this.env.CONCEPT_GENERATION_QUEUE;
|
|
92
|
+
}
|
|
93
|
+
}
|
package/base/index.ts
ADDED
|
File without changes
|
package/db/schema.ts
CHANGED
|
@@ -159,8 +159,8 @@ export const concepts = sqliteTable(
|
|
|
159
159
|
'concepts',
|
|
160
160
|
{
|
|
161
161
|
id: text('id').primaryKey(), // Unique Concept ID
|
|
162
|
-
name: text('name').notNull(), // Name of the Concept (e.g., "The Crown", "The
|
|
163
|
-
slug: text('slug').notNull(), // Name of the Concept (e.g., "crown", "
|
|
162
|
+
name: text('name').notNull(), // Name of the Concept (e.g., "The Crown", "The Amulet")
|
|
163
|
+
slug: text('slug').notNull(), // Name of the Concept (e.g., "crown", "amulet")
|
|
164
164
|
planet1: text('planet1').notNull(), // First planet (e.g., "Sun")
|
|
165
165
|
planet2: text('planet2').notNull(), // Second planet (e.g., "Moon")
|
|
166
166
|
planet3: text('planet3'), // Third planet (e.g., "Ascendant"), optional for some Concepts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zodic/shared",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.38",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"drizzle-orm": "^0.38.0",
|
|
30
30
|
"hono": "^4.6.13",
|
|
31
31
|
"inversify": "^6.2.1",
|
|
32
|
-
"jose": "^5.9.6"
|
|
32
|
+
"jose": "^5.9.6",
|
|
33
|
+
"reflect-metadata": "^0.2.2"
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
import { AppContext } from '../base/AppContext';
|
|
4
|
+
import { KVConcept, sizes } from '../types/scopes/legacy';
|
|
5
|
+
|
|
6
|
+
@injectable()
|
|
7
|
+
export class ConceptService {
|
|
8
|
+
constructor(@inject(AppContext) private context: AppContext) {}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generate basic info for a concept: name, description, and poem.
|
|
12
|
+
*/
|
|
13
|
+
async generateBasicInfo(
|
|
14
|
+
conceptSlug: string,
|
|
15
|
+
combinationString: string
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
const kvKey = `concepts:${conceptSlug}:${combinationString}`;
|
|
18
|
+
console.log(
|
|
19
|
+
`Generating basic info for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const messages = this.context
|
|
23
|
+
.buildChatGPTMessages()
|
|
24
|
+
.generateConceptBasicInfo({
|
|
25
|
+
combination: combinationString,
|
|
26
|
+
conceptSlug,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const response = await this.context.api().callChatGPT(messages, {});
|
|
30
|
+
if (!response) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to generate basic info for concept: ${conceptSlug}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const { name, description, poem } = this.parseBasicInfoResponse(response);
|
|
37
|
+
|
|
38
|
+
// Save basic info to KV
|
|
39
|
+
const concept = await this.getKVConcept(kvKey);
|
|
40
|
+
Object.assign(concept, { name, description, poem, status: 'idle' });
|
|
41
|
+
|
|
42
|
+
await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
|
|
43
|
+
console.log(
|
|
44
|
+
`Basic info stored for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private parseBasicInfoResponse(response: string): {
|
|
49
|
+
name: string;
|
|
50
|
+
description: string;
|
|
51
|
+
poem: string;
|
|
52
|
+
} {
|
|
53
|
+
console.log('Parsing basic info response from ChatGPT');
|
|
54
|
+
const nameMatch = response.match(/- Name: (.+)/);
|
|
55
|
+
const descriptionMatch = response.match(/- Description: (.+)/);
|
|
56
|
+
const poemMatch = response.match(/- Poem: (.+)/);
|
|
57
|
+
|
|
58
|
+
if (!nameMatch || !descriptionMatch || !poemMatch) {
|
|
59
|
+
throw new Error('Invalid basic info response format');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
name: nameMatch[1].trim(),
|
|
64
|
+
description: descriptionMatch[1].trim(),
|
|
65
|
+
poem: poemMatch[1].trim(),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Generate the Leonardo prompt for a concept.
|
|
71
|
+
*/
|
|
72
|
+
async generatePrompt(
|
|
73
|
+
conceptSlug: string,
|
|
74
|
+
combinationString: string
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
const kvKey = `concepts:${conceptSlug}:${combinationString}`;
|
|
77
|
+
console.log(
|
|
78
|
+
`Generating Leonardo prompt for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const concept = await this.getKVConcept(kvKey);
|
|
82
|
+
if (!concept.name || !concept.description || !concept.poem) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Basic info must be populated before generating prompt for concept: ${conceptSlug}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const messages = this.context
|
|
89
|
+
.buildChatGPTMessages()
|
|
90
|
+
.generateConceptLeonardoPrompt({
|
|
91
|
+
conceptSlug,
|
|
92
|
+
combination: combinationString,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const response = await this.context.api().callChatGPT(messages, {});
|
|
96
|
+
if (!response) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Failed to generate Leonardo prompt for concept: ${conceptSlug}`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
concept.leonardoPrompt = response.trim();
|
|
103
|
+
await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
|
|
104
|
+
console.log(
|
|
105
|
+
`Leonardo prompt stored for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Generate additional content for a concept.
|
|
111
|
+
*/
|
|
112
|
+
async generateContent(
|
|
113
|
+
conceptSlug: string,
|
|
114
|
+
combinationString: string
|
|
115
|
+
): Promise<void> {
|
|
116
|
+
const kvKey = `concepts:${conceptSlug}:${combinationString}`;
|
|
117
|
+
console.log(
|
|
118
|
+
`Generating additional content for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const concept = await this.getKVConcept(kvKey);
|
|
122
|
+
if (!concept.name || !concept.description || !concept.poem) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Basic info must be populated before generating content for concept: ${conceptSlug}`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const messages = this.context
|
|
129
|
+
.buildChatGPTMessages()
|
|
130
|
+
.generateConceptContent({
|
|
131
|
+
conceptSlug,
|
|
132
|
+
combination: combinationString,
|
|
133
|
+
name: concept.name,
|
|
134
|
+
description: concept.description,
|
|
135
|
+
poem: concept.poem,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const response = await this.context.api().callChatGPT(messages, {});
|
|
139
|
+
if (!response) {
|
|
140
|
+
throw new Error(`Failed to generate content for concept: ${conceptSlug}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
concept.content = response.trim();
|
|
144
|
+
await this.context.kvConceptsStore().put(kvKey, JSON.stringify(concept));
|
|
145
|
+
console.log(
|
|
146
|
+
`Content stored for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Queue image generation for a concept.
|
|
152
|
+
*/
|
|
153
|
+
async generateImages(
|
|
154
|
+
conceptSlug: string,
|
|
155
|
+
combinationString: string
|
|
156
|
+
): Promise<void> {
|
|
157
|
+
const kvKey = `concepts:${conceptSlug}:${combinationString}`;
|
|
158
|
+
console.log(
|
|
159
|
+
`Queuing image generation for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const concept = await this.getKVConcept(kvKey);
|
|
163
|
+
if (!concept.leonardoPrompt) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
`Leonardo prompt must be populated before generating images for concept: ${conceptSlug}`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const { width, height } = sizes['alchemy']['post4:5'];
|
|
170
|
+
|
|
171
|
+
await this.context.api().callLeonardo.generateImage({
|
|
172
|
+
prompt: concept.leonardoPrompt,
|
|
173
|
+
width,
|
|
174
|
+
height,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
console.log(
|
|
178
|
+
`Post images queued for concept: ${conceptSlug}, combination: ${combinationString}`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Fetch and initialize a KVConcept object if not present.
|
|
184
|
+
*/
|
|
185
|
+
private async getKVConcept(kvKey: string): Promise<KVConcept> {
|
|
186
|
+
const existingData = await this.context
|
|
187
|
+
.kvConceptsStore()
|
|
188
|
+
.get<KVConcept>(kvKey, 'json');
|
|
189
|
+
if (existingData) {
|
|
190
|
+
return existingData;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
console.log(
|
|
194
|
+
`No existing KV data found. Creating default entry for key: ${kvKey}`
|
|
195
|
+
);
|
|
196
|
+
return {
|
|
197
|
+
name: '',
|
|
198
|
+
description: '',
|
|
199
|
+
content: '',
|
|
200
|
+
poem: '',
|
|
201
|
+
leonardoPrompt: '',
|
|
202
|
+
postImages: [],
|
|
203
|
+
reelImages: [null, null, null],
|
|
204
|
+
status: 'idle',
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
package/tsconfig.json
CHANGED
package/types/scopes/generic.ts
CHANGED
|
@@ -118,3 +118,17 @@ export type DominantSign = {
|
|
|
118
118
|
sign_name: string;
|
|
119
119
|
percentage: number;
|
|
120
120
|
};
|
|
121
|
+
|
|
122
|
+
export type ChatMessages = ChatMessage[];
|
|
123
|
+
export type ChatMessage = {
|
|
124
|
+
role: 'user' | 'assistant' | 'system';
|
|
125
|
+
content: string;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export interface Crown {
|
|
129
|
+
sun: string;
|
|
130
|
+
ascendant: string;
|
|
131
|
+
moon: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type Concept = 'crown' | 'scepter' | 'amulet' | 'lantern' | 'orb';
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { BackendBindings } from './cloudflare';
|
|
2
|
+
import { Gender } from './generic';
|
|
3
|
+
|
|
4
|
+
export type ConceptPhase =
|
|
5
|
+
| 'name-description-poem'
|
|
6
|
+
| 'leonardo-prompt'
|
|
7
|
+
| 'content'
|
|
8
|
+
| 'images';
|
|
9
|
+
|
|
10
|
+
export const zodiacSigns = [
|
|
11
|
+
'Aries',
|
|
12
|
+
'Taurus',
|
|
13
|
+
'Gemini',
|
|
14
|
+
'Cancer',
|
|
15
|
+
'Leo',
|
|
16
|
+
'Virgo',
|
|
17
|
+
'Libra',
|
|
18
|
+
'Scorpio',
|
|
19
|
+
'Sagittarius',
|
|
20
|
+
'Capricorn',
|
|
21
|
+
'Aquarius',
|
|
22
|
+
'Pisces',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
export interface ChatGPTOptions {
|
|
26
|
+
model?: string;
|
|
27
|
+
options?: Record<string, any>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface LeonardoGenerateImageParams {
|
|
31
|
+
prompt: string;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
controlNets?: Array<{
|
|
35
|
+
initImageId: string;
|
|
36
|
+
initImageType: 'UPLOADED' | 'GENERATED';
|
|
37
|
+
preprocessorId: number;
|
|
38
|
+
strengthType: 'Low' | 'Mid' | 'High';
|
|
39
|
+
}>;
|
|
40
|
+
quantity?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type HouseCuspsReport = {
|
|
44
|
+
planetName: string; // Name of the planet (e.g., "Sun")
|
|
45
|
+
house: number; // House number (e.g., 5)
|
|
46
|
+
report: string; // Detailed report or description
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type NatalHouseCuspReport = {
|
|
50
|
+
house: number; // House number (e.g., 1)
|
|
51
|
+
sign: string; // Sign associated with the house (e.g., "Aquarius")
|
|
52
|
+
degree: number; // Degree value (e.g., 303.73276)
|
|
53
|
+
report: string; // Detailed report or description
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export interface LeonardoGeneratePresignedUrlParams {
|
|
57
|
+
extension: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface LeonardoUploadImageParams {
|
|
61
|
+
presignedUrl: string;
|
|
62
|
+
fields: string;
|
|
63
|
+
file: Blob | Uint8Array | ArrayBuffer;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface LeonardoGenerateImageResponse {
|
|
67
|
+
sdGenerationJob: {
|
|
68
|
+
generationId?: string;
|
|
69
|
+
apiCreditCost?: number;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type Size = 'post1:1' | 'post4:5' | 'post1.91:1' | 'reels';
|
|
74
|
+
|
|
75
|
+
export interface ImageDescriberOptions {
|
|
76
|
+
imageUrl: string;
|
|
77
|
+
prompt: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface Crown {
|
|
81
|
+
sun: string;
|
|
82
|
+
ascendant: string;
|
|
83
|
+
moon: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface GenerateLeonardoPromptParams {
|
|
87
|
+
env: BackendBindings;
|
|
88
|
+
archetypeName: string;
|
|
89
|
+
archetypeDescription: string;
|
|
90
|
+
gender: Gender;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface GenerateEndpointParams {
|
|
94
|
+
crown: Crown;
|
|
95
|
+
gender: Gender;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type GenerateLeonardoPromptParamsWithoutEnv = Omit<
|
|
99
|
+
GenerateLeonardoPromptParams,
|
|
100
|
+
'env'
|
|
101
|
+
>;
|
|
102
|
+
|
|
103
|
+
export type personalizeCosmicMirrorLeonardoPrompt = {
|
|
104
|
+
leonardoPrompt: string;
|
|
105
|
+
traits: string;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export type KVArchetype = {
|
|
109
|
+
name: string;
|
|
110
|
+
description: string;
|
|
111
|
+
content: string;
|
|
112
|
+
leonardoPrompt: string;
|
|
113
|
+
virtues: string;
|
|
114
|
+
images: LeonardoImage[];
|
|
115
|
+
status: 'idle' | 'generating' | 'completed';
|
|
116
|
+
};
|
|
117
|
+
export type KVConcept = {
|
|
118
|
+
name: string;
|
|
119
|
+
description: string;
|
|
120
|
+
content: string;
|
|
121
|
+
poem: string;
|
|
122
|
+
leonardoPrompt: string;
|
|
123
|
+
postImages: LeonardoImage[]; // Pre-generated in sequence
|
|
124
|
+
reelImages: Array<LeonardoImage | null>; // Initially null, aligned by index
|
|
125
|
+
status: 'idle' | 'generating' | 'completed';
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type KVGenerationObject = {
|
|
129
|
+
crown: string;
|
|
130
|
+
gender: Gender;
|
|
131
|
+
archetypeIndex: number;
|
|
132
|
+
prompt: string;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export type KVUserGenerationObject = {
|
|
136
|
+
userId: string; // ID of the user
|
|
137
|
+
productId: string; // ID of the product
|
|
138
|
+
productName: string;
|
|
139
|
+
createdAt: string; // Timestamp when the generation was created
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export type ArchetypeObj = {
|
|
143
|
+
name: string;
|
|
144
|
+
description: string;
|
|
145
|
+
generationId: string;
|
|
146
|
+
leonardoPrompt: string;
|
|
147
|
+
virtues: string;
|
|
148
|
+
imageCounter: number;
|
|
149
|
+
images: LeonardoImage[];
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export type LeonardoImage = {
|
|
153
|
+
leonardoId: string;
|
|
154
|
+
url: string;
|
|
155
|
+
height: number;
|
|
156
|
+
width: number;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export interface LeonardoRequestBody {
|
|
160
|
+
prompt: string;
|
|
161
|
+
width: number;
|
|
162
|
+
height: number;
|
|
163
|
+
negative_prompt: string;
|
|
164
|
+
num_images: number;
|
|
165
|
+
modelId: string;
|
|
166
|
+
presetStyle: string;
|
|
167
|
+
alchemy: boolean;
|
|
168
|
+
controlnets?: Array<{
|
|
169
|
+
initImageId: string;
|
|
170
|
+
initImageType: string;
|
|
171
|
+
preprocessorId: number;
|
|
172
|
+
strengthType: string;
|
|
173
|
+
}>;
|
|
174
|
+
init_generation_image_id?: string;
|
|
175
|
+
init_strength?: number;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface LeonardoInitImageResponse {
|
|
179
|
+
id: string;
|
|
180
|
+
createdAt: string;
|
|
181
|
+
userId: string;
|
|
182
|
+
url: string;
|
|
183
|
+
type: string; // e.g., "UPLOADED" or "GENERATED"
|
|
184
|
+
metadata: Record<string, any>; // Optional metadata if available
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export type TimezoneResponse = {
|
|
188
|
+
dstOffset: number; // Daylight Savings Time offset in seconds
|
|
189
|
+
rawOffset: number; // Raw UTC offset in seconds
|
|
190
|
+
status: string; // Response status, e.g., "OK"
|
|
191
|
+
timeZoneId: string; // Time zone ID, e.g., "America/Los_Angeles"
|
|
192
|
+
timeZoneName: string; // Time zone name, e.g., "Pacific Standard Time"
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export type AstrologyPlanetData = {
|
|
196
|
+
name: string; // Planet name (e.g., "Sun", "Moon")
|
|
197
|
+
fullDegree: number; // Full degree position of the planet
|
|
198
|
+
normDegree: number; // Normalized degree (0-29°)
|
|
199
|
+
speed: number; // Speed of the planet
|
|
200
|
+
isRetro: 'true' | 'false'; // Retrograde status as a string
|
|
201
|
+
sign: string; // Sign the planet is in (e.g., "Sagittarius")
|
|
202
|
+
house: number; // House number (1-12)
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export type AstrologyApiResponse = AstrologyPlanetData[];
|
|
206
|
+
|
|
207
|
+
type Sizes = {
|
|
208
|
+
[k: string]: {
|
|
209
|
+
[key in Size]: {
|
|
210
|
+
width: number;
|
|
211
|
+
height: number;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const sizes: Sizes = {
|
|
217
|
+
alchemy: {
|
|
218
|
+
// closest values of input to get the closest possible values of output fit for the social media
|
|
219
|
+
'post1:1': {
|
|
220
|
+
width: 624,
|
|
221
|
+
height: 624,
|
|
222
|
+
},
|
|
223
|
+
'post4:5': {
|
|
224
|
+
width: 624,
|
|
225
|
+
height: 784,
|
|
226
|
+
},
|
|
227
|
+
'post1.91:1': {
|
|
228
|
+
width: 912,
|
|
229
|
+
height: 512,
|
|
230
|
+
},
|
|
231
|
+
reels: {
|
|
232
|
+
width: 756,
|
|
233
|
+
height: 1344,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
noAlchemy: {
|
|
237
|
+
// exact values available on leonardo's dashboard
|
|
238
|
+
'post1:1': {
|
|
239
|
+
width: 1110,
|
|
240
|
+
height: 1110,
|
|
241
|
+
},
|
|
242
|
+
'post4:5': {
|
|
243
|
+
width: 990,
|
|
244
|
+
height: 1240,
|
|
245
|
+
},
|
|
246
|
+
'post1.91:1': {
|
|
247
|
+
width: 1500,
|
|
248
|
+
height: 810,
|
|
249
|
+
},
|
|
250
|
+
reels: {
|
|
251
|
+
width: 830,
|
|
252
|
+
height: 1480,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
};
|