@zodic/shared 0.0.296 → 0.0.298
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/services/ArchetypeService.ts +94 -25
- package/db/migrations/0013_lean_frightful_four.sql +7 -0
- package/db/migrations/meta/0013_snapshot.json +2649 -0
- package/db/migrations/meta/_journal.json +7 -0
- package/db/schema.ts +16 -2
- package/package.json +1 -1
- package/types/scopes/cloudflare.ts +2 -0
- package/utils/isEnglishNameDuplicate.ts +22 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq } from 'drizzle-orm';
|
|
1
|
+
import { and, eq } from 'drizzle-orm';
|
|
2
2
|
import { inject, injectable } from 'inversify';
|
|
3
3
|
import { ChatMessages, schema } from '../..';
|
|
4
4
|
import { KVArchetype, ZodiacSignSlug } from '../../types/scopes/legacy';
|
|
@@ -289,15 +289,11 @@ export class ArchetypeService {
|
|
|
289
289
|
combination: string,
|
|
290
290
|
overrideExisting: boolean = false
|
|
291
291
|
) {
|
|
292
|
+
const db = this.context.drizzle();
|
|
292
293
|
const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
|
|
293
294
|
|
|
294
295
|
const prompt = generateArchetypePrompt([{ sun, ascendant, moon }]);
|
|
295
|
-
const messages: ChatMessages = [
|
|
296
|
-
{
|
|
297
|
-
role: 'user',
|
|
298
|
-
content: prompt,
|
|
299
|
-
},
|
|
300
|
-
];
|
|
296
|
+
const messages: ChatMessages = [{ role: 'user', content: prompt }];
|
|
301
297
|
const response = await this.context.api().callTogether.single(messages, {});
|
|
302
298
|
|
|
303
299
|
if (!response) {
|
|
@@ -306,17 +302,33 @@ export class ArchetypeService {
|
|
|
306
302
|
);
|
|
307
303
|
}
|
|
308
304
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
305
|
+
let blocks: string[] = [];
|
|
306
|
+
let ptBlocks: string[] = [];
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
blocks = response
|
|
310
|
+
.split('-EN')[1]
|
|
311
|
+
.split('-PT')[0]
|
|
312
|
+
.trim()
|
|
313
|
+
.split(/\n\d\.\s*\n?/)
|
|
314
|
+
.filter(Boolean);
|
|
315
|
+
|
|
316
|
+
ptBlocks = response
|
|
317
|
+
.split('-PT')[1]
|
|
318
|
+
.trim()
|
|
319
|
+
.split(/\n\d\.\s*\n?/)
|
|
320
|
+
.filter(Boolean);
|
|
321
|
+
} catch (err) {
|
|
322
|
+
console.error(`Parsing failed for combination: ${combination}`, err);
|
|
323
|
+
await db.insert(schema.archetypeNameDumps).values({
|
|
324
|
+
id: combination,
|
|
325
|
+
combination,
|
|
326
|
+
rawText: response,
|
|
327
|
+
parsedSuccessfully: 0,
|
|
328
|
+
createdAt: Date.now(),
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
320
332
|
|
|
321
333
|
const englishNames = blocks.map((block) => {
|
|
322
334
|
const nameMatch = block.match(/• Name:\s*(.+)/);
|
|
@@ -334,16 +346,37 @@ export class ArchetypeService {
|
|
|
334
346
|
return { masc, fem, essenceLine: essence };
|
|
335
347
|
});
|
|
336
348
|
|
|
337
|
-
|
|
349
|
+
// Duplicate helper
|
|
350
|
+
async function isEnglishNameDuplicate(name: string): Promise<boolean> {
|
|
351
|
+
const result = await db
|
|
352
|
+
.select({ name: schema.archetypesData.name })
|
|
353
|
+
.from(schema.archetypesData)
|
|
354
|
+
.where(
|
|
355
|
+
and(
|
|
356
|
+
eq(schema.archetypesData.language, 'en-us'),
|
|
357
|
+
eq(schema.archetypesData.name, name)
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
.limit(1)
|
|
361
|
+
.execute();
|
|
362
|
+
|
|
363
|
+
return result.length > 0;
|
|
364
|
+
}
|
|
338
365
|
|
|
339
366
|
await Promise.all(
|
|
340
367
|
englishNames.map(async (entry, i) => {
|
|
341
368
|
const index = (i + 1).toString();
|
|
342
369
|
const ptVariant = portugueseVariants[i];
|
|
343
370
|
|
|
371
|
+
if (await isEnglishNameDuplicate(entry.name)) {
|
|
372
|
+
console.warn(`Duplicate name detected: "${entry.name}" — skipping.`);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
344
376
|
for (const gender of ['male', 'female']) {
|
|
345
377
|
const enId = `${combination}:${gender}:${index}`;
|
|
346
378
|
const ptId = `${combination}:${gender}:${index}:pt`;
|
|
379
|
+
const ptName = gender === 'female' ? ptVariant.fem : ptVariant.masc;
|
|
347
380
|
|
|
348
381
|
const existingEn = await db
|
|
349
382
|
.select({ id: schema.archetypesData.id })
|
|
@@ -374,8 +407,6 @@ export class ArchetypeService {
|
|
|
374
407
|
});
|
|
375
408
|
}
|
|
376
409
|
|
|
377
|
-
const ptName = gender === 'female' ? ptVariant.fem : ptVariant.masc;
|
|
378
|
-
|
|
379
410
|
const existingPt = await db
|
|
380
411
|
.select({ id: schema.archetypesData.id })
|
|
381
412
|
.from(schema.archetypesData)
|
|
@@ -413,6 +444,8 @@ export class ArchetypeService {
|
|
|
413
444
|
entries: Array<{ combination: string }>,
|
|
414
445
|
overrideExisting: boolean = false
|
|
415
446
|
) {
|
|
447
|
+
const db = this.context.drizzle();
|
|
448
|
+
|
|
416
449
|
const prompts = entries.map(({ combination }) => {
|
|
417
450
|
const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
|
|
418
451
|
return { sun, ascendant, moon };
|
|
@@ -426,18 +459,47 @@ export class ArchetypeService {
|
|
|
426
459
|
throw new Error('No response when generating batch archetype names');
|
|
427
460
|
}
|
|
428
461
|
|
|
429
|
-
const db = this.context.drizzle();
|
|
430
|
-
|
|
431
462
|
const blocks = response
|
|
432
463
|
.split(/Composition \d+/)
|
|
433
464
|
.slice(1)
|
|
434
465
|
.map((b) => b.trim());
|
|
435
466
|
|
|
467
|
+
async function isEnglishNameDuplicate(name: string): Promise<boolean> {
|
|
468
|
+
const result = await db
|
|
469
|
+
.select({ name: schema.archetypesData.name })
|
|
470
|
+
.from(schema.archetypesData)
|
|
471
|
+
.where(
|
|
472
|
+
and(
|
|
473
|
+
eq(schema.archetypesData.language, 'en-us'),
|
|
474
|
+
eq(schema.archetypesData.name, name)
|
|
475
|
+
)
|
|
476
|
+
)
|
|
477
|
+
.limit(1)
|
|
478
|
+
.execute();
|
|
479
|
+
|
|
480
|
+
return result.length > 0;
|
|
481
|
+
}
|
|
482
|
+
|
|
436
483
|
for (let i = 0; i < entries.length; i++) {
|
|
437
484
|
const { combination } = entries[i];
|
|
438
485
|
const block = blocks[i];
|
|
439
|
-
|
|
440
|
-
|
|
486
|
+
|
|
487
|
+
let en = '';
|
|
488
|
+
let pt = '';
|
|
489
|
+
try {
|
|
490
|
+
en = block.split('-EN')[1].split('-PT')[0].trim();
|
|
491
|
+
pt = block.split('-PT')[1].trim();
|
|
492
|
+
} catch (err) {
|
|
493
|
+
console.error(`Parsing failed for composition ${combination}`, err);
|
|
494
|
+
await db.insert(schema.archetypeNameDumps).values({
|
|
495
|
+
id: combination,
|
|
496
|
+
combination,
|
|
497
|
+
rawText: block,
|
|
498
|
+
parsedSuccessfully: 0,
|
|
499
|
+
createdAt: Date.now(),
|
|
500
|
+
});
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
441
503
|
|
|
442
504
|
const english = en
|
|
443
505
|
.split(/\n\d\.\s*\n?/)
|
|
@@ -461,6 +523,13 @@ export class ArchetypeService {
|
|
|
461
523
|
const englishEntry = english[j];
|
|
462
524
|
const ptEntry = portuguese[j];
|
|
463
525
|
|
|
526
|
+
if (await isEnglishNameDuplicate(englishEntry.name)) {
|
|
527
|
+
console.warn(
|
|
528
|
+
`Duplicate English name "${englishEntry.name}" — skipping.`
|
|
529
|
+
);
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
|
|
464
533
|
for (const gender of ['male', 'female']) {
|
|
465
534
|
const enId = `${combination}:${gender}:${index}`;
|
|
466
535
|
const ptId = `${combination}:${gender}:${index}:pt`;
|