Compare commits
1 Commits
main
...
feat-weapo
Author | SHA1 | Date |
---|---|---|
Nemesis | 659be3eecb |
|
@ -1,3 +1,2 @@
|
||||||
STRAPI_BASE_API_URL=https://strapi.accords-library.com|http://localhost:1337/api
|
STRAPI_BASE_API_URL=https://strapi.accords-library.com|http://localhost:1337/api
|
||||||
STRAPI_GRAPHQL=https://strapi.accords-library.com/graphql|http://localhost:1337/graphql
|
|
||||||
STRAPI_API_TOKEN=
|
STRAPI_API_TOKEN=
|
48
README.md
48
README.md
|
@ -2,50 +2,8 @@
|
||||||
|
|
||||||
## Scripts available
|
## Scripts available
|
||||||
|
|
||||||
### Import all
|
|
||||||
|
|
||||||
Models imported in following order:
|
|
||||||
|
|
||||||
- `rein-emblems`
|
|
||||||
- `rein-costumes`
|
|
||||||
- `weapon-stories`
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run import:all
|
|
||||||
```
|
|
||||||
|
|
||||||
### NieR Re[in]carnation
|
### NieR Re[in]carnation
|
||||||
|
|
||||||
#### Costume emblems
|
|
||||||
|
|
||||||
Import costume emblems (abyssal, celebratory...) from https://nierrein.guide/ database to Accord's Library database
|
|
||||||
|
|
||||||
|
|
||||||
Model: `rein-emblems`
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run import:emblems
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Costumes
|
|
||||||
|
|
||||||
Import costumes from https://nierrein.guide/ database to Accord's Library database
|
|
||||||
|
|
||||||
|
|
||||||
Model: `rein-costumes`
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
> ⚠️ Importing the emblems before the costumes is mandatory.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run import:costumes
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Weapon stories
|
#### Weapon stories
|
||||||
|
|
||||||
Import weapon stories from https://nierrein.guide/ database to Accord's Library database
|
Import weapon stories from https://nierrein.guide/ database to Accord's Library database
|
||||||
|
@ -57,10 +15,4 @@ Usage:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run import:weapon-stories
|
npm run import:weapon-stories
|
||||||
```
|
|
||||||
|
|
||||||
Related checks:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run check:weapon-stories-duplicates
|
|
||||||
```
|
```
|
|
@ -1,120 +0,0 @@
|
||||||
import 'dotenv/config';
|
|
||||||
import { NIERREIN_GUIDE_API_URL, NIERREIN_GUIDE_CDN_URL } from '../../config.mjs';
|
|
||||||
import { env } from '../../env.mjs';
|
|
||||||
import slugg from 'slugg';
|
|
||||||
|
|
||||||
let currentIndex = 1;
|
|
||||||
|
|
||||||
const { data: emblems } = await fetch(
|
|
||||||
`${env.STRAPI_BASE_API_URL}/rein-emblems`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization:
|
|
||||||
`bearer ${env.STRAPI_API_TOKEN}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!emblems || emblems.length === 0) {
|
|
||||||
console.error(`Got 0 emblems from "${env.STRAPI_BASE_API_URL}/rein-emblems". You may want to run "npm run import:emblems".`)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let costumes = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log('Fetching NieR Re[in]carnation costumes...')
|
|
||||||
costumes = await fetch(`${NIERREIN_GUIDE_API_URL}/costumes`)
|
|
||||||
.then((response) => response.json())
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`${costumes.length} costumes fetched from "${NIERREIN_GUIDE_API_URL}/costumes"`)
|
|
||||||
|
|
||||||
if (costumes.length === 0) {
|
|
||||||
console.error(`Got 0 costume from "${NIERREIN_GUIDE_API_URL}/costumes". Their database is probably in the process of being updated. Try again in 10 minutes.`)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const costume of costumes) {
|
|
||||||
if (!currentIndex > 1) continue
|
|
||||||
|
|
||||||
console.log(`Uploading n°${currentIndex}/${costumes.length} costumes.`);
|
|
||||||
|
|
||||||
// Get costume image blob for the sprite
|
|
||||||
const file = await fetch(`${NIERREIN_GUIDE_CDN_URL}${costume.image_path_base}full.png`).then(
|
|
||||||
(response) => response.blob()
|
|
||||||
);
|
|
||||||
|
|
||||||
const body = new FormData();
|
|
||||||
|
|
||||||
let costumeEmblem = {}
|
|
||||||
|
|
||||||
if (costume.emblem_id) {
|
|
||||||
costumeEmblem = emblems.find((emblem) => emblem.attributes.slug === slugg(costume.emblem.name))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the weapon-stories entry
|
|
||||||
body.append(
|
|
||||||
"data",
|
|
||||||
JSON.stringify({
|
|
||||||
slug: costume.slug,
|
|
||||||
translations: [
|
|
||||||
{
|
|
||||||
language: {
|
|
||||||
connect: [2], // en
|
|
||||||
},
|
|
||||||
name: costume.title,
|
|
||||||
description:
|
|
||||||
costume.description?.replaceAll(
|
|
||||||
"\\n",
|
|
||||||
"<br>"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
emblem: {
|
|
||||||
connect: [costumeEmblem.id].filter(Boolean),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add the weapon image blob
|
|
||||||
body.append("files.sprite", file, `${costume.slug}.png`);
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`${env.STRAPI_BASE_API_URL}/rein-costumes`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
body,
|
|
||||||
headers: {
|
|
||||||
Authorization:
|
|
||||||
`bearer ${env.STRAPI_API_TOKEN}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.catch((err) => err?.json());
|
|
||||||
|
|
||||||
currentIndex++;
|
|
||||||
|
|
||||||
if (response?.error) {
|
|
||||||
if (response.error.message === "This attribute must be unique") {
|
|
||||||
console.warn(
|
|
||||||
`[DUPLICATE] ${costume.name} (${costume.slug}) already exists.`
|
|
||||||
);
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(`[ERROR] ${costume.title} (${costume.slug}):`, response.error.message)
|
|
||||||
} else {
|
|
||||||
console.log(`[ADDED] "${costume.title}" (${costume.slug})`);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
import 'dotenv/config';
|
|
||||||
import { NIERREIN_GUIDE_API_URL } from '../../config.mjs';
|
|
||||||
import { env } from '../../env.mjs';
|
|
||||||
import slugg from 'slugg';
|
|
||||||
|
|
||||||
let currentIndex = 1;
|
|
||||||
|
|
||||||
let emblems = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log('Fetching NieR Re[in]carnation emblems...')
|
|
||||||
emblems = await fetch(`${NIERREIN_GUIDE_API_URL}/emblems`)
|
|
||||||
.then((response) => response.json())
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`${emblems.length} emblems fetched from "${NIERREIN_GUIDE_API_URL}/emblems"`)
|
|
||||||
|
|
||||||
if (emblems.length === 0) {
|
|
||||||
console.error(`Got 0 emblem from "${NIERREIN_GUIDE_API_URL}/emblems". Their database is probably in the process of being updated. Try again in 10 minutes.`)
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const emblem of emblems) {
|
|
||||||
if (!currentIndex > 1) continue
|
|
||||||
|
|
||||||
console.log(`Uploading n°${currentIndex}/${emblems.length} emblems.`);
|
|
||||||
|
|
||||||
const body = new FormData();
|
|
||||||
|
|
||||||
const description = `
|
|
||||||
${emblem.main_message?.replaceAll("\\n", "<br>")}<br>${emblem.small_messages?.replaceAll("\\n", "<br>")}
|
|
||||||
`.trim()
|
|
||||||
|
|
||||||
// Create the emblem entry
|
|
||||||
body.append(
|
|
||||||
"data",
|
|
||||||
JSON.stringify({
|
|
||||||
slug: slugg(emblem.name),
|
|
||||||
translations: [
|
|
||||||
{
|
|
||||||
language: {
|
|
||||||
connect: [2], // en
|
|
||||||
},
|
|
||||||
name: emblem.name,
|
|
||||||
description,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`${env.STRAPI_BASE_API_URL}/rein-emblems`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
body,
|
|
||||||
headers: {
|
|
||||||
Authorization:
|
|
||||||
`bearer ${env.STRAPI_API_TOKEN}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.catch((err) => err?.json());
|
|
||||||
|
|
||||||
currentIndex++;
|
|
||||||
|
|
||||||
if (response?.error) {
|
|
||||||
if (response.error.message === "This attribute must be unique") {
|
|
||||||
console.warn(
|
|
||||||
`[DUPLICATE] ${emblem.name} already exists.`
|
|
||||||
);
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(`[ERROR] ${emblem.name}:`, response.error.message)
|
|
||||||
} else {
|
|
||||||
console.log(`[ADDED] "${emblem.name}"`);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
import "dotenv/config";
|
|
||||||
|
|
||||||
const response = await fetch(`${process.env.STRAPI_GRAPHQL}`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `bearer ${process.env.STRAPI_API_TOKEN}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
query: `{
|
|
||||||
weaponStories(pagination: { limit: -1 }) {
|
|
||||||
data {
|
|
||||||
id
|
|
||||||
attributes {
|
|
||||||
slug
|
|
||||||
name { name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const normalizeName = (name) => {
|
|
||||||
return name
|
|
||||||
.toLowerCase()
|
|
||||||
.normalize("NFD")
|
|
||||||
.replace(/[\u0300-\u036f]/g, "")
|
|
||||||
.replace(/['’]/g, "'");
|
|
||||||
};
|
|
||||||
|
|
||||||
const weapons = (await response.json()).data.weaponStories.data;
|
|
||||||
|
|
||||||
const nameMap = new Map();
|
|
||||||
|
|
||||||
for (const weapon of weapons) {
|
|
||||||
for (const { name } of weapon.attributes.name) {
|
|
||||||
if (name === undefined || name === null) {
|
|
||||||
console.warn(name, "is nullable", weapon);
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalizedName = normalizeName(name);
|
|
||||||
|
|
||||||
if (nameMap.has(normalizedName))
|
|
||||||
console.warn(`
|
|
||||||
Duplicate names ${normalizedName} in:
|
|
||||||
1. ${nameMap.get(normalizedName).attributes.slug}
|
|
||||||
2. ${weapon.attributes.slug}`);
|
|
||||||
else {
|
|
||||||
nameMap.set(normalizedName, weapon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,18 +6,6 @@ let currentIndex = 1;
|
||||||
|
|
||||||
let weapons = [];
|
let weapons = [];
|
||||||
|
|
||||||
const slugSpecialCases = new Map([
|
|
||||||
["phoenix-lance", "phoenix-spear"],
|
|
||||||
["iron-will", "hymir-finger"],
|
|
||||||
["the-devil-queen", "widow-death"],
|
|
||||||
["kains-sword", "kaines-sword"],
|
|
||||||
["spear-of-the-usurper", "robber-king"],
|
|
||||||
["ancient-overlord", "kingsblood"],
|
|
||||||
["fang-of-the-twins", "twins-fang"],
|
|
||||||
["dragoon-lance", "knight-vow"],
|
|
||||||
["faith", "nobuyoshi"],
|
|
||||||
]);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Fetching NieR Re[in]carnation weapons...')
|
console.log('Fetching NieR Re[in]carnation weapons...')
|
||||||
weapons = await fetch(`${NIERREIN_GUIDE_API_URL}/weapons`)
|
weapons = await fetch(`${NIERREIN_GUIDE_API_URL}/weapons`)
|
||||||
|
@ -42,11 +30,6 @@ for (const weapon of weapons) {
|
||||||
(response) => response.blob()
|
(response) => response.blob()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Change slug if the weapon is known with a different name in accords-library
|
|
||||||
if (slugSpecialCases.has(weapon.slug)) {
|
|
||||||
weapon.slug = slugSpecialCases.get(weapon.slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
const body = new FormData();
|
const body = new FormData();
|
||||||
|
|
||||||
// Create the weapon-stories entry
|
// Create the weapon-stories entry
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"envsafe": "^2.0.3",
|
"envsafe": "^2.0.3"
|
||||||
"slugg": "^1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.13.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
|
@ -32,11 +28,6 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"node_modules/slugg": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/slugg/-/slugg-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-yzUY7d53sdY3wp6rGCc54fn+cel0aNsdG5lvRVN8bvlAXYQI2fIo36AAOVjArOaMzlidHYyAYqriHzuos93h+Q=="
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -49,11 +40,6 @@
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/envsafe/-/envsafe-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/envsafe/-/envsafe-2.0.3.tgz",
|
||||||
"integrity": "sha512-51lek8h5btjXhXUDW//Pno7HPydM1WQzltOb1/ONRKdwB2QkfAURnN4Qn0cJ5LzGvX2Km1ReR2O3K3Bqq9sBMg=="
|
"integrity": "sha512-51lek8h5btjXhXUDW//Pno7HPydM1WQzltOb1/ONRKdwB2QkfAURnN4Qn0cJ5LzGvX2Km1ReR2O3K3Bqq9sBMg=="
|
||||||
},
|
|
||||||
"slugg": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/slugg/-/slugg-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-yzUY7d53sdY3wp6rGCc54fn+cel0aNsdG5lvRVN8bvlAXYQI2fIo36AAOVjArOaMzlidHYyAYqriHzuos93h+Q=="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,10 @@
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"import:all": "npm run import:emblems && npm run import:costumes && npm run import:weapon-stories",
|
"import:weapon-stories": "node ./nier-reincarnation/weapon-stories/index.mjs"
|
||||||
"check:weapon-stories-duplicates": "node ./nier-reincarnation/weapon-stories/find-duplicates.mjs",
|
|
||||||
"import:weapon-stories": "node ./nier-reincarnation/weapon-stories/index.mjs",
|
|
||||||
"import:emblems": "node ./nier-reincarnation/emblems/index.mjs",
|
|
||||||
"import:costumes": "node ./nier-reincarnation/costumes/index.mjs"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"envsafe": "^2.0.3",
|
"envsafe": "^2.0.3"
|
||||||
"slugg": "^1.2.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue