Home > Net >  How do I utilize this javascript library in node.js?
How do I utilize this javascript library in node.js?

Time:07-30

I'm relatively new to node.js and am attempting to utilize a javascript library without any success.

The library itself is psn-api.

To set up for usage I have:

  1. Installed node.js locally
  2. Created my project folder
  3. Ran npm init and successfully created package.json
  4. Ran npm install i -s psn-api which has successfully installed psn-api to my project folder in node-modules and updated the dependencies in package.json.
  5. I've copied the sample code from the psn-api github (see below) and saved as index.ts file in my project folder.
  6. I run npx tsc --init which generates my tsconfig.json file
  7. I run npx tsc index.ts which compiles into index.js
  8. I run node index.js

Sample code (index.ts):

import * as fs from "fs";

import type { Trophy } from "psn-api";
import {
  exchangeCodeForAccessToken,
  exchangeNpssoForCode,
  getTitleTrophies,
  getUserTitles,
  getUserTrophiesEarnedForTitle,
  makeUniversalSearch,
  TrophyRarity
} from "psn-api";

async function main() {
  // 1. Authenticate and become authorized with PSN.
  // See the Authenticating Manually docs for how to get your NPSSO.
  const npsso = "xxxxxxxx";
  const accessCode = await exchangeNpssoForCode(npsso);
  const authorization = await exchangeCodeForAccessToken(accessCode);

  // 2. Get the user's `accountId` from the username.
  const allAccountsSearchResults = await makeUniversalSearch(
    authorization,
    "xelnia",
    "SocialAllAccounts"
  );

  const targetAccountId =
    allAccountsSearchResults.domainResponses[0].results[0].socialMetadata
      .accountId;

  // 3. Get the user's list of titles (games).
  const { trophyTitles } = await getUserTitles(authorization, targetAccountId);

  const games: any[] = [];
  for (const title of trophyTitles) {
    // 4. Get the list of trophies for each of the user's titles.
    const { trophies: titleTrophies } = await getTitleTrophies(
      authorization,
      title.npCommunicationId,
      "all",
      {
        npServiceName:
          title.trophyTitlePlatform !== "PS5" ? "trophy" : undefined
      }
    );

    // 5. Get the list of _earned_ trophies for each of the user's titles.
    const { trophies: earnedTrophies } = await getUserTrophiesEarnedForTitle(
      authorization,
      targetAccountId,
      title.npCommunicationId,
      "all",
      {
        npServiceName:
          title.trophyTitlePlatform !== "PS5" ? "trophy" : undefined
      }
    );

    // 6. Merge the two trophy lists.
    const mergedTrophies = mergeTrophyLists(titleTrophies, earnedTrophies);

    games.push({
      gameName: title.trophyTitleName,
      platform: title.trophyTitlePlatform,
      trophyTypeCounts: title.definedTrophies,
      earnedCounts: title.earnedTrophies,
      trophyList: mergedTrophies
    });
  }

  // 7. Write to a JSON file.
  fs.writeFileSync("./games.json", JSON.stringify(games));
}

const mergeTrophyLists = (
  titleTrophies: Trophy[],
  earnedTrophies: Trophy[]
) => {
  const mergedTrophies: any[] = [];

  for (const earnedTrophy of earnedTrophies) {
    const foundTitleTrophy = titleTrophies.find(
      (t) => t.trophyId === earnedTrophy.trophyId
    );

    mergedTrophies.push(
      normalizeTrophy({ ...earnedTrophy, ...foundTitleTrophy })
    );
  }

  return mergedTrophies;
};

const normalizeTrophy = (trophy: Trophy) => {
  return {
    isEarned: trophy.earned ?? false,
    earnedOn: trophy.earned ? trophy.earnedDateTime : "unearned",
    type: trophy.trophyType,
    rarity: rarityMap[trophy.trophyRare ?? 0],
    earnedRate: Number(trophy.trophyEarnedRate),
    trophyName: trophy.trophyName,
    groupId: trophy.trophyGroupId
  };
};

const rarityMap: Record<TrophyRarity, string> = {
  [TrophyRarity.VeryRare]: "Very Rare",
  [TrophyRarity.UltraRare]: "Ultra Rare",
  [TrophyRarity.Rare]: "Rare",
  [TrophyRarity.Common]: "Common"
};

I've run around in circles with possible fixes such as adding "type":"module" to the package.json, trying to import or otherwise define psn-api in my js file but I keep hitting error after error. I'm sure there's some fundamental misunderstanding I have. I'd really appreciate if someone could outline the direct steps I need to take to get the sample script running in the cmd line.

My package.json as it stands:

    {
  "name": "psnapitest",
  "version": "1.0.0",
  "description": "",
  "main": "index3.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/node": "^18.6.2",
    "psn-api": "^2.7.0"
  },
  "type": "module",
  "devDependencies": {
    "@tsconfig/node16": "^1.0.3",
    "typescript": "^4.7.4"
  }
}

My tsconfig.json as it stands (after advice in comments):

{
  "compilerOptions": {
    "target": "es2016",
    "module": "es6",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}

Current error when running compiled js:

Now compiles with no issues.

I run node index.js and get the following error

    exports.__esModule = true;
^

ReferenceError: exports is not defined in ES module scope

CodePudding user response:

Try instead of using import, use require:

const fs = require('fs')
const psn = require('psn-api')
const { Trophy } = psn
const { exchangeCodeForAccessToken } = psn
const { exchangeNpssoForCode } = psn
const { getTitleTrophies } = psn
const { getUserTitles } = psn
const { getUserTrophiesEarnedForTitle } = psn
const { makeUniversalSearch } = psn
const { TrophyRarity } = psn

CodePudding user response:

I tried this locally and no error

when using node library you need to set "moduleResolution": "node" on your tsconfig.json

index.ts

import fs from 'fs'

package.json

{
  "name": "psn-api-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsc index.ts",
    "start": "node index.js"
  },
  "type": "module",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "psn-api": "^2.7.0"
  },
  "devDependencies": {
    "@types/node": "^18.6.2",
    "typescript": "^4.7.4"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "es6",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true
  }
}
  • Related