TypeError: ImgurClient is not a constructor

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

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:

  1. .svelte-kit/output/server/chunks/Offcanvas.svelte_svelte_type_style_lang.js 5.40 kB
  2. .svelte-kit/output/server/chunks/Register.js 6.19 kB
  3. .svelte-kit/output/server/entries/pages/_page.svelte.js 8.41 kB
  4. .svelte-kit/output/server/chunks/index.js 11.33 kB
  5. .svelte-kit/output/server/chunks/Login.js 14.05 kB
  6. .svelte-kit/output/server/entries/pages/_layout.svelte.js 18.48 kB
  7. .svelte-kit/output/server/chunks/Portal.js 22.35 kB
  8. .svelte-kit/output/server/index.js 76.62 kB
  9. .svelte-kit/output/server/entries/pages/atlas/_page.svelte.js 615.65 kB
  10. file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35
  11. const client = new ImgurClient({
  12. ^
  13. TypeError: ImgurClient is not a constructor
  14. at file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35:16
  15. at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
  16. at async Promise.all (index 0)
  17. at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
  18. at async Promise.all (index 1)
  19. at async prerender (file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:370:18)
  20. [vite-plugin-sveltekit-compile] Prerendering failed with code 1
  21. error during build:
  22. Error: Prerendering failed with code 1
  23. at ChildProcess.<anonymous> (file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/node_modules/@sveltejs/kit/src/exports/vite/index.js:551:15)
  24. at ChildProcess.emit (node:events:513:28)
  25. at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)

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

  1. import ImgurClient from 'imgur';
  2. import type { PageServerLoad, Action, Actions } from './$types';
  3. import { mssqlConnection } from '../../db/mssqldb';
  4. import ppkg from 'mssql';
  5. const { Request } = ppkg;
  6. import { v4 as uuidv4 } from 'uuid';
  7. import { fail, redirect } from '@sveltejs/kit';
  8. let username: string;
  9. export const load: PageServerLoad = async ({ locals }) => {
  10. if (!locals.user) {
  11. throw redirect(302, 'login');
  12. } else {
  13. username = locals.user.username;
  14. if (process.env.NOVA_KEY) {
  15. const sessionKey = await fetchAstrometrySessionKey(process.env.NOVA_KEY);
  16. const data = await submitURL(sessionKey, 'http://apod.nasa.gov/apod/image/1206/ldn673s_block1123.jpg');
  17. console.log(data);
  18. const jobResult = await getJobResults(data)
  19. if (jobResult.status === "success") {
  20. console.log(jobResult.tags)
  21. if (jobResult.tags.length) {
  22. //post to 3d map
  23. console.log("found stars");
  24. const dataFor3dMap = await fetchData(jobResult.tags);
  25. const maybeJson=JSON.stringify( dataFor3dMap)
  26. console.log(maybeJson);
  27. await fetch(`http://localhost:5173/atlas/api/findStars?dataMap={${maybeJson}},{method:'POST'}`);
  28. } else {
  29. //no stars found
  30. fail(500, { error: false, noStars: true })
  31. }
  32. } else {
  33. //display error
  34. //ask the user to send the image again
  35. fail(500, { error: true, noStars: true })
  36. }
  37. }
  38. }
  39. };
  40. const client = new ImgurClient({
  41. accessToken: process.env.TOKEN,
  42. clientId: process.env.CLIENT_ID,
  43. clientSecret: process.env.CLIENT_SECRET,
  44. refreshToken: process.env.REFRESH_TOKEN
  45. });
  46. async function fetchData(starNames: object) {
  47. let formData="";
  48. let validStarNames = starNames.filter(starName => {
  49. return starName.match(/^\w+\s+\d+.*$/g) || starName.startsWith("The star");
  50. });
  51. for(let starName in validStarNames){
  52. formData+=await setStarNameAndCoordinates(validStarNames[starName],formData)
  53. }
  54. return formData;
  55. }
  56. async function setStarNameAndCoordinates(starName:string,formData:string) {
  57. if (starName.startsWith("The star")) {
  58. starName = starName.slice("The star".length).trim();
  59. }
  60. starName = starName.replace(/ /g, "+");
  61. const res = await fetch("https://cds.unistra.fr/cgi-bin/nph-sesame?" + starName);
  62. starName = starName.replace("+", " ");
  63. const text = await res.text();
  64. const row=getDataRow(text)
  65. return `${starName}:${row}`
  66. }
  67. function getDataRow(text: string): string {
  68. const lines = text.split("\n");
  69. for (let line of lines) {
  70. if (line.startsWith("%J")) {
  71. let index = line.indexOf("=");
  72. return line.slice(3, index).trim();
  73. }
  74. }
  75. return "";
  76. }
  77. async function saveURL(url: string) {
  78. const connection = await mssqlConnection();
  79. const selectRequest = new Request(connection);
  80. const selectResult = await selectRequest
  81. .input('Username', username)
  82. .query('SELECT Id FROM Users WHERE Username = @Username');
  83. const id = selectResult.recordset[0].Id;
  84. console.log(id);
  85. const insertRequest = new Request(connection);
  86. const insertResult = await insertRequest
  87. .input('Id', uuidv4())
  88. .input('UserId', id)
  89. .input('ImageURL', url)
  90. .query('INSERT INTO UsersImages(Id, UserId, ImageURL) VALUES(@Id, @UserId, @ImageURL)');
  91. return insertResult === undefined;
  92. }
  93. async function uploadToUmgur(file: File) {
  94. const buffer = Buffer.from(await file.arrayBuffer());
  95. const base64 = buffer.toString('base64');
  96. const response = await client.upload({
  97. image: base64,
  98. type: 'base64'
  99. });
  100. console.log(response.data);
  101. return response.data;
  102. }
  103. <details>
  104. <summary>英文:</summary>
  105. 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:
  106. https://github.com/KenEucker/imgur/tree/main
  107. When I run `npm run build` I get the following output:
  108. .svelte-kit/output/server/chunks/Offcanvas.svelte_svelte_type_style_lang.js 5.40 kB
  109. .svelte-kit/output/server/chunks/Register.js 6.19 kB
  110. .svelte-kit/output/server/entries/pages/_page.svelte.js 8.41 kB
  111. .svelte-kit/output/server/chunks/index.js 11.33 kB
  112. .svelte-kit/output/server/chunks/Login.js 14.05 kB
  113. .svelte-kit/output/server/entries/pages/_layout.svelte.js 18.48 kB
  114. .svelte-kit/output/server/chunks/Portal.js 22.35 kB
  115. .svelte-kit/output/server/index.js 76.62 kB
  116. .svelte-kit/output/server/entries/pages/atlas/_page.svelte.js 615.65 kB
  117. file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35
  118. const client = new ImgurClient({
  119. ^
  120. TypeError: ImgurClient is not a constructor
  121. at file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/.svelte-kit/output/server/entries/pages/uploadPhoto/_page.server.ts.js:35:16
  122. at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
  123. at async Promise.all (index 0)
  124. at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
  125. at async Promise.all (index 1)
  126. at async prerender (file:///C:/Users/marti/Documents/school/project/Olimpiada2023/svdemo/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:370:18)
  127. [vite-plugin-sveltekit-compile] Prerendering failed with code 1
  128. error during build:
  129. Error: Prerendering failed with code 1
  130. 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)
  131. at ChildProcess.emit (node:events:513:28)
  132. at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12)
  133. here is my uploadPhoto/+page.server.ts for reference:
  134. import ImgurClient from &#39;imgur&#39;;
  135. import type { PageServerLoad, Action, Actions } from &#39;./$types&#39;;
  136. import { mssqlConnection } from &#39;../../db/mssqldb&#39;;
  137. import ppkg from &#39;mssql&#39;;
  138. const { Request } = ppkg;
  139. import { v4 as uuidv4 } from &#39;uuid&#39;;
  140. import { fail, redirect } from &#39;@sveltejs/kit&#39;;
  141. let username: string;
  142. export const load: PageServerLoad = async ({ locals }) =&gt; {
  143. if (!locals.user) {
  144. throw redirect(302, &#39;login&#39;);
  145. } else {
  146. username = locals.user.username;
  147. if (process.env.NOVA_KEY) {
  148. const sessionKey = await fetchAstrometrySessionKey(process.env.NOVA_KEY);
  149. const data = await submitURL(sessionKey, &#39;http://apod.nasa.gov/apod/image/1206/ldn673s_block1123.jpg&#39;);
  150. console.log(data);
  151. const jobResult = await getJobResults(data)
  152. if (jobResult.status === &quot;success&quot;) {
  153. console.log(jobResult.tags)
  154. if (jobResult.tags.length) {
  155. //post to 3d map
  156. console.log(&quot;found stars&quot;);
  157. const dataFor3dMap = await fetchData(jobResult.tags);
  158. const maybeJson=JSON.stringify( dataFor3dMap)
  159. console.log(maybeJson);
  160. await fetch(`http://localhost:5173/atlas/api/findStars?dataMap={${maybeJson}},{method:&#39;POST&#39;}`);
  161. } else {
  162. //no stars found
  163. fail(500, { error: false, noStars: true })
  164. }
  165. } else {
  166. //display error
  167. //ask the user to send the image again
  168. fail(500, { error: true, noStars: true })
  169. }
  170. }
  171. }
  172. };
  173. const client = new ImgurClient({
  174. accessToken: process.env.TOKEN,
  175. clientId: process.env.CLIENT_ID,
  176. clientSecret: process.env.CLIENT_SECRET,
  177. refreshToken: process.env.REFRESH_TOKEN
  178. });
  179. async function fetchData(starNames: object) {
  180. let formData=&quot;&quot;;
  181. let validStarNames = starNames.filter(starName =&gt; {
  182. return starName.match(/^\w+\s+\d+.*$/g) || starName.startsWith(&quot;The star&quot;);
  183. });
  184. for(let starName in validStarNames){
  185. formData+=await setStarNameAndCoordinates(validStarNames[starName],formData)
  186. }
  187. return formData;
  188. }
  189. async function setStarNameAndCoordinates(starName:string,formData:string) {
  190. if (starName.startsWith(&quot;The star&quot;)) {
  191. starName = starName.slice(&quot;The star&quot;.length).trim();
  192. }
  193. starName = starName.replace(/ /g, &quot;+&quot;);
  194. const res = await fetch(&quot;https://cds.unistra.fr/cgi-bin/nph-sesame?&quot; + starName);
  195. starName = starName.replace(&quot;+&quot;, &quot; &quot;);
  196. const text = await res.text();
  197. const row=getDataRow(text)
  198. return `${starName}:${row}`
  199. }
  200. function getDataRow(text: string): string {
  201. const lines = text.split(&quot;\n&quot;);
  202. for (let line of lines) {
  203. if (line.startsWith(&quot;%J&quot;)) {
  204. let index = line.indexOf(&quot;=&quot;);
  205. return line.slice(3, index).trim();
  206. }
  207. }
  208. return &quot;&quot;;
  209. }
  210. async function saveURL(url: string) {
  211. const connection = await mssqlConnection();
  212. const selectRequest = new Request(connection);
  213. const selectResult = await selectRequest
  214. .input(&#39;Username&#39;, username)
  215. .query(&#39;SELECT Id FROM Users WHERE Username = @Username&#39;);
  216. const id = selectResult.recordset[0].Id;
  217. console.log(id);
  218. const insertRequest = new Request(connection);
  219. const insertResult = await insertRequest
  220. .input(&#39;Id&#39;, uuidv4())
  221. .input(&#39;UserId&#39;, id)
  222. .input(&#39;ImageURL&#39;, url)
  223. .query(&#39;INSERT INTO UsersImages(Id, UserId, ImageURL) VALUES(@Id, @UserId, @ImageURL)&#39;);
  224. return insertResult === undefined;
  225. }
  226. async function uploadToUmgur(file: File) {
  227. const buffer = Buffer.from(await file.arrayBuffer());
  228. const base64 = buffer.toString(&#39;base64&#39;);
  229. const response = await client.upload({
  230. image: base64,
  231. type: &#39;base64&#39;
  232. });
  233. console.log(response.data);
  234. return response.data;
  235. }
  236. async function fetchAstrometrySessionKey(apikey: string) {
  237. const response = await fetch(&#39;http://nova.astrometry.net/api/login&#39;, {
  238. method: &#39;POST&#39;,
  239. headers: {
  240. &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;
  241. },
  242. body: `request-json=${encodeURIComponent(JSON.stringify({ apikey }))}`
  243. });
  244. const data = await response.json();
  245. if (data.status !== &#39;success&#39;) {
  246. console.log(&#39;Could not obtain session key: &#39; + data.message);
  247. }
  248. return data.session;
  249. }
  250. async function submitURL(sessionId: string, url: string) {
  251. const options = {
  252. method: &#39;POST&#39;,
  253. body: new URLSearchParams({
  254. &quot;request-json&quot;: JSON.stringify({
  255. session: sessionId,
  256. url: url,
  257. scale_units: &#39;degwidth&#39;,
  258. scale_lower: 0.5,
  259. scale_upper: 1.0,
  260. center_ra: 290,
  261. center_dec: 11,
  262. radius: 2.0
  263. })
  264. })
  265. };
  266. const response = await fetch(&#39;http://nova.astrometry.net/api/url_upload&#39;, options);
  267. const result = await response.json();
  268. if (result.status === &#39;success&#39;) {
  269. console.log(`Successful submission: ${result.subid} with hash ${result.hash}`);
  270. return result.subid;
  271. } else {
  272. console.error(result);
  273. return null;
  274. }
  275. }
  276. async function getJobResults(jobid: string) {
  277. const response = await fetch(`https://nova.astrometry.net/api/jobs/${jobid}/info/`);
  278. return await response.json();
  279. }
  280. const upload: Action = async ({ request }) =&gt; {
  281. try {
  282. if (request.method === &#39;POST&#39;) {
  283. const form = await request.formData();
  284. const image = form.get(&#39;img&#39;) as File;
  285. console.log(form.get(&#39;img&#39;));
  286. if (image) {
  287. console.log(`Received file with name: ${image.name}`);
  288. const link = (await uploadToUmgur(image)).link;
  289. console.log(link);
  290. if (await saveURL(link)) {
  291. return link;
  292. } else {
  293. fail(500, { error: true, noStars: false });
  294. }
  295. }
  296. }
  297. } catch (e) {
  298. console.log(e);
  299. }
  300. };
  301. export const actions: Actions = { upload };
  302. In fewer words, I get error when I initialize the client variable:
  303. const client = new ImgurClient({
  304. accessToken: process.env.TOKEN,
  305. clientId: process.env.CLIENT_ID,
  306. clientSecret: process.env.CLIENT_SECRET,
  307. refreshToken: process.env.REFRESH_TOKEN
  308. });
  309. 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.
  310. --------EDIT-------
  311. so my initial goal was to follow the https://vitejs.dev/guide/build.html#building-for-production
  312. 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.
  313. ------------NEW EDIT------------
  314. After a research, I come up with a conclusion that this is just a bug with the library. I have changed the implementation to:
  315. async function uploadToUmgur(file: File) {
  316. const buffer = Buffer.from(await file.arrayBuffer());
  317. const base64 = buffer.toString(&#39;base64&#39;);
  318. let apiUrl = &#39;https://api.imgur.com/3/image&#39;;
  319. const formData= new FormData();
  320. formData.append(&quot;image&quot;,base64);
  321. let link=&quot;&quot;;
  322. await fetch(apiUrl,{
  323. method:&quot;post&quot;,
  324. headers:{
  325. Authorization: &quot;Client-ID &quot;+process.env.CLIENT_ID
  326. },
  327. body:formData
  328. }).then(data =&gt; data.json()).then(data=&gt;{
  329. link =data.data.link;
  330. })
  331. return link;
  332. }
  333. so yeah, the lesson is:
  334. not to follow unofficial libraries with little documentation
  335. </details>
  336. # 答案1
  337. **得分**: 1
  338. import { ImgurClient } from 'imgur';
  339. 您可以尝试这样写
  340. <details>
  341. <summary>英文:</summary>
  342. import ImgurClient from &#39;imgur&#39;;
  343. You are importing the entire module here as one object
  344. import { ImgurClient } from &#39;imgur&#39;;
  345. Try this instead.
  346. </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:

确定