typescript 类型错误:ImgurClient不是构造函数

tpgth1q7  于 2023-02-20  发布在  TypeScript
关注(0)|答案(1)|浏览(227)

我有一个用svelte kit、vite和typescript编写的项目。项目的一部分是上传图片到imgur。为了完成这个任务,我使用了一个非官方的库来连接imgur。下面是链接:https://github.com/KenEucker/imgur/tree/main
当我运行npm run build时,我得到以下输出:

.svelte-kit/output/server/chunks/Offcanvas.svelte_svelte_type_style_lang.js      5.40 kB
.svelte-kit/output/server/chunks/Register.js                                     6.19 kB
.svelte-kit/output/server/entries/pages/_page.svelte.js                          8.41 kB
.svelte-kit/output/server/chunks/index.js                                       11.33 kB
.svelte-kit/output/server/chunks/Login.js                                       14.05 kB
.svelte-kit/output/server/entries/pages/_layout.svelte.js                       18.48 kB
.svelte-kit/output/server/chunks/Portal.js                                      22.35 kB
.svelte-kit/output/server/index.js                                              76.62 kB
.svelte-kit/output/server/entries/pages/atlas/_page.svelte.js                  615.65 kB
file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35
const client = new ImgurClient({
            ^

TypeError: ImgurClient is not a constructor
    at file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35:16
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async Promise.all (index 1)
    at async prerender (file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:370:18)     
[vite-plugin-sveltekit-compile] Prerendering failed with code 1
error during build:
Error: Prerendering failed with code 1
    at ChildProcess.<anonymous> (file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/node_modules/@sveltejs/kit/src/exports/vite/index.js:551:15)  
    at ChildProcess.emit (node:events:513:28)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)

以下是我上传照片/+页面.server.ts以供参考:

import  ImgurClient from 'imgur';
import type { PageServerLoad, Action, Actions } from './$types';
import { mssqlConnection } from '../../db/mssqldb';
import ppkg from 'mssql';
const { Request } = ppkg;
import { v4 as uuidv4 } from 'uuid';
import { fail, redirect } from '@sveltejs/kit';
let username: string;

export const load: PageServerLoad = async ({ locals }) => {
    if (!locals.user) {
        throw redirect(302, 'login');
    } else {
        username = locals.user.username;

        if (process.env.NOVA_KEY) {
            const sessionKey = await fetchAstrometrySessionKey(process.env.NOVA_KEY);
            const data = await submitURL(sessionKey, 'http://apod.nasa.gov/apod/image/1206/ldn673s_block1123.jpg');
            console.log(data);
            const jobResult = await getJobResults(data)

            if (jobResult.status === "success") {
                console.log(jobResult.tags)
                if (jobResult.tags.length) {
                    //post to 3d map
                    console.log("found stars");

                    const dataFor3dMap = await fetchData(jobResult.tags);
                    const maybeJson=JSON.stringify( dataFor3dMap)
                    console.log(maybeJson);
                    await fetch(`http://localhost:5173/atlas/api/findStars?dataMap={${maybeJson}},{method:'POST'}`);

                } else {
                    //no stars found
                    fail(500, { error: false, noStars: true })
                }
            } else {
                //display error 
                //ask the user to send the image again
                fail(500, { error: true, noStars: true })
            }
        }
    }
};

const client = new ImgurClient({
    accessToken: process.env.TOKEN,
    clientId: process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    refreshToken: process.env.REFRESH_TOKEN
});

async function fetchData(starNames: object) {

    let formData="";

    let validStarNames = starNames.filter(starName => {
        return starName.match(/^\w+\s+\d+.*$/g) || starName.startsWith("The star");
    });
    for(let starName in validStarNames){
        
        formData+=await setStarNameAndCoordinates(validStarNames[starName],formData)
    }
    return formData;
}

async function setStarNameAndCoordinates(starName:string,formData:string) {
    if (starName.startsWith("The star")) {
        starName = starName.slice("The star".length).trim();
    }
    starName = starName.replace(/ /g, "+");
    const res = await fetch("https://cds.unistra.fr/cgi-bin/nph-sesame?" + starName);
    starName = starName.replace("+", " ");
    const text = await res.text();
    const row=getDataRow(text)  
    
    
    return `${starName}:${row}`
}

function getDataRow(text: string): string {
    const lines = text.split("\n");
    for (let line of lines) {
        if (line.startsWith("%J")) {
            let index = line.indexOf("=");

            return line.slice(3, index).trim();
        }
    }
    return "";
}

async function saveURL(url: string) {
    const connection = await mssqlConnection();
    const selectRequest = new Request(connection);
    const selectResult = await selectRequest
        .input('Username', username)
        .query('SELECT Id FROM Users WHERE Username = @Username');
    const id = selectResult.recordset[0].Id;
    console.log(id);
    const insertRequest = new Request(connection);
    const insertResult = await insertRequest
        .input('Id', uuidv4())
        .input('UserId', id)
        .input('ImageURL', url)
        .query('INSERT INTO UsersImages(Id, UserId, ImageURL) VALUES(@Id, @UserId, @ImageURL)');
    return insertResult === undefined;
}

async function uploadToUmgur(file: File) {
    const buffer = Buffer.from(await file.arrayBuffer());
    const base64 = buffer.toString('base64');
    const response = await client.upload({
        image: base64,
        type: 'base64'
    });
    console.log(response.data);
    return response.data;
}

async function fetchAstrometrySessionKey(apikey: string) {
    const response = await fetch('http://nova.astrometry.net/api/login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `request-json=${encodeURIComponent(JSON.stringify({ apikey }))}`
    });
    const data = await response.json();
    if (data.status !== 'success') {
        console.log('Could not obtain session key: ' + data.message);
    }
    return data.session;
}

async function submitURL(sessionId: string, url: string) {
    const options = {
        method: 'POST',
        body: new URLSearchParams({
            "request-json": JSON.stringify({
                session: sessionId,
                url: url,
                scale_units: 'degwidth',
                scale_lower: 0.5,
                scale_upper: 1.0,
                center_ra: 290,
                center_dec: 11,
                radius: 2.0
            })

        })
    };

    const response = await fetch('http://nova.astrometry.net/api/url_upload', options);
    const result = await response.json();

    if (result.status === 'success') {
        console.log(`Successful submission: ${result.subid} with hash ${result.hash}`);
        return result.subid;
    } else {
        console.error(result);
        return null;
    }
}

async function getJobResults(jobid: string) {
    const response = await fetch(`https://nova.astrometry.net/api/jobs/${jobid}/info/`);
    return await response.json();
}

const upload: Action = async ({ request }) => {
    try {
        if (request.method === 'POST') {
            const form = await request.formData();
            const image = form.get('img') as File;
            console.log(form.get('img'));
            if (image) {
                console.log(`Received file with name: ${image.name}`);
                const link = (await uploadToUmgur(image)).link;
                console.log(link);
                if (await saveURL(link)) {
                    return link;
                } else {
                    fail(500, { error: true, noStars: false });
                }
            }
        }
    } catch (e) {
        console.log(e);
    }
};

export const actions: Actions = { upload };

简而言之,当我初始化客户端变量时,我得到了错误:

const client = new ImgurClient({
    accessToken: process.env.TOKEN,
    clientId: process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    refreshToken: process.env.REFRESH_TOKEN
});

我得到的错误是ImgurClient不是构造函数。当我运行npm run dev时代码工作正常,没有得到任何错误。
-------编辑--------
所以我最初的目标是跟随https://vitejs.dev/guide/build.html#building-for-production
vite的教程,但正如你已经知道,我得到了很多错误。在这些错误之后,我开始寻找一个解决方案,我主机的网站使用npm运行开发或类似的东西。忘了说,这是我第一次部署,不知道它的任何东西。
-------------新编辑-----------经过研究,我得出结论,这只是库的bug,我已经将实现更改为:

async function uploadToUmgur(file: File) {
const buffer = Buffer.from(await file.arrayBuffer());
const base64 = buffer.toString('base64');
let apiUrl = 'https://api.imgur.com/3/image';
const formData= new FormData();
formData.append("image",base64);
let link="";
await fetch(apiUrl,{
    method:"post",
    headers:{
        Authorization: "Client-ID "+process.env.CLIENT_ID
    },
    body:formData
}).then(data => data.json()).then(data=>{
    link =data.data.link;
})
return link;
}

所以,我们得到的教训是不要跟随那些没有什么文献的非官方图书馆

bvjveswy

bvjveswy1#

import  ImgurClient from 'imgur';

您在此处将整个模块作为一个对象导入

import { ImgurClient } from 'imgur';

试试这个。

相关问题