@zodic/shared 0.0.244 → 0.0.246
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/ConceptService.ts +45 -7
- package/db/schema.ts +18 -0
- package/package.json +1 -1
- package/types/scopes/generic.ts +29 -9
- package/types/scopes/legacy.ts +41 -0
- package/utils/astroPrompts/index.ts +78 -0
|
@@ -2048,6 +2048,31 @@ export class ConceptService {
|
|
|
2048
2048
|
eq(aspectReports.aspect, params.aspectingType)
|
|
2049
2049
|
);
|
|
2050
2050
|
break;
|
|
2051
|
+
case "feature":
|
|
2052
|
+
table = astroFeatureReports;
|
|
2053
|
+
let nameValue: string;
|
|
2054
|
+
if (params.featureType === "element") {
|
|
2055
|
+
switch (params.subtype) {
|
|
2056
|
+
case "balanced":
|
|
2057
|
+
nameValue = "balanced";
|
|
2058
|
+
break;
|
|
2059
|
+
case "pure":
|
|
2060
|
+
nameValue = params.dominantElement;
|
|
2061
|
+
break;
|
|
2062
|
+
case "preponderant_lacking":
|
|
2063
|
+
nameValue = `${params.dominantElement}-${params.lackingElement}`;
|
|
2064
|
+
break;
|
|
2065
|
+
default:
|
|
2066
|
+
throw new Error(`Unknown element subtype: ${(params as any).subtype}`);
|
|
2067
|
+
}
|
|
2068
|
+
} else {
|
|
2069
|
+
nameValue = params.name;
|
|
2070
|
+
}
|
|
2071
|
+
whereClause = and(
|
|
2072
|
+
eq(astroFeatureReports.featureType, params.featureType),
|
|
2073
|
+
eq(astroFeatureReports.name, nameValue)
|
|
2074
|
+
);
|
|
2075
|
+
break;
|
|
2051
2076
|
default:
|
|
2052
2077
|
throw new Error(`Unknown report type: ${(params as any).reportType}`);
|
|
2053
2078
|
}
|
|
@@ -2204,9 +2229,9 @@ export class ConceptService {
|
|
|
2204
2229
|
console.log(`🔢 Split into ${lines.length} lines`);
|
|
2205
2230
|
|
|
2206
2231
|
let currentSection = '';
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
console.log(`📏 Processing line: "${line}"`);
|
|
2232
|
+
for (let j = 0; j < lines.length; j++) {
|
|
2233
|
+
const line = lines[j];
|
|
2234
|
+
console.log(`📏 Processing line ${j + 1}: "${line}"`);
|
|
2210
2235
|
|
|
2211
2236
|
if (line.startsWith('### ') && report.title.length === 0) {
|
|
2212
2237
|
const titleContent = cleanText(line.replace('### ', ''));
|
|
@@ -2233,15 +2258,28 @@ export class ConceptService {
|
|
|
2233
2258
|
if (line.match(/^\d+\.\s/) || line.startsWith('- ')) {
|
|
2234
2259
|
const listItem = line.replace(/^\d+\.\s|- /, '').trim();
|
|
2235
2260
|
console.log(`🔹 Bullet point detected: "${listItem}"`);
|
|
2236
|
-
const boldMatch = listItem.match(/^\*\*(.+?)\*\*[:\s]*(.+)
|
|
2261
|
+
const boldMatch = listItem.match(/^\*\*(.+?)\*\*[:\s]*(.+)?$/); // Updated to allow standalone bold
|
|
2262
|
+
|
|
2237
2263
|
if (boldMatch) {
|
|
2238
2264
|
const title = cleanText(boldMatch[1]);
|
|
2239
|
-
|
|
2240
|
-
|
|
2265
|
+
let content = boldMatch[2] ? cleanText(boldMatch[2]) : '';
|
|
2266
|
+
|
|
2267
|
+
// Look ahead for content if none on the same line
|
|
2268
|
+
if (!content && j + 1 < lines.length) {
|
|
2269
|
+
const nextLine = lines[j + 1];
|
|
2270
|
+
console.log(`🔍 Checking next line for content: "${nextLine}"`);
|
|
2271
|
+
if (nextLine && !nextLine.match(/^\d+\.\s|- /) && !nextLine.startsWith('#### ') && !nextLine.startsWith('### ')) {
|
|
2272
|
+
content = cleanText(nextLine);
|
|
2273
|
+
console.log(`✅ Found content in next line: "${content}"`);
|
|
2274
|
+
j++; // Skip the next line since we’ve consumed it
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
console.log(`✅ Bold match found - Title: "${title}", Content: "${content || 'None'}"`);
|
|
2241
2279
|
report.sections[currentSection].push({
|
|
2242
2280
|
type: 'bullet-point',
|
|
2243
2281
|
title,
|
|
2244
|
-
content,
|
|
2282
|
+
content: content || '', // Empty string if no content found
|
|
2245
2283
|
});
|
|
2246
2284
|
} else {
|
|
2247
2285
|
console.log(`❌ No bold match - Full content: "${listItem}"`);
|
package/db/schema.ts
CHANGED
|
@@ -247,6 +247,24 @@ export const aspectReports = sqliteTable(
|
|
|
247
247
|
]
|
|
248
248
|
);
|
|
249
249
|
|
|
250
|
+
export const astroFeatureReports = sqliteTable(
|
|
251
|
+
'astro_feature_reports',
|
|
252
|
+
{
|
|
253
|
+
id: text('id').primaryKey(), // Unique identifier
|
|
254
|
+
featureType: text('feature_type').notNull(), // e.g., "moon_phase", "element", "mode", "hemisphere_east_west", "hemisphere_north_south", "dominant_sign"
|
|
255
|
+
name: text('name').notNull(), // e.g., "last-quarter-moon", "fire", "cardinal", "east-west", "north-south", "capricorn"
|
|
256
|
+
enDescription: text('en_description'), // Introductory text in English
|
|
257
|
+
ptDescription: text('pt_description'), // Introductory text in Portuguese
|
|
258
|
+
enReport: text('en_report'), // Full report content in English (JSON string)
|
|
259
|
+
ptReport: text('pt_report'), // Full report content in Portuguese (JSON string)
|
|
260
|
+
createdAt: integer('created_at').default(sql`CURRENT_TIMESTAMP`),
|
|
261
|
+
updatedAt: integer('updated_at').default(sql`CURRENT_TIMESTAMP`),
|
|
262
|
+
},
|
|
263
|
+
(t) => [
|
|
264
|
+
index('astro_feature_reports_type_name_idx').on(t.featureType, t.name), // Optimized for lookups by type and name
|
|
265
|
+
]
|
|
266
|
+
);
|
|
267
|
+
|
|
250
268
|
export const concepts = sqliteTable(
|
|
251
269
|
'concepts',
|
|
252
270
|
{
|
package/package.json
CHANGED
package/types/scopes/generic.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AspectType, PointSlug, ZodiacSign } from
|
|
1
|
+
import { AspectType, PointSlug, ZodiacSign } from './legacy';
|
|
2
2
|
|
|
3
3
|
export type Provider = 'google' | 'facebook';
|
|
4
4
|
|
|
@@ -34,7 +34,7 @@ export type AstroEntity = {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export interface ContentItem {
|
|
37
|
-
type:
|
|
37
|
+
type: 'title' | 'subtitle' | 'p' | 'bullet-point';
|
|
38
38
|
title?: string;
|
|
39
39
|
content: string;
|
|
40
40
|
}
|
|
@@ -45,30 +45,50 @@ export interface AstrologicalReport {
|
|
|
45
45
|
sections: Record<string, ContentItem[]>;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
49
48
|
export type AstroReportParams =
|
|
50
49
|
| {
|
|
51
|
-
reportType:
|
|
52
|
-
type:
|
|
50
|
+
reportType: 'sign';
|
|
51
|
+
type: 'planet' | 'key_point' | 'karmic_point' | 'arabic_part';
|
|
53
52
|
pointName: PointSlug;
|
|
54
53
|
sign: ZodiacSign;
|
|
55
54
|
}
|
|
56
55
|
| {
|
|
57
|
-
reportType:
|
|
58
|
-
type:
|
|
56
|
+
reportType: 'house';
|
|
57
|
+
type: 'planet' | 'karmic_point'; // Only planets and karmic points for house reports
|
|
59
58
|
pointName: PointSlug;
|
|
60
59
|
house: number;
|
|
61
60
|
}
|
|
62
61
|
| {
|
|
63
|
-
reportType:
|
|
62
|
+
reportType: 'signInHouse';
|
|
64
63
|
sign: ZodiacSign;
|
|
65
64
|
houseNumber: number;
|
|
66
65
|
}
|
|
67
66
|
| {
|
|
68
|
-
reportType:
|
|
67
|
+
reportType: 'aspect';
|
|
69
68
|
aspectingPlanet: PointSlug;
|
|
70
69
|
aspectedPlanet: PointSlug;
|
|
71
70
|
aspectingType: AspectType;
|
|
71
|
+
}
|
|
72
|
+
| { reportType: 'feature'; featureType: 'moon_phase'; name: string }
|
|
73
|
+
| { reportType: 'feature'; featureType: 'element'; subtype: 'balanced' }
|
|
74
|
+
| {
|
|
75
|
+
reportType: 'feature';
|
|
76
|
+
featureType: 'element';
|
|
77
|
+
subtype: 'pure';
|
|
78
|
+
dominantElement: string;
|
|
79
|
+
}
|
|
80
|
+
| {
|
|
81
|
+
reportType: 'feature';
|
|
82
|
+
featureType: 'element';
|
|
83
|
+
subtype: 'preponderant_lacking';
|
|
84
|
+
dominantElement: string;
|
|
85
|
+
lackingElement: string;
|
|
86
|
+
}
|
|
87
|
+
| { reportType: 'feature'; featureType: 'mode'; name: string }
|
|
88
|
+
| {
|
|
89
|
+
reportType: 'feature';
|
|
90
|
+
featureType: 'hemisphere_east_west' | 'hemisphere_north_south';
|
|
91
|
+
name: 'east' | 'west' | 'north' | 'south';
|
|
72
92
|
};
|
|
73
93
|
|
|
74
94
|
export type NatalChartInterpretation = {
|
package/types/scopes/legacy.ts
CHANGED
|
@@ -31,6 +31,47 @@ export const aspects = [
|
|
|
31
31
|
] as const;
|
|
32
32
|
export type AspectType = (typeof aspects)[number];
|
|
33
33
|
|
|
34
|
+
export interface BalancedElementParams {
|
|
35
|
+
featureType: "element";
|
|
36
|
+
subtype: "balanced";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PureElementParams {
|
|
40
|
+
featureType: "element";
|
|
41
|
+
subtype: "pure";
|
|
42
|
+
dominantElement: string; // e.g., "fire"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface PreponderantLackingElementParams {
|
|
46
|
+
featureType: "element";
|
|
47
|
+
subtype: "preponderant_lacking";
|
|
48
|
+
dominantElement: string; // e.g., "fire"
|
|
49
|
+
lackingElement: string; // e.g., "water"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ElementParams = BalancedElementParams | PureElementParams | PreponderantLackingElementParams;
|
|
53
|
+
|
|
54
|
+
export interface MoonPhaseParams {
|
|
55
|
+
featureType: "moon_phase";
|
|
56
|
+
name: string; // e.g., "last-quarter"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ModeParams {
|
|
60
|
+
featureType: "mode";
|
|
61
|
+
name: string; // e.g., "cardinal"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface HemisphereParams {
|
|
65
|
+
featureType: "hemisphere_east_west" | "hemisphere_north_south";
|
|
66
|
+
name: "east" | "west" | "north" | "south"; // Highlighted hemisphere
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type FeatureParams =
|
|
70
|
+
| MoonPhaseParams
|
|
71
|
+
| ElementParams
|
|
72
|
+
| ModeParams
|
|
73
|
+
| HemisphereParams;
|
|
74
|
+
|
|
34
75
|
export const pointTypes: Record<PointSlug, string> = {
|
|
35
76
|
sun: 'planet',
|
|
36
77
|
moon: 'planet',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AspectType,
|
|
3
|
+
FeatureParams,
|
|
3
4
|
PointSlug,
|
|
4
5
|
ZodiacSign,
|
|
5
6
|
zodiacSignMap,
|
|
@@ -146,4 +147,81 @@ export const astroPrompts = {
|
|
|
146
147
|
[Portuguese Report - structured exactly the same as the English version]
|
|
147
148
|
`.trim();
|
|
148
149
|
},
|
|
150
|
+
|
|
151
|
+
feature: (params: FeatureParams): string => {
|
|
152
|
+
const baseFormat = `
|
|
153
|
+
The response should include an English version and a Portuguese version.
|
|
154
|
+
Use "###" for titles and "####" for subtitles.
|
|
155
|
+
The response format should be exactly like this:
|
|
156
|
+
|
|
157
|
+
-- EN
|
|
158
|
+
|
|
159
|
+
[English Report - structured with headings, sections, and detailed explanations]
|
|
160
|
+
|
|
161
|
+
-- PT
|
|
162
|
+
|
|
163
|
+
[Portuguese Report - structured exactly the same as the English version]
|
|
164
|
+
`.trim();
|
|
165
|
+
|
|
166
|
+
switch (params.featureType) {
|
|
167
|
+
case "moon_phase": {
|
|
168
|
+
const formattedName = params.name
|
|
169
|
+
.split('-')
|
|
170
|
+
.map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
171
|
+
.join(' ');
|
|
172
|
+
return `
|
|
173
|
+
Make me an astrological report for a person born under the Moon Phase: ${formattedName}.
|
|
174
|
+
${baseFormat}
|
|
175
|
+
`.trim();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
case "element": {
|
|
179
|
+
switch (params.subtype) {
|
|
180
|
+
case "balanced":
|
|
181
|
+
return `
|
|
182
|
+
Make me an astrological report for a person with a balanced elemental distribution in their birth chart.
|
|
183
|
+
${baseFormat}
|
|
184
|
+
`.trim();
|
|
185
|
+
case "pure": {
|
|
186
|
+
const dominant = params.dominantElement.charAt(0).toUpperCase() + params.dominantElement.slice(1);
|
|
187
|
+
return `
|
|
188
|
+
Make me an astrological report for a person with a preponderance of the ${dominant} element in their birth chart.
|
|
189
|
+
${baseFormat}
|
|
190
|
+
`.trim();
|
|
191
|
+
}
|
|
192
|
+
case "preponderant_lacking": {
|
|
193
|
+
const dominant = params.dominantElement.charAt(0).toUpperCase() + params.dominantElement.slice(1);
|
|
194
|
+
const lacking = params.lackingElement.charAt(0).toUpperCase() + params.lackingElement.slice(1);
|
|
195
|
+
return `
|
|
196
|
+
Make me an astrological report for a person with a preponderance of the ${dominant} element and a lack of the ${lacking} element in their birth chart.
|
|
197
|
+
${baseFormat}
|
|
198
|
+
`.trim();
|
|
199
|
+
}
|
|
200
|
+
default:
|
|
201
|
+
throw new Error(`Unknown element subtype: ${(params as any).subtype}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
case "mode": {
|
|
206
|
+
const formattedName = params.name.charAt(0).toUpperCase() + params.name.slice(1);
|
|
207
|
+
return `
|
|
208
|
+
Make me an astrological report for a person with a preponderance of the ${formattedName} mode in their birth chart.
|
|
209
|
+
${baseFormat}
|
|
210
|
+
`.trim();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
case "hemisphere_east_west":
|
|
214
|
+
case "hemisphere_north_south": {
|
|
215
|
+
const direction = params.name.charAt(0).toUpperCase() + params.name.slice(1);
|
|
216
|
+
const hemisphereType = params.featureType === "hemisphere_east_west" ? "East-West" : "North-South";
|
|
217
|
+
return `
|
|
218
|
+
Make me an astrological report for a person with the ${direction}ern hemisphere emphasized in their birth chart, based on the ${hemisphereType} orientation.
|
|
219
|
+
${baseFormat}
|
|
220
|
+
`.trim();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
default:
|
|
224
|
+
throw new Error(`Unknown feature type in params: ${params}`);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
149
227
|
};
|