TypeError: ImgurClient is not a constructor

huangapple go评论56阅读模式
英文:

TypeError: ImgurClient is not a constructor

问题

I have a project in svelte kit, vite and typescript. Part of the project is uploading images to imgur. For that task I use an unofficial library to connect to imgur. Here is the link:
https://github.com/KenEucker/imgur/tree/main

When I run npm run build I get the following output:

    .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)

Here is my uploadPhoto/+page.server.ts for reference:

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;
}



<details>
<summary>英文:</summary>

I have a project in svelte kit, vite and typescript. Part of the project is uploading images to imgur. For that task I use an unofficial library to connect to imgur. Here is the link:
https://github.com/KenEucker/imgur/tree/main

When I run `npm run build` I get the following output:

    	.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.&lt;anonymous&gt; (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)

here is my uploadPhoto/+page.server.ts for reference:

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

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

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

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

						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:&#39;POST&#39;}`);

					} 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=&quot;&quot;;

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

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


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


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


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

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

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

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


			})
		};

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

		if (result.status === &#39;success&#39;) {
			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 }) =&gt; {
		try {
			if (request.method === &#39;POST&#39;) {
				const form = await request.formData();
				const image = form.get(&#39;img&#39;) as File;
				console.log(form.get(&#39;img&#39;));
				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 };
In fewer words, I get error when I initialize the client variable:

    	const client = new ImgurClient({
		accessToken: process.env.TOKEN,
		clientId: process.env.CLIENT_ID,
		clientSecret: process.env.CLIENT_SECRET,
		refreshToken: process.env.REFRESH_TOKEN
	});
The error I get is that ImgurClient is not a constructor. The code works when I run `npm run dev` and I get no errors. 


--------EDIT-------


so my initial goal was to follow the https://vitejs.dev/guide/build.html#building-for-production

vite&#39;s tutorial, but as you already know, I get a lot of errors. After these errors I am starting to search for a solution where I host the site using npm run dev or something similar. Forgot to mention that this is my first time deploying and don&#39;t know anything about it. 

------------NEW EDIT------------
After a research, I come up with a conclusion that this is just a bug with the library. I have changed the implementation to:

    async function uploadToUmgur(file: File) {
	const buffer = Buffer.from(await file.arrayBuffer());
	const base64 = buffer.toString(&#39;base64&#39;);
	let apiUrl = &#39;https://api.imgur.com/3/image&#39;;
	const formData= new FormData();
	formData.append(&quot;image&quot;,base64);
	let link=&quot;&quot;;
	await fetch(apiUrl,{
		method:&quot;post&quot;,
		headers:{
			Authorization: &quot;Client-ID &quot;+process.env.CLIENT_ID
		},
		body:formData
	}).then(data =&gt; data.json()).then(data=&gt;{
		link =data.data.link;
	})
	return link;
    }
so yeah, the lesson is:
not to follow unofficial libraries with little documentation

</details>


# 答案1
**得分**: 1

import { ImgurClient } from 'imgur';

您可以尝试这样写

<details>
<summary>英文:</summary>

    import  ImgurClient from &#39;imgur&#39;;


You are importing the entire module here as one object 

    import { ImgurClient } from &#39;imgur&#39;;


Try this instead.

</details>



huangapple
  • 本文由 发表于 2023年2月18日 02:37:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定