@jam-nodes/nodes 0.1.2 → 0.2.0

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.
Files changed (93) hide show
  1. package/dist/ai/analyze-posts.d.ts +175 -0
  2. package/dist/ai/analyze-posts.d.ts.map +1 -0
  3. package/dist/ai/analyze-posts.js +172 -0
  4. package/dist/ai/analyze-posts.js.map +1 -0
  5. package/dist/ai/draft-emails.d.ts +45 -0
  6. package/dist/ai/draft-emails.d.ts.map +1 -0
  7. package/dist/ai/draft-emails.js +134 -0
  8. package/dist/ai/draft-emails.js.map +1 -0
  9. package/dist/ai/index.d.ts +4 -0
  10. package/dist/ai/index.d.ts.map +1 -0
  11. package/dist/ai/index.js +4 -0
  12. package/dist/ai/index.js.map +1 -0
  13. package/dist/ai/keyword-generator.d.ts +37 -0
  14. package/dist/ai/keyword-generator.d.ts.map +1 -0
  15. package/dist/ai/keyword-generator.js +124 -0
  16. package/dist/ai/keyword-generator.js.map +1 -0
  17. package/dist/index.d.ts +323 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +29 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/integrations/apollo/index.d.ts +2 -0
  22. package/dist/integrations/apollo/index.d.ts.map +1 -0
  23. package/dist/integrations/apollo/index.js +2 -0
  24. package/dist/integrations/apollo/index.js.map +1 -0
  25. package/dist/integrations/apollo/search-contacts.d.ts +158 -0
  26. package/dist/integrations/apollo/search-contacts.d.ts.map +1 -0
  27. package/dist/integrations/apollo/search-contacts.js +161 -0
  28. package/dist/integrations/apollo/search-contacts.js.map +1 -0
  29. package/dist/integrations/dataforseo/index.d.ts +3 -0
  30. package/dist/integrations/dataforseo/index.d.ts.map +1 -0
  31. package/dist/integrations/dataforseo/index.js +3 -0
  32. package/dist/integrations/dataforseo/index.js.map +1 -0
  33. package/dist/integrations/dataforseo/keyword-research.d.ts +96 -0
  34. package/dist/integrations/dataforseo/keyword-research.d.ts.map +1 -0
  35. package/dist/integrations/dataforseo/keyword-research.js +115 -0
  36. package/dist/integrations/dataforseo/keyword-research.js.map +1 -0
  37. package/dist/integrations/dataforseo/seo-audit.d.ts +257 -0
  38. package/dist/integrations/dataforseo/seo-audit.d.ts.map +1 -0
  39. package/dist/integrations/dataforseo/seo-audit.js +266 -0
  40. package/dist/integrations/dataforseo/seo-audit.js.map +1 -0
  41. package/dist/integrations/index.d.ts +5 -0
  42. package/dist/integrations/index.d.ts.map +1 -0
  43. package/dist/integrations/index.js +9 -0
  44. package/dist/integrations/index.js.map +1 -0
  45. package/dist/integrations/openai/index.d.ts +2 -0
  46. package/dist/integrations/openai/index.d.ts.map +1 -0
  47. package/dist/integrations/openai/index.js +2 -0
  48. package/dist/integrations/openai/index.js.map +1 -0
  49. package/dist/integrations/openai/sora-video.d.ts +89 -0
  50. package/dist/integrations/openai/sora-video.d.ts.map +1 -0
  51. package/dist/integrations/openai/sora-video.js +93 -0
  52. package/dist/integrations/openai/sora-video.js.map +1 -0
  53. package/dist/integrations/social/index.d.ts +4 -0
  54. package/dist/integrations/social/index.d.ts.map +1 -0
  55. package/dist/integrations/social/index.js +4 -0
  56. package/dist/integrations/social/index.js.map +1 -0
  57. package/dist/integrations/social/linkedin-monitor.d.ts +166 -0
  58. package/dist/integrations/social/linkedin-monitor.d.ts.map +1 -0
  59. package/dist/integrations/social/linkedin-monitor.js +167 -0
  60. package/dist/integrations/social/linkedin-monitor.js.map +1 -0
  61. package/dist/integrations/social/reddit-monitor.d.ts +177 -0
  62. package/dist/integrations/social/reddit-monitor.d.ts.map +1 -0
  63. package/dist/integrations/social/reddit-monitor.js +162 -0
  64. package/dist/integrations/social/reddit-monitor.js.map +1 -0
  65. package/dist/integrations/social/twitter-monitor.d.ts +186 -0
  66. package/dist/integrations/social/twitter-monitor.d.ts.map +1 -0
  67. package/dist/integrations/social/twitter-monitor.js +174 -0
  68. package/dist/integrations/social/twitter-monitor.js.map +1 -0
  69. package/dist/prompts/analyze-posts.d.ts +31 -0
  70. package/dist/prompts/analyze-posts.d.ts.map +1 -0
  71. package/dist/prompts/analyze-posts.js +87 -0
  72. package/dist/prompts/analyze-posts.js.map +1 -0
  73. package/dist/prompts/draft-emails.d.ts +19 -0
  74. package/dist/prompts/draft-emails.d.ts.map +1 -0
  75. package/dist/prompts/draft-emails.js +117 -0
  76. package/dist/prompts/draft-emails.js.map +1 -0
  77. package/dist/prompts/index.d.ts +4 -0
  78. package/dist/prompts/index.d.ts.map +1 -0
  79. package/dist/prompts/index.js +7 -0
  80. package/dist/prompts/index.js.map +1 -0
  81. package/dist/prompts/keyword-generator.d.ts +17 -0
  82. package/dist/prompts/keyword-generator.d.ts.map +1 -0
  83. package/dist/prompts/keyword-generator.js +61 -0
  84. package/dist/prompts/keyword-generator.js.map +1 -0
  85. package/dist/schemas/ai.d.ts +1212 -0
  86. package/dist/schemas/ai.d.ts.map +1 -0
  87. package/dist/schemas/ai.js +119 -0
  88. package/dist/schemas/ai.js.map +1 -0
  89. package/dist/schemas/index.d.ts +2 -0
  90. package/dist/schemas/index.d.ts.map +1 -0
  91. package/dist/schemas/index.js +9 -0
  92. package/dist/schemas/index.js.map +1 -0
  93. package/package.json +14 -6
@@ -0,0 +1,158 @@
1
+ import { z } from 'zod';
2
+ export declare const SearchContactsInputSchema: z.ZodObject<{
3
+ /** Job titles to search for */
4
+ personTitles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5
+ /** Person locations (cities/countries) */
6
+ personLocations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
+ /** Organization locations */
8
+ organizationLocations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
9
+ /** Company employee count ranges (e.g., "1-10", "11-50") */
10
+ employeeRanges: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
11
+ /** Keywords for search */
12
+ keywords: z.ZodOptional<z.ZodString>;
13
+ /** Maximum number of contacts to return */
14
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
15
+ /** Include similar job titles */
16
+ includeSimilarTitles: z.ZodOptional<z.ZodBoolean>;
17
+ /** Seniority levels (e.g., "vp", "director", "manager") */
18
+ personSeniorities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
19
+ /** Technologies used by the company */
20
+ technologies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
+ /** Industry tag IDs */
22
+ industryTagIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ /** Departments (e.g., "engineering", "sales") */
24
+ departments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ limit: number;
27
+ keywords?: string | undefined;
28
+ personTitles?: string[] | undefined;
29
+ personLocations?: string[] | undefined;
30
+ organizationLocations?: string[] | undefined;
31
+ employeeRanges?: string[] | undefined;
32
+ includeSimilarTitles?: boolean | undefined;
33
+ personSeniorities?: string[] | undefined;
34
+ technologies?: string[] | undefined;
35
+ industryTagIds?: string[] | undefined;
36
+ departments?: string[] | undefined;
37
+ }, {
38
+ keywords?: string | undefined;
39
+ limit?: number | undefined;
40
+ personTitles?: string[] | undefined;
41
+ personLocations?: string[] | undefined;
42
+ organizationLocations?: string[] | undefined;
43
+ employeeRanges?: string[] | undefined;
44
+ includeSimilarTitles?: boolean | undefined;
45
+ personSeniorities?: string[] | undefined;
46
+ technologies?: string[] | undefined;
47
+ industryTagIds?: string[] | undefined;
48
+ departments?: string[] | undefined;
49
+ }>;
50
+ export type SearchContactsInput = z.infer<typeof SearchContactsInputSchema>;
51
+ export declare const SearchContactsOutputSchema: z.ZodObject<{
52
+ contacts: z.ZodArray<z.ZodObject<{
53
+ id: z.ZodString;
54
+ name: z.ZodString;
55
+ firstName: z.ZodOptional<z.ZodString>;
56
+ lastName: z.ZodOptional<z.ZodString>;
57
+ email: z.ZodString;
58
+ title: z.ZodOptional<z.ZodString>;
59
+ company: z.ZodString;
60
+ linkedinUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
61
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
62
+ }, "strip", z.ZodTypeAny, {
63
+ id: string;
64
+ company: string;
65
+ name: string;
66
+ email: string;
67
+ title?: string | undefined;
68
+ firstName?: string | undefined;
69
+ lastName?: string | undefined;
70
+ linkedinUrl?: string | null | undefined;
71
+ location?: string | null | undefined;
72
+ }, {
73
+ id: string;
74
+ company: string;
75
+ name: string;
76
+ email: string;
77
+ title?: string | undefined;
78
+ firstName?: string | undefined;
79
+ lastName?: string | undefined;
80
+ linkedinUrl?: string | null | undefined;
81
+ location?: string | null | undefined;
82
+ }>, "many">;
83
+ totalFound: z.ZodNumber;
84
+ }, "strip", z.ZodTypeAny, {
85
+ totalFound: number;
86
+ contacts: {
87
+ id: string;
88
+ company: string;
89
+ name: string;
90
+ email: string;
91
+ title?: string | undefined;
92
+ firstName?: string | undefined;
93
+ lastName?: string | undefined;
94
+ linkedinUrl?: string | null | undefined;
95
+ location?: string | null | undefined;
96
+ }[];
97
+ }, {
98
+ totalFound: number;
99
+ contacts: {
100
+ id: string;
101
+ company: string;
102
+ name: string;
103
+ email: string;
104
+ title?: string | undefined;
105
+ firstName?: string | undefined;
106
+ lastName?: string | undefined;
107
+ linkedinUrl?: string | null | undefined;
108
+ location?: string | null | undefined;
109
+ }[];
110
+ }>;
111
+ export type SearchContactsOutput = z.infer<typeof SearchContactsOutputSchema>;
112
+ /**
113
+ * Search Contacts Node
114
+ *
115
+ * Searches for contacts using Apollo.io API with email enrichment.
116
+ * Requires `context.services.apollo` to be provided by the host application.
117
+ *
118
+ * Process:
119
+ * 1. Search Apollo for contacts matching criteria
120
+ * 2. Enrich contacts to reveal email addresses
121
+ * 3. Return contacts with verified emails
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * const result = await searchContactsNode.executor({
126
+ * personTitles: ['CTO', 'VP Engineering'],
127
+ * personLocations: ['San Francisco'],
128
+ * limit: 25
129
+ * }, context);
130
+ * ```
131
+ */
132
+ export declare const searchContactsNode: import("@jam-nodes/core").NodeDefinition<{
133
+ keywords?: string | undefined;
134
+ limit?: number | undefined;
135
+ personTitles?: string[] | undefined;
136
+ personLocations?: string[] | undefined;
137
+ organizationLocations?: string[] | undefined;
138
+ employeeRanges?: string[] | undefined;
139
+ includeSimilarTitles?: boolean | undefined;
140
+ personSeniorities?: string[] | undefined;
141
+ technologies?: string[] | undefined;
142
+ industryTagIds?: string[] | undefined;
143
+ departments?: string[] | undefined;
144
+ }, {
145
+ totalFound: number;
146
+ contacts: {
147
+ id: string;
148
+ company: string;
149
+ name: string;
150
+ email: string;
151
+ title?: string | undefined;
152
+ firstName?: string | undefined;
153
+ lastName?: string | undefined;
154
+ linkedinUrl?: string | null | undefined;
155
+ location?: string | null | undefined;
156
+ }[];
157
+ }>;
158
+ //# sourceMappingURL=search-contacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-contacts.d.ts","sourceRoot":"","sources":["../../../src/integrations/apollo/search-contacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,yBAAyB;IACpC,+BAA+B;;IAE/B,0CAA0C;;IAE1C,6BAA6B;;IAE7B,4DAA4D;;IAE5D,0BAA0B;;IAE1B,2CAA2C;;IAE3C,iCAAiC;;IAEjC,2DAA2D;;IAE3D,uCAAuC;;IAEvC,uBAAuB;;IAEvB,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;EAEjD,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAarC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;EA4G7B,CAAC"}
@@ -0,0 +1,161 @@
1
+ import { z } from 'zod';
2
+ import { defineNode } from '@jam-nodes/core';
3
+ // =============================================================================
4
+ // Schemas
5
+ // =============================================================================
6
+ export const SearchContactsInputSchema = z.object({
7
+ /** Job titles to search for */
8
+ personTitles: z.array(z.string()).optional(),
9
+ /** Person locations (cities/countries) */
10
+ personLocations: z.array(z.string()).optional(),
11
+ /** Organization locations */
12
+ organizationLocations: z.array(z.string()).optional(),
13
+ /** Company employee count ranges (e.g., "1-10", "11-50") */
14
+ employeeRanges: z.array(z.string()).optional(),
15
+ /** Keywords for search */
16
+ keywords: z.string().optional(),
17
+ /** Maximum number of contacts to return */
18
+ limit: z.number().optional().default(10),
19
+ /** Include similar job titles */
20
+ includeSimilarTitles: z.boolean().optional(),
21
+ /** Seniority levels (e.g., "vp", "director", "manager") */
22
+ personSeniorities: z.array(z.string()).optional(),
23
+ /** Technologies used by the company */
24
+ technologies: z.array(z.string()).optional(),
25
+ /** Industry tag IDs */
26
+ industryTagIds: z.array(z.string()).optional(),
27
+ /** Departments (e.g., "engineering", "sales") */
28
+ departments: z.array(z.string()).optional(),
29
+ });
30
+ export const SearchContactsOutputSchema = z.object({
31
+ contacts: z.array(z.object({
32
+ id: z.string(),
33
+ name: z.string(),
34
+ firstName: z.string().optional(),
35
+ lastName: z.string().optional(),
36
+ email: z.string(),
37
+ title: z.string().optional(),
38
+ company: z.string(),
39
+ linkedinUrl: z.string().nullable().optional(),
40
+ location: z.string().nullable().optional(),
41
+ })),
42
+ totalFound: z.number(),
43
+ });
44
+ // =============================================================================
45
+ // Node Definition
46
+ // =============================================================================
47
+ /**
48
+ * Search Contacts Node
49
+ *
50
+ * Searches for contacts using Apollo.io API with email enrichment.
51
+ * Requires `context.services.apollo` to be provided by the host application.
52
+ *
53
+ * Process:
54
+ * 1. Search Apollo for contacts matching criteria
55
+ * 2. Enrich contacts to reveal email addresses
56
+ * 3. Return contacts with verified emails
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const result = await searchContactsNode.executor({
61
+ * personTitles: ['CTO', 'VP Engineering'],
62
+ * personLocations: ['San Francisco'],
63
+ * limit: 25
64
+ * }, context);
65
+ * ```
66
+ */
67
+ export const searchContactsNode = defineNode({
68
+ type: 'search_contacts',
69
+ name: 'Search Contacts',
70
+ description: 'Search for contacts using Apollo.io People Search API',
71
+ category: 'integration',
72
+ inputSchema: SearchContactsInputSchema,
73
+ outputSchema: SearchContactsOutputSchema,
74
+ estimatedDuration: 5,
75
+ capabilities: {
76
+ supportsEnrichment: true,
77
+ supportsBulkActions: true,
78
+ supportsRerun: true,
79
+ },
80
+ executor: async (input, context) => {
81
+ try {
82
+ // Require Apollo service
83
+ if (!context.services?.apollo) {
84
+ return {
85
+ success: false,
86
+ error: 'Apollo service not configured. Please provide context.services.apollo.',
87
+ };
88
+ }
89
+ // Search contacts
90
+ const results = await context.services.apollo.searchContacts({
91
+ personTitles: input.personTitles,
92
+ personLocations: input.personLocations,
93
+ organizationLocations: input.organizationLocations,
94
+ keywords: input.keywords,
95
+ limit: Math.min(input.limit || 10, 100),
96
+ personSeniorities: input.personSeniorities,
97
+ technologies: input.technologies,
98
+ });
99
+ if (results.length === 0) {
100
+ return {
101
+ success: true,
102
+ output: {
103
+ contacts: [],
104
+ totalFound: 0,
105
+ },
106
+ };
107
+ }
108
+ // Enrich contacts to get emails
109
+ const enrichedContacts = [];
110
+ for (const contact of results) {
111
+ if (contact.id) {
112
+ try {
113
+ const enriched = await context.services.apollo.enrichContact(contact.id);
114
+ if (enriched.email) {
115
+ enrichedContacts.push({
116
+ id: enriched.id,
117
+ name: enriched.name,
118
+ firstName: enriched.firstName,
119
+ lastName: enriched.lastName,
120
+ email: enriched.email,
121
+ title: enriched.title,
122
+ company: enriched.company,
123
+ linkedinUrl: enriched.linkedinUrl,
124
+ location: enriched.location,
125
+ });
126
+ }
127
+ }
128
+ catch {
129
+ // Skip contacts that fail to enrich
130
+ }
131
+ }
132
+ }
133
+ // Transform to output format
134
+ const contacts = enrichedContacts.map(person => ({
135
+ id: person.id,
136
+ name: person.name,
137
+ firstName: person.firstName,
138
+ lastName: person.lastName,
139
+ email: person.email,
140
+ title: person.title,
141
+ company: person.company || 'Unknown',
142
+ linkedinUrl: person.linkedinUrl || null,
143
+ location: person.location || null,
144
+ }));
145
+ return {
146
+ success: true,
147
+ output: {
148
+ contacts,
149
+ totalFound: results.length,
150
+ },
151
+ };
152
+ }
153
+ catch (error) {
154
+ return {
155
+ success: false,
156
+ error: error instanceof Error ? error.message : 'Failed to search contacts',
157
+ };
158
+ }
159
+ },
160
+ });
161
+ //# sourceMappingURL=search-contacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-contacts.js","sourceRoot":"","sources":["../../../src/integrations/apollo/search-contacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { seoKeywordResearchNode, SeoKeywordResearchInputSchema, SeoKeywordResearchOutputSchema, type SeoKeywordResearchInput, type SeoKeywordResearchOutput, } from './keyword-research';
2
+ export { seoAuditNode, SeoAuditInputSchema, SeoAuditOutputSchema, type SeoAuditInput, type SeoAuditOutput, type SeoIssue, } from './seo-audit';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/dataforseo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,8BAA8B,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,QAAQ,GACd,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { seoKeywordResearchNode, SeoKeywordResearchInputSchema, SeoKeywordResearchOutputSchema, } from './keyword-research';
2
+ export { seoAuditNode, SeoAuditInputSchema, SeoAuditOutputSchema, } from './seo-audit';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/dataforseo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,8BAA8B,GAG/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,GAIrB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { z } from 'zod';
2
+ export declare const SeoKeywordResearchInputSchema: z.ZodObject<{
3
+ /** Seed keywords to research */
4
+ seedKeywords: z.ZodArray<z.ZodString, "many">;
5
+ /** Location code (default: 2840 = US) */
6
+ locationCode: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
7
+ /** Language code (default: 'en') */
8
+ languageCode: z.ZodDefault<z.ZodOptional<z.ZodString>>;
9
+ /** Maximum keywords to return per seed */
10
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ limit: number;
13
+ seedKeywords: string[];
14
+ locationCode: number;
15
+ languageCode: string;
16
+ }, {
17
+ seedKeywords: string[];
18
+ limit?: number | undefined;
19
+ locationCode?: number | undefined;
20
+ languageCode?: string | undefined;
21
+ }>;
22
+ export type SeoKeywordResearchInput = z.infer<typeof SeoKeywordResearchInputSchema>;
23
+ export declare const SeoKeywordResearchOutputSchema: z.ZodObject<{
24
+ keywords: z.ZodArray<z.ZodObject<{
25
+ keyword: z.ZodString;
26
+ searchVolume: z.ZodNumber;
27
+ keywordDifficulty: z.ZodNumber;
28
+ cpc: z.ZodString;
29
+ searchIntent: z.ZodEnum<["informational", "commercial", "navigational", "transactional"]>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ keyword: string;
32
+ searchVolume: number;
33
+ keywordDifficulty: number;
34
+ cpc: string;
35
+ searchIntent: "informational" | "commercial" | "navigational" | "transactional";
36
+ }, {
37
+ keyword: string;
38
+ searchVolume: number;
39
+ keywordDifficulty: number;
40
+ cpc: string;
41
+ searchIntent: "informational" | "commercial" | "navigational" | "transactional";
42
+ }>, "many">;
43
+ totalResearched: z.ZodNumber;
44
+ }, "strip", z.ZodTypeAny, {
45
+ keywords: {
46
+ keyword: string;
47
+ searchVolume: number;
48
+ keywordDifficulty: number;
49
+ cpc: string;
50
+ searchIntent: "informational" | "commercial" | "navigational" | "transactional";
51
+ }[];
52
+ totalResearched: number;
53
+ }, {
54
+ keywords: {
55
+ keyword: string;
56
+ searchVolume: number;
57
+ keywordDifficulty: number;
58
+ cpc: string;
59
+ searchIntent: "informational" | "commercial" | "navigational" | "transactional";
60
+ }[];
61
+ totalResearched: number;
62
+ }>;
63
+ export type SeoKeywordResearchOutput = z.infer<typeof SeoKeywordResearchOutputSchema>;
64
+ /**
65
+ * SEO Keyword Research Node
66
+ *
67
+ * Takes seed keywords and enriches them with search volume, keyword difficulty,
68
+ * CPC, and search intent data using DataForSEO API.
69
+ *
70
+ * Requires `context.services.dataForSeo` to be provided by the host application.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const result = await seoKeywordResearchNode.executor({
75
+ * seedKeywords: ['typescript tutorial', 'nodejs best practices'],
76
+ * locationCode: 2840, // US
77
+ * limit: 20
78
+ * }, context);
79
+ * ```
80
+ */
81
+ export declare const seoKeywordResearchNode: import("@jam-nodes/core").NodeDefinition<{
82
+ seedKeywords: string[];
83
+ limit?: number | undefined;
84
+ locationCode?: number | undefined;
85
+ languageCode?: string | undefined;
86
+ }, {
87
+ keywords: {
88
+ keyword: string;
89
+ searchVolume: number;
90
+ keywordDifficulty: number;
91
+ cpc: string;
92
+ searchIntent: "informational" | "commercial" | "navigational" | "transactional";
93
+ }[];
94
+ totalResearched: number;
95
+ }>;
96
+ //# sourceMappingURL=keyword-research.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-research.d.ts","sourceRoot":"","sources":["../../../src/integrations/dataforseo/keyword-research.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,6BAA6B;IACxC,gCAAgC;;IAEhC,yCAAyC;;IAEzC,oCAAoC;;IAEpC,0CAA0C;;;;;;;;;;;;EAE1C,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASzC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAMtF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;EA2EjC,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { z } from 'zod';
2
+ import { defineNode } from '@jam-nodes/core';
3
+ // =============================================================================
4
+ // Schemas
5
+ // =============================================================================
6
+ export const SeoKeywordResearchInputSchema = z.object({
7
+ /** Seed keywords to research */
8
+ seedKeywords: z.array(z.string()),
9
+ /** Location code (default: 2840 = US) */
10
+ locationCode: z.number().optional().default(2840),
11
+ /** Language code (default: 'en') */
12
+ languageCode: z.string().optional().default('en'),
13
+ /** Maximum keywords to return per seed */
14
+ limit: z.number().optional().default(30),
15
+ });
16
+ export const SeoKeywordResearchOutputSchema = z.object({
17
+ keywords: z.array(z.object({
18
+ keyword: z.string(),
19
+ searchVolume: z.number(),
20
+ keywordDifficulty: z.number(),
21
+ cpc: z.string(),
22
+ searchIntent: z.enum(['informational', 'commercial', 'navigational', 'transactional']),
23
+ })),
24
+ totalResearched: z.number(),
25
+ });
26
+ // =============================================================================
27
+ // Node Definition
28
+ // =============================================================================
29
+ /**
30
+ * SEO Keyword Research Node
31
+ *
32
+ * Takes seed keywords and enriches them with search volume, keyword difficulty,
33
+ * CPC, and search intent data using DataForSEO API.
34
+ *
35
+ * Requires `context.services.dataForSeo` to be provided by the host application.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const result = await seoKeywordResearchNode.executor({
40
+ * seedKeywords: ['typescript tutorial', 'nodejs best practices'],
41
+ * locationCode: 2840, // US
42
+ * limit: 20
43
+ * }, context);
44
+ * ```
45
+ */
46
+ export const seoKeywordResearchNode = defineNode({
47
+ type: 'seo_keyword_research',
48
+ name: 'Keyword Research',
49
+ description: 'Research keywords to get search volume, difficulty, and intent data',
50
+ category: 'integration',
51
+ inputSchema: SeoKeywordResearchInputSchema,
52
+ outputSchema: SeoKeywordResearchOutputSchema,
53
+ estimatedDuration: 10,
54
+ capabilities: {
55
+ supportsRerun: true,
56
+ },
57
+ executor: async (input, context) => {
58
+ try {
59
+ // Require DataForSEO service
60
+ if (!context.services?.dataForSeo) {
61
+ return {
62
+ success: false,
63
+ error: 'DataForSEO service not configured. Please provide context.services.dataForSeo.',
64
+ };
65
+ }
66
+ const researchedKeywords = [];
67
+ const processedKeywords = new Set();
68
+ // Research each seed keyword
69
+ for (const seedKeyword of input.seedKeywords) {
70
+ if (!seedKeyword.trim())
71
+ continue;
72
+ try {
73
+ const results = await context.services.dataForSeo.getRelatedKeywords([seedKeyword], {
74
+ locationCode: input.locationCode ?? 2840,
75
+ languageCode: input.languageCode ?? 'en',
76
+ limit: input.limit ?? 30,
77
+ });
78
+ for (const kw of results) {
79
+ // Skip duplicates
80
+ if (processedKeywords.has(kw.keyword.toLowerCase()))
81
+ continue;
82
+ processedKeywords.add(kw.keyword.toLowerCase());
83
+ researchedKeywords.push({
84
+ keyword: kw.keyword,
85
+ searchVolume: kw.searchVolume,
86
+ keywordDifficulty: kw.keywordDifficulty,
87
+ cpc: kw.cpc.toString(),
88
+ searchIntent: kw.searchIntent,
89
+ });
90
+ }
91
+ }
92
+ catch (kwError) {
93
+ // Continue with other keywords on individual failures
94
+ console.warn(`Error researching keyword "${seedKeyword}":`, kwError);
95
+ }
96
+ }
97
+ // Sort by search volume descending
98
+ researchedKeywords.sort((a, b) => b.searchVolume - a.searchVolume);
99
+ return {
100
+ success: true,
101
+ output: {
102
+ keywords: researchedKeywords,
103
+ totalResearched: researchedKeywords.length,
104
+ },
105
+ };
106
+ }
107
+ catch (error) {
108
+ return {
109
+ success: false,
110
+ error: error instanceof Error ? error.message : 'Failed to research keywords',
111
+ };
112
+ }
113
+ },
114
+ });
115
+ //# sourceMappingURL=keyword-research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-research.js","sourceRoot":"","sources":["../../../src/integrations/dataforseo/keyword-research.ts"],"names":[],"mappings":"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"}