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