@meago/core 0.2.0

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/dist/index.js ADDED
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ API_ACTIONS: () => API_ACTIONS,
24
+ API_CONTROLLERS: () => API_CONTROLLERS,
25
+ API_VERSION: () => API_VERSION,
26
+ AuthMode: () => AuthMode,
27
+ CoreError: () => CoreError,
28
+ CoreErrorCode: () => CoreErrorCode,
29
+ ESortDir: () => ESortDir,
30
+ EUserStatus: () => EUserStatus,
31
+ MeagoApi: () => api_exports,
32
+ MeagoAuth: () => auth_exports2,
33
+ MeagoConstants: () => constants_exports,
34
+ MeagoDto: () => auth_exports,
35
+ MeagoEnums: () => enums_exports,
36
+ MeagoErrors: () => errors_exports,
37
+ MeagoInterfacesCommon: () => common_exports,
38
+ MeagoInterfacesModels: () => models_exports,
39
+ MeagoPagination: () => pagination_exports,
40
+ MeagoPermissions: () => permissions_exports,
41
+ MeagoPorts: () => ports_exports,
42
+ MeagoResult: () => result_exports,
43
+ PERMISSIONS: () => PERMISSIONS,
44
+ createErrorResponse: () => createErrorResponse,
45
+ createPaginatedResult: () => createPaginatedResult,
46
+ createSuccessResponse: () => createSuccessResponse,
47
+ err: () => err,
48
+ getPaginationOffset: () => getPaginationOffset,
49
+ hasAllPermissions: () => hasAllPermissions,
50
+ hasAnyPermission: () => hasAnyPermission,
51
+ isCoreError: () => isCoreError,
52
+ isErr: () => isErr,
53
+ isOk: () => isOk,
54
+ joinApiPath: () => joinApiPath,
55
+ mapResult: () => mapResult,
56
+ normalizePagination: () => normalizePagination,
57
+ ok: () => ok,
58
+ systemClock: () => systemClock,
59
+ unwrapResult: () => unwrapResult
60
+ });
61
+ module.exports = __toCommonJS(index_exports);
62
+
63
+ // src/constants/index.ts
64
+ var constants_exports = {};
65
+ __export(constants_exports, {
66
+ API_ACTIONS: () => API_ACTIONS,
67
+ API_CONTROLLERS: () => API_CONTROLLERS,
68
+ API_VERSION: () => API_VERSION,
69
+ PERMISSIONS: () => PERMISSIONS
70
+ });
71
+ var API_VERSION = "/api/v1";
72
+ var API_CONTROLLERS = {
73
+ AUTH: "auth",
74
+ USERS: "users",
75
+ ROLES: "roles",
76
+ STORIES: "stories"
77
+ };
78
+ var API_ACTIONS = {
79
+ LOGIN: "login",
80
+ REGISTER: "register",
81
+ REFRESH: "refresh",
82
+ LOGOUT: "logout",
83
+ LOGOUT_ALL: "logout-all",
84
+ ME: "me"
85
+ };
86
+ var PERMISSIONS = {
87
+ USER: {
88
+ READ: "user:read",
89
+ MANAGE: "user:manage"
90
+ },
91
+ ROLE: {
92
+ READ: "role:read",
93
+ MANAGE: "role:manage"
94
+ },
95
+ STORY: {
96
+ CREATE: "story:create",
97
+ READ: "story:read",
98
+ MANAGE: "story:manage"
99
+ }
100
+ };
101
+
102
+ // src/enums/index.ts
103
+ var enums_exports = {};
104
+ __export(enums_exports, {
105
+ ESortDir: () => ESortDir,
106
+ EUserStatus: () => EUserStatus
107
+ });
108
+ var EUserStatus = /* @__PURE__ */ ((EUserStatus2) => {
109
+ EUserStatus2["ACTIVE"] = "active";
110
+ EUserStatus2["BLOCKED"] = "blocked";
111
+ return EUserStatus2;
112
+ })(EUserStatus || {});
113
+ var ESortDir = /* @__PURE__ */ ((ESortDir2) => {
114
+ ESortDir2["ASC"] = "ASC";
115
+ ESortDir2["DESC"] = "DESC";
116
+ return ESortDir2;
117
+ })(ESortDir || {});
118
+
119
+ // src/dto/auth/index.ts
120
+ var auth_exports = {};
121
+
122
+ // src/interfaces/common/index.ts
123
+ var common_exports = {};
124
+
125
+ // src/interfaces/models/index.ts
126
+ var models_exports = {};
127
+
128
+ // src/core/api/index.ts
129
+ var api_exports = {};
130
+ __export(api_exports, {
131
+ createErrorResponse: () => createErrorResponse,
132
+ createSuccessResponse: () => createSuccessResponse,
133
+ joinApiPath: () => joinApiPath
134
+ });
135
+ function createSuccessResponse(data, meta = {}) {
136
+ return {
137
+ statusCode: meta.statusCode ?? 200,
138
+ message: meta.message ?? "Success",
139
+ data,
140
+ timestamp: meta.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
141
+ };
142
+ }
143
+ function createErrorResponse(input) {
144
+ return {
145
+ statusCode: input.statusCode ?? 500,
146
+ error: input.error,
147
+ message: input.message,
148
+ path: input.path,
149
+ timestamp: input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
150
+ ...input.code === void 0 ? {} : { code: input.code },
151
+ ...input.details === void 0 ? {} : { details: input.details }
152
+ };
153
+ }
154
+ function joinApiPath(...parts) {
155
+ const values = parts.filter((part) => part !== null && part !== void 0);
156
+ if (values.length === 0) return "";
157
+ return values.map((part, index) => {
158
+ const value = String(part);
159
+ return index === 0 ? value.replace(/\/+$/g, "") : value.replace(/^\/+|\/+$/g, "");
160
+ }).filter(Boolean).join("/");
161
+ }
162
+
163
+ // src/core/auth/index.ts
164
+ var auth_exports2 = {};
165
+ __export(auth_exports2, {
166
+ AuthMode: () => AuthMode
167
+ });
168
+ var AuthMode = { JWT: "jwt", SESSION: "session" };
169
+
170
+ // src/core/errors/index.ts
171
+ var errors_exports = {};
172
+ __export(errors_exports, {
173
+ CoreError: () => CoreError,
174
+ CoreErrorCode: () => CoreErrorCode,
175
+ isCoreError: () => isCoreError
176
+ });
177
+ var CoreErrorCode = {
178
+ VALIDATION: "VALIDATION",
179
+ UNAUTHENTICATED: "UNAUTHENTICATED",
180
+ FORBIDDEN: "FORBIDDEN",
181
+ NOT_FOUND: "NOT_FOUND",
182
+ CONFLICT: "CONFLICT",
183
+ RATE_LIMITED: "RATE_LIMITED",
184
+ UNAVAILABLE: "UNAVAILABLE",
185
+ INTERNAL: "INTERNAL"
186
+ };
187
+ var CoreError = class extends Error {
188
+ constructor(options) {
189
+ super(options.message);
190
+ this.name = "CoreError";
191
+ this.code = options.code;
192
+ this.details = options.details;
193
+ this.cause = options.cause;
194
+ }
195
+ };
196
+ function isCoreError(error) {
197
+ return error instanceof CoreError;
198
+ }
199
+
200
+ // src/core/pagination/index.ts
201
+ var pagination_exports = {};
202
+ __export(pagination_exports, {
203
+ createPaginatedResult: () => createPaginatedResult,
204
+ getPaginationOffset: () => getPaginationOffset,
205
+ normalizePagination: () => normalizePagination
206
+ });
207
+ function normalizePagination(input, policy = {}) {
208
+ const defaultPage = positiveInteger(policy.defaultPage, 1);
209
+ const defaultLimit = positiveInteger(policy.defaultLimit, 20);
210
+ const maxLimit = positiveInteger(policy.maxLimit, 100);
211
+ return {
212
+ page: positiveInteger(input.page, defaultPage),
213
+ limit: Math.min(positiveInteger(input.limit, defaultLimit), maxLimit)
214
+ };
215
+ }
216
+ function getPaginationOffset(pagination) {
217
+ return (pagination.page - 1) * pagination.limit;
218
+ }
219
+ function createPaginatedResult(items, totalItems, pagination) {
220
+ const safeTotal = Math.max(0, Math.trunc(totalItems));
221
+ const totalPages = safeTotal === 0 ? 0 : Math.ceil(safeTotal / pagination.limit);
222
+ return {
223
+ items,
224
+ totalItems: safeTotal,
225
+ page: pagination.page,
226
+ limit: pagination.limit,
227
+ totalPages,
228
+ hasNextPage: pagination.page < totalPages,
229
+ hasPreviousPage: pagination.page > 1 && totalPages > 0
230
+ };
231
+ }
232
+ function positiveInteger(value, fallback) {
233
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : fallback;
234
+ }
235
+
236
+ // src/core/permissions/index.ts
237
+ var permissions_exports = {};
238
+ __export(permissions_exports, {
239
+ hasAllPermissions: () => hasAllPermissions,
240
+ hasAnyPermission: () => hasAnyPermission
241
+ });
242
+ function hasAllPermissions(granted, required) {
243
+ if (required.length === 0) return true;
244
+ const values = granted instanceof Set ? granted : new Set(granted);
245
+ return required.every((permission) => values.has(permission));
246
+ }
247
+ function hasAnyPermission(granted, required) {
248
+ if (required.length === 0) return true;
249
+ const values = granted instanceof Set ? granted : new Set(granted);
250
+ return required.some((permission) => values.has(permission));
251
+ }
252
+
253
+ // src/core/ports/index.ts
254
+ var ports_exports = {};
255
+ __export(ports_exports, {
256
+ systemClock: () => systemClock
257
+ });
258
+ var systemClock = { now: () => /* @__PURE__ */ new Date() };
259
+
260
+ // src/core/result/index.ts
261
+ var result_exports = {};
262
+ __export(result_exports, {
263
+ err: () => err,
264
+ isErr: () => isErr,
265
+ isOk: () => isOk,
266
+ mapResult: () => mapResult,
267
+ ok: () => ok,
268
+ unwrapResult: () => unwrapResult
269
+ });
270
+ function ok(value) {
271
+ return { ok: true, value };
272
+ }
273
+ function err(error) {
274
+ return { ok: false, error };
275
+ }
276
+ function isOk(result) {
277
+ return result.ok;
278
+ }
279
+ function isErr(result) {
280
+ return !result.ok;
281
+ }
282
+ function unwrapResult(result) {
283
+ if (result.ok) return result.value;
284
+ throw result.error;
285
+ }
286
+ function mapResult(result, mapper) {
287
+ return result.ok ? ok(mapper(result.value)) : result;
288
+ }
289
+ // Annotate the CommonJS export names for ESM import in node:
290
+ 0 && (module.exports = {
291
+ API_ACTIONS,
292
+ API_CONTROLLERS,
293
+ API_VERSION,
294
+ AuthMode,
295
+ CoreError,
296
+ CoreErrorCode,
297
+ ESortDir,
298
+ EUserStatus,
299
+ MeagoApi,
300
+ MeagoAuth,
301
+ MeagoConstants,
302
+ MeagoDto,
303
+ MeagoEnums,
304
+ MeagoErrors,
305
+ MeagoInterfacesCommon,
306
+ MeagoInterfacesModels,
307
+ MeagoPagination,
308
+ MeagoPermissions,
309
+ MeagoPorts,
310
+ MeagoResult,
311
+ PERMISSIONS,
312
+ createErrorResponse,
313
+ createPaginatedResult,
314
+ createSuccessResponse,
315
+ err,
316
+ getPaginationOffset,
317
+ hasAllPermissions,
318
+ hasAnyPermission,
319
+ isCoreError,
320
+ isErr,
321
+ isOk,
322
+ joinApiPath,
323
+ mapResult,
324
+ normalizePagination,
325
+ ok,
326
+ systemClock,
327
+ unwrapResult
328
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,271 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/constants/index.ts
8
+ var constants_exports = {};
9
+ __export(constants_exports, {
10
+ API_ACTIONS: () => API_ACTIONS,
11
+ API_CONTROLLERS: () => API_CONTROLLERS,
12
+ API_VERSION: () => API_VERSION,
13
+ PERMISSIONS: () => PERMISSIONS
14
+ });
15
+ var API_VERSION = "/api/v1";
16
+ var API_CONTROLLERS = {
17
+ AUTH: "auth",
18
+ USERS: "users",
19
+ ROLES: "roles",
20
+ STORIES: "stories"
21
+ };
22
+ var API_ACTIONS = {
23
+ LOGIN: "login",
24
+ REGISTER: "register",
25
+ REFRESH: "refresh",
26
+ LOGOUT: "logout",
27
+ LOGOUT_ALL: "logout-all",
28
+ ME: "me"
29
+ };
30
+ var PERMISSIONS = {
31
+ USER: {
32
+ READ: "user:read",
33
+ MANAGE: "user:manage"
34
+ },
35
+ ROLE: {
36
+ READ: "role:read",
37
+ MANAGE: "role:manage"
38
+ },
39
+ STORY: {
40
+ CREATE: "story:create",
41
+ READ: "story:read",
42
+ MANAGE: "story:manage"
43
+ }
44
+ };
45
+
46
+ // src/enums/index.ts
47
+ var enums_exports = {};
48
+ __export(enums_exports, {
49
+ ESortDir: () => ESortDir,
50
+ EUserStatus: () => EUserStatus
51
+ });
52
+ var EUserStatus = /* @__PURE__ */ ((EUserStatus2) => {
53
+ EUserStatus2["ACTIVE"] = "active";
54
+ EUserStatus2["BLOCKED"] = "blocked";
55
+ return EUserStatus2;
56
+ })(EUserStatus || {});
57
+ var ESortDir = /* @__PURE__ */ ((ESortDir2) => {
58
+ ESortDir2["ASC"] = "ASC";
59
+ ESortDir2["DESC"] = "DESC";
60
+ return ESortDir2;
61
+ })(ESortDir || {});
62
+
63
+ // src/dto/auth/index.ts
64
+ var auth_exports = {};
65
+
66
+ // src/interfaces/common/index.ts
67
+ var common_exports = {};
68
+
69
+ // src/interfaces/models/index.ts
70
+ var models_exports = {};
71
+
72
+ // src/core/api/index.ts
73
+ var api_exports = {};
74
+ __export(api_exports, {
75
+ createErrorResponse: () => createErrorResponse,
76
+ createSuccessResponse: () => createSuccessResponse,
77
+ joinApiPath: () => joinApiPath
78
+ });
79
+ function createSuccessResponse(data, meta = {}) {
80
+ return {
81
+ statusCode: meta.statusCode ?? 200,
82
+ message: meta.message ?? "Success",
83
+ data,
84
+ timestamp: meta.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
85
+ };
86
+ }
87
+ function createErrorResponse(input) {
88
+ return {
89
+ statusCode: input.statusCode ?? 500,
90
+ error: input.error,
91
+ message: input.message,
92
+ path: input.path,
93
+ timestamp: input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
94
+ ...input.code === void 0 ? {} : { code: input.code },
95
+ ...input.details === void 0 ? {} : { details: input.details }
96
+ };
97
+ }
98
+ function joinApiPath(...parts) {
99
+ const values = parts.filter((part) => part !== null && part !== void 0);
100
+ if (values.length === 0) return "";
101
+ return values.map((part, index) => {
102
+ const value = String(part);
103
+ return index === 0 ? value.replace(/\/+$/g, "") : value.replace(/^\/+|\/+$/g, "");
104
+ }).filter(Boolean).join("/");
105
+ }
106
+
107
+ // src/core/auth/index.ts
108
+ var auth_exports2 = {};
109
+ __export(auth_exports2, {
110
+ AuthMode: () => AuthMode
111
+ });
112
+ var AuthMode = { JWT: "jwt", SESSION: "session" };
113
+
114
+ // src/core/errors/index.ts
115
+ var errors_exports = {};
116
+ __export(errors_exports, {
117
+ CoreError: () => CoreError,
118
+ CoreErrorCode: () => CoreErrorCode,
119
+ isCoreError: () => isCoreError
120
+ });
121
+ var CoreErrorCode = {
122
+ VALIDATION: "VALIDATION",
123
+ UNAUTHENTICATED: "UNAUTHENTICATED",
124
+ FORBIDDEN: "FORBIDDEN",
125
+ NOT_FOUND: "NOT_FOUND",
126
+ CONFLICT: "CONFLICT",
127
+ RATE_LIMITED: "RATE_LIMITED",
128
+ UNAVAILABLE: "UNAVAILABLE",
129
+ INTERNAL: "INTERNAL"
130
+ };
131
+ var CoreError = class extends Error {
132
+ constructor(options) {
133
+ super(options.message);
134
+ this.name = "CoreError";
135
+ this.code = options.code;
136
+ this.details = options.details;
137
+ this.cause = options.cause;
138
+ }
139
+ };
140
+ function isCoreError(error) {
141
+ return error instanceof CoreError;
142
+ }
143
+
144
+ // src/core/pagination/index.ts
145
+ var pagination_exports = {};
146
+ __export(pagination_exports, {
147
+ createPaginatedResult: () => createPaginatedResult,
148
+ getPaginationOffset: () => getPaginationOffset,
149
+ normalizePagination: () => normalizePagination
150
+ });
151
+ function normalizePagination(input, policy = {}) {
152
+ const defaultPage = positiveInteger(policy.defaultPage, 1);
153
+ const defaultLimit = positiveInteger(policy.defaultLimit, 20);
154
+ const maxLimit = positiveInteger(policy.maxLimit, 100);
155
+ return {
156
+ page: positiveInteger(input.page, defaultPage),
157
+ limit: Math.min(positiveInteger(input.limit, defaultLimit), maxLimit)
158
+ };
159
+ }
160
+ function getPaginationOffset(pagination) {
161
+ return (pagination.page - 1) * pagination.limit;
162
+ }
163
+ function createPaginatedResult(items, totalItems, pagination) {
164
+ const safeTotal = Math.max(0, Math.trunc(totalItems));
165
+ const totalPages = safeTotal === 0 ? 0 : Math.ceil(safeTotal / pagination.limit);
166
+ return {
167
+ items,
168
+ totalItems: safeTotal,
169
+ page: pagination.page,
170
+ limit: pagination.limit,
171
+ totalPages,
172
+ hasNextPage: pagination.page < totalPages,
173
+ hasPreviousPage: pagination.page > 1 && totalPages > 0
174
+ };
175
+ }
176
+ function positiveInteger(value, fallback) {
177
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : fallback;
178
+ }
179
+
180
+ // src/core/permissions/index.ts
181
+ var permissions_exports = {};
182
+ __export(permissions_exports, {
183
+ hasAllPermissions: () => hasAllPermissions,
184
+ hasAnyPermission: () => hasAnyPermission
185
+ });
186
+ function hasAllPermissions(granted, required) {
187
+ if (required.length === 0) return true;
188
+ const values = granted instanceof Set ? granted : new Set(granted);
189
+ return required.every((permission) => values.has(permission));
190
+ }
191
+ function hasAnyPermission(granted, required) {
192
+ if (required.length === 0) return true;
193
+ const values = granted instanceof Set ? granted : new Set(granted);
194
+ return required.some((permission) => values.has(permission));
195
+ }
196
+
197
+ // src/core/ports/index.ts
198
+ var ports_exports = {};
199
+ __export(ports_exports, {
200
+ systemClock: () => systemClock
201
+ });
202
+ var systemClock = { now: () => /* @__PURE__ */ new Date() };
203
+
204
+ // src/core/result/index.ts
205
+ var result_exports = {};
206
+ __export(result_exports, {
207
+ err: () => err,
208
+ isErr: () => isErr,
209
+ isOk: () => isOk,
210
+ mapResult: () => mapResult,
211
+ ok: () => ok,
212
+ unwrapResult: () => unwrapResult
213
+ });
214
+ function ok(value) {
215
+ return { ok: true, value };
216
+ }
217
+ function err(error) {
218
+ return { ok: false, error };
219
+ }
220
+ function isOk(result) {
221
+ return result.ok;
222
+ }
223
+ function isErr(result) {
224
+ return !result.ok;
225
+ }
226
+ function unwrapResult(result) {
227
+ if (result.ok) return result.value;
228
+ throw result.error;
229
+ }
230
+ function mapResult(result, mapper) {
231
+ return result.ok ? ok(mapper(result.value)) : result;
232
+ }
233
+ export {
234
+ API_ACTIONS,
235
+ API_CONTROLLERS,
236
+ API_VERSION,
237
+ AuthMode,
238
+ CoreError,
239
+ CoreErrorCode,
240
+ ESortDir,
241
+ EUserStatus,
242
+ api_exports as MeagoApi,
243
+ auth_exports2 as MeagoAuth,
244
+ constants_exports as MeagoConstants,
245
+ auth_exports as MeagoDto,
246
+ enums_exports as MeagoEnums,
247
+ errors_exports as MeagoErrors,
248
+ common_exports as MeagoInterfacesCommon,
249
+ models_exports as MeagoInterfacesModels,
250
+ pagination_exports as MeagoPagination,
251
+ permissions_exports as MeagoPermissions,
252
+ ports_exports as MeagoPorts,
253
+ result_exports as MeagoResult,
254
+ PERMISSIONS,
255
+ createErrorResponse,
256
+ createPaginatedResult,
257
+ createSuccessResponse,
258
+ err,
259
+ getPaginationOffset,
260
+ hasAllPermissions,
261
+ hasAnyPermission,
262
+ isCoreError,
263
+ isErr,
264
+ isOk,
265
+ joinApiPath,
266
+ mapResult,
267
+ normalizePagination,
268
+ ok,
269
+ systemClock,
270
+ unwrapResult
271
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@meago/core",
3
+ "version": "0.2.0",
4
+ "description": "Framework-neutral contracts and core primitives for Meago applications",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "sideEffects": false,
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "check": "tsc --noEmit",
22
+ "check:watch": "tsc --noEmit --watch",
23
+ "test": "node scripts/smoke.mjs",
24
+ "pack:check": "npm pack --dry-run --cache .npm-cache",
25
+ "verify": "npm run check && npm run build && npm run test && npm run pack:check",
26
+ "pub": "npm run build && npm publish"
27
+ },
28
+ "publishConfig": {
29
+ "access": "restricted"
30
+ },
31
+ "author": "Meago",
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "tsup": "^8.5.1",
35
+ "typescript": "^5.9.3"
36
+ }
37
+ }