{"_id":"@bck-inc/nsb","_rev":"2-a8533d104cb757ed20bba71fecc25880","name":"@bck-inc/nsb","dist-tags":{"latest":"1.0.41"},"versions":{"1.0.40":{"name":"@bck-inc/nsb","version":"1.0.40","keywords":["discord","sdk","nsb"],"author":{"name":"Blackknight"},"license":"MIT","_id":"@bck-inc/nsb@1.0.40","maintainers":[{"name":"dragclover","email":"dragclover@gmail.com"},{"name":"y0rokobi","email":"kelyan.nunes@hotmail.com"}],"dist":{"shasum":"b505573c0c63d2967f386a45a6fbf870cf0d1009","tarball":"https://registry.npmjs.org/@bck-inc/nsb/-/nsb-1.0.40.tgz","fileCount":17,"integrity":"sha512-1Wdfsqr+Cq5DDo4ry90PVCrq8K1r0P7YSF5zb3zjOV+QZlelqOg+z0h+srJX6kqlk37xRVKtc9QMt61DeWTyxw==","signatures":[{"sig":"MEQCIA1m4vTzJvENI+YM8YGOFa+tlr7A2FrFl+/Fw80vDrQfAiBn1vkKwEMsESXr6QHj243FfAjXteooMGDv0jChje1GJA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69283},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"scripts":{"dev":"ts-node-dev --respawn src/scratch.ts","test":"vitest run","build":"tsc -p tsconfig.json","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"dragclover","email":"dragclover@gmail.com"},"_npmVersion":"11.7.0","description":"SDK officiel pour l'API NSB (Néon Spinellia BCK) - 100 % fetch natif","directories":{},"_nodeVersion":"25.4.0","dependencies":{"undici":"^7.19.0","discord.js":"^13.17.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.8.3","ts-node-dev":"^2.0.0","undici-types":"^7.12.0"},"_npmOperationalInternal":{"tmp":"tmp/nsb_1.0.40_1777316578743_0.8598064265045933","host":"s3://npm-registry-packages-npm-production"}},"1.0.41":{"name":"@bck-inc/nsb","version":"1.0.41","description":"SDK officiel pour l'API NSB (Néon Spinellia BCK) - 100 % fetch natif","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"require":"./dist/index.js","import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc -p tsconfig.json","dev":"ts-node-dev --respawn src/scratch.ts","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"keywords":["discord","sdk","nsb"],"publishConfig":{"access":"public"},"dependencies":{"discord.js":"^13.17.1","undici":"^7.19.0"},"devDependencies":{"ts-node-dev":"^2.0.0","typescript":"^5.8.3","undici-types":"^7.12.0","vitest":"^3.2.4"},"author":{"name":"Blackknight"},"license":"MIT","engines":{"node":">=18"},"_id":"@bck-inc/nsb@1.0.41","_nodeVersion":"25.4.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-UngdFZcYsJC+A3TqePMCnnm/EQDJfNYLUvOYg8sIviEFQ4WPt1nR9lKrqFslE0zV9QDNnCqkJFch1U0StUataA==","shasum":"a84a5276b7e8a15c1fdb16cb09c190cd05754803","tarball":"https://registry.npmjs.org/@bck-inc/nsb/-/nsb-1.0.41.tgz","fileCount":17,"unpackedSize":79963,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCXnO0wo8cKMizsF23LmWKmrYJ3LOPB7KS9G8+icwtW0QIgbWJhlYzvkU1u9FmWEcCMp/VrNMa5/xee4PudDBgaq2E="}]},"_npmUser":{"name":"dragclover","email":"dragclover@gmail.com"},"directories":{},"maintainers":[{"name":"dragclover","email":"dragclover@gmail.com"},{"name":"y0rokobi","email":"kelyan.nunes@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nsb_1.0.41_1777331174090_0.5513332870529002"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-27T19:02:58.619Z","modified":"2026-04-27T23:06:14.422Z","1.0.40":"2026-04-27T19:02:58.884Z","1.0.41":"2026-04-27T23:06:14.266Z"},"author":{"name":"Blackknight"},"license":"MIT","keywords":["discord","sdk","nsb"],"description":"SDK officiel pour l'API NSB (Néon Spinellia BCK) - 100 % fetch natif","maintainers":[{"name":"dragclover","email":"dragclover@gmail.com"},{"name":"y0rokobi","email":"kelyan.nunes@hotmail.com"}],"readme":"<div align=\"center\">\r\n\r\n# @bck-inc/nsb\r\n\r\n*SDK TypeScript / Node.js pour l'API **NSB** (Néon Spinellia BCK)*\r\n\r\n<a href=\"https://www.npmjs.com/package/@bck-inc/nsb\"><img alt=\"npm\" src=\"https://img.shields.io/npm/v/@bck-inc/nsb?color=cb3837&logo=npm\" /></a> <a href=\"https://www.npmjs.com/package/@bck-inc/nsb\"><img alt=\"types\" src=\"https://img.shields.io/npm/types/@bck-inc/nsb?label=TypeScript\" /></a> <img alt=\"node\" src=\"https://img.shields.io/node/v/@bck-inc/nsb?color=5fa04e&logo=node.js\" /> <img alt=\"license\" src=\"https://img.shields.io/npm/l/@bck-inc/nsb?color=blue\" />\r\n\r\n</div>\r\n\r\n> **TL;DR :** `import { NSBCore } from '@bck-inc/nsb'` → appelez votre premier endpoint en 10 lignes.\r\n\r\n---\r\n\r\n## ✨ Caractéristiques principales\r\n\r\n|                        |                                                                                              |\r\n| :--------------------- | :------------------------------------------------------------------------------------------- |\r\n| **Fetch natif**        | Aucun client HTTP externe — Node ≥ 18 requis (polyfill possible).                            |\r\n| **ESM & CJS**          | Fonctionne avec `import` **et** `require`.                                                   |\r\n| **Type safe**          | Déclarations `.d.ts` + type‑guards runtime.                                                  |\r\n| **Cache TTL (1,5 s)**  | Réponses GET mises en cache pour amortir les floods.                                         |\r\n| **Rate‑limit intégré** | 55 req/s (tokens valides) / 1 req/s (non autorisés).                                         |\r\n| **Errors typées**      | `NSBError`, `NSBHTTPError` pour des `catch` ciblés.                                          |\r\n| **Évènements**         | `request`, `response`, `cacheHit`, `validationError`, `moduleStateChanged`, `ping`, `error`. |\r\n| **Zéro config**        | Instanciez, appelez : headers et baseURL gérés pour vous.                                    |\r\n\r\n---\r\n\r\n## 🚀 Installation\r\n\r\n```bash\r\nnpm i @bck-inc/nsb           # pnpm add @bck-inc/nsb / yarn add @bck-inc/nsb\r\n```\r\n\r\n> **Node ≥ 18** recommandé pour `fetch` et `URL` globaux.\r\n> Sur Node 16 :\r\n>\r\n> ```ts\r\n> import fetch from 'node-fetch';\r\n> // @ts-ignore\r\n> globalThis.fetch = fetch;\r\n> ```\r\n\r\n---\r\n\r\n## ⚡ Exemple rapide (TS / ESM)\r\n\r\n```ts\r\nimport { NSBCore, NSBCodes, NSBState } from '@bck-inc/nsb';\r\n\r\nconst core = new NSBCore({\r\n  token: process.env.NSB_TOKEN!,\r\n  botId:  process.env.BOT_ID!,\r\n  debug:  true,\r\n});\r\n\r\ncore.on('cacheHit', ({ url })  => console.log('⚡ cache', url))\r\n    .on('ping',     ({ rtt })  => console.log('ping', rtt, 'ms'))\r\n    .on('error',    console.error);\r\n\r\n// Active le module \"welcome\" sur un serveur\r\nconst res = await core.setModuleState({\r\n  bot_id:     core['botId']!,\r\n  server_id:  '987654321098765432',\r\n  module_name:'welcome',\r\n  newState:   NSBState.enabled,\r\n});\r\n\r\nif (res.code === NSBCodes.VALID) console.log('Module OK');\r\n```\r\n\r\n---\r\n\r\n## 📚 API en bref\r\n\r\n### Constructeur\r\n\r\n```ts\r\nnew NSBCore({ token, botId, baseURL?, debug? });\r\n```\r\n\r\n### Méthodes\r\n\r\n| Méthode                                     | Effet                                             |\r\n| ------------------------------------------- | ------------------------------------------------- |\r\n| `fetchModules(query?)`                      | GET `/modules/get` + cache TTL (1.5s)             |\r\n| `insertModule(body)` / `updateModule(body)` | CRUD module                                       |\r\n| `setModuleState(params)`                    | Insert ou update + événement `moduleStateChanged` |\r\n| `enableModule(p)` / `disableModule(p)`      | Sucrage autour de `setModuleState`                |\r\n| `isStandardized(name)`                      | Vérifie si « standard » côté API                  |\r\n| `getStandardizedModules()`                  | Récupère la liste complète des modules standards  |\r\n| `getPing(timeout?)`                         | Retourne la latence RTT (ms) et émet `ping`       |\r\n| `connectWebSocket(options?)`                | Ouvre le WS NSB + gère `TOGGLE`/`ACK`             |\r\n| `disconnectWebSocket(code?, reason?)`       | Ferme le WS et stoppe la reconnexion auto         |\r\n\r\n### Évènements (auto‑complétés dans VS Code)\r\n\r\n| Event                | Payload                      |\r\n| :------------------- | :--------------------------- |\r\n| `request`            | `{ url, method }`            |\r\n| `response`           | `{ url, status }`            |\r\n| `cacheHit`           | `{ url, ttlLeft }`           |\r\n| `validationError`    | `{ url, issues }`            |\r\n| `moduleStateChanged` | `{ module, type, newState }` |\r\n| `ping`               | `{ rtt }` (`‑1` si timeout)  |\r\n| `error`              | `unknown`                    |\r\n| `wsOpen`             | `{ url }`                    |\r\n| `wsClose`            | `{ code, reason }`           |\r\n| `wsMessage`          | `unknown`                    |\r\n| `wsReconnect`        | `{ retryInMs }`              |\r\n| `wsError`            | `unknown`                    |\r\n\r\nTypes & enums détaillés dans [`src/types.ts`](./src/types.ts).\r\n\r\n---\r\n\r\n## 🔌 WebSocket NSB (conversion de ton snippet)\r\n\r\nLe SDK intègre maintenant un client WebSocket prêt à l'emploi.\r\n\r\n```ts\r\nimport { NSBCore } from '@bck-inc/nsb';\r\n\r\nconst core = new NSBCore({\r\n  token: process.env.NSB_TOKEN!,\r\n  botId: client.user!.id,\r\n});\r\n\r\ncore.connectWebSocket({\r\n  wsURL: 'wss://api.neon-inc.fr/nsb/ws', // optionnel (défaut identique)\r\n  reconnectDelayMs: 5000,\r\n  autoReconnect: true,\r\n\r\n  onOpen: () => {\r\n    console.log('✅ Connecté au WebSocket NSB');\r\n  },\r\n\r\n  onError: (error) => {\r\n    console.error('❌ Erreur WebSocket NSB:', error);\r\n  },\r\n\r\n  // Équivalent du bloc TOGGLE de ton code.\r\n  // Si cette fonction réussit: ACK success=true envoyé automatiquement.\r\n  // Si elle throw: ACK success=false envoyé automatiquement avec error.message.\r\n  onToggle: async (data) => {\r\n    await client.db.execute(\r\n      'UPDATE server_modules SET server_status = ? WHERE module_name = ? AND serverID = ?',\r\n      [data.state, data.module_name, data.server_id]\r\n    );\r\n  },\r\n\r\n  onClose: () => {\r\n    console.warn('💥 Connexion WS fermée (reconnexion auto si activée)');\r\n  }\r\n});\r\n\r\n// Plus tard (arrêt propre)\r\n// core.disconnectWebSocket();\r\n```\r\n\r\n### Exemple complet (Discord.js + DB)\r\n\r\n```ts\r\nimport { Client, GatewayIntentBits } from 'discord.js';\r\nimport mysql from 'mysql2/promise';\r\nimport { NSBCore } from '@bck-inc/nsb';\r\n\r\nconst client = new Client({\r\n  intents: [GatewayIntentBits.Guilds]\r\n});\r\n\r\nconst db = await mysql.createPool({\r\n  host: process.env.DB_HOST,\r\n  user: process.env.DB_USER,\r\n  password: process.env.DB_PASSWORD,\r\n  database: process.env.DB_NAME,\r\n});\r\n\r\nclient.once('ready', () => {\r\n  const core = new NSBCore({\r\n    token: process.env.NSB_TOKEN!,\r\n    botId: client.user!.id,\r\n    debug: true,\r\n  });\r\n\r\n  core.on('wsReconnect', ({ retryInMs }) => {\r\n    console.warn(`WS reconnect dans ${retryInMs}ms`);\r\n  });\r\n\r\n  core.connectWebSocket({\r\n    onToggle: async ({ state, module_name, server_id }) => {\r\n      await db.execute(\r\n        'UPDATE server_modules SET server_status = ? WHERE module_name = ? AND serverID = ?',\r\n        [state, module_name, server_id]\r\n      );\r\n    },\r\n    onError: (err) => {\r\n      console.error('WS error:', err);\r\n    }\r\n  });\r\n\r\n  const stop = () => {\r\n    core.disconnectWebSocket();\r\n    db.end();\r\n  };\r\n\r\n  process.on('SIGINT', stop);\r\n  process.on('SIGTERM', stop);\r\n});\r\n\r\nawait client.login(process.env.DISCORD_TOKEN);\r\n```\r\n\r\n## 🔒 Authentification & Sécurité\r\n\r\nToutes les requêtes requièrent deux en-têtes obligatoires :\r\n\r\n```ts\r\nconst core = new NSBCore({\r\n  token: process.env.NSB_TOKEN,   // Bearer token (haché SHA-256 côté serveur)\r\n  botId:  process.env.BOT_ID,     // ID Discord du bot\r\n  baseURL: 'https://api.neon-inc.fr/api/nsb' // Par défaut\r\n});\r\n```\r\n\r\n**Rate‑limiting :**\r\n- ✅ Bots autorisés : **55 req/s**\r\n- ⚠️  Tokens invalides : **1 req/s**\r\n- ❌ Dépassement → HTTP `429 (Too Many Requests)`\r\n\r\nEn cas d'erreur `401`, le SDK bascule automatiquement sur la limite basse.\r\n\r\n---\r\n\r\n## 🧪 Tests\r\n\r\n```bash\r\npnpm test        # Vitest en CI\r\npnpm test:watch  # watch mode\r\n```\r\n\r\n---\r\n\r\n## 🤝 Contribuer\r\n\r\n1. **Fork** puis `git checkout -b feat/ma-feature`\r\n2. `pnpm i && pnpm test`\r\n3. PR + description claire.\r\n\r\n> Toute idée ou bug ? Ouvrez une *Issue* — on répond vite !\r\n\r\n---\r\n\r\n## 📜 Licence\r\n\r\nMIT — © BCK Inc. 2025","readmeFilename":"README.md"}