diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..35d8ec7
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,2 @@
+STRAPI_BASE_API_URL=https://strapi.accords-library.com|http://localhost:1337/api
+STRAPI_API_TOKEN=
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1dcef2d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+.env
\ No newline at end of file
diff --git a/README.md b/README.md
index 01655c5..5db20c8 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,18 @@
-# Import-tools
\ No newline at end of file
+# Import-tools
+
+## Scripts available
+
+### NieR Re[in]carnation
+
+#### Weapon stories
+
+Import weapon stories from https://nierrein.guide/ database to Accord's Library database
+
+
+Model: `weapon-stories`
+
+Usage:
+
+```sh
+npm run import:weapon-stories
+```
\ No newline at end of file
diff --git a/config.mjs b/config.mjs
new file mode 100644
index 0000000..65d53de
--- /dev/null
+++ b/config.mjs
@@ -0,0 +1,11 @@
+export const WEAPON_TYPES_RELATION_IDS = {
+ SWORD: 7,
+ BIG_SWORD: 13,
+ FIST: 3,
+ GUN: 16,
+ SPEAR: 10,
+ STAFF: 11,
+};
+
+export const NIERREIN_GUIDE_API_URL = "https://nierrein.guide/api"
+export const NIERREIN_GUIDE_CDN_URL = "https://assets.nierrein.guide/"
\ No newline at end of file
diff --git a/env.mjs b/env.mjs
new file mode 100644
index 0000000..de31c11
--- /dev/null
+++ b/env.mjs
@@ -0,0 +1,8 @@
+import { str, envsafe, url } from 'envsafe';
+
+export const env = envsafe({
+ STRAPI_BASE_API_URL: url({
+ devDefault: 'http://127.0.01:1337/api/',
+ }),
+ STRAPI_API_TOKEN: str(),
+});
diff --git a/nier-reincarnation/weapon-stories/.gitkeep b/nier-reincarnation/weapon-stories/.gitkeep
deleted file mode 100644
index 8b13789..0000000
--- a/nier-reincarnation/weapon-stories/.gitkeep
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/nier-reincarnation/weapon-stories/index.mjs b/nier-reincarnation/weapon-stories/index.mjs
new file mode 100644
index 0000000..3e203cd
--- /dev/null
+++ b/nier-reincarnation/weapon-stories/index.mjs
@@ -0,0 +1,124 @@
+import 'dotenv/config';
+import { NIERREIN_GUIDE_API_URL, NIERREIN_GUIDE_CDN_URL, WEAPON_TYPES_RELATION_IDS } from '../../config.mjs';
+import { env } from '../../env.mjs';
+
+let currentIndex = 1;
+
+let weapons = [];
+
+try {
+ console.log('Fetching NieR Re[in]carnation weapons...')
+ weapons = await fetch(`${NIERREIN_GUIDE_API_URL}/weapons`)
+ .then((response) => response.json())
+} catch (error) {
+ console.error(error)
+ process.exit(1);
+}
+
+console.log(`${weapons.length} weapons fetched from "${NIERREIN_GUIDE_API_URL}/weapons"`)
+
+if (weapons.length === 0) {
+ console.error(`Got 0 weapons from "${NIERREIN_GUIDE_API_URL}/weapons". Their database is probably in the process of being updated. Try again in 10 minutes.`)
+ process.exit(1);
+}
+
+for (const weapon of weapons) {
+ console.log(`Uploading n°${currentIndex}/${weapons.length} weapons.`);
+
+ // Get weapon image blob for the thumbnail
+ const file = await fetch(`${NIERREIN_GUIDE_CDN_URL}${weapon.image_path}full.png`).then(
+ (response) => response.blob()
+ );
+
+ const body = new FormData();
+
+ // Create the weapon-stories entry
+ body.append(
+ "data",
+ JSON.stringify({
+ slug: weapon.slug,
+ name: [
+ {
+ name: weapon.name,
+ language: {
+ connect: [2], // en
+ },
+ },
+ ],
+ stories: [
+ {
+ categories: {
+ connect: [8], // nier reincarnation
+ },
+ translations: [
+ {
+ language: {
+ connect: [2], // en
+ },
+ status: "Done",
+ level_1:
+ weapon.weapon_story_link[0].weapon_story.story?.replaceAll(
+ "\\n",
+ "
"
+ ),
+ level_2:
+ weapon.weapon_story_link[1].weapon_story.story?.replaceAll(
+ "\\n",
+ "
"
+ ),
+ level_3:
+ weapon.weapon_story_link[2].weapon_story.story?.replaceAll(
+ "\\n",
+ "
"
+ ),
+ level_4:
+ weapon.weapon_story_link[3].weapon_story.story?.replaceAll(
+ "\\n",
+ "
"
+ ),
+ },
+ ],
+ },
+ ],
+ categories: {
+ connect: [8], // nier reincarnation
+ },
+ type: {
+ connect: [WEAPON_TYPES_RELATION_IDS[weapon.weapon_type]], // weapon type
+ },
+ })
+ );
+
+ // Add the weapon image blob
+ body.append("files.thumbnail", file, `${weapon.slug}.png`);
+
+ const response = await fetch(
+ `${env.STRAPI_BASE_API_URL}/weapon-stories`,
+ {
+ method: "POST",
+ body,
+ headers: {
+ Authorization:
+ `bearer ${env.STRAPI_API_TOKEN}`,
+ },
+ }
+ )
+ .then((res) => res.json())
+ .catch((err) => err?.json());
+
+ if (response?.error) {
+ if (response.error.message === "This attribute must be unique") {
+ console.warn(
+ `[DUPLICATE] ${weapon.name} (${weapon.slug}) already exists.`
+ );
+
+ continue
+ }
+
+ console.error(`[ERROR] ${weapon.name} (${weapon.slug}):`, response.error.message)
+ } else {
+ console.log(`[ADDED] "${weapon.name}" (${weapon.slug})`);
+ }
+
+ currentIndex++;
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..fb14c24
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,45 @@
+{
+ "name": "accords-library-scripts",
+ "version": "0.1.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "accords-library-scripts",
+ "version": "0.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "dotenv": "^16.0.3",
+ "envsafe": "^2.0.3"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.0.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
+ "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/envsafe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/envsafe/-/envsafe-2.0.3.tgz",
+ "integrity": "sha512-51lek8h5btjXhXUDW//Pno7HPydM1WQzltOb1/ONRKdwB2QkfAURnN4Qn0cJ5LzGvX2Km1ReR2O3K3Bqq9sBMg==",
+ "engines": {
+ "node": ">=10"
+ }
+ }
+ },
+ "dependencies": {
+ "dotenv": {
+ "version": "16.0.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
+ "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
+ },
+ "envsafe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/envsafe/-/envsafe-2.0.3.tgz",
+ "integrity": "sha512-51lek8h5btjXhXUDW//Pno7HPydM1WQzltOb1/ONRKdwB2QkfAURnN4Qn0cJ5LzGvX2Km1ReR2O3K3Bqq9sBMg=="
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b085631
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "accords-library-scripts",
+ "version": "0.1.0",
+ "type": "module",
+ "engines": {
+ "node": ">=18.13.0"
+ },
+ "description": "",
+ "license": "MIT",
+ "scripts": {
+ "import:weapon-stories": "node ./nier-reincarnation/weapon-stories/index.mjs"
+ },
+ "dependencies": {
+ "dotenv": "^16.0.3",
+ "envsafe": "^2.0.3"
+ }
+}