@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.
@@ -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
- const blocks = response
310
- .split('-EN')[1]
311
- .split('-PT')[0]
312
- .trim()
313
- .split(/\n\d\.\s*\n?/)
314
- .filter(Boolean);
315
- const ptBlocks = response
316
- .split('-PT')[1]
317
- .trim()
318
- .split(/\n\d\.\s*\n?/)
319
- .filter(Boolean);
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
- const db = this.context.drizzle();
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
- const en = block.split('-EN')[1].split('-PT')[0].trim();
440
- const pt = block.split('-PT')[1].trim();
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`;
@@ -0,0 +1,7 @@
1
+ CREATE TABLE `archetype_name_dumps` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `combination` text NOT NULL,
4
+ `raw_text` text NOT NULL,
5
+ `parsed_successfully` integer DEFAULT 0,
6
+ `created_at` integer DEFAULT CURRENT_TIMESTAMP
7
+ );