import { describe, it, expect, vi, beforeEach } from 'vitest' import { ExternalPluginStore } from '../external-plugin-store' vi.mock('../../../app/capabilities', async importOriginal => ({ ...await importOriginal(), areThirdPartyPluginsEnabled: () => true, })) import { createMockLocalStorage } from './test-utils' describe('CJS require("util") fallback', () => { let store: ExternalPluginStore beforeEach(() => { vi.stubGlobal('URL', { ...URL, createObjectURL: vi.fn((_blob: Blob) => `blob:test-${Date.now()}`), revokeObjectURL: vi.fn(), }) vi.stubGlobal('localStorage', createMockLocalStorage()) store = new ExternalPluginStore() }) it('plugin source using require("util") does not throw', () => { const manifest = { id: 'util-test', name: 'Util Test', author: 'Test', version: '1.0.0', minAppVersion: '0.0.0', description: 'Tests util require', } // This source uses require("util") which Periodic Notes does const source = ` var util = require("util"); var obsidian = require("obsidian"); class TestPlugin extends obsidian.Plugin { onload() { var deprecatedFn = util.deprecate(function() {}, "old method"); } } module.exports = TestPlugin; ` // install() calls createBlobUrl() which wraps the source. // If require("util") throws, the blob execution will fail later. // For this test, we just verify install works (blob creation doesn't fail). expect(() => store.install(manifest, source)).not.toThrow() }) it('evalCjsPlugin with util require resolves to a shim', () => { const source = ` var util = require("util"); module.exports = { hasDeprecate: typeof util.deprecate === 'function' }; ` // We need a require function that handles both 'obsidian' and 'util' // This mirrors what the CJS wrapper should do const utilShim = { deprecate: (fn: Function, _msg: string) => fn, } const moduleObj = { exports: {} as any } const requireFn = (mod: string) => { if (mod === 'obsidian') return {} if (mod === 'util') return utilShim throw new Error(`Cannot require module: ${mod}`) } const fn = new Function('require', 'module', 'exports', source) fn(requireFn, moduleObj, moduleObj.exports) expect(moduleObj.exports.hasDeprecate).toBe(true) }) })