seishiro 0.2.1-release → 0.2.2-release

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +201 -661
  2. package/README.md +1 -12
  3. package/cjs/action-tool/action-elysia.js +1 -0
  4. package/cjs/action-tool/action-express.js +1 -0
  5. package/cjs/action-tool/action-fastify.js +1 -0
  6. package/cjs/action-tool/action-hono.js +1 -0
  7. package/cjs/action-tool/action-next.js +1 -0
  8. package/cjs/action-tool/zod-validate.js +1 -0
  9. package/cjs/index.js +1 -1
  10. package/cjs/lib/actions.js +1 -1
  11. package/cjs/lib/message.js +1 -1
  12. package/cjs/lib/policy.js +1 -1
  13. package/cjs/lib/registry.js +1 -1
  14. package/cjs/utils/extract-lang.js +1 -1
  15. package/cjs/utils/format-key.js +1 -1
  16. package/cjs/utils/system-helpers.js +1 -0
  17. package/esm/action-tool/action-elysia.d.ts +18 -0
  18. package/esm/action-tool/action-elysia.js +1 -0
  19. package/esm/action-tool/action-express.d.ts +19 -0
  20. package/esm/action-tool/action-express.js +1 -0
  21. package/esm/action-tool/action-fastify.d.ts +18 -0
  22. package/esm/action-tool/action-fastify.js +1 -0
  23. package/esm/action-tool/action-hono.d.ts +18 -0
  24. package/esm/action-tool/action-hono.js +1 -0
  25. package/esm/action-tool/action-next.d.ts +19 -0
  26. package/esm/action-tool/action-next.js +1 -0
  27. package/esm/action-tool/zod-validate.d.ts +29 -0
  28. package/esm/action-tool/zod-validate.js +1 -0
  29. package/esm/index.d.ts +14 -0
  30. package/esm/index.js +1 -1
  31. package/esm/lib/actions.d.ts +18 -13
  32. package/esm/lib/actions.js +1 -1
  33. package/esm/lib/message.js +1 -1
  34. package/esm/lib/policy.js +1 -1
  35. package/esm/lib/registry.js +1 -1
  36. package/esm/utils/extract-lang.js +1 -1
  37. package/esm/utils/format-key.js +1 -1
  38. package/esm/utils/system-helpers.d.ts +15 -0
  39. package/esm/utils/system-helpers.js +1 -0
  40. package/package.json +9 -6
package/README.md CHANGED
@@ -1,18 +1,6 @@
1
1
  # Seishiro API
2
2
 
3
3
  Seishiro eliminates the complexity of routing folder structures and replaces them with a single control center. Just use one endpoint, manage it through the Registry, and control your entire application data flow (Web, Mobile, and SSR) with consistent standards.
4
- <!--
5
- ## Tasks
6
-
7
- - [x] Registry Controllers
8
- - [x] Message Builder Error
9
- - [x] UnRegistry Base System
10
- - [x] Multi Language Respon
11
- - [x] Protocol Response
12
- - [x] Middleware Runner
13
- - [x] Action Executed
14
- - [x] Versioning Header
15
- - [x] Language Switch -->
16
4
 
17
5
  ## Installation
18
6
 
@@ -22,6 +10,7 @@ Seishiro eliminates the complexity of routing folder structures and replaces the
22
10
  npm install seishiro
23
11
  # OR
24
12
  bun add seishiro
13
+ # OR
25
14
  yarn add seishiro
26
15
  ```
27
16
 
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionRequest=t,exports.ActionResponse=r;const e=require("../utils/system-helpers.js");async function t(t){const r=(0,e.mapHeaders)(t.request.headers),s={};t.cookie&&Object.entries(t.cookie).forEach(([e,t])=>s[e]=String(t.value).trim());const o=t.body||{};return{system:{headers:r,cookies:s,ip:(0,e.getIp)(r,t.request.headers.get("x-real-ip")),location:(0,e.getLocation)(r)},type:String(o?.type||""),data:o?.data||{}}}function r(e,t){if(!t.redirect)return Array.isArray(t.header)&&t.header.forEach(t=>{t.key&&t.value&&(e.headers[t.key]=t.value)}),e.status=t.status||200,t.response||{};e.redirect=t.redirect}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionRequest=r,exports.ActionResponse=o;const e=require("../utils/system-helpers.js");function r(r){const o=(0,e.mapHeaders)(r.headers),t={};r.cookies&&Object.entries(r.cookies).forEach(([e,r])=>t[e]=String(r).trim());const s=r.body||{};return{system:{headers:o,cookies:t,ip:(0,e.getIp)(o,r.ip||r.connection?.remoteAddress),location:(0,e.getLocation)(o)},type:String(s?.type||""),data:s?.data||{}}}function o(e,r){return r.redirect?e.redirect(r.redirect):(e.status(r.status||200),Array.isArray(r.header)&&r.header.forEach(r=>{r.key&&r.value&&e.set(r.key,r.value)}),Array.isArray(r.set_cookie)&&r.set_cookie.forEach(r=>{r.key&&r.value&&e.cookie(r.key,r.value,r.options||{})}),Array.isArray(r.rm_cookie)&&r.rm_cookie.forEach(r=>{const o="string"==typeof r?r:r?.key;o&&e.clearCookie(o)}),e.json(r.response||{}))}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionRequest=o,exports.ActionResponse=r;const e=require("../utils/system-helpers.js");function o(o){const r=(0,e.mapHeaders)(o.headers),t={};o.cookies&&Object.entries(o.cookies).forEach(([e,o])=>t[e]=String(o).trim());const s=o.body||{};return{system:{headers:r,cookies:t,ip:(0,e.getIp)(r,o.ip),location:(0,e.getLocation)(r)},type:String(s?.type||""),data:s?.data||{}}}function r(e,o){return o.redirect?e.redirect(o.redirect):(Array.isArray(o.header)&&o.header.forEach(o=>{o.key&&o.value&&e.header(o.key,o.value)}),Array.isArray(o.set_cookie)&&o.set_cookie.forEach(o=>{o.key&&o.value&&"function"==typeof e.setCookie?e.setCookie(o.key,o.value,o.options||{}):o.key&&o.value&&e.header("Set-Cookie",`${o.key}=${o.value}`,{append:!0})}),Array.isArray(o.rm_cookie)&&o.rm_cookie.forEach(o=>{const r="string"==typeof o?o:o?.key;r&&"function"==typeof e.clearCookie&&e.clearCookie(r)}),e.code(o.status||200).send(o.response||{}))}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionRequest=t,exports.ActionResponse=r;const e=require("../utils/system-helpers.js");async function t(t){const r=(0,e.mapHeaders)(t.req.header()),a={};(t.req.header("cookie")||"").split(";").forEach(e=>{const[t,r]=e.split("=").map(e=>e.trim());t&&r&&(a[t]=r)});let s={type:"",data:{}};try{s=(t.req.header("content-type")||"").includes("json")?await t.req.json():await t.req.parseBody()}catch(e){}return{system:{headers:r,cookies:a,ip:(0,e.getIp)(r),location:(0,e.getLocation)(r)},type:String(s?.type||""),data:s?.data||{}}}function r(e,t){return t.redirect?e.redirect(t.redirect):(Array.isArray(t.header)&&t.header.forEach(t=>{t.key&&t.value&&e.header(t.key,t.value)}),Array.isArray(t.set_cookie)&&t.set_cookie.forEach(t=>{t.key&&t.value&&e.header("Set-Cookie",`${t.key}=${t.value}`,{append:!0})}),e.json(t.response||{},t.status||200))}
@@ -0,0 +1 @@
1
+ "use strict";var e=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var n=Object.getOwnPropertyDescriptor(t,r);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,n)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),t=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(){var r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},r(e)};return function(o){if(o&&o.__esModule)return o;var n={};if(null!=o)for(var i=r(o),s=0;s<i.length;s++)"default"!==i[s]&&e(n,o,i[s]);return t(n,o),n}}();Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionRequest=n,exports.ActionResponse=i;const o=require("../utils/system-helpers.js");async function n(e){const{headers:t,cookies:n}=await Promise.resolve().then(()=>r(require("next/headers"))),{ipAddress:i}=await Promise.resolve().then(()=>r(require("@vercel/functions"))),s=await t(),a=await n(),c=(0,o.mapHeaders)(s),u=(0,o.getIp)(c,"function"==typeof i?i({headers:s}):void 0),l=(0,o.getLocation)(c),f=s.get("content-type")||"";let d={type:"",data:{}};try{if(f.includes("application/json"))d=await e.json();else if(f.includes("multipart/form-data")||f.includes("application/x-www-form-urlencoded")){const t=await e.formData(),r={};for(const[e,o]of t.entries()){const t=e.split(".");let n=r;for(let e=0;e<t.length;e++){const r=t[e];if(e===t.length-1)if(o instanceof Blob){const e=await o.arrayBuffer();n[r]=Buffer.from(e)}else n[r]=o;else n[r]=n[r]||{},n=n[r]}}d=r}}catch(e){console.error("[Seishiro ActionRequest]: Body parsing failed:",e.message)}const p={},y=a.getAll();if(Array.isArray(y))for(const e of y)p[e.name]=String(e.value).trim();return{system:{headers:c,cookies:p,ip:u,location:l},type:String(d?.type||""),data:d?.data||{}}}async function i(e,t){const{NextResponse:o}=await Promise.resolve().then(()=>r(require("next/server")));if(t.redirect)return o.redirect(new URL(t.redirect,e.url));const n=o.json(t.response||{},{status:t.status||200});return Array.isArray(t.header)&&t.header.forEach(e=>{e.key&&e.value&&n.headers.set(e.key,e.value)}),Array.isArray(t.set_cookie)&&t.set_cookie.forEach(e=>{e.key&&e.value&&n.cookies.set(e.key,e.value,e.options||{})}),Array.isArray(t.rm_cookie)&&t.rm_cookie.forEach(e=>{const t="string"==typeof e?e:e?.key;t&&n.cookies.delete(t)}),n}
@@ -0,0 +1 @@
1
+ "use strict";function r(r){const[e,...s]=String(r||"").trim().split("|");return{error:e,error_params:Object.fromEntries(s.map(r=>r.split(":")))}}function e(e="",s,t={}){const o=s.safeParse(t);if(o.success)return null;let n="";const a=o.error?.issues.map((e,s)=>{const t=r(e.message);return n+=(0===s?"":"|")+t.error.trim(),t.error_params})||[];return{error:`${e}:${n}`,params:a}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=e;
package/cjs/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.Actions=exports.PolicyBuilder=exports.MessageBuilder=exports.RegistryBuilder=void 0;var registry_js_1=require("./lib/registry.js");Object.defineProperty(exports,"RegistryBuilder",{enumerable:!0,get:function(){return __importDefault(registry_js_1).default}});var message_js_1=require("./lib/message.js");Object.defineProperty(exports,"MessageBuilder",{enumerable:!0,get:function(){return __importDefault(message_js_1).default}});var policy_js_1=require("./lib/policy.js");Object.defineProperty(exports,"PolicyBuilder",{enumerable:!0,get:function(){return __importDefault(policy_js_1).default}});var actions_js_1=require("./lib/actions.js");Object.defineProperty(exports,"Actions",{enumerable:!0,get:function(){return __importDefault(actions_js_1).default}});
1
+ "use strict";var e=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,i)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),t=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(){var r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},r(e)};return function(o){if(o&&o.__esModule)return o;var i={};if(null!=o)for(var n=r(o),u=0;u<n.length;u++)"default"!==n[u]&&e(i,o,n[u]);return t(i,o),i}}(),o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ActionTools=exports.Actions=exports.PolicyBuilder=exports.MessageBuilder=exports.RegistryBuilder=void 0;const i=o(require("./action-tool/zod-validate.js")),n=r(require("./action-tool/action-next.js")),u=r(require("./action-tool/action-express.js")),a=r(require("./action-tool/action-hono.js")),s=r(require("./action-tool/action-fastify.js")),l=r(require("./action-tool/action-elysia.js"));var c=require("./lib/registry.js");Object.defineProperty(exports,"RegistryBuilder",{enumerable:!0,get:function(){return o(c).default}});var f=require("./lib/message.js");Object.defineProperty(exports,"MessageBuilder",{enumerable:!0,get:function(){return o(f).default}});var d=require("./lib/policy.js");Object.defineProperty(exports,"PolicyBuilder",{enumerable:!0,get:function(){return o(d).default}});var p=require("./lib/actions.js");Object.defineProperty(exports,"Actions",{enumerable:!0,get:function(){return o(p).default}}),exports.ActionTools={ZodValidatorContent:i.default,NextJS:n,ExpressJS:u,Hono:a,Fastify:s,Elysia:l};
@@ -1 +1 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const crypto_1=__importDefault(require("crypto")),buffer_1=require("buffer"),extract_lang_js_1=__importDefault(require("../utils/extract-lang.js"));class Actions{registry;message;policy;cache_book;constructor({registry:e,message:t,policy:r}){this.registry=e,this.message=t,this.policy=r,this.cache_book=null}BookRegistry(){if(this.cache_book)return this.cache_book;const e="hex",t=crypto_1.default.randomBytes(16),r=this.policy.apply(),s=this.registry.apply(),i=crypto_1.default.createHash("sha256").update(String(r.passkey||"").trim()).digest(),o={listkey:Object.keys(s).filter(e=>!r.noaction_api.includes(e)),version_now:r.version_now,version_min:r.version_min,version_forceupdate:r.version_forceupdate},a=crypto_1.default.createCipheriv("aes-256-ctr",i,t),n=buffer_1.Buffer.concat([t,a.update(JSON.stringify(o),"utf-8"),a.final()]),c={iv_length:16,type_base:e,iv:t.toString(e),data:n.toString(e)};return this.cache_book=c,c}ResponseBuilder(e={},t,r="en"){const s=!e||"object"!=typeof e||Array.isArray(e)||!!e.error||!e.data,i=e?.status||(s?400:200),o=e?.redirect||null,a=[];if(e?.headers&&"object"==typeof e.headers&&!Array.isArray(e.headers))for(const[t,r]of Object.entries(e.headers))a.push({key:t,value:r});const n=[];if(Array.isArray(e?.set_cookie))for(const t of e.set_cookie)t&&"object"==typeof t&&t.key&&t.value&&n.push(t);const c=[];if(Array.isArray(e?.rm_cookie))for(const t of e.rm_cookie)t&&"string"==typeof t&&c.push(t);const l={header:a,set_cookie:n,rm_cookie:c,status:i,redirect:o};if(s){const t=e?.error||"system:no-response-sending",s=this.message.error(t,e?.params||[],r);return{...l,error:t,response:{status:i,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...l,error:null,response:{status:i,data:e.data||{}}}}async SystemAction({system:e,middleware:t={},context_manager:r="system-action",type:s,data:i}){const o=e?.headers||{},a=o["x-seishiro-lang"]||o["accept-language"],n=a?(0,extract_lang_js_1.default)(a):e?.lang||"en";try{const a=this.policy.apply(),c=o["x-seishiro-client"];if("api-action"===r&&!c)return this.ResponseBuilder({error:"system:client-version-required",status:400},e,n);if(c&&"api-action"===r){const t=this.policy.version_info(c);if(!t.is_version_min&&t.info_upgrade)return this.ResponseBuilder({error:"system:need-upgrade-client",status:426,params:[{min:a.version_min,now:a.version_now}]},e,n)}const l=this.registry.get(s||"");if(!l)return this.ResponseBuilder({error:"system:no-registry",status:404},e,n);const u={...e,lang:n};let p=t,y=l;if(Array.isArray(l)){const[e,r]=l,o=await e({system:u,middleware:t,type:s,data:i});p=a.skip_middleware_context||o?.skipBuilder?o:this.ResponseBuilder(o,u,n),y=r}const d=await y({system:u,middleware:p,type:s,data:i});return this.ResponseBuilder(d,u,n)}catch(t){return console.error("[Seishiro Core Error]:",t),this.ResponseBuilder({error:"system:internal-server-error",status:500},e,n)}}async ServerAction({system:e,middleware:t,type:r,data:s}){if(this.policy.apply().noaction_server.includes(r||"")){const t=(0,extract_lang_js_1.default)(e?.headers?.["x-seishiro-lang"]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,t)}return this.SystemAction({system:e,middleware:t,context_manager:"server-action",type:r,data:s})}async APIAction({system:e,middleware:t,type:r,data:s}){if(this.policy.apply().noaction_api.includes(r||"")){const t=(0,extract_lang_js_1.default)(e?.headers?.["x-seishiro-lang"]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,t)}return this.SystemAction({system:e,middleware:t,context_manager:"api-action",type:r,data:s})}}exports.default=Actions;
1
+ "use strict";var e=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const t=e(require("../utils/extract-lang.js")),r=e(require("crypto")),s=require("buffer");class i{registry;message;policy;heading;cache_book;constructor({registry:e,message:t,policy:r,heading:s={version:"x-seishiro-client",lang:"x-seishiro-lang"}}){this.registry=e,this.message=t,this.policy=r,this.heading=s,this.cache_book=null}BookRegistry(){if(this.cache_book)return this.cache_book;const e="hex",t=r.default.randomBytes(16),i=this.policy.apply(),a=this.registry.apply(),n=r.default.createHash("sha256").update(String(i.passkey||"").trim()).digest(),o={listkey:Object.keys(a).filter(e=>!i.noaction_api.includes(e)),version_now:i.version_now,version_min:i.version_min,version_forceupdate:i.version_forceupdate},c=r.default.createCipheriv("aes-256-ctr",n,t),l=s.Buffer.concat([t,c.update(JSON.stringify(o),"utf-8"),c.final()]),d={iv_length:16,type_base:e,iv:t.toString(e),data:l.toString(e)};return this.cache_book=d,d}ResponseBuilder(e={},t,r="en"){const s=!e||"object"!=typeof e||Array.isArray(e)||!!e.error||!e.data,i=e?.status||(s?400:200),a={header:Object.entries(e?.headers||{}).filter(([e,t])=>void 0!==t).map(([e,t])=>({key:e,value:t})),set_cookie:(Array.isArray(e?.set_cookie)?e.set_cookie:[]).filter(e=>e?.key&&e?.value),rm_cookie:(Array.isArray(e?.rm_cookie)?e.rm_cookie:[]).filter(e=>"string"==typeof e||e?.key),status:i,redirect:e?.redirect||null};if(s){const t=e?.error||"system:no-response-sending",s=this.message.error(t,e?.params||[],r);return{...a,error:t,response:{status:i,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...a,error:null,response:{status:i,data:e.data||{}}}}async SystemAction({system:e,middleware:r={},context_manager:s="system-action",type:i,data:a}){const n=(0,t.default)(e?.headers?.[this.heading.lang]||e?.headers?.["accept-language"]||e?.lang||"en");try{const t=this.policy.apply(),o=String(e?.headers?.[this.heading.version]||"").trim();if("api-action"===s&&!o)return this.ResponseBuilder({error:"system:client-version-required",status:400},e,n);if(o&&"api-action"===s){const r=this.policy.version_info(o);if(!r.is_version_min&&r.info_upgrade)return this.ResponseBuilder({error:"system:need-upgrade-client",status:426,params:[{min:t.version_min,now:t.version_now}]},e,n)}const c=this.registry.get(i||"");if(!c)return this.ResponseBuilder({error:"system:no-registry",status:404},e,n);const l={...e,lang:n};let d=r,u=c;if(Array.isArray(c)){const[e,s]=c,o=await e({system:l,middleware:r,type:i,data:a});d=t.skip_middleware_context||o?.skipBuilder?o:this.ResponseBuilder(o,l,n),u=s}const y=await u({system:l,middleware:d,type:i,data:a});return this.ResponseBuilder(y,l,n)}catch(t){return console.error("[Seishiro Core Error]:",t),this.ResponseBuilder({error:"system:internal-server-error",status:500},e,n)}}async ServerAction({system:e,middleware:r,type:s,data:i}){if(this.policy.apply().noaction_server.includes(s||"")){const r=(0,t.default)(e?.headers?.[this.heading.lang]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,r)}return this.SystemAction({system:e,middleware:r,context_manager:"server-action",type:s,data:i})}async APIAction({system:e,middleware:r,type:s,data:i}){if(this.policy.apply().noaction_api.includes(s||"")){const r=(0,t.default)(e?.headers?.[this.heading.lang]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,r)}return this.SystemAction({system:e,middleware:r,context_manager:"api-action",type:s,data:i})}}exports.default=i;
@@ -1 +1 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const format_key_js_1=__importDefault(require("../utils/format-key.js")),message_js_1=require("../constants/message.js");class MessageBuilder{message_build_lang="";message_logic=new Map;constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic=new Map}set(e,s){if("string"!=typeof s||"string"!=typeof e)throw new Error("Key and Value must be string!");const t=(0,format_key_js_1.default)(e);this.message_logic.has(this.message_build_lang)||this.message_logic.set(this.message_build_lang,new Map),this.message_logic.get(this.message_build_lang).set(t,s.trim())}get(e="",s=this.message_build_lang){const t=(0,format_key_js_1.default)(e);let a=this.message_logic.get(s);return a||(a=this.message_logic.get(message_js_1.DefaultLanguage),!a&&this.message_logic.size>0&&(a=this.message_logic.values().next().value)),a?a.get(t)||"":`[!NoneVariable ${t}]`}errorMessage(e="",s={},t=this.message_build_lang){const a=this.get(e,t);return s&&0!==Object.keys(s).length?a.replace(/{{(\w+)}}/g,(e,t)=>s[t]||e):a}error(e="",s=[],t=this.message_build_lang){const a=e.indexOf(":");if(-1===a)return{protocol:"unknown",context:[e],params:s,message:e};const i=(0,format_key_js_1.default)(e.substring(0,a)),r=e.substring(a+1).split("|");let g="";for(let e=0;e<r.length;e++){g+=(0===e?"":", ")+this.errorMessage(r[e],s[e],t)}return{protocol:i,context:r,params:s,message:g}}apply(){return this.message_logic}use(e){if(e instanceof MessageBuilder){e.apply().forEach((e,s)=>{let t=this.message_logic.get(s);t||(t=new Map,this.message_logic.set(s,t)),e.forEach((e,s)=>{t.set(s,e)})})}else{if("object"!=typeof e||null===e)throw new Error('The "use" input must be a MessageBuilder or mapping object!');for(const s in e)Object.prototype.hasOwnProperty.call(e,s)&&this.set(s,e[s])}}}exports.default=MessageBuilder;
1
+ "use strict";var e=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const s=e(require("../utils/format-key.js")),t=require("../constants/message.js");class a{message_build_lang="";message_logic=new Map;constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic=new Map}set(e,t){if("string"!=typeof t||"string"!=typeof e)throw new Error("Key and Value must be string!");this.message_logic.has(this.message_build_lang)||this.message_logic.set(this.message_build_lang,new Map),this.message_logic.get(this.message_build_lang).set((0,s.default)(e),t.trim())}get(e="",a=this.message_build_lang){const i=(0,s.default)(e);let g=this.message_logic.get(a);return g||(g=this.message_logic.get(t.DefaultLanguage),!g&&this.message_logic.size>0&&(g=this.message_logic.values().next().value)),g?g.get(i)||"":`[!NoneVariable ${i}]`}errorMessage(e="",s={},t=this.message_build_lang){const a=this.get(e,t);return s&&0!==Object.keys(s).length?a.replace(/{{(\w+)}}/g,(e,t)=>s[t]||e):a}error(e="",t=[],a=this.message_build_lang){const i=e.indexOf(":");if(-1===i)return{protocol:"unknown",context:[e],params:t,message:e};const g=(0,s.default)(e.substring(0,i)),r=e.substring(i+1).split("|");let l="";for(let e=0;e<r.length;e++){l+=(0===e?"":", ")+this.errorMessage(r[e],t[e],a)}return{protocol:g,context:r,params:t,message:l}}apply(){return this.message_logic}use(e){if(e instanceof a)e.apply().forEach((e,s)=>{const t=this.message_logic.get(s)||new Map;this.message_logic.has(s)||this.message_logic.set(s,t),e.forEach((e,s)=>t.set(s,e))});else{if("object"!=typeof e||!e)throw new Error("Invalid 'use' input!");Object.entries(e).forEach(([e,s])=>this.set(e,String(s)))}}}exports.default=a;
package/cjs/lib/policy.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});class PolicyBuilder{passkey;version_now;version_min;version_forceupdate;noaction_api;noaction_server;compiled_policy=null;skip_middleware_context;parsed_min;parsed_now;constructor({passkey:e,version_now:i,version_min:o,version_forceupdate:s=!0,skip_middleware_context:r=!1}){if(!e||!i||!o)throw new Error("PolicyBuilder: passkey, version_now, and version_min are required!");this.passkey=e,this.version_now=i,this.version_min=o,this.parsed_min=this.parseVersion(o),this.parsed_now=this.parseVersion(i),this.version_forceupdate=s,this.noaction_api=[],this.noaction_server=[],this.skip_middleware_context=r,this.refresh()}noaction(e="",i=[]){const o=["server-action","api-action"];for(let e of i)if(!o.includes(e))throw new Error(`Invalid action type: ${e}. Only allowed actions are: ${o.join(", ")}`);if("string"!=typeof e)throw new Error("Invalid key type, it only string!");for(let o of i)"api-action"===o?this.noaction_api.push(e):"server-action"===o&&this.noaction_server.push(e)}parseVersion(e){return e.split(".").map(Number)}compare(e,i){const o=Math.max(e.length,i.length);for(let s=0;s<o;s++){const o=e[s]||0,r=i[s]||0;if(o!==r)return o>r?1:-1}return 0}version_info(e=""){const i=this.parseVersion(e);return{info_upgrade:this.version_forceupdate,is_version_min:this.compare(i,this.parsed_min)>=0,is_version_now:this.compare(i,this.parsed_now)>=0}}refresh(){this.compiled_policy={passkey:this.passkey,version_now:this.version_now,version_min:this.version_min,version_forceupdate:this.version_forceupdate,noaction_api:this.noaction_api,noaction_server:this.noaction_server,skip_middleware_context:this.skip_middleware_context}}apply(){return this.compiled_policy}}exports.default=PolicyBuilder;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});class e{passkey;version_now;version_min;version_forceupdate;noaction_api;noaction_server;compiled_policy=null;skip_middleware_context;parsed_min;parsed_now;constructor({passkey:e,version_now:i,version_min:o,version_forceupdate:s=!0,skip_middleware_context:r=!1}){if(!e||!i||!o)throw new Error("PolicyBuilder: passkey, version_now, and version_min are required!");this.passkey=e,this.version_now=i,this.version_min=o,this.parsed_min=this.parseVersion(o),this.parsed_now=this.parseVersion(i),this.version_forceupdate=s,this.noaction_api=[],this.noaction_server=[],this.skip_middleware_context=r,this.refresh()}noaction(e="",i=[]){const o=["server-action","api-action"];for(let e of i)if(!o.includes(e))throw new Error(`Invalid action type: ${e}. Only allowed actions are: ${o.join(", ")}`);if("string"!=typeof e)throw new Error("Invalid key type, it only string!");for(let o of i)"api-action"===o?this.noaction_api.push(e):"server-action"===o&&this.noaction_server.push(e)}parseVersion(e){return e.split(".").map(Number)}compare(e,i){const o=Math.max(e.length,i.length);for(let s=0;s<o;s++){const o=e[s]||0,r=i[s]||0;if(o!==r)return o>r?1:-1}return 0}version_info(e=""){const i=this.parseVersion(e);return{info_upgrade:this.version_forceupdate,is_version_min:this.compare(i,this.parsed_min)>=0,is_version_now:this.compare(i,this.parsed_now)>=0}}refresh(){this.compiled_policy={passkey:this.passkey,version_now:this.version_now,version_min:this.version_min,version_forceupdate:this.version_forceupdate,noaction_api:this.noaction_api,noaction_server:this.noaction_server,skip_middleware_context:this.skip_middleware_context}}apply(){return this.compiled_policy}}exports.default=e;
@@ -1 +1 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0});const format_key_js_1=__importDefault(require("../utils/format-key.js"));class RegistryBuilder{registry_logic;constructor(){this.registry_logic=new Map}set(t,e,r){const i=(0,format_key_js_1.default)(t);if("function"!=typeof e)throw new Error("Registry function is only type function!");if("string"!=typeof t)throw new Error("Registry key is only type string!");r&&"function"==typeof r?this.registry_logic.set(i,[r,e]):this.registry_logic.set(i,e)}get(t){const e=(0,format_key_js_1.default)(t);return this.registry_logic.get(e)||void 0}apply(){return this.registry_logic}use(t){if(t instanceof RegistryBuilder)for(const[e,r]of t.registry_logic)this.registry_logic.set(e,r);else{if("object"!=typeof t||null===t)throw new Error('The "use" input must be a RegistryBuilder or mapping object!');for(const[e,r]of Object.entries(t))Array.isArray(r)?this.set(e,r[1],r[0]):"function"==typeof r&&this.set(e,r)}}}exports.default=RegistryBuilder;
1
+ "use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0});const e=t(require("../utils/format-key.js"));class r{registry_logic;constructor(){this.registry_logic=new Map}set(t,r,i){const s=(0,e.default)(t);if("function"!=typeof r)throw new Error("Registry function is only type function!");if("string"!=typeof t)throw new Error("Registry key is only type string!");i&&"function"==typeof i?this.registry_logic.set(s,[i,r]):this.registry_logic.set(s,r)}get(t){const r=(0,e.default)(t);return this.registry_logic.get(r)||void 0}apply(){return this.registry_logic}use(t){if(t instanceof r)t.apply().forEach((t,e)=>this.registry_logic.set(e,t));else{if("object"!=typeof t||!t)throw new Error("Invalid 'use' input!");Object.entries(t).forEach(([t,e])=>{Array.isArray(e)?this.set(t,e[1],e[0]):this.set(t,e)})}}}exports.default=r;
@@ -1 +1 @@
1
- "use strict";function extractLanguage(t=""){return String(t||"").trim().split(",").map(t=>t.split(";")[0].split("-")[0].trim()).filter((t,e,r)=>r.indexOf(t)===e)[0]}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=extractLanguage;
1
+ "use strict";function e(e=""){return(String(e||"").split(",")[0]||"en").split(";")[0].split("-")[0].trim().toLowerCase()||"en"}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=e;
@@ -1 +1 @@
1
- "use strict";function formatKey(e=""){const t=String(e||"").trim().replace(/[^a-zA-Z0-9-.:]/g,"");return String(t||"").toLowerCase()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=formatKey;
1
+ "use strict";function e(e=""){const t=String(e||"").trim().replace(/[^a-zA-Z0-9-.:]/g,"");return String(t||"").toLowerCase()}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=e;
@@ -0,0 +1 @@
1
+ "use strict";function r(r){const e={};if(!r)return e;if("function"==typeof r.forEach)r.forEach((r,t)=>{e[t.toLowerCase()]=String(r).trim()});else for(const[t,o]of Object.entries(r))e[t.toLowerCase()]=Array.isArray(o)?o.join(", "):String(o||"").trim();return e}function e(r,e){return r["x-real-ip"]||r["x-forwarded-for"]?.split(",")[0].trim()||e||"127.0.0.1"}function t(r){return r["x-vercel-ip-country"]?[r["x-vercel-ip-country"],r["x-vercel-ip-country-region"],r["x-vercel-ip-city"]].filter(Boolean).join(", "):r["cf-ipcountry"]||"Local/Unknown"}Object.defineProperty(exports,"__esModule",{value:!0}),exports.mapHeaders=r,exports.getIp=e,exports.getLocation=t;
@@ -0,0 +1,18 @@
1
+ export declare function ActionRequest(ctx: any): Promise<{
2
+ system: {
3
+ headers: Record<string, string>;
4
+ cookies: Record<string, string>;
5
+ ip: string;
6
+ location: string;
7
+ };
8
+ type: string;
9
+ data: any;
10
+ }>;
11
+ /**
12
+ * @function ActionResponse
13
+ * @description Constructs an Elysia response using the context (set) object.
14
+ * @param {any} set - The Elysia set object (set).
15
+ * @param {any} requestdata - The response configuration from Seishiro.
16
+ * @returns {any} The JSON response object.
17
+ */
18
+ export declare function ActionResponse(set: any, requestdata: any): any;
@@ -0,0 +1 @@
1
+ import{mapHeaders as e,getIp as r,getLocation as t}from"../utils/system-helpers.js";export async function ActionRequest(s){const o=e(s.request.headers),a={};s.cookie&&Object.entries(s.cookie).forEach(([e,r])=>a[e]=String(r.value).trim());const i=s.body||{};return{system:{headers:o,cookies:a,ip:r(o,s.request.headers.get("x-real-ip")),location:t(o)},type:String(i?.type||""),data:i?.data||{}}}export function ActionResponse(e,r){if(!r.redirect)return Array.isArray(r.header)&&r.header.forEach(r=>{r.key&&r.value&&(e.headers[r.key]=r.value)}),e.status=r.status||200,r.response||{};e.redirect=r.redirect}
@@ -0,0 +1,19 @@
1
+ export declare function ActionRequest(req: any): {
2
+ system: {
3
+ headers: Record<string, string>;
4
+ cookies: Record<string, string>;
5
+ ip: string;
6
+ location: string;
7
+ };
8
+ type: string;
9
+ data: any;
10
+ };
11
+ /**
12
+ * @function ActionResponse
13
+ * @description Constructs an Express.js Response object, handling redirects,
14
+ * response data, custom headers, and cookie management.
15
+ * @param {any} res - The Express.js Response object (res).
16
+ * @param {any} requestdata - The response configuration from Seishiro.
17
+ * @returns {any} The Express response object.
18
+ */
19
+ export declare function ActionResponse(res: any, requestdata: any): any;
@@ -0,0 +1 @@
1
+ import{mapHeaders as e,getIp as r,getLocation as o}from"../utils/system-helpers.js";export function ActionRequest(t){const s=e(t.headers),i={};t.cookies&&Object.entries(t.cookies).forEach(([e,r])=>i[e]=String(r).trim());const c=t.body||{};return{system:{headers:s,cookies:i,ip:r(s,t.ip||t.connection?.remoteAddress),location:o(s)},type:String(c?.type||""),data:c?.data||{}}}export function ActionResponse(e,r){return r.redirect?e.redirect(r.redirect):(e.status(r.status||200),Array.isArray(r.header)&&r.header.forEach(r=>{r.key&&r.value&&e.set(r.key,r.value)}),Array.isArray(r.set_cookie)&&r.set_cookie.forEach(r=>{r.key&&r.value&&e.cookie(r.key,r.value,r.options||{})}),Array.isArray(r.rm_cookie)&&r.rm_cookie.forEach(r=>{const o="string"==typeof r?r:r?.key;o&&e.clearCookie(o)}),e.json(r.response||{}))}
@@ -0,0 +1,18 @@
1
+ export declare function ActionRequest(req: any): {
2
+ system: {
3
+ headers: Record<string, string>;
4
+ cookies: Record<string, string>;
5
+ ip: string;
6
+ location: string;
7
+ };
8
+ type: string;
9
+ data: any;
10
+ };
11
+ /**
12
+ * @function ActionResponse
13
+ * @description Constructs a Fastify Response using the reply object.
14
+ * @param {any} reply - The Fastify Reply object (reply).
15
+ * @param {any} requestdata - The response configuration from Seishiro.
16
+ * @returns {any} The Fastify reply object.
17
+ */
18
+ export declare function ActionResponse(reply: any, requestdata: any): any;
@@ -0,0 +1 @@
1
+ import{mapHeaders as e,getIp as o,getLocation as r}from"../utils/system-helpers.js";export function ActionRequest(t){const i=e(t.headers),s={};t.cookies&&Object.entries(t.cookies).forEach(([e,o])=>s[e]=String(o).trim());const a=t.body||{};return{system:{headers:i,cookies:s,ip:o(i,t.ip),location:r(i)},type:String(a?.type||""),data:a?.data||{}}}export function ActionResponse(e,o){return o.redirect?e.redirect(o.redirect):(Array.isArray(o.header)&&o.header.forEach(o=>{o.key&&o.value&&e.header(o.key,o.value)}),Array.isArray(o.set_cookie)&&o.set_cookie.forEach(o=>{o.key&&o.value&&"function"==typeof e.setCookie?e.setCookie(o.key,o.value,o.options||{}):o.key&&o.value&&e.header("Set-Cookie",`${o.key}=${o.value}`,{append:!0})}),Array.isArray(o.rm_cookie)&&o.rm_cookie.forEach(o=>{const r="string"==typeof o?o:o?.key;r&&"function"==typeof e.clearCookie&&e.clearCookie(r)}),e.code(o.status||200).send(o.response||{}))}
@@ -0,0 +1,18 @@
1
+ export declare function ActionRequest(c: any): Promise<{
2
+ system: {
3
+ headers: Record<string, string>;
4
+ cookies: Record<string, string>;
5
+ ip: string;
6
+ location: string;
7
+ };
8
+ type: string;
9
+ data: any;
10
+ }>;
11
+ /**
12
+ * @function ActionResponse
13
+ * @description Constructs a Hono Response using the context object.
14
+ * @param {any} c - The Hono Context object (c).
15
+ * @param {any} requestdata - The response configuration from Seishiro.
16
+ * @returns {any} The Hono response object.
17
+ */
18
+ export declare function ActionResponse(c: any, requestdata: any): any;
@@ -0,0 +1 @@
1
+ import{mapHeaders as e,getIp as r,getLocation as t}from"../utils/system-helpers.js";export async function ActionRequest(a){const o=e(a.req.header()),s={};(a.req.header("cookie")||"").split(";").forEach(e=>{const[r,t]=e.split("=").map(e=>e.trim());r&&t&&(s[r]=t)});let i={type:"",data:{}};try{i=(a.req.header("content-type")||"").includes("json")?await a.req.json():await a.req.parseBody()}catch(e){}return{system:{headers:o,cookies:s,ip:r(o),location:t(o)},type:String(i?.type||""),data:i?.data||{}}}export function ActionResponse(e,r){return r.redirect?e.redirect(r.redirect):(Array.isArray(r.header)&&r.header.forEach(r=>{r.key&&r.value&&e.header(r.key,r.value)}),Array.isArray(r.set_cookie)&&r.set_cookie.forEach(r=>{r.key&&r.value&&e.header("Set-Cookie",`${r.key}=${r.value}`,{append:!0})}),e.json(r.response||{},r.status||200))}
@@ -0,0 +1,19 @@
1
+ export declare function ActionRequest(req: Request): Promise<{
2
+ system: {
3
+ headers: Record<string, string>;
4
+ cookies: Record<string, string>;
5
+ ip: string;
6
+ location: string;
7
+ };
8
+ type: string;
9
+ data: any;
10
+ }>;
11
+ /**
12
+ * @function ActionResponse
13
+ * @description Constructs a Next.js Response object, handling redirects,
14
+ * response data, custom headers, and cookie management.
15
+ * @param {Request} req - The original Request object (used for absolute URL redirects).
16
+ * @param {any} requestdata - The response configuration from Seishiro.
17
+ * @returns {Promise<Response>} A Next.js NextResponse object.
18
+ */
19
+ export declare function ActionResponse(req: Request, requestdata: any): Promise<any>;
@@ -0,0 +1 @@
1
+ import{mapHeaders as e,getIp as t,getLocation as r}from"../utils/system-helpers.js";export async function ActionRequest(o){const{headers:s,cookies:a}=await import("next/headers"),{ipAddress:i}=await import("@vercel/functions"),n=await s(),c=await a(),l=e(n),f=t(l,"function"==typeof i?i({headers:n}):void 0),p=r(l),y=n.get("content-type")||"";let d={type:"",data:{}};try{if(y.includes("application/json"))d=await o.json();else if(y.includes("multipart/form-data")||y.includes("application/x-www-form-urlencoded")){const e=await o.formData(),t={};for(const[r,o]of e.entries()){const e=r.split(".");let s=t;for(let t=0;t<e.length;t++){const r=e[t];if(t===e.length-1)if(o instanceof Blob){const e=await o.arrayBuffer();s[r]=Buffer.from(e)}else s[r]=o;else s[r]=s[r]||{},s=s[r]}}d=t}}catch(e){console.error("[Seishiro ActionRequest]: Body parsing failed:",e.message)}const u={},m=c.getAll();if(Array.isArray(m))for(const e of m)u[e.name]=String(e.value).trim();return{system:{headers:l,cookies:u,ip:f,location:p},type:String(d?.type||""),data:d?.data||{}}}export async function ActionResponse(e,t){const{NextResponse:r}=await import("next/server");if(t.redirect)return r.redirect(new URL(t.redirect,e.url));const o=r.json(t.response||{},{status:t.status||200});return Array.isArray(t.header)&&t.header.forEach(e=>{e.key&&e.value&&o.headers.set(e.key,e.value)}),Array.isArray(t.set_cookie)&&t.set_cookie.forEach(e=>{e.key&&e.value&&o.cookies.set(e.key,e.value,e.options||{})}),Array.isArray(t.rm_cookie)&&t.rm_cookie.forEach(e=>{const t="string"==typeof e?e:e?.key;t&&o.cookies.delete(t)}),o}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @interface ZodLike
3
+ * @description Defines a minimal Zod-compatible interface to allow structural typing
4
+ * without a direct dependency on the Zod library.
5
+ */
6
+ interface ZodLike {
7
+ safeParse(data: any): {
8
+ success: boolean;
9
+ error?: {
10
+ issues: Array<{
11
+ message: string;
12
+ }>;
13
+ };
14
+ };
15
+ }
16
+ /**
17
+ * @function ValidatorContent
18
+ * @description Validates the provided data against a Zod schema (zodObject) and returns
19
+ * formatted error messages compatible with the Seishiro message system.
20
+ * @param {string} schemaProtocol - The protocol identifier for the error message (e.g., "auth").
21
+ * @param {ZodLike} zodObject - A Zod schema object or any object implementing .safeParse().
22
+ * @param {any} data - The data payload to be validated.
23
+ * @returns {null|Object} Returns null if validation succeeds, or a formatted error object if it fails.
24
+ */
25
+ export default function ZodValidatorContent(schemaProtocol: string | undefined, zodObject: ZodLike, data?: any): {
26
+ error: string;
27
+ params: any[];
28
+ } | null;
29
+ export {};
@@ -0,0 +1 @@
1
+ function r(r){const[e,...s]=String(r||"").trim().split("|");return{error:e,error_params:Object.fromEntries(s.map(r=>r.split(":")))}}export default function e(e="",s,t={}){const n=s.safeParse(t);if(n.success)return null;let o="";const a=n.error?.issues.map((e,s)=>{const t=r(e.message);return o+=(0===s?"":"|")+t.error.trim(),t.error_params})||[];return{error:`${e}:${o}`,params:a}}
package/esm/index.d.ts CHANGED
@@ -1,4 +1,18 @@
1
+ import ZodValidatorContent from "./action-tool/zod-validate.js";
2
+ import * as NextJSAction from "./action-tool/action-next.js";
3
+ import * as ExpressJSAction from "./action-tool/action-express.js";
4
+ import * as HonoAction from "./action-tool/action-hono.js";
5
+ import * as FastifyAction from "./action-tool/action-fastify.js";
6
+ import * as ElysiaAction from "./action-tool/action-elysia.js";
1
7
  export { default as RegistryBuilder } from "./lib/registry.js";
2
8
  export { default as MessageBuilder } from "./lib/message.js";
3
9
  export { default as PolicyBuilder } from "./lib/policy.js";
4
10
  export { default as Actions } from "./lib/actions.js";
11
+ export declare const ActionTools: {
12
+ ZodValidatorContent: typeof ZodValidatorContent;
13
+ NextJS: typeof NextJSAction;
14
+ ExpressJS: typeof ExpressJSAction;
15
+ Hono: typeof HonoAction;
16
+ Fastify: typeof FastifyAction;
17
+ Elysia: typeof ElysiaAction;
18
+ };
package/esm/index.js CHANGED
@@ -1 +1 @@
1
- export{default as RegistryBuilder}from"./lib/registry.js";export{default as MessageBuilder}from"./lib/message.js";export{default as PolicyBuilder}from"./lib/policy.js";export{default as Actions}from"./lib/actions.js";
1
+ import o from"./action-tool/zod-validate.js";import*as t from"./action-tool/action-next.js";import*as i from"./action-tool/action-express.js";import*as s from"./action-tool/action-hono.js";import*as a from"./action-tool/action-fastify.js";import*as r from"./action-tool/action-elysia.js";export{default as RegistryBuilder}from"./lib/registry.js";export{default as MessageBuilder}from"./lib/message.js";export{default as PolicyBuilder}from"./lib/policy.js";export{default as Actions}from"./lib/actions.js";export const ActionTools={ZodValidatorContent:o,NextJS:t,ExpressJS:i,Hono:s,Fastify:a,Elysia:r};
@@ -11,6 +11,7 @@ export default class Actions {
11
11
  private registry;
12
12
  private message;
13
13
  private policy;
14
+ private heading;
14
15
  private cache_book;
15
16
  /**
16
17
  * @constructor
@@ -19,10 +20,14 @@ export default class Actions {
19
20
  * @param {MessageBuilder} params.message - Instance to handle localized error/response messages.
20
21
  * @param {PolicyBuilder} params.policy - Instance to manage security and versioning rules.
21
22
  */
22
- constructor({ registry, message, policy, }: {
23
+ constructor({ registry, message, policy, heading, }: {
23
24
  registry: RegistryBuilder;
24
25
  message: MessageBuilder;
25
26
  policy: PolicyBuilder;
27
+ heading?: {
28
+ version: string;
29
+ lang: string;
30
+ };
26
31
  });
27
32
  /**
28
33
  * @method BookRegistry
@@ -65,8 +70,8 @@ export default class Actions {
65
70
  key: string;
66
71
  value: unknown;
67
72
  }[];
68
- set_cookie: any[];
69
- rm_cookie: string[];
73
+ set_cookie: any;
74
+ rm_cookie: any;
70
75
  status: any;
71
76
  redirect: any;
72
77
  } | {
@@ -83,8 +88,8 @@ export default class Actions {
83
88
  key: string;
84
89
  value: unknown;
85
90
  }[];
86
- set_cookie: any[];
87
- rm_cookie: string[];
91
+ set_cookie: any;
92
+ rm_cookie: any;
88
93
  status: any;
89
94
  redirect: any;
90
95
  }>;
@@ -109,8 +114,8 @@ export default class Actions {
109
114
  key: string;
110
115
  value: unknown;
111
116
  }[];
112
- set_cookie: any[];
113
- rm_cookie: string[];
117
+ set_cookie: any;
118
+ rm_cookie: any;
114
119
  status: any;
115
120
  redirect: any;
116
121
  } | {
@@ -127,8 +132,8 @@ export default class Actions {
127
132
  key: string;
128
133
  value: unknown;
129
134
  }[];
130
- set_cookie: any[];
131
- rm_cookie: string[];
135
+ set_cookie: any;
136
+ rm_cookie: any;
132
137
  status: any;
133
138
  redirect: any;
134
139
  }>;
@@ -153,8 +158,8 @@ export default class Actions {
153
158
  key: string;
154
159
  value: unknown;
155
160
  }[];
156
- set_cookie: any[];
157
- rm_cookie: string[];
161
+ set_cookie: any;
162
+ rm_cookie: any;
158
163
  status: any;
159
164
  redirect: any;
160
165
  } | {
@@ -171,8 +176,8 @@ export default class Actions {
171
176
  key: string;
172
177
  value: unknown;
173
178
  }[];
174
- set_cookie: any[];
175
- rm_cookie: string[];
179
+ set_cookie: any;
180
+ rm_cookie: any;
176
181
  status: any;
177
182
  redirect: any;
178
183
  }>;
@@ -1 +1 @@
1
- import crypto from"crypto";import{Buffer}from"buffer";import extractLanguage from"../utils/extract-lang.js";export default class Actions{registry;message;policy;cache_book;constructor({registry:e,message:r,policy:t}){this.registry=e,this.message=r,this.policy=t,this.cache_book=null}BookRegistry(){if(this.cache_book)return this.cache_book;const e="hex",r=crypto.randomBytes(16),t=this.policy.apply(),s=this.registry.apply(),o=crypto.createHash("sha256").update(String(t.passkey||"").trim()).digest(),i={listkey:Object.keys(s).filter(e=>!t.noaction_api.includes(e)),version_now:t.version_now,version_min:t.version_min,version_forceupdate:t.version_forceupdate},a=crypto.createCipheriv("aes-256-ctr",o,r),n=Buffer.concat([r,a.update(JSON.stringify(i),"utf-8"),a.final()]),c={iv_length:16,type_base:e,iv:r.toString(e),data:n.toString(e)};return this.cache_book=c,c}ResponseBuilder(e={},r,t="en"){const s=!e||"object"!=typeof e||Array.isArray(e)||!!e.error||!e.data,o=e?.status||(s?400:200),i=e?.redirect||null,a=[];if(e?.headers&&"object"==typeof e.headers&&!Array.isArray(e.headers))for(const[r,t]of Object.entries(e.headers))a.push({key:r,value:t});const n=[];if(Array.isArray(e?.set_cookie))for(const r of e.set_cookie)r&&"object"==typeof r&&r.key&&r.value&&n.push(r);const c=[];if(Array.isArray(e?.rm_cookie))for(const r of e.rm_cookie)r&&"string"==typeof r&&c.push(r);const p={header:a,set_cookie:n,rm_cookie:c,status:o,redirect:i};if(s){const r=e?.error||"system:no-response-sending",s=this.message.error(r,e?.params||[],t);return{...p,error:r,response:{status:o,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...p,error:null,response:{status:o,data:e.data||{}}}}async SystemAction({system:e,middleware:r={},context_manager:t="system-action",type:s,data:o}){const i=e?.headers||{},a=i["x-seishiro-lang"]||i["accept-language"],n=a?extractLanguage(a):e?.lang||"en";try{const a=this.policy.apply(),c=i["x-seishiro-client"];if("api-action"===t&&!c)return this.ResponseBuilder({error:"system:client-version-required",status:400},e,n);if(c&&"api-action"===t){const r=this.policy.version_info(c);if(!r.is_version_min&&r.info_upgrade)return this.ResponseBuilder({error:"system:need-upgrade-client",status:426,params:[{min:a.version_min,now:a.version_now}]},e,n)}const p=this.registry.get(s||"");if(!p)return this.ResponseBuilder({error:"system:no-registry",status:404},e,n);const y={...e,lang:n};let l=r,u=p;if(Array.isArray(p)){const[e,t]=p,i=await e({system:y,middleware:r,type:s,data:o});l=a.skip_middleware_context||i?.skipBuilder?i:this.ResponseBuilder(i,y,n),u=t}const d=await u({system:y,middleware:l,type:s,data:o});return this.ResponseBuilder(d,y,n)}catch(r){return console.error("[Seishiro Core Error]:",r),this.ResponseBuilder({error:"system:internal-server-error",status:500},e,n)}}async ServerAction({system:e,middleware:r,type:t,data:s}){if(this.policy.apply().noaction_server.includes(t||"")){const r=extractLanguage(e?.headers?.["x-seishiro-lang"]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,r)}return this.SystemAction({system:e,middleware:r,context_manager:"server-action",type:t,data:s})}async APIAction({system:e,middleware:r,type:t,data:s}){if(this.policy.apply().noaction_api.includes(t||"")){const r=extractLanguage(e?.headers?.["x-seishiro-lang"]||e?.headers?.["accept-language"]||e?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},e,r)}return this.SystemAction({system:e,middleware:r,context_manager:"api-action",type:t,data:s})}}
1
+ import e from"../utils/extract-lang.js";import r from"crypto";import{Buffer as t}from"buffer";export default class s{registry;message;policy;heading;cache_book;constructor({registry:e,message:r,policy:t,heading:s={version:"x-seishiro-client",lang:"x-seishiro-lang"}}){this.registry=e,this.message=r,this.policy=t,this.heading=s,this.cache_book=null}BookRegistry(){if(this.cache_book)return this.cache_book;const e="hex",s=r.randomBytes(16),i=this.policy.apply(),a=this.registry.apply(),o=r.createHash("sha256").update(String(i.passkey||"").trim()).digest(),n={listkey:Object.keys(a).filter(e=>!i.noaction_api.includes(e)),version_now:i.version_now,version_min:i.version_min,version_forceupdate:i.version_forceupdate},c=r.createCipheriv("aes-256-ctr",o,s),l=t.concat([s,c.update(JSON.stringify(n),"utf-8"),c.final()]),d={iv_length:16,type_base:e,iv:s.toString(e),data:l.toString(e)};return this.cache_book=d,d}ResponseBuilder(e={},r,t="en"){const s=!e||"object"!=typeof e||Array.isArray(e)||!!e.error||!e.data,i=e?.status||(s?400:200),a={header:Object.entries(e?.headers||{}).filter(([e,r])=>void 0!==r).map(([e,r])=>({key:e,value:r})),set_cookie:(Array.isArray(e?.set_cookie)?e.set_cookie:[]).filter(e=>e?.key&&e?.value),rm_cookie:(Array.isArray(e?.rm_cookie)?e.rm_cookie:[]).filter(e=>"string"==typeof e||e?.key),status:i,redirect:e?.redirect||null};if(s){const r=e?.error||"system:no-response-sending",s=this.message.error(r,e?.params||[],t);return{...a,error:r,response:{status:i,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...a,error:null,response:{status:i,data:e.data||{}}}}async SystemAction({system:r,middleware:t={},context_manager:s="system-action",type:i,data:a}){const o=e(r?.headers?.[this.heading.lang]||r?.headers?.["accept-language"]||r?.lang||"en");try{const e=this.policy.apply(),n=String(r?.headers?.[this.heading.version]||"").trim();if("api-action"===s&&!n)return this.ResponseBuilder({error:"system:client-version-required",status:400},r,o);if(n&&"api-action"===s){const t=this.policy.version_info(n);if(!t.is_version_min&&t.info_upgrade)return this.ResponseBuilder({error:"system:need-upgrade-client",status:426,params:[{min:e.version_min,now:e.version_now}]},r,o)}const c=this.registry.get(i||"");if(!c)return this.ResponseBuilder({error:"system:no-registry",status:404},r,o);const l={...r,lang:o};let d=t,y=c;if(Array.isArray(c)){const[r,s]=c,n=await r({system:l,middleware:t,type:i,data:a});d=e.skip_middleware_context||n?.skipBuilder?n:this.ResponseBuilder(n,l,o),y=s}const p=await y({system:l,middleware:d,type:i,data:a});return this.ResponseBuilder(p,l,o)}catch(e){return console.error("[Seishiro Core Error]:",e),this.ResponseBuilder({error:"system:internal-server-error",status:500},r,o)}}async ServerAction({system:r,middleware:t,type:s,data:i}){if(this.policy.apply().noaction_server.includes(s||"")){const t=e(r?.headers?.[this.heading.lang]||r?.headers?.["accept-language"]||r?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},r,t)}return this.SystemAction({system:r,middleware:t,context_manager:"server-action",type:s,data:i})}async APIAction({system:r,middleware:t,type:s,data:i}){if(this.policy.apply().noaction_api.includes(s||"")){const t=e(r?.headers?.[this.heading.lang]||r?.headers?.["accept-language"]||r?.lang||"en");return this.ResponseBuilder({error:"system:no-registry",status:404},r,t)}return this.SystemAction({system:r,middleware:t,context_manager:"api-action",type:s,data:i})}}
@@ -1 +1 @@
1
- import formatKey from"../utils/format-key.js";import{DefaultLanguage}from"../constants/message.js";export default class MessageBuilder{message_build_lang="";message_logic=new Map;constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic=new Map}set(e,s){if("string"!=typeof s||"string"!=typeof e)throw new Error("Key and Value must be string!");const t=formatKey(e);this.message_logic.has(this.message_build_lang)||this.message_logic.set(this.message_build_lang,new Map),this.message_logic.get(this.message_build_lang).set(t,s.trim())}get(e="",s=this.message_build_lang){const t=formatKey(e);let a=this.message_logic.get(s);return a||(a=this.message_logic.get(DefaultLanguage),!a&&this.message_logic.size>0&&(a=this.message_logic.values().next().value)),a?a.get(t)||"":`[!NoneVariable ${t}]`}errorMessage(e="",s={},t=this.message_build_lang){const a=this.get(e,t);return s&&0!==Object.keys(s).length?a.replace(/{{(\w+)}}/g,(e,t)=>s[t]||e):a}error(e="",s=[],t=this.message_build_lang){const a=e.indexOf(":");if(-1===a)return{protocol:"unknown",context:[e],params:s,message:e};const g=formatKey(e.substring(0,a)),i=e.substring(a+1).split("|");let r="";for(let e=0;e<i.length;e++){r+=(0===e?"":", ")+this.errorMessage(i[e],s[e],t)}return{protocol:g,context:i,params:s,message:r}}apply(){return this.message_logic}use(e){if(e instanceof MessageBuilder){e.apply().forEach((e,s)=>{let t=this.message_logic.get(s);t||(t=new Map,this.message_logic.set(s,t)),e.forEach((e,s)=>{t.set(s,e)})})}else{if("object"!=typeof e||null===e)throw new Error('The "use" input must be a MessageBuilder or mapping object!');for(const s in e)Object.prototype.hasOwnProperty.call(e,s)&&this.set(s,e[s])}}}
1
+ import e from"../utils/format-key.js";import{DefaultLanguage as s}from"../constants/message.js";export default class t{message_build_lang="";message_logic=new Map;constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic=new Map}set(s,t){if("string"!=typeof t||"string"!=typeof s)throw new Error("Key and Value must be string!");this.message_logic.has(this.message_build_lang)||this.message_logic.set(this.message_build_lang,new Map),this.message_logic.get(this.message_build_lang).set(e(s),t.trim())}get(t="",i=this.message_build_lang){const a=e(t);let g=this.message_logic.get(i);return g||(g=this.message_logic.get(s),!g&&this.message_logic.size>0&&(g=this.message_logic.values().next().value)),g?g.get(a)||"":`[!NoneVariable ${a}]`}errorMessage(e="",s={},t=this.message_build_lang){const i=this.get(e,t);return s&&0!==Object.keys(s).length?i.replace(/{{(\w+)}}/g,(e,t)=>s[t]||e):i}error(s="",t=[],i=this.message_build_lang){const a=s.indexOf(":");if(-1===a)return{protocol:"unknown",context:[s],params:t,message:s};const g=e(s.substring(0,a)),r=s.substring(a+1).split("|");let o="";for(let e=0;e<r.length;e++){o+=(0===e?"":", ")+this.errorMessage(r[e],t[e],i)}return{protocol:g,context:r,params:t,message:o}}apply(){return this.message_logic}use(e){if(e instanceof t)e.apply().forEach((e,s)=>{const t=this.message_logic.get(s)||new Map;this.message_logic.has(s)||this.message_logic.set(s,t),e.forEach((e,s)=>t.set(s,e))});else{if("object"!=typeof e||!e)throw new Error("Invalid 'use' input!");Object.entries(e).forEach(([e,s])=>this.set(e,String(s)))}}}
package/esm/lib/policy.js CHANGED
@@ -1 +1 @@
1
- export default class PolicyBuilder{passkey;version_now;version_min;version_forceupdate;noaction_api;noaction_server;compiled_policy=null;skip_middleware_context;parsed_min;parsed_now;constructor({passkey:i,version_now:e,version_min:o,version_forceupdate:s=!0,skip_middleware_context:n=!1}){if(!i||!e||!o)throw new Error("PolicyBuilder: passkey, version_now, and version_min are required!");this.passkey=i,this.version_now=e,this.version_min=o,this.parsed_min=this.parseVersion(o),this.parsed_now=this.parseVersion(e),this.version_forceupdate=s,this.noaction_api=[],this.noaction_server=[],this.skip_middleware_context=n,this.refresh()}noaction(i="",e=[]){const o=["server-action","api-action"];for(let i of e)if(!o.includes(i))throw new Error(`Invalid action type: ${i}. Only allowed actions are: ${o.join(", ")}`);if("string"!=typeof i)throw new Error("Invalid key type, it only string!");for(let o of e)"api-action"===o?this.noaction_api.push(i):"server-action"===o&&this.noaction_server.push(i)}parseVersion(i){return i.split(".").map(Number)}compare(i,e){const o=Math.max(i.length,e.length);for(let s=0;s<o;s++){const o=i[s]||0,n=e[s]||0;if(o!==n)return o>n?1:-1}return 0}version_info(i=""){const e=this.parseVersion(i);return{info_upgrade:this.version_forceupdate,is_version_min:this.compare(e,this.parsed_min)>=0,is_version_now:this.compare(e,this.parsed_now)>=0}}refresh(){this.compiled_policy={passkey:this.passkey,version_now:this.version_now,version_min:this.version_min,version_forceupdate:this.version_forceupdate,noaction_api:this.noaction_api,noaction_server:this.noaction_server,skip_middleware_context:this.skip_middleware_context}}apply(){return this.compiled_policy}}
1
+ export default class i{passkey;version_now;version_min;version_forceupdate;noaction_api;noaction_server;compiled_policy=null;skip_middleware_context;parsed_min;parsed_now;constructor({passkey:i,version_now:e,version_min:o,version_forceupdate:s=!0,skip_middleware_context:n=!1}){if(!i||!e||!o)throw new Error("PolicyBuilder: passkey, version_now, and version_min are required!");this.passkey=i,this.version_now=e,this.version_min=o,this.parsed_min=this.parseVersion(o),this.parsed_now=this.parseVersion(e),this.version_forceupdate=s,this.noaction_api=[],this.noaction_server=[],this.skip_middleware_context=n,this.refresh()}noaction(i="",e=[]){const o=["server-action","api-action"];for(let i of e)if(!o.includes(i))throw new Error(`Invalid action type: ${i}. Only allowed actions are: ${o.join(", ")}`);if("string"!=typeof i)throw new Error("Invalid key type, it only string!");for(let o of e)"api-action"===o?this.noaction_api.push(i):"server-action"===o&&this.noaction_server.push(i)}parseVersion(i){return i.split(".").map(Number)}compare(i,e){const o=Math.max(i.length,e.length);for(let s=0;s<o;s++){const o=i[s]||0,n=e[s]||0;if(o!==n)return o>n?1:-1}return 0}version_info(i=""){const e=this.parseVersion(i);return{info_upgrade:this.version_forceupdate,is_version_min:this.compare(e,this.parsed_min)>=0,is_version_now:this.compare(e,this.parsed_now)>=0}}refresh(){this.compiled_policy={passkey:this.passkey,version_now:this.version_now,version_min:this.version_min,version_forceupdate:this.version_forceupdate,noaction_api:this.noaction_api,noaction_server:this.noaction_server,skip_middleware_context:this.skip_middleware_context}}apply(){return this.compiled_policy}}
@@ -1 +1 @@
1
- import formatKey from"../utils/format-key.js";export default class RegistryBuilder{registry_logic;constructor(){this.registry_logic=new Map}set(t,r,e){const i=formatKey(t);if("function"!=typeof r)throw new Error("Registry function is only type function!");if("string"!=typeof t)throw new Error("Registry key is only type string!");e&&"function"==typeof e?this.registry_logic.set(i,[e,r]):this.registry_logic.set(i,r)}get(t){const r=formatKey(t);return this.registry_logic.get(r)||void 0}apply(){return this.registry_logic}use(t){if(t instanceof RegistryBuilder)for(const[r,e]of t.registry_logic)this.registry_logic.set(r,e);else{if("object"!=typeof t||null===t)throw new Error('The "use" input must be a RegistryBuilder or mapping object!');for(const[r,e]of Object.entries(t))Array.isArray(e)?this.set(r,e[1],e[0]):"function"==typeof e&&this.set(r,e)}}}
1
+ import t from"../utils/format-key.js";export default class r{registry_logic;constructor(){this.registry_logic=new Map}set(r,i,e){const s=t(r);if("function"!=typeof i)throw new Error("Registry function is only type function!");if("string"!=typeof r)throw new Error("Registry key is only type string!");e&&"function"==typeof e?this.registry_logic.set(s,[e,i]):this.registry_logic.set(s,i)}get(r){const i=t(r);return this.registry_logic.get(i)||void 0}apply(){return this.registry_logic}use(t){if(t instanceof r)t.apply().forEach((t,r)=>this.registry_logic.set(r,t));else{if("object"!=typeof t||!t)throw new Error("Invalid 'use' input!");Object.entries(t).forEach(([t,r])=>{Array.isArray(r)?this.set(t,r[1],r[0]):this.set(t,r)})}}}
@@ -1 +1 @@
1
- export default function extractLanguage(t=""){return String(t||"").trim().split(",").map(t=>t.split(";")[0].split("-")[0].trim()).filter((t,i,r)=>r.indexOf(t)===i)[0]}
1
+ export default function t(t=""){return(String(t||"").split(",")[0]||"en").split(";")[0].split("-")[0].trim().toLowerCase()||"en"}
@@ -1 +1 @@
1
- export default function formatKey(t=""){const r=String(t||"").trim().replace(/[^a-zA-Z0-9-.:]/g,"");return String(r||"").toLowerCase()}
1
+ export default function t(t=""){const r=String(t||"").trim().replace(/[^a-zA-Z0-9-.:]/g,"");return String(r||"").toLowerCase()}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @function mapHeaders
3
+ * @description Converts a Headers object or a plain object to a clean Record<string, string>.
4
+ */
5
+ export declare function mapHeaders(headers: any): Record<string, string>;
6
+ /**
7
+ * @function getIp
8
+ * @description Extracts IP address from various header sources.
9
+ */
10
+ export declare function getIp(headers: Record<string, string>, remoteAddress?: string): string;
11
+ /**
12
+ * @function getLocation
13
+ * @description Extracts location string from common proxy headers.
14
+ */
15
+ export declare function getLocation(headers: Record<string, string>): string;
@@ -0,0 +1 @@
1
+ export function mapHeaders(r){const e={};if(!r)return e;if("function"==typeof r.forEach)r.forEach((r,o)=>{e[o.toLowerCase()]=String(r).trim()});else for(const[o,t]of Object.entries(r))e[o.toLowerCase()]=Array.isArray(t)?t.join(", "):String(t||"").trim();return e}export function getIp(r,e){return r["x-real-ip"]||r["x-forwarded-for"]?.split(",")[0].trim()||e||"127.0.0.1"}export function getLocation(r){return r["x-vercel-ip-country"]?[r["x-vercel-ip-country"],r["x-vercel-ip-country-region"],r["x-vercel-ip-city"]].filter(Boolean).join(", "):r["cf-ipcountry"]||"Local/Unknown"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seishiro",
3
- "version": "0.2.1-release",
4
- "description": "A simple response context API that eliminates the complexity of routing folder structures and replaces them with a single control center.",
3
+ "version": "0.2.2-release",
4
+ "description": "The Centralized API Orchestrator for Modern Web Applications.",
5
5
  "type": "module",
6
6
  "main": "./cjs/index.js",
7
7
  "module": "./esm/index.js",
@@ -26,11 +26,14 @@
26
26
  "license": "AGPL-3.0",
27
27
  "author": "Ernestoyoofi",
28
28
  "devDependencies": {
29
- "@biomejs/biome": "^2.3.13",
29
+ "@biomejs/biome": "^2.4.4",
30
30
  "@types/jest": "^30.0.0",
31
- "@types/node": "^25.2.2",
32
- "glob": "^13.0.2",
33
- "terser": "^5.46.0"
31
+ "@types/node": "^25.3.2",
32
+ "@vercel/functions": "^3.4.3",
33
+ "glob": "^13.0.6",
34
+ "next": "^16.1.6",
35
+ "terser": "^5.46.0",
36
+ "typescript": "^5.9.3"
34
37
  },
35
38
  "repository": {
36
39
  "type": "git",