seishiro 0.1.6-untest → 0.1.8-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.
Files changed (58) hide show
  1. package/README.md +3 -2
  2. package/{lib → cjs/lib}/actions.d.ts +44 -1
  3. package/cjs/lib/actions.js +207 -0
  4. package/cjs/lib/message.d.ts +69 -0
  5. package/cjs/lib/message.js +156 -0
  6. package/cjs/lib/policy.d.ts +70 -0
  7. package/{lib → cjs/lib}/policy.js +44 -1
  8. package/cjs/lib/registry.d.ts +46 -0
  9. package/cjs/lib/registry.js +89 -0
  10. package/cjs/utils/extract-lang.d.ts +11 -0
  11. package/cjs/utils/extract-lang.js +25 -0
  12. package/cjs/utils/format-key.d.ts +13 -0
  13. package/cjs/utils/format-key.js +21 -0
  14. package/esm/constants/message.d.ts +1 -0
  15. package/esm/constants/message.js +1 -0
  16. package/esm/constants/registry.d.ts +3 -0
  17. package/esm/constants/registry.js +3 -0
  18. package/esm/index.d.ts +4 -0
  19. package/esm/index.js +4 -0
  20. package/esm/lib/actions.d.ts +178 -0
  21. package/esm/lib/actions.js +201 -0
  22. package/esm/lib/message.d.ts +69 -0
  23. package/esm/lib/message.js +150 -0
  24. package/esm/lib/policy.d.ts +70 -0
  25. package/esm/lib/policy.js +113 -0
  26. package/esm/lib/registry.d.ts +46 -0
  27. package/esm/lib/registry.js +83 -0
  28. package/esm/types/message.type.d.ts +13 -0
  29. package/esm/types/message.type.js +2 -0
  30. package/esm/types/policy.type.d.ts +10 -0
  31. package/esm/types/policy.type.js +1 -0
  32. package/esm/types/registry.type.d.ts +16 -0
  33. package/esm/types/registry.type.js +1 -0
  34. package/esm/utils/extract-lang.d.ts +11 -0
  35. package/esm/utils/extract-lang.js +25 -0
  36. package/esm/utils/format-key.d.ts +13 -0
  37. package/esm/utils/format-key.js +18 -0
  38. package/package.json +15 -4
  39. package/helper/format-key.d.ts +0 -1
  40. package/helper/format-key.js +0 -9
  41. package/lib/actions.js +0 -175
  42. package/lib/message.d.ts +0 -41
  43. package/lib/message.js +0 -122
  44. package/lib/policy.d.ts +0 -33
  45. package/lib/registry.d.ts +0 -29
  46. package/lib/registry.js +0 -72
  47. /package/{var → cjs/constants}/message.d.ts +0 -0
  48. /package/{var → cjs/constants}/message.js +0 -0
  49. /package/{var → cjs/constants}/registry.d.ts +0 -0
  50. /package/{var → cjs/constants}/registry.js +0 -0
  51. /package/{index.d.ts → cjs/index.d.ts} +0 -0
  52. /package/{index.js → cjs/index.js} +0 -0
  53. /package/{types → cjs/types}/message.type.d.ts +0 -0
  54. /package/{types → cjs/types}/message.type.js +0 -0
  55. /package/{types → cjs/types}/policy.type.d.ts +0 -0
  56. /package/{types → cjs/types}/policy.type.js +0 -0
  57. /package/{types → cjs/types}/registry.type.d.ts +0 -0
  58. /package/{types → cjs/types}/registry.type.js +0 -0
package/README.md CHANGED
@@ -11,7 +11,8 @@ Seishiro eliminates the complexity of routing folder structures and replaces the
11
11
  - [x] Protocol Response
12
12
  - [x] Middleware Runner
13
13
  - [x] Action Executed
14
- - [ ] Versioning Header
14
+ - [ ] Versioning Header (Pending...)
15
+ - [ ] Language Switch (Pending...)
15
16
 
16
17
  ## Installation
17
18
 
@@ -24,7 +25,7 @@ Seishiro eliminates the complexity of routing folder structures and replaces the
24
25
  yarn add seishiro
25
26
  ```
26
27
 
27
- 2. Copy the file `./example/api/action.(js/ts)` and then copy some of its structure for the sample. You can manage this system to be much more complex.
28
+ 2. Copy the file example and then copy some of its structure for the sample. You can manage this system to be much more complex.
28
29
  3. Set up and customize it as you like.
29
30
  4. Add auth-cookie to put the default placeholder and client version.
30
31
  5. Boom! Done!
@@ -3,24 +3,53 @@ import RegistryBuilder from "./registry";
3
3
  import MessageBuilder from "./message";
4
4
  import PolicyBuilder from "./policy";
5
5
  /**
6
- * @name Actions
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.
7
9
  */
8
10
  export default class Actions {
9
11
  private registry;
10
12
  private message;
11
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
+ */
12
21
  constructor({ registry, message, policy, }: {
13
22
  registry: RegistryBuilder;
14
23
  message: MessageBuilder;
15
24
  policy: PolicyBuilder;
16
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
+ */
17
32
  BookRegistry(): {
18
33
  iv_length: number;
19
34
  type_base: string;
20
35
  iv: string;
21
36
  data: string;
22
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
+ */
23
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
+ */
24
53
  SystemAction({ system, middleware, type, data }: RegistryParams): Promise<{
25
54
  header: {
26
55
  key: string;
@@ -58,6 +87,13 @@ export default class Actions {
58
87
  params?: undefined;
59
88
  };
60
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
+ */
61
97
  ServerAction({ system, middleware, type, data }: RegistryParams): Promise<{
62
98
  header: {
63
99
  key: string;
@@ -95,6 +131,13 @@ export default class Actions {
95
131
  params?: undefined;
96
132
  };
97
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
+ */
98
141
  APIAction({ system, middleware, type, data }: RegistryParams): Promise<{
99
142
  header: {
100
143
  key: string;
@@ -0,0 +1,207 @@
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;
@@ -0,0 +1,69 @@
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
+ }
@@ -0,0 +1,156 @@
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;
@@ -0,0 +1,70 @@
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
+ }