seishiro 0.1.90-dev → 0.2.0-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.
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_1=require("./lib/registry");Object.defineProperty(exports,"RegistryBuilder",{enumerable:!0,get:function(){return __importDefault(registry_1).default}});var message_1=require("./lib/message");Object.defineProperty(exports,"MessageBuilder",{enumerable:!0,get:function(){return __importDefault(message_1).default}});var policy_1=require("./lib/policy");Object.defineProperty(exports,"PolicyBuilder",{enumerable:!0,get:function(){return __importDefault(policy_1).default}});var actions_1=require("./lib/actions");Object.defineProperty(exports,"Actions",{enumerable:!0,get:function(){return __importDefault(actions_1).default}});
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 +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");class Actions{registry;message;policy;constructor({registry:e,message:r,policy:t}){this.registry=e,this.message=r,this.policy=t}BookRegistry(){const e="hex",r=crypto_1.default.randomBytes(16),t=this.policy.apply(),s=this.registry.apply(),i=crypto_1.default.createHash("sha256").update(String(t.passkey||"").trim()).digest(),o={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_1.default.createCipheriv("aes-256-ctr",i,r),n=buffer_1.Buffer.concat([r,a.update(JSON.stringify(o),"utf-8"),a.final()]);return{iv_length:16,type_base:e,iv:r.toString(e),data:n.toString(e)}}ResponseBuilder(e={},r){const t=!e.data||e.error||!e||"object"!=typeof e||Array.isArray(e)?e.status||400:e.status||200,s="object"!=typeof e.headers||Array.isArray(e.headers)?[]:Object.entries(e.headers).map(([e,r])=>({key:e,value:r})),i=Array.isArray(e.set_cookie)?(e.set_cookie||[]).filter(e=>"object"==typeof e&&!Array.isArray(e)&&e.key&&e.value):[],o=Array.isArray(e.rm_cookie)?(e.rm_cookie||[]).filter(e=>"object"==typeof e&&!Array.isArray(e)&&e.key):[],a=e.redirect||null;if(!e.data||e.error||!e||"object"!=typeof e||Array.isArray(e)){const r=this.message.error(e.error||"system:no-response-sending",e.params||[]);return{header:s,set_cookie:i,rm_cookie:o,status:t,redirect:a,error:e.error||"system:no-response-sending",response:{status:t,message:r.message,protocol:r.protocol,context:r.context,params:r.params}}}return{header:s,set_cookie:i,rm_cookie:o,status:t,redirect:a,error:null,response:{status:t,data:e.data||{}}}}async SystemAction({system:e,middleware:r={},type:t,data:s}){try{const i=this.registry.get(t||"");if(!i)return this.ResponseBuilder({error:"system:no-registry",status:404},e);if(Array.isArray(i)){const o=await i[0]({system:e,middleware:r,type:t,data:s});let a=o;o?.skipBuilder||(a=this.ResponseBuilder(o,e));const n=await i[1]({system:e,middleware:a,type:t,data:s});return this.ResponseBuilder(n,e)}const o=await i({system:e,middleware:r,type:t,data:s});return this.ResponseBuilder(o,e)}catch(r){return console.log("[Context Action Error Internal!]:",r),this.ResponseBuilder({error:"system:internal-server-error",status:500},e)}}async ServerAction({system:e,middleware:r,type:t,data:s}){return this.policy.apply().noaction_server.includes(t||"")?this.ResponseBuilder({error:"system:no-registry",status:404},e):this.SystemAction({system:e,middleware:r,type:t,data:s})}async APIAction({system:e,middleware:r,type:t,data:s}){return this.policy.apply().noaction_api.includes(t||"")?this.ResponseBuilder({error:"system:no-registry",status:404},e):this.SystemAction({system:e,middleware:r,type:t,data:s})}}exports.default=Actions;
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(),a=crypto_1.default.createHash("sha256").update(String(r.passkey||"").trim()).digest(),i={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},o=crypto_1.default.createCipheriv("aes-256-ctr",a,t),n=buffer_1.Buffer.concat([t,o.update(JSON.stringify(i),"utf-8"),o.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,a=e?.status||(s?400:200),i=e?.redirect||null,o=[];if(e?.headers&&"object"==typeof e.headers&&!Array.isArray(e.headers))for(const[t,r]of Object.entries(e.headers))o.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:o,set_cookie:n,rm_cookie:c,status:a,redirect:i};if(s){const t=e?.error||"system:no-response-sending",s=this.message.error(t,e?.params||[],r);return{...l,error:t,response:{status:a,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...l,error:null,response:{status:a,data:e.data||{}}}}async SystemAction({system:e,middleware:t={},context_manager:r="system-action",type:s,data:a}){const i=e?.headers||{},o=i["x-seishiro-lang"]||i["accept-language"],n=o?(0,extract_lang_js_1.default)(o):e?.lang||"en";try{const o=this.policy.apply(),c=i["x-seishiro-client"];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:o.version_min,now:o.version_now}]},e,n)}const l=this.registry.get(s||"");if(!l)return this.ResponseBuilder({error:"system:no-registry",status:404},e,n);const p={...e,lang:n};let u=t,y=l;if(Array.isArray(l)){const[e,r]=l,i=await e({system:p,middleware:t,type:s,data:a});u=o.skip_middleware_context||i?.skipBuilder?i:this.ResponseBuilder(i,p,n),y=r}const d=await y({system:p,middleware:u,type:s,data:a});return this.ResponseBuilder(d,p,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 +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_1=__importDefault(require("../utils/format-key")),message_1=require("../constants/message");class MessageBuilder{message_build_lang="";message_logic={};constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic={}}set(e,s){const t=(0,format_key_1.default)(e);if("string"!=typeof s)throw new Error("Message value is only type string!");if("string"!=typeof e)throw new Error("Message key is only type string!");this.message_logic[this.message_build_lang]||(this.message_logic[this.message_build_lang]={}),this.message_logic[this.message_build_lang][t]=String(s).trim()}get(e="",s=this.message_build_lang){const t=(0,format_key_1.default)(e);let a=s;return this.message_logic[a]||(console.warn("[Debugging Message]: Language not found on logic, using default language!"),a=this.message_logic[message_1.DefaultLanguage]?message_1.DefaultLanguage:Object.keys(this.message_logic||{})[0]),this.message_logic[a]?String(this.message_logic[a][t]||"").trim():(console.warn("[Debugging Message]: Language or variable not found on logic!"),String(`[!NoneVariable ${t}]`))}errorMessage(e="",s={},t=this.message_build_lang){let a=this.get(e,t);return Object.keys(s||{}).forEach(e=>{const t=s[e]||"",i=new RegExp(`{{${e}}}`,"g");a=a.replace(i,t)}),a}error(e="",s=[],t=this.message_build_lang){const[a,...i]=String(e||"").split(":"),g=String(i.join(":")).split("|"),o=g.map((e,a)=>{const i=s[a];return this.errorMessage(e,i,t)}).join(", ");return{protocol:(0,format_key_1.default)(a),context:g,params:s,message:o}}apply(){return this.message_logic}use(e){if(e instanceof MessageBuilder){const s=e.apply();for(const e in s)if(Object.prototype.hasOwnProperty.call(s,e)){const t=s[e];this.message_logic[e]||(this.message_logic[e]={}),Object.assign(this.message_logic[e],t)}}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 __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;
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;constructor({passkey:i,version_now:e,version_min:o,version_forceupdate:n=!0}){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.version_forceupdate=n,this.noaction_api=[],this.noaction_server=[]}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)}compareVersions(i,e){const o=i=>i.replace(/-.*$/,""),n=o(i).split(".").map(Number),r=o(e).split(".").map(Number);for(let i=0;i<Math.max(n.length,r.length);i++){const e=n[i]||0,o=r[i]||0;if(e>o)return 1;if(e<o)return-1}return 0}version_info(i=""){const e=this.compareVersions(i,this.version_min)>=0,o=this.compareVersions(i,this.version_now)>=0;return{info_upgrade:this.version_forceupdate,is_version_min:e,is_version_now:o}}apply(){return{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}}}exports.default=PolicyBuilder;
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 +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_1=__importDefault(require("../utils/format-key"));class RegistryBuilder{registry_logic={};constructor(){this.registry_logic={}}set(t,e,r){const i=(0,format_key_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!");this.registry_logic[i]=r&&"function"==typeof r?[r,e]:e}get(t){const e=(0,format_key_1.default)(t);return this.registry_logic[e]||void 0}apply(){return this.registry_logic}use(t){const e=t instanceof RegistryBuilder?t.registry_logic:t;if("object"!=typeof e||null===e)throw new Error('The "use" input must be a RegistryBuilder or mapping object!');Object.entries(e).forEach(([t,e])=>{if(Array.isArray(e)){const[r,i]=e;this.set(t,i,r)}else"function"==typeof e&&this.set(t,e)})}}exports.default=RegistryBuilder;
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;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -1 +1 @@
1
- "use strict";function extractLanguage(t=""){return String(t||"").trim().split(",").map(t=>t.split(";")[0].split("-")[0].trim()).filter((t,i,r)=>r.indexOf(t)===i)}
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;
package/esm/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { default as RegistryBuilder } from "./lib/registry";
2
- export { default as MessageBuilder } from "./lib/message";
3
- export { default as PolicyBuilder } from "./lib/policy";
4
- export { default as Actions } from "./lib/actions";
1
+ export { default as RegistryBuilder } from "./lib/registry.js";
2
+ export { default as MessageBuilder } from "./lib/message.js";
3
+ export { default as PolicyBuilder } from "./lib/policy.js";
4
+ export { default as Actions } from "./lib/actions.js";
package/esm/index.js CHANGED
@@ -1 +1 @@
1
- export{default as RegistryBuilder}from"./lib/registry";export{default as MessageBuilder}from"./lib/message";export{default as PolicyBuilder}from"./lib/policy";export{default as Actions}from"./lib/actions";
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,7 +1,7 @@
1
- import { RegistryParams } from "../types/registry.type";
2
- import RegistryBuilder from "./registry";
3
- import MessageBuilder from "./message";
4
- import PolicyBuilder from "./policy";
1
+ import { RegistryParams } from "../types/registry.type.js";
2
+ import RegistryBuilder from "./registry.js";
3
+ import MessageBuilder from "./message.js";
4
+ import PolicyBuilder from "./policy.js";
5
5
  /**
6
6
  * @class Actions
7
7
  * @description The main orchestrator of the Seishiro API. It handles the execution flow
@@ -11,6 +11,7 @@ export default class Actions {
11
11
  private registry;
12
12
  private message;
13
13
  private policy;
14
+ private cache_book;
14
15
  /**
15
16
  * @constructor
16
17
  * @param {Object} params - Configuration instances.
@@ -27,7 +28,7 @@ export default class Actions {
27
28
  * @method BookRegistry
28
29
  * @description Generates an encrypted list of available API registries and application versions.
29
30
  * This is used to securely expose allowed actions to the client side.
30
- * @returns {Object} An object containing encryption metadata (iv, type_base) and the encrypted 'data' string.
31
+ * @returns {Object} An object containing encryption metadata (iv, type_base) and the encrypted "data" string.
31
32
  */
32
33
  BookRegistry(): {
33
34
  iv_length: number;
@@ -50,33 +51,25 @@ export default class Actions {
50
51
  * @param {RegistryParams} params - The request payload containing system info, type, data, and optional middleware state.
51
52
  * @returns {Promise<Object>} A promise that resolves to a standardized response object via ResponseBuilder.
52
53
  */
53
- SystemAction({ system, middleware, type, data }: RegistryParams): Promise<{
54
- header: {
55
- key: string;
56
- value: unknown;
57
- }[];
58
- set_cookie: any;
59
- rm_cookie: any;
60
- status: any;
61
- redirect: any;
54
+ SystemAction({ system, middleware, context_manager, type, data, }: RegistryParams): Promise<{
62
55
  error: any;
63
56
  response: {
64
57
  status: any;
65
58
  message: string;
66
59
  protocol: string;
67
60
  context: string[];
68
- params: object[];
61
+ params: import("../types/message.type.js").MessageErrorContextOpt[];
69
62
  data?: undefined;
70
63
  };
71
- } | {
72
64
  header: {
73
65
  key: string;
74
66
  value: unknown;
75
67
  }[];
76
- set_cookie: any;
77
- rm_cookie: any;
68
+ set_cookie: any[];
69
+ rm_cookie: string[];
78
70
  status: any;
79
71
  redirect: any;
72
+ } | {
80
73
  error: null;
81
74
  response: {
82
75
  status: any;
@@ -86,6 +79,14 @@ export default class Actions {
86
79
  context?: undefined;
87
80
  params?: undefined;
88
81
  };
82
+ header: {
83
+ key: string;
84
+ value: unknown;
85
+ }[];
86
+ set_cookie: any[];
87
+ rm_cookie: string[];
88
+ status: any;
89
+ redirect: any;
89
90
  }>;
90
91
  /**
91
92
  * @method ServerAction
@@ -95,32 +96,24 @@ export default class Actions {
95
96
  * @returns {Promise<Object>} The standardized response or a 404 error if the action is restricted by policy.
96
97
  */
97
98
  ServerAction({ system, middleware, type, data }: RegistryParams): Promise<{
98
- header: {
99
- key: string;
100
- value: unknown;
101
- }[];
102
- set_cookie: any;
103
- rm_cookie: any;
104
- status: any;
105
- redirect: any;
106
99
  error: any;
107
100
  response: {
108
101
  status: any;
109
102
  message: string;
110
103
  protocol: string;
111
104
  context: string[];
112
- params: object[];
105
+ params: import("../types/message.type.js").MessageErrorContextOpt[];
113
106
  data?: undefined;
114
107
  };
115
- } | {
116
108
  header: {
117
109
  key: string;
118
110
  value: unknown;
119
111
  }[];
120
- set_cookie: any;
121
- rm_cookie: any;
112
+ set_cookie: any[];
113
+ rm_cookie: string[];
122
114
  status: any;
123
115
  redirect: any;
116
+ } | {
124
117
  error: null;
125
118
  response: {
126
119
  status: any;
@@ -130,6 +123,14 @@ export default class Actions {
130
123
  context?: undefined;
131
124
  params?: undefined;
132
125
  };
126
+ header: {
127
+ key: string;
128
+ value: unknown;
129
+ }[];
130
+ set_cookie: any[];
131
+ rm_cookie: string[];
132
+ status: any;
133
+ redirect: any;
133
134
  }>;
134
135
  /**
135
136
  * @method APIAction
@@ -139,32 +140,24 @@ export default class Actions {
139
140
  * @returns {Promise<Object>} The standardized response or a 404 error if the action is restricted by policy.
140
141
  */
141
142
  APIAction({ system, middleware, type, data }: RegistryParams): Promise<{
142
- header: {
143
- key: string;
144
- value: unknown;
145
- }[];
146
- set_cookie: any;
147
- rm_cookie: any;
148
- status: any;
149
- redirect: any;
150
143
  error: any;
151
144
  response: {
152
145
  status: any;
153
146
  message: string;
154
147
  protocol: string;
155
148
  context: string[];
156
- params: object[];
149
+ params: import("../types/message.type.js").MessageErrorContextOpt[];
157
150
  data?: undefined;
158
151
  };
159
- } | {
160
152
  header: {
161
153
  key: string;
162
154
  value: unknown;
163
155
  }[];
164
- set_cookie: any;
165
- rm_cookie: any;
156
+ set_cookie: any[];
157
+ rm_cookie: string[];
166
158
  status: any;
167
159
  redirect: any;
160
+ } | {
168
161
  error: null;
169
162
  response: {
170
163
  status: any;
@@ -174,5 +167,13 @@ export default class Actions {
174
167
  context?: undefined;
175
168
  params?: undefined;
176
169
  };
170
+ header: {
171
+ key: string;
172
+ value: unknown;
173
+ }[];
174
+ set_cookie: any[];
175
+ rm_cookie: string[];
176
+ status: any;
177
+ redirect: any;
177
178
  }>;
178
179
  }
@@ -1 +1 @@
1
- import crypto from"crypto";import{Buffer}from"buffer";export default class Actions{registry;message;policy;constructor({registry:e,message:r,policy:t}){this.registry=e,this.message=r,this.policy=t}BookRegistry(){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()]);return{iv_length:16,type_base:e,iv:r.toString(e),data:n.toString(e)}}ResponseBuilder(e={},r){const t=!e.data||e.error||!e||"object"!=typeof e||Array.isArray(e)?e.status||400:e.status||200,s="object"!=typeof e.headers||Array.isArray(e.headers)?[]:Object.entries(e.headers).map(([e,r])=>({key:e,value:r})),o=Array.isArray(e.set_cookie)?(e.set_cookie||[]).filter(e=>"object"==typeof e&&!Array.isArray(e)&&e.key&&e.value):[],i=Array.isArray(e.rm_cookie)?(e.rm_cookie||[]).filter(e=>"object"==typeof e&&!Array.isArray(e)&&e.key):[],a=e.redirect||null;if(!e.data||e.error||!e||"object"!=typeof e||Array.isArray(e)){const r=this.message.error(e.error||"system:no-response-sending",e.params||[]);return{header:s,set_cookie:o,rm_cookie:i,status:t,redirect:a,error:e.error||"system:no-response-sending",response:{status:t,message:r.message,protocol:r.protocol,context:r.context,params:r.params}}}return{header:s,set_cookie:o,rm_cookie:i,status:t,redirect:a,error:null,response:{status:t,data:e.data||{}}}}async SystemAction({system:e,middleware:r={},type:t,data:s}){try{const o=this.registry.get(t||"");if(!o)return this.ResponseBuilder({error:"system:no-registry",status:404},e);if(Array.isArray(o)){const i=await o[0]({system:e,middleware:r,type:t,data:s});let a=i;i?.skipBuilder||(a=this.ResponseBuilder(i,e));const n=await o[1]({system:e,middleware:a,type:t,data:s});return this.ResponseBuilder(n,e)}const i=await o({system:e,middleware:r,type:t,data:s});return this.ResponseBuilder(i,e)}catch(r){return console.log("[Context Action Error Internal!]:",r),this.ResponseBuilder({error:"system:internal-server-error",status:500},e)}}async ServerAction({system:e,middleware:r,type:t,data:s}){return this.policy.apply().noaction_server.includes(t||"")?this.ResponseBuilder({error:"system:no-registry",status:404},e):this.SystemAction({system:e,middleware:r,type:t,data:s})}async APIAction({system:e,middleware:r,type:t,data:s}){return this.policy.apply().noaction_api.includes(t||"")?this.ResponseBuilder({error:"system:no-registry",status:404},e):this.SystemAction({system:e,middleware:r,type:t,data:s})}}
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: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.randomBytes(16),r=this.policy.apply(),s=this.registry.apply(),o=crypto.createHash("sha256").update(String(r.passkey||"").trim()).digest(),a={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},i=crypto.createCipheriv("aes-256-ctr",o,t),n=Buffer.concat([t,i.update(JSON.stringify(a),"utf-8"),i.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,o=e?.status||(s?400:200),a=e?.redirect||null,i=[];if(e?.headers&&"object"==typeof e.headers&&!Array.isArray(e.headers))for(const[t,r]of Object.entries(e.headers))i.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 y={header:i,set_cookie:n,rm_cookie:c,status:o,redirect:a};if(s){const t=e?.error||"system:no-response-sending",s=this.message.error(t,e?.params||[],r);return{...y,error:t,response:{status:o,message:s.message,protocol:s.protocol,context:s.context,params:s.params}}}return{...y,error:null,response:{status:o,data:e.data||{}}}}async SystemAction({system:e,middleware:t={},context_manager:r="system-action",type:s,data:o}){const a=e?.headers||{},i=a["x-seishiro-lang"]||a["accept-language"],n=i?extractLanguage(i):e?.lang||"en";try{const i=this.policy.apply(),c=a["x-seishiro-client"];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:i.version_min,now:i.version_now}]},e,n)}const y=this.registry.get(s||"");if(!y)return this.ResponseBuilder({error:"system:no-registry",status:404},e,n);const p={...e,lang:n};let l=t,d=y;if(Array.isArray(y)){const[e,r]=y,a=await e({system:p,middleware:t,type:s,data:o});l=i.skip_middleware_context||a?.skipBuilder?a:this.ResponseBuilder(a,p,n),d=r}const u=await d({system:p,middleware:l,type:s,data:o});return this.ResponseBuilder(u,p,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=extractLanguage(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=extractLanguage(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})}}
@@ -1,4 +1,4 @@
1
- import type { MessageKey, MessageValue, MessageLang, MessageLogic, MessageLogicLang, MessageErrorContext, MessageErrorContextOpt, MessageErrorContextSlug } from "../types/message.type";
1
+ import type { MessageKey, MessageValue, MessageLang, MessageLogic, MessageLogicLang, MessageErrorContext, MessageErrorContextOpt, MessageErrorContextSlug } from "../types/message.type.js";
2
2
  /**
3
3
  * @class MessageBuilder
4
4
  * @description Handles multi-language response messages, error formatting, and dynamic template replacement.
@@ -50,7 +50,7 @@ export default class MessageBuilder {
50
50
  error(errorStr?: MessageErrorContext, errorOpts?: MessageErrorContextOpt[], lang?: MessageLang): {
51
51
  protocol: string;
52
52
  context: string[];
53
- params: object[];
53
+ params: MessageErrorContextOpt[];
54
54
  message: string;
55
55
  };
56
56
  /**
@@ -1 +1 @@
1
- import formatKey from"../utils/format-key";import{DefaultLanguage}from"../constants/message";export default class MessageBuilder{message_build_lang="";message_logic={};constructor(e="en"){this.message_build_lang=String(e||"en").toLowerCase().replace(/[^a-z]/g,"").slice(0,2),this.message_logic={}}set(e,s){const t=formatKey(e);if("string"!=typeof s)throw new Error("Message value is only type string!");if("string"!=typeof e)throw new Error("Message key is only type string!");this.message_logic[this.message_build_lang]||(this.message_logic[this.message_build_lang]={}),this.message_logic[this.message_build_lang][t]=String(s).trim()}get(e="",s=this.message_build_lang){const t=formatKey(e);let g=s;return this.message_logic[g]||(console.warn("[Debugging Message]: Language not found on logic, using default language!"),g=this.message_logic[DefaultLanguage]?DefaultLanguage:Object.keys(this.message_logic||{})[0]),this.message_logic[g]?String(this.message_logic[g][t]||"").trim():(console.warn("[Debugging Message]: Language or variable not found on logic!"),String(`[!NoneVariable ${t}]`))}errorMessage(e="",s={},t=this.message_build_lang){let g=this.get(e,t);return Object.keys(s||{}).forEach(e=>{const t=s[e]||"",a=new RegExp(`{{${e}}}`,"g");g=g.replace(a,t)}),g}error(e="",s=[],t=this.message_build_lang){const[g,...a]=String(e||"").split(":"),i=String(a.join(":")).split("|"),o=i.map((e,g)=>{const a=s[g];return this.errorMessage(e,a,t)}).join(", ");return{protocol:formatKey(g),context:i,params:s,message:o}}apply(){return this.message_logic}use(e){if(e instanceof MessageBuilder){const s=e.apply();for(const e in s)if(Object.prototype.hasOwnProperty.call(s,e)){const t=s[e];this.message_logic[e]||(this.message_logic[e]={}),Object.assign(this.message_logic[e],t)}}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 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,4 +1,4 @@
1
- import { PolicyNoActionAPIAction, PolicyNoActionServerAction, PolicyNoActionKey, PolicyNoActionBase } from "../types/policy.type";
1
+ import { PolicyNoActionKey, PolicyNoActionBase } from "../types/policy.type.js";
2
2
  /**
3
3
  * @class PolicyBuilder
4
4
  * @description Manages application policies including security passkeys, version control,
@@ -11,6 +11,10 @@ export default class PolicyBuilder {
11
11
  private version_forceupdate;
12
12
  private noaction_api;
13
13
  private noaction_server;
14
+ private compiled_policy;
15
+ private skip_middleware_context;
16
+ private parsed_min;
17
+ private parsed_now;
14
18
  /**
15
19
  * @constructor
16
20
  * @param {Object} config - The policy configuration.
@@ -20,11 +24,12 @@ export default class PolicyBuilder {
20
24
  * @param {boolean} [config.version_forceupdate=true] - Flag to indicate if clients below version_min must update.
21
25
  * @throws {Error} If passkey, version_now, or version_min is missing.
22
26
  */
23
- constructor({ passkey, version_now, version_min, version_forceupdate, }: {
27
+ constructor({ passkey, version_now, version_min, version_forceupdate, skip_middleware_context, }: {
24
28
  passkey: string;
25
29
  version_now: string;
26
30
  version_min: string;
27
31
  version_forceupdate?: boolean;
32
+ skip_middleware_context?: boolean;
28
33
  });
29
34
  /**
30
35
  * @method noaction
@@ -34,37 +39,28 @@ export default class PolicyBuilder {
34
39
  * @throws {Error} If the protocol type is invalid or the key is not a string.
35
40
  */
36
41
  noaction(type?: PolicyNoActionKey, action?: PolicyNoActionBase): void;
37
- /**
38
- * @method compareVersions
39
- * @private
40
- * @description Compares two semantic version strings to determine their order.
41
- * @param {string} v1 - First version string.
42
- * @param {string} v2 - Second version string.
43
- * @returns {number} 1 if v1 > v2, -1 if v1 < v2, and 0 if they are equal.
44
- */
45
- private compareVersions;
42
+ private parseVersion;
43
+ private compare;
46
44
  /**
47
45
  * @method version_info
48
46
  * @description Checks a provided version against the minimum and current version requirements.
49
47
  * @param {string} [version=""] - The version string to validate (usually from the client).
50
48
  * @returns {Object} An object containing upgrade flags and version compatibility status.
51
49
  */
52
- version_info(version?: string): {
50
+ version_info(clientVersion?: string): {
53
51
  info_upgrade: boolean;
54
52
  is_version_min: boolean;
55
53
  is_version_now: boolean;
56
54
  };
55
+ /**
56
+ * @method refresh
57
+ * @description Refreshes the compiled policy.
58
+ */
59
+ private refresh;
57
60
  /**
58
61
  * @method apply
59
62
  * @description Retrieves the compiled policy configuration.
60
63
  * @returns {Object} All policy settings including restricted actions and versioning data.
61
64
  */
62
- apply(): {
63
- passkey: string;
64
- version_now: string;
65
- version_min: string;
66
- version_forceupdate: boolean;
67
- noaction_api: PolicyNoActionAPIAction;
68
- noaction_server: PolicyNoActionServerAction;
69
- };
65
+ apply(): any;
70
66
  }
package/esm/lib/policy.js CHANGED
@@ -1 +1 @@
1
- export default class PolicyBuilder{passkey;version_now;version_min;version_forceupdate;noaction_api;noaction_server;constructor({passkey:i,version_now:o,version_min:n,version_forceupdate:e=!0}){if(!i||!o||!n)throw new Error("PolicyBuilder: passkey, version_now, and version_min are required!");this.passkey=i,this.version_now=o,this.version_min=n,this.version_forceupdate=e,this.noaction_api=[],this.noaction_server=[]}noaction(i="",o=[]){const n=["server-action","api-action"];for(let i of o)if(!n.includes(i))throw new Error(`Invalid action type: ${i}. Only allowed actions are: ${n.join(", ")}`);if("string"!=typeof i)throw new Error("Invalid key type, it only string!");for(let n of o)"api-action"===n?this.noaction_api.push(i):"server-action"===n&&this.noaction_server.push(i)}compareVersions(i,o){const n=i=>i.replace(/-.*$/,""),e=n(i).split(".").map(Number),r=n(o).split(".").map(Number);for(let i=0;i<Math.max(e.length,r.length);i++){const o=e[i]||0,n=r[i]||0;if(o>n)return 1;if(o<n)return-1}return 0}version_info(i=""){const o=this.compareVersions(i,this.version_min)>=0,n=this.compareVersions(i,this.version_now)>=0;return{info_upgrade:this.version_forceupdate,is_version_min:o,is_version_now:n}}apply(){return{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}}}
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,4 +1,4 @@
1
- import type { RegistryKey, RegistryFunction, RegistryLogic, RegistryMiddleware } from "../types/registry.type";
1
+ import type { RegistryKey, RegistryFunction, RegistryLogic, RegistryMiddleware } from "../types/registry.type.js";
2
2
  /**
3
3
  * @class RegistryBuilder
4
4
  * @description Centralizes the mapping of unique action keys to their respective controllers
@@ -1 +1 @@
1
- import formatKey from"../utils/format-key";export default class RegistryBuilder{registry_logic={};constructor(){this.registry_logic={}}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!");this.registry_logic[i]=e&&"function"==typeof e?[e,r]:r}get(t){const r=formatKey(t);return this.registry_logic[r]||void 0}apply(){return this.registry_logic}use(t){const r=t instanceof RegistryBuilder?t.registry_logic:t;if("object"!=typeof r||null===r)throw new Error('The "use" input must be a RegistryBuilder or mapping object!');Object.entries(r).forEach(([t,r])=>{if(Array.isArray(r)){const[e,i]=r;this.set(t,i,e)}else"function"==typeof r&&this.set(t,r)})}}
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)}}}
@@ -0,0 +1,6 @@
1
+ export type cacheBookType = {
2
+ iv_length: number;
3
+ type_base: string;
4
+ iv: string;
5
+ data: string;
6
+ } | null;
@@ -0,0 +1 @@
1
+ export{};
@@ -3,11 +3,7 @@ export type MessageLang = string | "en" | "id";
3
3
  export type MessageValue = string;
4
4
  export type MessageErrorContext = string;
5
5
  export type MessageErrorContextSlug = string;
6
- export type MessageErrorContextOpt = object;
6
+ export type MessageErrorContextOpt = Record<string, string>;
7
7
  export type MessageErrorContextTrack = string;
8
- export type MessageLogicLang = {
9
- [key: MessageLang]: {
10
- [key: MessageKey]: MessageValue;
11
- };
12
- };
8
+ export type MessageLogicLang = Map<MessageLang, Map<MessageKey, MessageValue>>;
13
9
  export type MessageLogic = Record<MessageKey, MessageValue>;
@@ -1,16 +1,21 @@
1
1
  export type RegistryKey = string;
2
2
  export type RegistryParams = {
3
3
  system: {
4
- cookies: object;
5
- headers: object;
4
+ cookies: {
5
+ [key: string]: any;
6
+ };
7
+ headers: {
8
+ [key: string]: any;
9
+ };
6
10
  ip: string;
7
11
  location: string;
8
12
  lang: string | "en";
9
13
  };
10
14
  type: RegistryKey;
15
+ context_manager?: string;
11
16
  middleware?: object | Function | Promise<any>;
12
17
  data: object;
13
18
  };
14
19
  export type RegistryFunction = (params: RegistryParams) => any;
15
20
  export type RegistryMiddleware = (params: RegistryParams) => any;
16
- export type RegistryLogic = Record<RegistryKey, RegistryFunction | [RegistryMiddleware, RegistryFunction]>;
21
+ export type RegistryLogic = Map<RegistryKey, RegistryFunction | [RegistryMiddleware, RegistryFunction]>;
@@ -8,4 +8,4 @@
8
8
  * extractLanguage("en-GB,en-US;q=0.9,id;q=0.8")
9
9
  * // returns ["en", "id"]
10
10
  */
11
- declare function extractLanguage(lang?: string): string[];
11
+ export default function extractLanguage(lang?: string): string;
@@ -1 +1 @@
1
- "use strict";function extractLanguage(t=""){return String(t||"").trim().split(",").map(t=>t.split(";")[0].split("-")[0].trim()).filter((t,i,r)=>r.indexOf(t)===i)}
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]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seishiro",
3
- "version": "0.1.90-dev",
3
+ "version": "0.2.0-release",
4
4
  "description": "A simple response context API that eliminates the complexity of routing folder structures and replaces them with a single control center.",
5
5
  "type": "module",
6
6
  "main": "./cjs/index.js",
@@ -1 +0,0 @@
1
- export declare const DefaultLanguage: string;
@@ -1,3 +0,0 @@
1
- export declare const ServerAction: string;
2
- export declare const APIAction: string;
3
- export declare const PolicyAction: string[];
package/cjs/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export { default as RegistryBuilder } from "./lib/registry";
2
- export { default as MessageBuilder } from "./lib/message";
3
- export { default as PolicyBuilder } from "./lib/policy";
4
- export { default as Actions } from "./lib/actions";
@@ -1,178 +0,0 @@
1
- import { RegistryParams } from "../types/registry.type";
2
- import RegistryBuilder from "./registry";
3
- import MessageBuilder from "./message";
4
- import PolicyBuilder from "./policy";
5
- /**
6
- * @class Actions
7
- * @description The main orchestrator of the Seishiro API. It handles the execution flow
8
- * by coordinating between Registry, Message, and Policy builders across different protocols.
9
- */
10
- export default class Actions {
11
- private registry;
12
- private message;
13
- private policy;
14
- /**
15
- * @constructor
16
- * @param {Object} params - Configuration instances.
17
- * @param {RegistryBuilder} params.registry - Instance to manage route/controller mapping.
18
- * @param {MessageBuilder} params.message - Instance to handle localized error/response messages.
19
- * @param {PolicyBuilder} params.policy - Instance to manage security and versioning rules.
20
- */
21
- constructor({ registry, message, policy, }: {
22
- registry: RegistryBuilder;
23
- message: MessageBuilder;
24
- policy: PolicyBuilder;
25
- });
26
- /**
27
- * @method BookRegistry
28
- * @description Generates an encrypted list of available API registries and application versions.
29
- * This is used to securely expose allowed actions to the client side.
30
- * @returns {Object} An object containing encryption metadata (iv, type_base) and the encrypted 'data' string.
31
- */
32
- BookRegistry(): {
33
- iv_length: number;
34
- type_base: string;
35
- iv: string;
36
- data: string;
37
- };
38
- /**
39
- * @method ResponseBuilder
40
- * @private
41
- * @description Standardizes the response structure for all action types, handling headers, cookies, and errors.
42
- * @param {any} dataRes - The raw result or error object from the controller/middleware.
43
- * @param {RegistryParams["system"]} system - The system context (headers, cookies, ip, etc.) from the request.
44
- * @returns {Object} A unified response object containing headers, cookies, status code, and the final data/error payload.
45
- */
46
- private ResponseBuilder;
47
- /**
48
- * @method SystemAction
49
- * @description The core execution engine that processes controllers and middlewares.
50
- * @param {RegistryParams} params - The request payload containing system info, type, data, and optional middleware state.
51
- * @returns {Promise<Object>} A promise that resolves to a standardized response object via ResponseBuilder.
52
- */
53
- SystemAction({ system, middleware, type, data }: RegistryParams): Promise<{
54
- header: {
55
- key: string;
56
- value: unknown;
57
- }[];
58
- set_cookie: any;
59
- rm_cookie: any;
60
- status: any;
61
- redirect: any;
62
- error: any;
63
- response: {
64
- status: any;
65
- message: string;
66
- protocol: string;
67
- context: string[];
68
- params: object[];
69
- data?: undefined;
70
- };
71
- } | {
72
- header: {
73
- key: string;
74
- value: unknown;
75
- }[];
76
- set_cookie: any;
77
- rm_cookie: any;
78
- status: any;
79
- redirect: any;
80
- error: null;
81
- response: {
82
- status: any;
83
- data: any;
84
- message?: undefined;
85
- protocol?: undefined;
86
- context?: undefined;
87
- params?: undefined;
88
- };
89
- }>;
90
- /**
91
- * @method ServerAction
92
- * @description Entry point for Server-side actions (e.g., Next.js Server Actions).
93
- * It checks against server-specific policies before executing.
94
- * @param {RegistryParams} params - The request payload.
95
- * @returns {Promise<Object>} The standardized response or a 404 error if the action is restricted by policy.
96
- */
97
- ServerAction({ system, middleware, type, data }: RegistryParams): Promise<{
98
- header: {
99
- key: string;
100
- value: unknown;
101
- }[];
102
- set_cookie: any;
103
- rm_cookie: any;
104
- status: any;
105
- redirect: any;
106
- error: any;
107
- response: {
108
- status: any;
109
- message: string;
110
- protocol: string;
111
- context: string[];
112
- params: object[];
113
- data?: undefined;
114
- };
115
- } | {
116
- header: {
117
- key: string;
118
- value: unknown;
119
- }[];
120
- set_cookie: any;
121
- rm_cookie: any;
122
- status: any;
123
- redirect: any;
124
- error: null;
125
- response: {
126
- status: any;
127
- data: any;
128
- message?: undefined;
129
- protocol?: undefined;
130
- context?: undefined;
131
- params?: undefined;
132
- };
133
- }>;
134
- /**
135
- * @method APIAction
136
- * @description Entry point for REST API requests.
137
- * It checks against API-specific policies to prevent unauthorized access to sensitive endpoints.
138
- * @param {RegistryParams} params - The request payload.
139
- * @returns {Promise<Object>} The standardized response or a 404 error if the action is restricted by policy.
140
- */
141
- APIAction({ system, middleware, type, data }: RegistryParams): Promise<{
142
- header: {
143
- key: string;
144
- value: unknown;
145
- }[];
146
- set_cookie: any;
147
- rm_cookie: any;
148
- status: any;
149
- redirect: any;
150
- error: any;
151
- response: {
152
- status: any;
153
- message: string;
154
- protocol: string;
155
- context: string[];
156
- params: object[];
157
- data?: undefined;
158
- };
159
- } | {
160
- header: {
161
- key: string;
162
- value: unknown;
163
- }[];
164
- set_cookie: any;
165
- rm_cookie: any;
166
- status: any;
167
- redirect: any;
168
- error: null;
169
- response: {
170
- status: any;
171
- data: any;
172
- message?: undefined;
173
- protocol?: undefined;
174
- context?: undefined;
175
- params?: undefined;
176
- };
177
- }>;
178
- }
@@ -1,69 +0,0 @@
1
- import type { MessageKey, MessageValue, MessageLang, MessageLogic, MessageLogicLang, MessageErrorContext, MessageErrorContextOpt, MessageErrorContextSlug } from "../types/message.type";
2
- /**
3
- * @class MessageBuilder
4
- * @description Handles multi-language response messages, error formatting, and dynamic template replacement.
5
- * It allows the application to return consistent, localized messages across different platforms.
6
- */
7
- export default class MessageBuilder {
8
- private message_build_lang;
9
- private message_logic;
10
- /**
11
- * @constructor
12
- * @param {MessageLang} [language="en"] - The default language code (e.g., 'en', 'id').
13
- * It will be sanitized to a 2-character lowercase string.
14
- */
15
- constructor(language?: MessageLang);
16
- /**
17
- * @method set
18
- * @description Registers a specific message template for the current active language.
19
- * @param {MessageKey} key - The unique identifier for the message.
20
- * @param {MessageValue} value - The message string (supports {{variable}} placeholders).
21
- * @throws {Error} If key or value is not a string.
22
- */
23
- set(key: MessageKey, value: MessageValue): void;
24
- /**
25
- * @method get
26
- * @description Retrieves a raw message template based on the key and language.
27
- * Falls back to the default language if the requested language is not found.
28
- * @param {MessageKey} [key=""] - The message identifier to look up.
29
- * @param {MessageLang} [lang=this.message_build_lang] - Optional language override.
30
- * @returns {MessageValue} The raw message string or a fallback indicator if not found.
31
- */
32
- get(key?: MessageKey, lang?: MessageLang): MessageValue;
33
- /**
34
- * @method errorMessage
35
- * @description Processes a template by replacing {{key}} placeholders with actual values.
36
- * @param {MessageErrorContextSlug} [errorSlug=""] - The message key/slug.
37
- * @param {MessageErrorContextOpt} [errorOpt={}] - Object containing key-value pairs for replacement.
38
- * @param {MessageLang} [lang=this.message_build_lang] - The language to use.
39
- * @returns {string} The fully formatted message string.
40
- */
41
- errorMessage(errorSlug?: MessageErrorContextSlug, errorOpt?: MessageErrorContextOpt, lang?: MessageLang): string;
42
- /**
43
- * @method error
44
- * @description Parses a complex error string (protocol:slug|slug) and returns a structured error object.
45
- * @param {MessageErrorContext} [errorStr=""] - The raw error string (e.g., "auth:user-not-found").
46
- * @param {MessageErrorContextOpt[]} [errorOpts=[]] - Array of option objects for multiple slugs.
47
- * @param {MessageLang} [lang=this.message_build_lang] - The target language.
48
- * @returns {Object} Structured error containing protocol, context array, params, and the final joined message.
49
- */
50
- error(errorStr?: MessageErrorContext, errorOpts?: MessageErrorContextOpt[], lang?: MessageLang): {
51
- protocol: string;
52
- context: string[];
53
- params: object[];
54
- message: string;
55
- };
56
- /**
57
- * @method apply
58
- * @description Returns the entire compiled message logic object.
59
- * @returns {MessageLogicLang} The internal storage of languages and their messages.
60
- */
61
- apply(): MessageLogicLang;
62
- /**
63
- * @method use
64
- * @description Merges messages from another MessageBuilder instance or a plain object into the current one.
65
- * @param {MessageBuilder | MessageLogic} input - The source of new messages.
66
- * @throws {Error} If the input type is invalid.
67
- */
68
- use(input: MessageBuilder | MessageLogic): void;
69
- }
@@ -1,70 +0,0 @@
1
- import { PolicyNoActionAPIAction, PolicyNoActionServerAction, PolicyNoActionKey, PolicyNoActionBase } from "../types/policy.type";
2
- /**
3
- * @class PolicyBuilder
4
- * @description Manages application policies including security passkeys, version control,
5
- * and protocol-specific action restrictions (Gatekeeping).
6
- */
7
- export default class PolicyBuilder {
8
- private passkey;
9
- private version_now;
10
- private version_min;
11
- private version_forceupdate;
12
- private noaction_api;
13
- private noaction_server;
14
- /**
15
- * @constructor
16
- * @param {Object} config - The policy configuration.
17
- * @param {string} config.passkey - Secret key used for registry encryption (SHA-256).
18
- * @param {string} config.version_now - The current stable version of the application.
19
- * @param {string} config.version_min - The minimum required version for clients to operate.
20
- * @param {boolean} [config.version_forceupdate=true] - Flag to indicate if clients below version_min must update.
21
- * @throws {Error} If passkey, version_now, or version_min is missing.
22
- */
23
- constructor({ passkey, version_now, version_min, version_forceupdate, }: {
24
- passkey: string;
25
- version_now: string;
26
- version_min: string;
27
- version_forceupdate?: boolean;
28
- });
29
- /**
30
- * @method noaction
31
- * @description Restricts specific action types from being accessed via certain protocols.
32
- * @param {PolicyNoActionKey} [type=""] - The registry key/action type to restrict.
33
- * @param {PolicyNoActionBase} [action=[]] - Array of protocols to block ('server-action' or 'api-action').
34
- * @throws {Error} If the protocol type is invalid or the key is not a string.
35
- */
36
- noaction(type?: PolicyNoActionKey, action?: PolicyNoActionBase): void;
37
- /**
38
- * @method compareVersions
39
- * @private
40
- * @description Compares two semantic version strings to determine their order.
41
- * @param {string} v1 - First version string.
42
- * @param {string} v2 - Second version string.
43
- * @returns {number} 1 if v1 > v2, -1 if v1 < v2, and 0 if they are equal.
44
- */
45
- private compareVersions;
46
- /**
47
- * @method version_info
48
- * @description Checks a provided version against the minimum and current version requirements.
49
- * @param {string} [version=""] - The version string to validate (usually from the client).
50
- * @returns {Object} An object containing upgrade flags and version compatibility status.
51
- */
52
- version_info(version?: string): {
53
- info_upgrade: boolean;
54
- is_version_min: boolean;
55
- is_version_now: boolean;
56
- };
57
- /**
58
- * @method apply
59
- * @description Retrieves the compiled policy configuration.
60
- * @returns {Object} All policy settings including restricted actions and versioning data.
61
- */
62
- apply(): {
63
- passkey: string;
64
- version_now: string;
65
- version_min: string;
66
- version_forceupdate: boolean;
67
- noaction_api: PolicyNoActionAPIAction;
68
- noaction_server: PolicyNoActionServerAction;
69
- };
70
- }
@@ -1,46 +0,0 @@
1
- import type { RegistryKey, RegistryFunction, RegistryLogic, RegistryMiddleware } from "../types/registry.type";
2
- /**
3
- * @class RegistryBuilder
4
- * @description Centralizes the mapping of unique action keys to their respective controllers
5
- * and optional middlewares. It acts as the routing table for the Seishiro API system.
6
- */
7
- export default class RegistryBuilder {
8
- private registry_logic;
9
- /**
10
- * @constructor
11
- * @description Initializes an empty registry storage.
12
- */
13
- constructor();
14
- /**
15
- * @method set
16
- * @description Registers a controller and an optional middleware to a specific key.
17
- * If a middleware is provided, the registry will store them as an array [middleware, function].
18
- * @param {RegistryKey} key - The unique identifier for the action (e.g., 'user:login').
19
- * @param {RegistryFunction} function_regis - The main controller function to execute.
20
- * @param {RegistryMiddleware} [middleware] - Optional middleware function to execute before the main controller.
21
- * @throws {Error} If the controller is not a function or the key is not a string.
22
- */
23
- set(key: RegistryKey, function_regis: RegistryFunction, middleware?: RegistryMiddleware): void;
24
- /**
25
- * @method get
26
- * @description Retrieves the registered function(s) associated with a specific key.
27
- * @param {RegistryKey} key - The key to look up in the registry.
28
- * @returns {RegistryFunction | [RegistryMiddleware, RegistryFunction] | undefined}
29
- * Returns a single function, an array containing [middleware, controller], or undefined if not found.
30
- */
31
- get(key: RegistryKey): RegistryFunction | [RegistryMiddleware, RegistryFunction] | undefined;
32
- /**
33
- * @method apply
34
- * @description Returns the raw internal registry logic mapping.
35
- * @returns {RegistryLogic} The complete object mapping of keys to functions/middlewares.
36
- */
37
- apply(): RegistryLogic;
38
- /**
39
- * @method use
40
- * @description Merges another RegistryBuilder instance or a raw registry object into the current instance.
41
- * This is useful for modularizing routes across different files.
42
- * @param {RegistryBuilder | RegistryLogic} input - The source registry to be merged.
43
- * @throws {Error} If the input is not a RegistryBuilder instance or a valid mapping object.
44
- */
45
- use(input: RegistryBuilder | RegistryLogic): void;
46
- }
@@ -1,13 +0,0 @@
1
- export type MessageKey = string;
2
- export type MessageLang = string | "en" | "id";
3
- export type MessageValue = string;
4
- export type MessageErrorContext = string;
5
- export type MessageErrorContextSlug = string;
6
- export type MessageErrorContextOpt = object;
7
- export type MessageErrorContextTrack = string;
8
- export type MessageLogicLang = {
9
- [key: MessageLang]: {
10
- [key: MessageKey]: MessageValue;
11
- };
12
- };
13
- export type MessageLogic = Record<MessageKey, MessageValue>;
@@ -1,10 +0,0 @@
1
- export type PolicyPassKey = string;
2
- export type PolicyVersionNow = string;
3
- export type PolicyVersionMin = string;
4
- export type PolicyVersionForceUpdate = boolean;
5
- export type PolicyNoActionKey = string;
6
- type AllowedActions = "server-action" | "api-action";
7
- export type PolicyNoActionBase = AllowedActions[];
8
- export type PolicyNoActionAPIAction = string[];
9
- export type PolicyNoActionServerAction = string[];
10
- export {};
@@ -1,16 +0,0 @@
1
- export type RegistryKey = string;
2
- export type RegistryParams = {
3
- system: {
4
- cookies: object;
5
- headers: object;
6
- ip: string;
7
- location: string;
8
- lang: string | "en";
9
- };
10
- type: RegistryKey;
11
- middleware?: object | Function | Promise<any>;
12
- data: object;
13
- };
14
- export type RegistryFunction = (params: RegistryParams) => any;
15
- export type RegistryMiddleware = (params: RegistryParams) => any;
16
- export type RegistryLogic = Record<RegistryKey, RegistryFunction | [RegistryMiddleware, RegistryFunction]>;
@@ -1,11 +0,0 @@
1
- /**
2
- * @function extractLanguage
3
- * @description Parses the HTTP 'Accept-Language' header string into a clean array of unique language codes.
4
- * It handles weights (q-values) and sub-tags (e.g., 'en-US' becomes 'en') to simplify language matching.
5
- * * @param {string} [lang=""] - The raw Accept-Language header string (e.g., "en-US,en;q=0.9,id;q=0.8").
6
- * @returns {string[]} An array of unique, two-letter language codes (e.g., ["en", "id"]).
7
- * * @example
8
- * extractLanguage("en-GB,en-US;q=0.9,id;q=0.8")
9
- * // returns ["en", "id"]
10
- */
11
- declare function extractLanguage(lang?: string): string[];
@@ -1,13 +0,0 @@
1
- /**
2
- * @function formatKey
3
- * @description Sanitizes and standardizes a string key by removing whitespace and illegal characters.
4
- * It ensures that keys used in Registry, Message, and Policy builders remain consistent
5
- * and safe for object property mapping.
6
- * * @param {string} [strkey=""] - The raw string key to be formatted.
7
- * @param {string} Returns a sanitized string containing only alphanumeric characters,
8
- * hyphens (-), dots (.), and colons (:).
9
- * * @example
10
- * formatKey(" user:login @") // returns "user:login"
11
- * formatKey("System-Error!") // returns "System-error"
12
- */
13
- export default function formatKey(strkey?: string): string;