@zodic/shared 0.0.295 → 0.0.297

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.
@@ -287,18 +287,13 @@ export class ArchetypeService {
287
287
 
288
288
  async generateArchetypeNames(
289
289
  combination: string,
290
- gender: 'male' | 'female' | 'non-binary',
291
290
  overrideExisting: boolean = false
292
291
  ) {
292
+ const db = this.context.drizzle();
293
293
  const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
294
294
 
295
295
  const prompt = generateArchetypePrompt([{ sun, ascendant, moon }]);
296
- const messages: ChatMessages = [
297
- {
298
- role: 'user',
299
- content: prompt,
300
- },
301
- ];
296
+ const messages: ChatMessages = [{ role: 'user', content: prompt }];
302
297
  const response = await this.context.api().callTogether.single(messages, {});
303
298
 
304
299
  if (!response) {
@@ -307,17 +302,33 @@ export class ArchetypeService {
307
302
  );
308
303
  }
309
304
 
310
- const blocks = response
311
- .split('-EN')[1]
312
- .split('-PT')[0]
313
- .trim()
314
- .split(/\n\d\.\s*\n?/)
315
- .filter(Boolean);
316
- const ptBlocks = response
317
- .split('-PT')[1]
318
- .trim()
319
- .split(/\n\d\.\s*\n?/)
320
- .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
+ }
321
332
 
322
333
  const englishNames = blocks.map((block) => {
323
334
  const nameMatch = block.match(/• Name:\s*(.+)/);
@@ -335,81 +346,102 @@ export class ArchetypeService {
335
346
  return { masc, fem, essenceLine: essence };
336
347
  });
337
348
 
338
- 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
+ }
339
365
 
340
366
  await Promise.all(
341
367
  englishNames.map(async (entry, i) => {
342
368
  const index = (i + 1).toString();
343
- const existingEntry = await db
344
- .select({ id: schema.archetypesData.id })
345
- .from(schema.archetypesData)
346
- .where(
347
- eq(schema.archetypesData.id, `${combination}:${gender}:${index}`)
348
- )
349
- .execute();
350
-
351
- if (overrideExisting || existingEntry.length === 0) {
352
- await db
353
- .insert(schema.archetypesData)
354
- .values({
355
- id: `${combination}:${gender}:${index}`,
356
- combination,
357
- gender,
358
- archetypeIndex: index,
359
- language: 'en-us',
360
- name: entry.name,
361
- essenceLine: entry.essenceLine,
362
- status: 'idle',
363
- })
364
- .onConflictDoUpdate({
365
- target: [schema.archetypesData.id],
366
- set: {
369
+ const ptVariant = portugueseVariants[i];
370
+
371
+ if (await isEnglishNameDuplicate(entry.name)) {
372
+ console.warn(`Duplicate name detected: "${entry.name}" — skipping.`);
373
+ return;
374
+ }
375
+
376
+ for (const gender of ['male', 'female']) {
377
+ const enId = `${combination}:${gender}:${index}`;
378
+ const ptId = `${combination}:${gender}:${index}:pt`;
379
+ const ptName = gender === 'female' ? ptVariant.fem : ptVariant.masc;
380
+
381
+ const existingEn = await db
382
+ .select({ id: schema.archetypesData.id })
383
+ .from(schema.archetypesData)
384
+ .where(eq(schema.archetypesData.id, enId))
385
+ .execute();
386
+
387
+ if (overrideExisting || existingEn.length === 0) {
388
+ await db
389
+ .insert(schema.archetypesData)
390
+ .values({
391
+ id: enId,
392
+ combination,
393
+ gender,
394
+ archetypeIndex: index,
395
+ language: 'en-us',
367
396
  name: entry.name,
368
397
  essenceLine: entry.essenceLine,
369
- updatedAt: new Date().getTime(),
370
- },
371
- });
372
- }
398
+ status: 'idle',
399
+ })
400
+ .onConflictDoUpdate({
401
+ target: [schema.archetypesData.id],
402
+ set: {
403
+ name: entry.name,
404
+ essenceLine: entry.essenceLine,
405
+ updatedAt: new Date().getTime(),
406
+ },
407
+ });
408
+ }
373
409
 
374
- const existingEntryPt = await db
375
- .select({ id: schema.archetypesData.id })
376
- .from(schema.archetypesData)
377
- .where(
378
- eq(schema.archetypesData.id, `${combination}:${gender}:${index}:pt`)
379
- )
380
- .execute();
381
-
382
- if (overrideExisting || existingEntryPt.length === 0) {
383
- await db
384
- .insert(schema.archetypesData)
385
- .values({
386
- id: `${combination}:${gender}:${index}:pt`,
387
- combination,
388
- gender,
389
- archetypeIndex: index,
390
- language: 'pt-br',
391
- name: portugueseVariants[i].masc,
392
- essenceLine: portugueseVariants[i].essenceLine,
393
- status: 'idle',
394
- })
395
- .onConflictDoUpdate({
396
- target: [schema.archetypesData.id],
397
- set: {
398
- name: portugueseVariants[i].masc,
399
- essenceLine: portugueseVariants[i].essenceLine,
400
- updatedAt: new Date().getTime(),
401
- },
402
- });
410
+ const existingPt = await db
411
+ .select({ id: schema.archetypesData.id })
412
+ .from(schema.archetypesData)
413
+ .where(eq(schema.archetypesData.id, ptId))
414
+ .execute();
415
+
416
+ if (overrideExisting || existingPt.length === 0) {
417
+ await db
418
+ .insert(schema.archetypesData)
419
+ .values({
420
+ id: ptId,
421
+ combination,
422
+ gender,
423
+ archetypeIndex: index,
424
+ language: 'pt-br',
425
+ name: ptName,
426
+ essenceLine: ptVariant.essenceLine,
427
+ status: 'idle',
428
+ })
429
+ .onConflictDoUpdate({
430
+ target: [schema.archetypesData.id],
431
+ set: {
432
+ name: ptName,
433
+ essenceLine: ptVariant.essenceLine,
434
+ updatedAt: new Date().getTime(),
435
+ },
436
+ });
437
+ }
403
438
  }
404
439
  })
405
440
  );
406
441
  }
407
442
 
408
443
  async generateArchetypeNamesBatch(
409
- entries: Array<{
410
- combination: string;
411
- gender: 'male' | 'female' | 'non-binary';
412
- }>,
444
+ entries: Array<{ combination: string }>,
413
445
  overrideExisting: boolean = false
414
446
  ) {
415
447
  const prompts = entries.map(({ combination }) => {
@@ -421,8 +453,9 @@ export class ArchetypeService {
421
453
  const messages: ChatMessages = [{ role: 'user', content: prompt }];
422
454
  const response = await this.context.api().callTogether.single(messages, {});
423
455
 
424
- if (!response)
456
+ if (!response) {
425
457
  throw new Error('No response when generating batch archetype names');
458
+ }
426
459
 
427
460
  const db = this.context.drizzle();
428
461
 
@@ -432,7 +465,7 @@ export class ArchetypeService {
432
465
  .map((b) => b.trim());
433
466
 
434
467
  for (let i = 0; i < entries.length; i++) {
435
- const { combination, gender } = entries[i];
468
+ const { combination } = entries[i];
436
469
  const block = blocks[i];
437
470
  const en = block.split('-EN')[1].split('-PT')[0].trim();
438
471
  const pt = block.split('-PT')[1].trim();
@@ -450,72 +483,77 @@ export class ArchetypeService {
450
483
  .filter(Boolean)
451
484
  .map((line) => ({
452
485
  masc: line.match(/• Masculino:\s*(.+)/)?.[1]?.trim() || '',
486
+ fem: line.match(/• Feminino:\s*(.+)/)?.[1]?.trim() || '',
453
487
  essenceLine: line.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '',
454
488
  }));
455
489
 
456
490
  for (let j = 0; j < 3; j++) {
457
491
  const index = (j + 1).toString();
492
+ const englishEntry = english[j];
493
+ const ptEntry = portuguese[j];
494
+
495
+ for (const gender of ['male', 'female']) {
496
+ const enId = `${combination}:${gender}:${index}`;
497
+ const ptId = `${combination}:${gender}:${index}:pt`;
498
+ const ptName = gender === 'female' ? ptEntry.fem : ptEntry.masc;
499
+
500
+ const existingEn = await db
501
+ .select({ id: schema.archetypesData.id })
502
+ .from(schema.archetypesData)
503
+ .where(eq(schema.archetypesData.id, enId))
504
+ .execute();
505
+
506
+ if (overrideExisting || existingEn.length === 0) {
507
+ await db
508
+ .insert(schema.archetypesData)
509
+ .values({
510
+ id: enId,
511
+ combination,
512
+ gender,
513
+ archetypeIndex: index,
514
+ language: 'en-us',
515
+ name: englishEntry.name,
516
+ essenceLine: englishEntry.essenceLine,
517
+ status: 'idle',
518
+ })
519
+ .onConflictDoUpdate({
520
+ target: [schema.archetypesData.id],
521
+ set: {
522
+ name: englishEntry.name,
523
+ essenceLine: englishEntry.essenceLine,
524
+ updatedAt: new Date().getTime(),
525
+ },
526
+ });
527
+ }
458
528
 
459
- const existingEntry = await db
460
- .select({ id: schema.archetypesData.id })
461
- .from(schema.archetypesData)
462
- .where(
463
- eq(schema.archetypesData.id, `${combination}:${gender}:${index}`)
464
- )
465
- .execute();
466
-
467
- if (overrideExisting || existingEntry.length === 0) {
468
- await db
469
- .insert(schema.archetypesData)
470
- .values({
471
- id: `${combination}:${gender}:${index}`,
472
- combination,
473
- gender,
474
- archetypeIndex: index,
475
- language: 'en-us',
476
- name: english[j].name,
477
- essenceLine: english[j].essenceLine,
478
- status: 'idle',
479
- })
480
- .onConflictDoUpdate({
481
- target: [schema.archetypesData.id],
482
- set: {
483
- name: english[j].name,
484
- essenceLine: english[j].essenceLine,
485
- updatedAt: new Date().getTime(),
486
- },
487
- });
488
- }
489
-
490
- const existingEntryPt = await db
491
- .select({ id: schema.archetypesData.id })
492
- .from(schema.archetypesData)
493
- .where(
494
- eq(schema.archetypesData.id, `${combination}:${gender}:${index}:pt`)
495
- )
496
- .execute();
497
-
498
- if (overrideExisting || existingEntryPt.length === 0) {
499
- await db
500
- .insert(schema.archetypesData)
501
- .values({
502
- id: `${combination}:${gender}:${index}:pt`,
503
- combination,
504
- gender,
505
- archetypeIndex: index,
506
- language: 'pt-br',
507
- name: portuguese[j].masc,
508
- essenceLine: portuguese[j].essenceLine,
509
- status: 'idle',
510
- })
511
- .onConflictDoUpdate({
512
- target: [schema.archetypesData.id],
513
- set: {
514
- name: portuguese[j].masc,
515
- essenceLine: portuguese[j].essenceLine,
516
- updatedAt: new Date().getTime(),
517
- },
518
- });
529
+ const existingPt = await db
530
+ .select({ id: schema.archetypesData.id })
531
+ .from(schema.archetypesData)
532
+ .where(eq(schema.archetypesData.id, ptId))
533
+ .execute();
534
+
535
+ if (overrideExisting || existingPt.length === 0) {
536
+ await db
537
+ .insert(schema.archetypesData)
538
+ .values({
539
+ id: ptId,
540
+ combination,
541
+ gender,
542
+ archetypeIndex: index,
543
+ language: 'pt-br',
544
+ name: ptName,
545
+ essenceLine: ptEntry.essenceLine,
546
+ status: 'idle',
547
+ })
548
+ .onConflictDoUpdate({
549
+ target: [schema.archetypesData.id],
550
+ set: {
551
+ name: ptName,
552
+ essenceLine: ptEntry.essenceLine,
553
+ updatedAt: new Date().getTime(),
554
+ },
555
+ });
556
+ }
519
557
  }
520
558
  }
521
559
  }
@@ -89,11 +89,9 @@ export class ArchetypeWorkflow {
89
89
 
90
90
  async generateNames({
91
91
  combinations,
92
- gender,
93
92
  overrideExisting,
94
93
  }: {
95
94
  combinations: string[];
96
- gender: Gender;
97
95
  overrideExisting?: boolean;
98
96
  }): Promise<void> {
99
97
  if (combinations.length === 0) return;
@@ -101,16 +99,17 @@ export class ArchetypeWorkflow {
101
99
  if (combinations.length === 1) {
102
100
  await this.archetypeService.generateArchetypeNames(
103
101
  combinations[0],
104
- gender,
105
102
  overrideExisting
106
103
  );
107
104
  } else {
108
105
  const entries = combinations.map((combination) => ({
109
106
  combination,
110
- gender,
111
107
  }));
112
108
 
113
- await this.archetypeService.generateArchetypeNamesBatch(entries, overrideExisting);
109
+ await this.archetypeService.generateArchetypeNamesBatch(
110
+ entries,
111
+ overrideExisting
112
+ );
114
113
  }
115
114
  }
116
115
 
@@ -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
+ );