node-yahoo-finance2 icon indicating copy to clipboard operation
node-yahoo-finance2 copied to clipboard

esgScore module support request

Open arthurwolf opened this issue 4 months ago • 6 comments

Feature Request

Wanted Feature

I can pass a bunch of modules to quoteSummary:

const all_modules = [
            'assetProfile',
            'summaryProfile',
            'summaryDetail',
            'defaultKeyStatistics',
            'financialData',
            'calendarEvents',
            'earnings',
            'earningsHistory',
            'earningsTrend',
            'recommendationTrend',
            'upgradeDowngradeHistory',
            'insiderHolders',
            'insiderTransactions',
            'institutionOwnership',
            'majorHoldersBreakdown',
            'balanceSheetHistory',
            'balanceSheetHistoryQuarterly',
            'cashflowStatementHistory',
            'cashflowStatementHistoryQuarterly',
            'incomeStatementHistory',
            'incomeStatementHistoryQuarterly',
            'netSharePurchaseActivity',
            'secFilings',
            'fundOwnership',
            'fundPerformance',
            'fundProfile',
            'indexTrend',
            'industryTrend',
            'majorDirectHolders',
            'price',
            'quoteType',
            'sectorTrend',
            'topHoldings'
];

However, i've found that there is a module for "ESG" scores (on the API side), but if I try to use it, the library refuses at some sort of "validation" step.

Is there some way to "force" a module through?

Or a recommended way to add support?

Could I do a PR to add support for it?

Or is there some other recommended way to get this to work?

For reference here's how the actual page itself gets it:

<script type = "application/json" data-sveltekit-fetched data-url = "https://query1.finance.yahoo.com/v10/finance/quoteSummary/AAPL?formatted=true&amp;modules=esgScores%2Cprice%2CsummaryDetail%2CpageViews%2CfinancialsTemplate%2CquoteUnadjustedPerformanceOverview&amp;enablePrivateCompany=true&amp;overnightPrice=true&amp;lang=en-US&amp;region=US&amp;crumb=c.re1X5t1hw" data-ttl = "0">

Any recommendation would be very welcome.

Thank you!

Use Cases

Get the ESG data.

Potential Example Usage

This feature could be used in the following way:

const YahooFinance = require('yahoo-finance2').default;
const yf = new YahooFinance();
const esgData = await yf.quoteSummary('AAPL', { modules: ['esgScores'] });
console.log(esgData.quoteSummary.result[0].esgScores);

arthurwolf avatar Aug 26 '25 22:08 arthurwolf

Note: got it to work using this patch:

diff --git a/node_modules/yahoo-finance2/dist/esm/src/modules/quoteSummary.js b/node_modules/yahoo-finance2/dist/esm/src/modules/quoteSummary.js
--- a/node_modules/yahoo-finance2/dist/esm/src/modules/quoteSummary.js
+++ b/node_modules/yahoo-finance2/dist/esm/src/modules/quoteSummary.js
@@ -1,12 +1,14 @@
-    Type.Literal("upgradeDowngradeHistory"),
+    Type.Literal("upgradeDowngradeHistory"),
+    Type.Literal("esgScores"),
 ]
 
@@ -1,12 +1,14 @@
-  "upgradeDowngradeHistory",
+  "upgradeDowngradeHistory",
+  "esgScores",
 ]
 
diff --git a/node_modules/yahoo-finance2/dist/cjs/src/modules/quoteSummary.js b/node_modules/yahoo-finance2/dist/cjs/src/modules/quoteSummary.js
--- a/node_modules/yahoo-finance2/dist/cjs/src/modules/quoteSummary.js
+++ b/node_modules/yahoo-finance2/dist/cjs/src/modules/quoteSummary.js
@@ -1,12 +1,14 @@
-    typebox_1.Type.Literal("upgradeDowngradeHistory"),
+    typebox_1.Type.Literal("upgradeDowngradeHistory"),
+    typebox_1.Type.Literal("esgScores"),
 ]
 
@@ -1,12 +1,14 @@
-  "upgradeDowngradeHistory",
+  "upgradeDowngradeHistory",
+  "esgScores",
 ]

or


#!/usr/bin/env bun

/**
 * Patch script to add ESG Scores support to yahoo-finance2 library
 * 
 * This script modifies the yahoo-finance2 module in node_modules to add
 * support for the 'esgScores' module which exists in Yahoo's API but is
 * not officially supported by the library.
 * 
 * Run this after npm/yarn install to re-apply the patch.
 * 
 * Usage: bun run src/scripts/fix/patch-yahoo-finance2-esg.ts
 */

import * as fs from 'fs';
import * as path from 'path';

// Define the files to patch
const files_to_patch = [
    'node_modules/yahoo-finance2/dist/cjs/src/modules/quoteSummary.js',
    'node_modules/yahoo-finance2/dist/esm/src/modules/quoteSummary.js'
];

// Function to patch a file
async function patch_file(file_path: string) {
    const full_path = path.resolve(file_path);
    
    // Check if file exists
    if (!fs.existsSync(full_path)) {
        console.log(`⚠️  File not found: ${file_path}`);
        return false;
    }
    
    // Read the file
    let content = await Bun.file(full_path).text();
    const original_content = content;
    
    // Check if already patched
    if (content.includes('esgScores')) {
        console.log(`✅ Already patched: ${file_path}`);
        return true;
    }
    
    // Determine the Type/typebox syntax based on the file type
    const is_esm = file_path.includes('/esm/');
    const type_prefix = is_esm ? 'Type.' : 'typebox_1.Type.';
    
    // Patch 1: Add to Type.Union array
    const union_pattern = new RegExp(
        `(${type_prefix}Literal\\("upgradeDowngradeHistory"\\),)(\\s*\\])`
    );
    
    if (union_pattern.test(content)) {
        content = content.replace(
            union_pattern,
            `$1\n    ${type_prefix}Literal("esgScores"),$2`
        );
        console.log(`  ✓ Added esgScores to Type.Union`);
    } else {
        console.log(`  ⚠️  Could not find Type.Union pattern to patch`);
    }
    
    // Patch 2: Add to quoteSummaryModules array
    const array_pattern = /"upgradeDowngradeHistory",(\s*\])/;
    
    if (array_pattern.test(content)) {
        content = content.replace(
            array_pattern,
            '"upgradeDowngradeHistory",\n    "esgScores",$1'
        );
        console.log(`  ✓ Added esgScores to modules array`);
    } else {
        console.log(`  ⚠️  Could not find modules array pattern to patch`);
    }
    
    // Check if anything was patched
    if (content === original_content) {
        console.log(`❌ Failed to patch: ${file_path}`);
        return false;
    }
    
    // Write the patched file
    await Bun.write(full_path, content);
    console.log(`✅ Successfully patched: ${file_path}`);
    return true;
}

// Main function
async function main() {
    console.log('🔧 Patching yahoo-finance2 to support ESG Scores\n');
    console.log('=' .repeat(60));
    
    let success_count = 0;
    let total_count = files_to_patch.length;
    
    for (const file_path of files_to_patch) {
        console.log(`\n📁 Processing: ${file_path}`);
        const success = await patch_file(file_path);
        if (success) success_count++;
    }
    
    console.log('\n' + '=' .repeat(60));
    console.log(`\n📊 Results: ${success_count}/${total_count} files patched successfully`);
    
    if (success_count === total_count) {
        console.log('✅ All patches applied successfully!');
        console.log('\nYou can now use the esgScores module in yahoo-finance2:');
        console.log(`  const data = await yahooFinance.quoteSummary('AAPL', { modules: ['esgScores'] });`);
    } else if (success_count > 0) {
        console.log('⚠️  Some patches were applied, but not all files were patched.');
        console.log('The library may not work correctly.');
    } else {
        console.log('❌ No patches were applied. Please check if yahoo-finance2 is installed.');
    }
    
}

// Run the script
main().catch(console.error);

Is this the correct way to do this, and if so, is this worth a PR?

arthurwolf avatar Aug 26 '25 22:08 arthurwolf

Ah wow... you've been busy! Thanks!! 🙏😁

Yes, a PR would be amazing. A few comments:

  1. The dev branch is already the v3 code, so the codebase will look a little different than from v2, e.g. no more typebox. The single source of truth are the typescript interfaces, and then there's a script to re-generate the JSON schemas used for validation. More useful info on this and other important things in https://github.com/gadicc/yahoo-finance2/blob/dev/CONTRIBUTING.md.

  2. Just adding the one type literal for esgScores worked in a patched dist release because we have less strict rules there, i.e. allowing { additionalProperties: true }, whereas in the dev environment, we're stricter and make sure that everything is covered with an appropriate typescript interface for better DX. This usually involves adding a test for it (e.g. in quoteSummary.test.ts), and then making sure the interface covers all the fields.

  3. Because quoteSummary module in particular is so big, we host the actual interfaces in quoteSummary-iface.ts.

With all that in mind, would you still be interested in submitting a PR? If so, I'll be available for any questions, and will be very happy to improve anything in the CONTRIBUTING file that's not crystal clear. If not, that's fine too, and I'll get to this when I have a chance.

gadicc avatar Aug 27 '25 09:08 gadicc

So I should do my PR against the dev branch right?

I'll make an attempt, will probably be a bit of a mess but hopefully you can walk me through anything I missed.

arthurwolf avatar Sep 08 '25 13:09 arthurwolf

That would be amazing! Please don't hesitate to be in touch with any questions... v3 is very new, and I'd love to make onboarding easy. I'll use your feedback to improve things for both you and future contributors :)

gadicc avatar Sep 08 '25 13:09 gadicc

Ok I made an attempt at https://github.com/gadicc/yahoo-finance2/pull/956 please tell me what needs to be changed etc...

arthurwolf avatar Sep 08 '25 13:09 arthurwolf

Oh wow, brilliant! I just left the office, will try take a look at this a bit later but might only get a chance tomorrow. Sorry about that. And thanks so much 🙏

-- Sent by mobile. Please excuse brevity.

On Mon, Sep 8, 2025, 14:57 Arthur Wolf @.***> wrote:

arthurwolf left a comment (gadicc/yahoo-finance2#952) https://github.com/gadicc/yahoo-finance2/issues/952#issuecomment-3266463947

Ok I made an attempt at #956 https://github.com/gadicc/yahoo-finance2/pull/956 please tell me what needs to be changed etc...

— Reply to this email directly, view it on GitHub https://github.com/gadicc/yahoo-finance2/issues/952#issuecomment-3266463947, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAC5IGQBAGQID6SIAGEGXG33RWDNVAVCNFSM6AAAAACE4OF6M6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTENRWGQ3DGOJUG4 . You are receiving this because you commented.Message ID: @.***>

gadicc avatar Sep 08 '25 14:09 gadicc