@mesob/common 0.3.5 → 0.4.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/entity/entity-list.ts"],"sourcesContent":["import type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQLWrapper,\n} from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n or,\n type SQL,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\nconst operatorMap: Partial<\n Record<\n FilterOperator,\n (\n column:\n | Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n | SQLWrapper,\n value?: string,\n ) => SQLWrapper | SQL\n >\n> = {\n eq: (col, val) =>\n eq(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n neq: (col, val) =>\n ne(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gt: (col, val) =>\n gt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gte: (col, val) =>\n gte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lt: (col, val) =>\n lt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lte: (col, val) =>\n lte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n like: (col, val) =>\n like(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n ilike: (col, val) =>\n ilike(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n};\n\ntype EntityListParams<T> = {\n search?: SQLWrapper[];\n filter?: EntityListRequest['f'];\n booleanFilter?: {\n column: Column<ColumnBaseConfig<ColumnDataType, string>, object, object>;\n value: boolean;\n };\n orderByConfig?: {\n column: string | SQLWrapper;\n direction: 'asc' | 'desc';\n };\n p?: number;\n pp?: number;\n tenantId?: string;\n entity: T;\n skipTenantIdFilter?: boolean;\n};\n\nexport const entityList = <T extends Record<string, unknown>>({\n search = [],\n filter,\n booleanFilter,\n orderByConfig = { column: 'createdAt', direction: 'desc' },\n p = 1,\n pp = 10,\n tenantId,\n entity,\n skipTenantIdFilter = false,\n}: EntityListParams<T>) => {\n const page = Number(p);\n const pageSize = Number(pp);\n const conditions: (SQL | SQLWrapper)[] = [];\n\n if (tenantId && !skipTenantIdFilter && 'tenantId' in entity) {\n const tenantColumn = (\n entity as unknown as {\n tenantId: Column<\n ColumnBaseConfig<ColumnDataType, string>,\n object,\n object\n >;\n }\n ).tenantId;\n conditions.push(eq(tenantColumn, tenantId));\n }\n\n if (search.length > 0) {\n const searchConditions = search.map((column) => column);\n const searchCondition = or(...searchConditions);\n if (searchCondition) {\n conditions.push(searchCondition);\n }\n }\n\n if (filter) {\n conditions.push(\n ...filter.map((column) => {\n const op = (column.o ?? 'eq') as FilterOperator;\n const columnObj = (\n entity as Record<\n string,\n Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n >\n )[column.f];\n\n if (!columnObj) {\n throw new Error(`Column '${column.f}' not found on entity`);\n }\n\n if (op === 'is') {\n return isNull(columnObj);\n }\n if (op === 'is_not') {\n return not(isNull(columnObj));\n }\n\n const operatorFn = operatorMap[op];\n if (!operatorFn) {\n throw new Error(`Unsupported operator: ${op}`);\n }\n\n return operatorFn(columnObj, column.v);\n }),\n );\n }\n\n if (booleanFilter) {\n conditions.push(eq(booleanFilter.column, booleanFilter.value));\n }\n\n return {\n conditions,\n orderByConfig,\n offset: (page - 1) * pageSize,\n limit: pageSize,\n };\n};\n\nexport const entityResponse = <T extends { totalCount: number }>(\n result: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = result.length > 0 ? result[0].totalCount : 0;\n\n const data = result.map((item) => {\n // biome-ignore lint/correctness/noUnusedVariables: intentionally destructuring to remove totalCount\n const { totalCount, ...rest } = item;\n return rest;\n }) as Omit<T, 'totalCount'>[];\n\n return {\n data,\n total,\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/entity/entity-list.ts"],"sourcesContent":["import type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQLWrapper,\n} from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n or,\n type SQL,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\nconst operatorMap: Partial<\n Record<\n FilterOperator,\n (\n column:\n | Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n | SQLWrapper,\n value?: string,\n ) => SQLWrapper | SQL\n >\n> = {\n eq: (col, val) =>\n eq(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n neq: (col, val) =>\n ne(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gt: (col, val) =>\n gt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gte: (col, val) =>\n gte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lt: (col, val) =>\n lt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lte: (col, val) =>\n lte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n like: (col, val) =>\n like(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n ilike: (col, val) =>\n ilike(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n};\n\ntype EntityListParams<T> = {\n search?: SQLWrapper[];\n filter?: EntityListRequest['f'];\n booleanFilter?: {\n column: Column<ColumnBaseConfig<ColumnDataType, string>, object, object>;\n value: boolean;\n };\n orderByConfig?: {\n column: string | SQLWrapper;\n direction: 'asc' | 'desc';\n };\n p?: number;\n pp?: number;\n tenantId?: string;\n entity: T;\n skipTenantIdFilter?: boolean;\n};\n\nexport const entityList = <T extends Record<string, unknown>>({\n search = [],\n filter,\n booleanFilter,\n orderByConfig = { column: 'createdAt', direction: 'desc' },\n p = 1,\n pp = 10,\n tenantId,\n entity,\n skipTenantIdFilter = false,\n}: EntityListParams<T>) => {\n const page = Number(p);\n const pageSize = Number(pp);\n const conditions: (SQL | SQLWrapper)[] = [];\n\n if (tenantId && !skipTenantIdFilter && 'tenantId' in entity) {\n const tenantColumn = (\n entity as unknown as {\n tenantId: Column<\n ColumnBaseConfig<ColumnDataType, string>,\n object,\n object\n >;\n }\n ).tenantId;\n conditions.push(eq(tenantColumn, tenantId));\n }\n\n if (search.length > 0) {\n const searchConditions = search.map((column) => column);\n const searchCondition = or(...searchConditions);\n if (searchCondition) {\n conditions.push(searchCondition);\n }\n }\n\n if (filter) {\n conditions.push(\n ...filter.map((column) => {\n const op = (column.o ?? 'eq') as FilterOperator;\n const columnObj = (\n entity as Record<\n string,\n Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n >\n )[column.f];\n\n if (!columnObj) {\n throw new Error(`Column '${column.f}' not found on entity`);\n }\n\n if (op === 'is') {\n return isNull(columnObj);\n }\n if (op === 'is_not') {\n return not(isNull(columnObj));\n }\n\n const operatorFn = operatorMap[op];\n if (!operatorFn) {\n throw new Error(`Unsupported operator: ${op}`);\n }\n\n return operatorFn(columnObj, column.v);\n }),\n );\n }\n\n if (booleanFilter) {\n conditions.push(eq(booleanFilter.column, booleanFilter.value));\n }\n\n return {\n conditions,\n orderByConfig,\n offset: (page - 1) * pageSize,\n limit: pageSize,\n };\n};\n\nexport const entityResponse = <T extends { totalCount: number }>(\n result: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = result.length > 0 ? result[0].totalCount : 0;\n\n const data = result.map((item) => {\n const { totalCount, ...rest } = item;\n return rest;\n }) as Omit<T, 'totalCount'>[];\n\n return {\n data,\n total,\n };\n};\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { entityListRequestSchema } from './entity/entity-list-request-schema.js'
5
5
  export { EntityListResponse } from './entity/entity-list-response.js';
6
6
  export { entityPaginatedRows } from './entity/entity-pagination.js';
7
7
  export { default as dayjs } from 'dayjs';
8
+ export { PERMISSION, PermissionCatalog, PermissionEntry, PermissionTree, PermissionType, deny, extendPermission, getPermissionEntries, getPermissionValues, grant, matchesPermission } from './permission/index.js';
8
9
  export { DEFAULT_LANGUAGE, LOCALE_INPUT_DEFAULT, LOCALE_OPTIONAL_INPUT_SCHEMA, LOCALE_REQUIRED_INPUT_SCHEMA, Locale, LocaleKey, SUPPORTED_LANGUAGES, SupportedLanguage, Translation, createLocalInputSchema, createLocalRequiredInputSchema, getLocaleInputDefault } from './utility/locale.js';
9
10
  export { default as logger } from './utility/logger.js';
10
11
  export { toTitleCase } from './utility/string.js';
package/dist/index.js CHANGED
@@ -258,6 +258,68 @@ dayjs.extend(minmax);
258
258
  dayjs.extend(duration);
259
259
  var dayjs_default = dayjs;
260
260
 
261
+ // src/permission/index.ts
262
+ var PERMISSION = {
263
+ ALL: {
264
+ ALL: {
265
+ ALL: "all:all:all"
266
+ }
267
+ }
268
+ };
269
+ function extendPermission(...trees) {
270
+ return Object.assign({}, ...trees, PERMISSION);
271
+ }
272
+ function getPermissionEntries(tree) {
273
+ if (!tree) {
274
+ return [];
275
+ }
276
+ const entries = [];
277
+ const visit = (value) => {
278
+ if (typeof value === "string") {
279
+ const [application = "all", feature = "all", activity = "all"] = value.split(":");
280
+ entries.push({
281
+ code: value,
282
+ application,
283
+ feature,
284
+ activity
285
+ });
286
+ return;
287
+ }
288
+ for (const nestedValue of Object.values(value)) {
289
+ visit(nestedValue);
290
+ }
291
+ };
292
+ visit(tree);
293
+ return entries;
294
+ }
295
+ function getPermissionValues(tree) {
296
+ return getPermissionEntries(tree).map((entry) => entry.code);
297
+ }
298
+ function matchesPermission(requiredPermission, userPermission) {
299
+ const [requiredApplication, requiredFeature, requiredActivity] = requiredPermission.split(":");
300
+ const [userApplication, userFeature, userActivity] = userPermission.split(":");
301
+ return (requiredApplication === userApplication || requiredApplication === "all" || userApplication === "all") && (requiredFeature === userFeature || requiredFeature === "all" || userFeature === "all") && (requiredActivity === userActivity || requiredActivity === "all" || userActivity === "all");
302
+ }
303
+ function grant(permissionList, userPermissions) {
304
+ if (!permissionList?.length) {
305
+ return true;
306
+ }
307
+ if (!userPermissions?.length) {
308
+ return false;
309
+ }
310
+ return permissionList.some((requiredPermission) => {
311
+ return userPermissions.some((userPermission) => {
312
+ return matchesPermission(requiredPermission, userPermission);
313
+ });
314
+ });
315
+ }
316
+ function deny(permissionList, userPermissions) {
317
+ if (!permissionList?.length) {
318
+ return false;
319
+ }
320
+ return !grant(permissionList, userPermissions);
321
+ }
322
+
261
323
  // src/utility/locale.ts
262
324
  import { z as z2 } from "zod";
263
325
  var DEFAULT_LANGUAGE = "en";
@@ -306,6 +368,11 @@ function createLocalRequiredInputSchema(supportedLanguages, validation) {
306
368
  // src/utility/logger.ts
307
369
  var noop = () => void 0;
308
370
  var noopTable = () => void 0;
371
+ var DEBUG_KEY = "mesob:debug";
372
+ var isBrowserRuntime = () => {
373
+ const g = globalThis;
374
+ return typeof g.window !== "undefined" && typeof g.document !== "undefined";
375
+ };
309
376
  var getLocalStorage = () => {
310
377
  try {
311
378
  const storage = globalThis.localStorage;
@@ -318,42 +385,41 @@ var getLocalStorage = () => {
318
385
  }
319
386
  };
320
387
  var LoggerService = class {
321
- debugMode = false;
322
- constructor() {
388
+ shouldLog() {
389
+ if (!isBrowserRuntime()) {
390
+ return true;
391
+ }
323
392
  const storage = getLocalStorage();
324
- const envDebug = process.env.NODE_ENV === "development";
325
393
  if (!storage) {
326
- this.debugMode = envDebug;
327
- return;
394
+ return false;
328
395
  }
329
- const stored = storage.getItem("mesob:debug");
396
+ const stored = storage.getItem(DEBUG_KEY);
330
397
  if (!stored) {
331
- this.debugMode = envDebug;
332
- return;
398
+ return false;
333
399
  }
334
400
  try {
335
- this.debugMode = JSON.parse(stored);
401
+ return Boolean(JSON.parse(stored));
336
402
  } catch {
337
- this.debugMode = envDebug;
403
+ return false;
338
404
  }
339
405
  }
340
406
  get log() {
341
- return this.debugMode ? console.log.bind(console) : noop;
407
+ return this.shouldLog() ? console.log.bind(console) : noop;
342
408
  }
343
409
  get debug() {
344
- return this.debugMode ? console.debug.bind(console) : noop;
410
+ return this.shouldLog() ? console.debug.bind(console) : noop;
345
411
  }
346
412
  get info() {
347
- return this.debugMode ? console.info.bind(console) : noop;
413
+ return this.shouldLog() ? console.info.bind(console) : noop;
348
414
  }
349
415
  get warn() {
350
- return this.debugMode ? console.warn.bind(console) : noop;
416
+ return this.shouldLog() ? console.warn.bind(console) : noop;
351
417
  }
352
418
  get error() {
353
- return this.debugMode ? console.error.bind(console) : noop;
419
+ return this.shouldLog() ? console.error.bind(console) : noop;
354
420
  }
355
421
  get table() {
356
- return this.debugMode ? console.table.bind(console) : noopTable;
422
+ return this.shouldLog() ? console.table.bind(console) : noopTable;
357
423
  }
358
424
  };
359
425
  var logger = new LoggerService();
@@ -380,17 +446,24 @@ export {
380
446
  LOCALE_INPUT_DEFAULT,
381
447
  LOCALE_OPTIONAL_INPUT_SCHEMA,
382
448
  LOCALE_REQUIRED_INPUT_SCHEMA,
449
+ PERMISSION,
383
450
  SUPPORTED_LANGUAGES,
384
451
  createLocalInputSchema,
385
452
  createLocalRequiredInputSchema,
386
453
  dayjs_default as dayjs,
454
+ deny,
387
455
  entityFilterCondition,
388
456
  entityList,
389
457
  entityListRequestSchema,
390
458
  entityPaginatedRows,
391
459
  entityResponse,
460
+ extendPermission,
392
461
  getLocaleInputDefault,
462
+ getPermissionEntries,
463
+ getPermissionValues,
464
+ grant,
393
465
  logger_default as logger,
466
+ matchesPermission,
394
467
  toTitleCase
395
468
  };
396
469
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/entity/entity-filter-condition.ts","../src/entity/entity-list.ts","../src/entity/entity-list-request-schema.ts","../src/entity/entity-pagination.ts","../src/lib/dayjs/index.ts","../src/utility/locale.ts","../src/utility/logger.ts","../src/utility/string.ts"],"sourcesContent":["import type { SQL, SQLWrapper } from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\ntype Column = SQLWrapper | SQL;\n\nconst operatorMap: Record<\n Exclude<FilterOperator, 'is' | 'is_not'>,\n (col: Column, val: string) => SQL\n> = {\n eq: (col, val) => eq(col as SQL, val),\n neq: (col, val) => ne(col as SQL, val),\n gt: (col, val) => gt(col as SQL, val),\n gte: (col, val) => gte(col as SQL, val),\n lt: (col, val) => lt(col as SQL, val),\n lte: (col, val) => lte(col as SQL, val),\n like: (col, val) => like(col as SQL, val),\n ilike: (col, val) => ilike(col as SQL, val),\n};\n\nconst buildCondition = (\n column: Column,\n value: string,\n operator: FilterOperator = 'eq',\n): SQL | undefined => {\n if (operator === 'is') {\n return isNull(column as any);\n }\n if (operator === 'is_not') {\n return not(isNull(column as any));\n }\n const fn = operatorMap[operator];\n return fn ? fn(column, value) : undefined;\n};\n\nexport const entityFilterCondition = <T extends Record<string, Column>>(\n filters: EntityListRequest['f'],\n columnMap: T,\n): SQL[] => {\n if (!filters) {\n return [];\n }\n\n const conditions: SQL[] = [];\n for (const filter of filters) {\n const col = columnMap[filter.f as keyof T];\n if (!col) {\n continue;\n }\n const condition = buildCondition(col, filter.v, filter.o ?? 'eq');\n if (condition) {\n conditions.push(condition);\n }\n }\n return conditions;\n};\n","import type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQLWrapper,\n} from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n or,\n type SQL,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\nconst operatorMap: Partial<\n Record<\n FilterOperator,\n (\n column:\n | Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n | SQLWrapper,\n value?: string,\n ) => SQLWrapper | SQL\n >\n> = {\n eq: (col, val) =>\n eq(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n neq: (col, val) =>\n ne(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gt: (col, val) =>\n gt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gte: (col, val) =>\n gte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lt: (col, val) =>\n lt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lte: (col, val) =>\n lte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n like: (col, val) =>\n like(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n ilike: (col, val) =>\n ilike(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n};\n\ntype EntityListParams<T> = {\n search?: SQLWrapper[];\n filter?: EntityListRequest['f'];\n booleanFilter?: {\n column: Column<ColumnBaseConfig<ColumnDataType, string>, object, object>;\n value: boolean;\n };\n orderByConfig?: {\n column: string | SQLWrapper;\n direction: 'asc' | 'desc';\n };\n p?: number;\n pp?: number;\n tenantId?: string;\n entity: T;\n skipTenantIdFilter?: boolean;\n};\n\nexport const entityList = <T extends Record<string, unknown>>({\n search = [],\n filter,\n booleanFilter,\n orderByConfig = { column: 'createdAt', direction: 'desc' },\n p = 1,\n pp = 10,\n tenantId,\n entity,\n skipTenantIdFilter = false,\n}: EntityListParams<T>) => {\n const page = Number(p);\n const pageSize = Number(pp);\n const conditions: (SQL | SQLWrapper)[] = [];\n\n if (tenantId && !skipTenantIdFilter && 'tenantId' in entity) {\n const tenantColumn = (\n entity as unknown as {\n tenantId: Column<\n ColumnBaseConfig<ColumnDataType, string>,\n object,\n object\n >;\n }\n ).tenantId;\n conditions.push(eq(tenantColumn, tenantId));\n }\n\n if (search.length > 0) {\n const searchConditions = search.map((column) => column);\n const searchCondition = or(...searchConditions);\n if (searchCondition) {\n conditions.push(searchCondition);\n }\n }\n\n if (filter) {\n conditions.push(\n ...filter.map((column) => {\n const op = (column.o ?? 'eq') as FilterOperator;\n const columnObj = (\n entity as Record<\n string,\n Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n >\n )[column.f];\n\n if (!columnObj) {\n throw new Error(`Column '${column.f}' not found on entity`);\n }\n\n if (op === 'is') {\n return isNull(columnObj);\n }\n if (op === 'is_not') {\n return not(isNull(columnObj));\n }\n\n const operatorFn = operatorMap[op];\n if (!operatorFn) {\n throw new Error(`Unsupported operator: ${op}`);\n }\n\n return operatorFn(columnObj, column.v);\n }),\n );\n }\n\n if (booleanFilter) {\n conditions.push(eq(booleanFilter.column, booleanFilter.value));\n }\n\n return {\n conditions,\n orderByConfig,\n offset: (page - 1) * pageSize,\n limit: pageSize,\n };\n};\n\nexport const entityResponse = <T extends { totalCount: number }>(\n result: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = result.length > 0 ? result[0].totalCount : 0;\n\n const data = result.map((item) => {\n // biome-ignore lint/correctness/noUnusedVariables: intentionally destructuring to remove totalCount\n const { totalCount, ...rest } = item;\n return rest;\n }) as Omit<T, 'totalCount'>[];\n\n return {\n data,\n total,\n };\n};\n","import { z } from 'zod';\n\nexport const entityListRequestSchema = z\n .object({\n s: z.string().optional().describe('Search term'),\n l: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .describe('Limit (per page)'),\n f: z\n .union([\n z.array(\n z.object({\n f: z.string().describe('Field name'),\n v: z.string().describe('Field value'),\n o: z\n .enum([\n 'eq',\n 'neq',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'like',\n 'ilike',\n 'is',\n 'is_not',\n ])\n .optional()\n .default('eq')\n .describe('Filter operator'),\n }),\n ),\n z.string().transform((str, ctx) => {\n try {\n return JSON.parse(str) as Array<{\n f: string;\n v: string;\n o?:\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n }>;\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid JSON string for filter',\n });\n return z.NEVER;\n }\n }),\n ])\n .optional()\n .describe('Filters'),\n o: z\n .union([\n z.object({\n f: z.string().describe('Order field'),\n d: z\n .enum(['asc', 'desc'])\n .default('desc')\n .describe('Order direction'),\n }),\n z.string().transform((str, ctx) => {\n try {\n const parsed = JSON.parse(str) as { f: string; d?: 'asc' | 'desc' };\n return {\n f: parsed.f,\n d: parsed.d || 'desc',\n };\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid JSON string for order',\n });\n return z.NEVER;\n }\n }),\n ])\n .optional()\n .describe('Ordering'),\n p: z.coerce.number().min(1).optional().describe('Page number'),\n pp: z.coerce.number().min(1).max(100).optional().describe('Per page'),\n })\n .strict();\n","/**\n * Parses rows from a query using COUNT(*) OVER() window function\n * Returns clean data without totalCount and extracts total\n */\nexport const entityPaginatedRows = <T extends { totalCount: number }>(\n rows: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = rows[0]?.totalCount ?? 0;\n const data = rows.map(({ totalCount: _, ...rest }) => rest) as Omit<\n T,\n 'totalCount'\n >[];\n return { data, total };\n};\n","// biome-ignore lint/style/noExportedImports: this is a library\nimport dayjs from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport duration from 'dayjs/plugin/duration';\nimport isBetween from 'dayjs/plugin/isBetween';\nimport isToday from 'dayjs/plugin/isToday';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport minmax from 'dayjs/plugin/minMax';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport timeZone from 'dayjs/plugin/timezone';\nimport toArray from 'dayjs/plugin/toArray';\nimport utc from 'dayjs/plugin/utc';\n\ndayjs.extend(customParseFormat);\ndayjs.extend(isBetween);\ndayjs.extend(isToday);\ndayjs.extend(localizedFormat);\ndayjs.extend(relativeTime);\ndayjs.extend(timeZone);\ndayjs.extend(toArray);\ndayjs.extend(utc);\ndayjs.extend(minmax);\ndayjs.extend(duration);\n\nexport default dayjs;\n","import { z } from 'zod';\n\nexport type LocaleKey = 'am' | 'en' | 'om' | 'ti' | 'so' | 'sw' | 'fr' | 'ar';\n\nexport type Locale = {\n [Key in LocaleKey | string]?: string;\n};\n\nexport type Translation = (key: string) => string;\n\n/** Fallback when MesobProvider does not receive defaultLanguage/supportedLanguages */\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport type SupportedLanguage = { value: string; label: string; key: string };\n\n/** Fallback when MesobProvider does not receive supportedLanguages */\nexport const SUPPORTED_LANGUAGES: SupportedLanguage[] = [\n { value: 'en', label: 'English', key: 'En' },\n { value: 'am', label: 'አማርኛ', key: 'አማ' },\n];\n\nconst localeRecord = z.record(z.string(), z.string());\nexport const LOCALE_INPUT_DEFAULT: Locale = {};\nexport const LOCALE_REQUIRED_INPUT_SCHEMA = localeRecord.refine(\n (o) => Object.keys(o).length > 0,\n { error: 'At least one locale required' },\n);\nexport const LOCALE_OPTIONAL_INPUT_SCHEMA = localeRecord;\n\nexport function getLocaleInputDefault(\n supportedLanguages: SupportedLanguage[],\n): Record<string, string> {\n return Object.fromEntries(supportedLanguages.map(({ value }) => [value, '']));\n}\n\ntype SchemaAccumulator = {\n [key: string]: z.ZodTypeAny;\n};\n\nexport function createLocalInputSchema(\n defaultLanguage: string,\n supportedLanguages: SupportedLanguage[],\n defaultValidation: z.ZodTypeAny,\n otherValidation: z.ZodTypeAny,\n): z.ZodObject<SchemaAccumulator> {\n const schemaDefinition: { [key: string]: z.ZodTypeAny } =\n supportedLanguages.reduce((acc: SchemaAccumulator, { value }) => {\n acc[value] =\n value === defaultLanguage ? defaultValidation : otherValidation;\n return acc;\n }, {});\n\n return z.object(schemaDefinition);\n}\n\nexport function createLocalRequiredInputSchema(\n supportedLanguages: SupportedLanguage[],\n validation: z.ZodTypeAny,\n): z.ZodObject<SchemaAccumulator> {\n const schemaDefinition: { [key: string]: z.ZodTypeAny } =\n supportedLanguages.reduce((acc: SchemaAccumulator, { value }) => {\n acc[value] = validation;\n return acc;\n }, {});\n\n return z.object(schemaDefinition).superRefine((data, ctx) => {\n const hasValue = Object.values(data).some(\n (value) => typeof value === 'string' && value.trim().length > 0,\n );\n\n if (!hasValue) {\n for (const { value } of supportedLanguages) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'field is required',\n path: [value],\n });\n }\n }\n });\n}\n","/** biome-ignore-all lint/suspicious/noConsole: <explanation> */\n\ntype LogMethod = (...args: unknown[]) => void;\ntype TableMethod = (tabularData?: unknown, properties?: string[]) => void;\ntype LocalStorageLike = { getItem: (key: string) => string | null };\n\nconst noop: LogMethod = () => undefined;\nconst noopTable: TableMethod = () => undefined;\n\nconst getLocalStorage = (): LocalStorageLike | null => {\n try {\n const storage = (globalThis as { localStorage?: LocalStorageLike })\n .localStorage;\n\n if (!storage) {\n return null;\n }\n\n return storage;\n } catch {\n return null;\n }\n};\n\nclass LoggerService {\n debugMode = false;\n\n constructor() {\n const storage = getLocalStorage();\n const envDebug = process.env.NODE_ENV === 'development';\n\n if (!storage) {\n this.debugMode = envDebug;\n return;\n }\n\n const stored = storage.getItem('mesob:debug');\n if (!stored) {\n this.debugMode = envDebug;\n return;\n }\n\n try {\n this.debugMode = JSON.parse(stored);\n } catch {\n this.debugMode = envDebug;\n }\n }\n\n public get log(): LogMethod {\n return this.debugMode ? console.log.bind(console) : noop;\n }\n public get debug(): LogMethod {\n return this.debugMode ? console.debug.bind(console) : noop;\n }\n public get info(): LogMethod {\n return this.debugMode ? console.info.bind(console) : noop;\n }\n public get warn(): LogMethod {\n return this.debugMode ? console.warn.bind(console) : noop;\n }\n\n public get error(): LogMethod {\n return this.debugMode ? console.error.bind(console) : noop;\n }\n\n public get table(): TableMethod {\n return this.debugMode ? console.table.bind(console) : noopTable;\n }\n}\n\nconst logger = new LoggerService();\n\nexport default logger;\n","const normalizeTitleInput = (value: string): string => {\n const spaced = value\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n return spaced;\n};\n\nexport const toTitleCase = (value: string): string => {\n const normalized = normalizeTitleInput(value);\n\n if (!normalized) {\n return '';\n }\n\n return normalized\n .split(' ')\n .map((word) => {\n const first = word[0];\n const rest = word.slice(1);\n\n return `${first.toUpperCase()}${rest.toLowerCase()}`;\n })\n .join(' ');\n};\n"],"mappings":"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","names":["eq","gt","gte","ilike","isNull","like","lt","lte","ne","not","operatorMap","z"]}
1
+ {"version":3,"sources":["../src/entity/entity-filter-condition.ts","../src/entity/entity-list.ts","../src/entity/entity-list-request-schema.ts","../src/entity/entity-pagination.ts","../src/lib/dayjs/index.ts","../src/permission/index.ts","../src/utility/locale.ts","../src/utility/logger.ts","../src/utility/string.ts"],"sourcesContent":["import type { SQL, SQLWrapper } from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\ntype Column = SQLWrapper | SQL;\n\nconst operatorMap: Record<\n Exclude<FilterOperator, 'is' | 'is_not'>,\n (col: Column, val: string) => SQL\n> = {\n eq: (col, val) => eq(col as SQL, val),\n neq: (col, val) => ne(col as SQL, val),\n gt: (col, val) => gt(col as SQL, val),\n gte: (col, val) => gte(col as SQL, val),\n lt: (col, val) => lt(col as SQL, val),\n lte: (col, val) => lte(col as SQL, val),\n like: (col, val) => like(col as SQL, val),\n ilike: (col, val) => ilike(col as SQL, val),\n};\n\nconst buildCondition = (\n column: Column,\n value: string,\n operator: FilterOperator = 'eq',\n): SQL | undefined => {\n if (operator === 'is') {\n return isNull(column as any);\n }\n if (operator === 'is_not') {\n return not(isNull(column as any));\n }\n const fn = operatorMap[operator];\n return fn ? fn(column, value) : undefined;\n};\n\nexport const entityFilterCondition = <T extends Record<string, Column>>(\n filters: EntityListRequest['f'],\n columnMap: T,\n): SQL[] => {\n if (!filters) {\n return [];\n }\n\n const conditions: SQL[] = [];\n for (const filter of filters) {\n const col = columnMap[filter.f as keyof T];\n if (!col) {\n continue;\n }\n const condition = buildCondition(col, filter.v, filter.o ?? 'eq');\n if (condition) {\n conditions.push(condition);\n }\n }\n return conditions;\n};\n","import type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQLWrapper,\n} from 'drizzle-orm';\nimport {\n eq,\n gt,\n gte,\n ilike,\n isNull,\n like,\n lt,\n lte,\n ne,\n not,\n or,\n type SQL,\n} from 'drizzle-orm';\nimport type { EntityListRequest } from './entity-list-request';\n\ntype FilterOperator =\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n\nconst operatorMap: Partial<\n Record<\n FilterOperator,\n (\n column:\n | Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n | SQLWrapper,\n value?: string,\n ) => SQLWrapper | SQL\n >\n> = {\n eq: (col, val) =>\n eq(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n neq: (col, val) =>\n ne(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gt: (col, val) =>\n gt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n gte: (col, val) =>\n gte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lt: (col, val) =>\n lt(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n lte: (col, val) =>\n lte(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n like: (col, val) =>\n like(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n ilike: (col, val) =>\n ilike(\n col as Column<ColumnBaseConfig<ColumnDataType, string>, object, object>,\n val ?? '',\n ),\n};\n\ntype EntityListParams<T> = {\n search?: SQLWrapper[];\n filter?: EntityListRequest['f'];\n booleanFilter?: {\n column: Column<ColumnBaseConfig<ColumnDataType, string>, object, object>;\n value: boolean;\n };\n orderByConfig?: {\n column: string | SQLWrapper;\n direction: 'asc' | 'desc';\n };\n p?: number;\n pp?: number;\n tenantId?: string;\n entity: T;\n skipTenantIdFilter?: boolean;\n};\n\nexport const entityList = <T extends Record<string, unknown>>({\n search = [],\n filter,\n booleanFilter,\n orderByConfig = { column: 'createdAt', direction: 'desc' },\n p = 1,\n pp = 10,\n tenantId,\n entity,\n skipTenantIdFilter = false,\n}: EntityListParams<T>) => {\n const page = Number(p);\n const pageSize = Number(pp);\n const conditions: (SQL | SQLWrapper)[] = [];\n\n if (tenantId && !skipTenantIdFilter && 'tenantId' in entity) {\n const tenantColumn = (\n entity as unknown as {\n tenantId: Column<\n ColumnBaseConfig<ColumnDataType, string>,\n object,\n object\n >;\n }\n ).tenantId;\n conditions.push(eq(tenantColumn, tenantId));\n }\n\n if (search.length > 0) {\n const searchConditions = search.map((column) => column);\n const searchCondition = or(...searchConditions);\n if (searchCondition) {\n conditions.push(searchCondition);\n }\n }\n\n if (filter) {\n conditions.push(\n ...filter.map((column) => {\n const op = (column.o ?? 'eq') as FilterOperator;\n const columnObj = (\n entity as Record<\n string,\n Column<ColumnBaseConfig<ColumnDataType, string>, object, object>\n >\n )[column.f];\n\n if (!columnObj) {\n throw new Error(`Column '${column.f}' not found on entity`);\n }\n\n if (op === 'is') {\n return isNull(columnObj);\n }\n if (op === 'is_not') {\n return not(isNull(columnObj));\n }\n\n const operatorFn = operatorMap[op];\n if (!operatorFn) {\n throw new Error(`Unsupported operator: ${op}`);\n }\n\n return operatorFn(columnObj, column.v);\n }),\n );\n }\n\n if (booleanFilter) {\n conditions.push(eq(booleanFilter.column, booleanFilter.value));\n }\n\n return {\n conditions,\n orderByConfig,\n offset: (page - 1) * pageSize,\n limit: pageSize,\n };\n};\n\nexport const entityResponse = <T extends { totalCount: number }>(\n result: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = result.length > 0 ? result[0].totalCount : 0;\n\n const data = result.map((item) => {\n const { totalCount, ...rest } = item;\n return rest;\n }) as Omit<T, 'totalCount'>[];\n\n return {\n data,\n total,\n };\n};\n","import { z } from 'zod';\n\nexport const entityListRequestSchema = z\n .object({\n s: z.string().optional().describe('Search term'),\n l: z.coerce\n .number()\n .min(1)\n .max(100)\n .optional()\n .describe('Limit (per page)'),\n f: z\n .union([\n z.array(\n z.object({\n f: z.string().describe('Field name'),\n v: z.string().describe('Field value'),\n o: z\n .enum([\n 'eq',\n 'neq',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'like',\n 'ilike',\n 'is',\n 'is_not',\n ])\n .optional()\n .default('eq')\n .describe('Filter operator'),\n }),\n ),\n z.string().transform((str, ctx) => {\n try {\n return JSON.parse(str) as Array<{\n f: string;\n v: string;\n o?:\n | 'eq'\n | 'neq'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'like'\n | 'ilike'\n | 'is'\n | 'is_not';\n }>;\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid JSON string for filter',\n });\n return z.NEVER;\n }\n }),\n ])\n .optional()\n .describe('Filters'),\n o: z\n .union([\n z.object({\n f: z.string().describe('Order field'),\n d: z\n .enum(['asc', 'desc'])\n .default('desc')\n .describe('Order direction'),\n }),\n z.string().transform((str, ctx) => {\n try {\n const parsed = JSON.parse(str) as { f: string; d?: 'asc' | 'desc' };\n return {\n f: parsed.f,\n d: parsed.d || 'desc',\n };\n } catch {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid JSON string for order',\n });\n return z.NEVER;\n }\n }),\n ])\n .optional()\n .describe('Ordering'),\n p: z.coerce.number().min(1).optional().describe('Page number'),\n pp: z.coerce.number().min(1).max(100).optional().describe('Per page'),\n })\n .strict();\n","/**\n * Parses rows from a query using COUNT(*) OVER() window function\n * Returns clean data without totalCount and extracts total\n */\nexport const entityPaginatedRows = <T extends { totalCount: number }>(\n rows: T[],\n): { data: Omit<T, 'totalCount'>[]; total: number } => {\n const total = rows[0]?.totalCount ?? 0;\n const data = rows.map(({ totalCount: _, ...rest }) => rest) as Omit<\n T,\n 'totalCount'\n >[];\n return { data, total };\n};\n","// biome-ignore lint/style/noExportedImports: this is a library\nimport dayjs from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport duration from 'dayjs/plugin/duration';\nimport isBetween from 'dayjs/plugin/isBetween';\nimport isToday from 'dayjs/plugin/isToday';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport minmax from 'dayjs/plugin/minMax';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport timeZone from 'dayjs/plugin/timezone';\nimport toArray from 'dayjs/plugin/toArray';\nimport utc from 'dayjs/plugin/utc';\n\ndayjs.extend(customParseFormat);\ndayjs.extend(isBetween);\ndayjs.extend(isToday);\ndayjs.extend(localizedFormat);\ndayjs.extend(relativeTime);\ndayjs.extend(timeZone);\ndayjs.extend(toArray);\ndayjs.extend(utc);\ndayjs.extend(minmax);\ndayjs.extend(duration);\n\nexport default dayjs;\n","export const PERMISSION = {\n ALL: {\n ALL: {\n ALL: 'all:all:all',\n },\n },\n} as const;\n\ntype PermissionLeaf = string;\ntype PermissionTreeValue = PermissionLeaf | PermissionTree;\n\nexport type PermissionTree = {\n readonly [key: string]: PermissionTreeValue;\n};\n\ntype UnionToIntersection<U> = (\n U extends unknown\n ? (arg: U) => void\n : never\n) extends (arg: infer I) => void\n ? I\n : never;\n\ntype Simplify<T> = {\n [K in keyof T]: T[K];\n} & {};\n\nexport type PermissionCatalog = PermissionTree;\n\ntype ExtractPermissionValues<T> =\n T extends Record<string, infer U>\n ? U extends string\n ? U\n : U extends Record<string, unknown>\n ? ExtractPermissionValues<U>\n : never\n : never;\n\nexport type PermissionType<T extends PermissionTree = typeof PERMISSION> =\n ExtractPermissionValues<T>;\n\nexport type PermissionEntry = {\n code: string;\n application: string;\n feature: string;\n activity: string;\n};\n\ntype MergePermissionTrees<T extends readonly PermissionTree[]> = Simplify<\n UnionToIntersection<T[number]> & PermissionCatalog\n>;\n\nexport function extendPermission<const T extends readonly PermissionTree[]>(\n ...trees: T\n): MergePermissionTrees<T> {\n return Object.assign({}, ...trees, PERMISSION) as MergePermissionTrees<T>;\n}\n\nexport function getPermissionEntries(\n tree?: PermissionTree | null,\n): PermissionEntry[] {\n if (!tree) {\n return [];\n }\n\n const entries: PermissionEntry[] = [];\n const visit = (value: PermissionTreeValue): void => {\n if (typeof value === 'string') {\n const [application = 'all', feature = 'all', activity = 'all'] =\n value.split(':');\n entries.push({\n code: value,\n application,\n feature,\n activity,\n });\n return;\n }\n\n for (const nestedValue of Object.values(value)) {\n visit(nestedValue);\n }\n };\n\n visit(tree);\n\n return entries;\n}\n\nexport function getPermissionValues(tree?: PermissionTree | null): string[] {\n return getPermissionEntries(tree).map((entry) => entry.code);\n}\n\nexport function matchesPermission(\n requiredPermission: string,\n userPermission: string,\n): boolean {\n const [requiredApplication, requiredFeature, requiredActivity] =\n requiredPermission.split(':');\n const [userApplication, userFeature, userActivity] =\n userPermission.split(':');\n\n return (\n (requiredApplication === userApplication ||\n requiredApplication === 'all' ||\n userApplication === 'all') &&\n (requiredFeature === userFeature ||\n requiredFeature === 'all' ||\n userFeature === 'all') &&\n (requiredActivity === userActivity ||\n requiredActivity === 'all' ||\n userActivity === 'all')\n );\n}\n\nexport function grant(\n permissionList: readonly string[] | null | undefined,\n userPermissions: readonly string[] | null | undefined,\n): boolean {\n if (!permissionList?.length) {\n return true;\n }\n\n if (!userPermissions?.length) {\n return false;\n }\n\n return permissionList.some((requiredPermission) => {\n return userPermissions.some((userPermission) => {\n return matchesPermission(requiredPermission, userPermission);\n });\n });\n}\n\nexport function deny(\n permissionList: readonly string[] | null | undefined,\n userPermissions: readonly string[] | null | undefined,\n): boolean {\n if (!permissionList?.length) {\n return false;\n }\n\n return !grant(permissionList, userPermissions);\n}\n","import { z } from 'zod';\n\nexport type LocaleKey = 'am' | 'en' | 'om' | 'ti' | 'so' | 'sw' | 'fr' | 'ar';\n\nexport type Locale = {\n [Key in LocaleKey | string]?: string;\n};\n\nexport type Translation = (key: string) => string;\n\n/** Fallback when MesobProvider does not receive defaultLanguage/supportedLanguages */\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport type SupportedLanguage = { value: string; label: string; key: string };\n\n/** Fallback when MesobProvider does not receive supportedLanguages */\nexport const SUPPORTED_LANGUAGES: SupportedLanguage[] = [\n { value: 'en', label: 'English', key: 'En' },\n { value: 'am', label: 'አማርኛ', key: 'አማ' },\n];\n\nconst localeRecord = z.record(z.string(), z.string());\nexport const LOCALE_INPUT_DEFAULT: Locale = {};\nexport const LOCALE_REQUIRED_INPUT_SCHEMA = localeRecord.refine(\n (o) => Object.keys(o).length > 0,\n { error: 'At least one locale required' },\n);\nexport const LOCALE_OPTIONAL_INPUT_SCHEMA = localeRecord;\n\nexport function getLocaleInputDefault(\n supportedLanguages: SupportedLanguage[],\n): Record<string, string> {\n return Object.fromEntries(supportedLanguages.map(({ value }) => [value, '']));\n}\n\ntype SchemaAccumulator = {\n [key: string]: z.ZodTypeAny;\n};\n\nexport function createLocalInputSchema(\n defaultLanguage: string,\n supportedLanguages: SupportedLanguage[],\n defaultValidation: z.ZodTypeAny,\n otherValidation: z.ZodTypeAny,\n): z.ZodObject<SchemaAccumulator> {\n const schemaDefinition: { [key: string]: z.ZodTypeAny } =\n supportedLanguages.reduce((acc: SchemaAccumulator, { value }) => {\n acc[value] =\n value === defaultLanguage ? defaultValidation : otherValidation;\n return acc;\n }, {});\n\n return z.object(schemaDefinition);\n}\n\nexport function createLocalRequiredInputSchema(\n supportedLanguages: SupportedLanguage[],\n validation: z.ZodTypeAny,\n): z.ZodObject<SchemaAccumulator> {\n const schemaDefinition: { [key: string]: z.ZodTypeAny } =\n supportedLanguages.reduce((acc: SchemaAccumulator, { value }) => {\n acc[value] = validation;\n return acc;\n }, {});\n\n return z.object(schemaDefinition).superRefine((data, ctx) => {\n const hasValue = Object.values(data).some(\n (value) => typeof value === 'string' && value.trim().length > 0,\n );\n\n if (!hasValue) {\n for (const { value } of supportedLanguages) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'field is required',\n path: [value],\n });\n }\n }\n });\n}\n","/** biome-ignore-all lint/suspicious/noConsole: logger package intentionally uses console */\n\ntype LogMethod = (...args: unknown[]) => void;\ntype TableMethod = (tabularData?: unknown, properties?: string[]) => void;\ntype LocalStorageLike = { getItem: (key: string) => string | null };\n\nconst noop: LogMethod = () => undefined;\nconst noopTable: TableMethod = () => undefined;\nconst DEBUG_KEY = 'mesob:debug';\n\nconst isBrowserRuntime = (): boolean => {\n const g = globalThis as { window?: unknown; document?: unknown };\n return typeof g.window !== 'undefined' && typeof g.document !== 'undefined';\n};\n\nconst getLocalStorage = (): LocalStorageLike | null => {\n try {\n const storage = (globalThis as { localStorage?: LocalStorageLike })\n .localStorage;\n\n if (!storage) {\n return null;\n }\n\n return storage;\n } catch {\n return null;\n }\n};\n\nclass LoggerService {\n private shouldLog(): boolean {\n if (!isBrowserRuntime()) {\n return true;\n }\n\n const storage = getLocalStorage();\n\n if (!storage) {\n return false;\n }\n\n const stored = storage.getItem(DEBUG_KEY);\n if (!stored) {\n return false;\n }\n\n try {\n return Boolean(JSON.parse(stored));\n } catch {\n return false;\n }\n }\n\n public get log(): LogMethod {\n return this.shouldLog() ? console.log.bind(console) : noop;\n }\n public get debug(): LogMethod {\n return this.shouldLog() ? console.debug.bind(console) : noop;\n }\n public get info(): LogMethod {\n return this.shouldLog() ? console.info.bind(console) : noop;\n }\n public get warn(): LogMethod {\n return this.shouldLog() ? console.warn.bind(console) : noop;\n }\n\n public get error(): LogMethod {\n return this.shouldLog() ? console.error.bind(console) : noop;\n }\n\n public get table(): TableMethod {\n return this.shouldLog() ? console.table.bind(console) : noopTable;\n }\n}\n\nconst logger = new LoggerService();\n\nexport default logger;\n","const normalizeTitleInput = (value: string): string => {\n const spaced = value\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n\n return spaced;\n};\n\nexport const toTitleCase = (value: string): string => {\n const normalized = normalizeTitleInput(value);\n\n if (!normalized) {\n return '';\n }\n\n return normalized\n .split(' ')\n .map((word) => {\n const first = word[0];\n const rest = word.slice(1);\n\n return `${first.toUpperCase()}${rest.toLowerCase()}`;\n })\n .join(' ');\n};\n"],"mappings":"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","names":["eq","gt","gte","ilike","isNull","like","lt","lte","ne","not","operatorMap","z"]}
@@ -0,0 +1,34 @@
1
+ declare const PERMISSION: {
2
+ readonly ALL: {
3
+ readonly ALL: {
4
+ readonly ALL: "all:all:all";
5
+ };
6
+ };
7
+ };
8
+ type PermissionLeaf = string;
9
+ type PermissionTreeValue = PermissionLeaf | PermissionTree;
10
+ type PermissionTree = {
11
+ readonly [key: string]: PermissionTreeValue;
12
+ };
13
+ type UnionToIntersection<U> = (U extends unknown ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never;
14
+ type Simplify<T> = {
15
+ [K in keyof T]: T[K];
16
+ } & {};
17
+ type PermissionCatalog = PermissionTree;
18
+ type ExtractPermissionValues<T> = T extends Record<string, infer U> ? U extends string ? U : U extends Record<string, unknown> ? ExtractPermissionValues<U> : never : never;
19
+ type PermissionType<T extends PermissionTree = typeof PERMISSION> = ExtractPermissionValues<T>;
20
+ type PermissionEntry = {
21
+ code: string;
22
+ application: string;
23
+ feature: string;
24
+ activity: string;
25
+ };
26
+ type MergePermissionTrees<T extends readonly PermissionTree[]> = Simplify<UnionToIntersection<T[number]> & PermissionCatalog>;
27
+ declare function extendPermission<const T extends readonly PermissionTree[]>(...trees: T): MergePermissionTrees<T>;
28
+ declare function getPermissionEntries(tree?: PermissionTree | null): PermissionEntry[];
29
+ declare function getPermissionValues(tree?: PermissionTree | null): string[];
30
+ declare function matchesPermission(requiredPermission: string, userPermission: string): boolean;
31
+ declare function grant(permissionList: readonly string[] | null | undefined, userPermissions: readonly string[] | null | undefined): boolean;
32
+ declare function deny(permissionList: readonly string[] | null | undefined, userPermissions: readonly string[] | null | undefined): boolean;
33
+
34
+ export { PERMISSION, type PermissionCatalog, type PermissionEntry, type PermissionTree, type PermissionType, deny, extendPermission, getPermissionEntries, getPermissionValues, grant, matchesPermission };
@@ -0,0 +1,71 @@
1
+ // src/permission/index.ts
2
+ var PERMISSION = {
3
+ ALL: {
4
+ ALL: {
5
+ ALL: "all:all:all"
6
+ }
7
+ }
8
+ };
9
+ function extendPermission(...trees) {
10
+ return Object.assign({}, ...trees, PERMISSION);
11
+ }
12
+ function getPermissionEntries(tree) {
13
+ if (!tree) {
14
+ return [];
15
+ }
16
+ const entries = [];
17
+ const visit = (value) => {
18
+ if (typeof value === "string") {
19
+ const [application = "all", feature = "all", activity = "all"] = value.split(":");
20
+ entries.push({
21
+ code: value,
22
+ application,
23
+ feature,
24
+ activity
25
+ });
26
+ return;
27
+ }
28
+ for (const nestedValue of Object.values(value)) {
29
+ visit(nestedValue);
30
+ }
31
+ };
32
+ visit(tree);
33
+ return entries;
34
+ }
35
+ function getPermissionValues(tree) {
36
+ return getPermissionEntries(tree).map((entry) => entry.code);
37
+ }
38
+ function matchesPermission(requiredPermission, userPermission) {
39
+ const [requiredApplication, requiredFeature, requiredActivity] = requiredPermission.split(":");
40
+ const [userApplication, userFeature, userActivity] = userPermission.split(":");
41
+ return (requiredApplication === userApplication || requiredApplication === "all" || userApplication === "all") && (requiredFeature === userFeature || requiredFeature === "all" || userFeature === "all") && (requiredActivity === userActivity || requiredActivity === "all" || userActivity === "all");
42
+ }
43
+ function grant(permissionList, userPermissions) {
44
+ if (!permissionList?.length) {
45
+ return true;
46
+ }
47
+ if (!userPermissions?.length) {
48
+ return false;
49
+ }
50
+ return permissionList.some((requiredPermission) => {
51
+ return userPermissions.some((userPermission) => {
52
+ return matchesPermission(requiredPermission, userPermission);
53
+ });
54
+ });
55
+ }
56
+ function deny(permissionList, userPermissions) {
57
+ if (!permissionList?.length) {
58
+ return false;
59
+ }
60
+ return !grant(permissionList, userPermissions);
61
+ }
62
+ export {
63
+ PERMISSION,
64
+ deny,
65
+ extendPermission,
66
+ getPermissionEntries,
67
+ getPermissionValues,
68
+ grant,
69
+ matchesPermission
70
+ };
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/permission/index.ts"],"sourcesContent":["export const PERMISSION = {\n ALL: {\n ALL: {\n ALL: 'all:all:all',\n },\n },\n} as const;\n\ntype PermissionLeaf = string;\ntype PermissionTreeValue = PermissionLeaf | PermissionTree;\n\nexport type PermissionTree = {\n readonly [key: string]: PermissionTreeValue;\n};\n\ntype UnionToIntersection<U> = (\n U extends unknown\n ? (arg: U) => void\n : never\n) extends (arg: infer I) => void\n ? I\n : never;\n\ntype Simplify<T> = {\n [K in keyof T]: T[K];\n} & {};\n\nexport type PermissionCatalog = PermissionTree;\n\ntype ExtractPermissionValues<T> =\n T extends Record<string, infer U>\n ? U extends string\n ? U\n : U extends Record<string, unknown>\n ? ExtractPermissionValues<U>\n : never\n : never;\n\nexport type PermissionType<T extends PermissionTree = typeof PERMISSION> =\n ExtractPermissionValues<T>;\n\nexport type PermissionEntry = {\n code: string;\n application: string;\n feature: string;\n activity: string;\n};\n\ntype MergePermissionTrees<T extends readonly PermissionTree[]> = Simplify<\n UnionToIntersection<T[number]> & PermissionCatalog\n>;\n\nexport function extendPermission<const T extends readonly PermissionTree[]>(\n ...trees: T\n): MergePermissionTrees<T> {\n return Object.assign({}, ...trees, PERMISSION) as MergePermissionTrees<T>;\n}\n\nexport function getPermissionEntries(\n tree?: PermissionTree | null,\n): PermissionEntry[] {\n if (!tree) {\n return [];\n }\n\n const entries: PermissionEntry[] = [];\n const visit = (value: PermissionTreeValue): void => {\n if (typeof value === 'string') {\n const [application = 'all', feature = 'all', activity = 'all'] =\n value.split(':');\n entries.push({\n code: value,\n application,\n feature,\n activity,\n });\n return;\n }\n\n for (const nestedValue of Object.values(value)) {\n visit(nestedValue);\n }\n };\n\n visit(tree);\n\n return entries;\n}\n\nexport function getPermissionValues(tree?: PermissionTree | null): string[] {\n return getPermissionEntries(tree).map((entry) => entry.code);\n}\n\nexport function matchesPermission(\n requiredPermission: string,\n userPermission: string,\n): boolean {\n const [requiredApplication, requiredFeature, requiredActivity] =\n requiredPermission.split(':');\n const [userApplication, userFeature, userActivity] =\n userPermission.split(':');\n\n return (\n (requiredApplication === userApplication ||\n requiredApplication === 'all' ||\n userApplication === 'all') &&\n (requiredFeature === userFeature ||\n requiredFeature === 'all' ||\n userFeature === 'all') &&\n (requiredActivity === userActivity ||\n requiredActivity === 'all' ||\n userActivity === 'all')\n );\n}\n\nexport function grant(\n permissionList: readonly string[] | null | undefined,\n userPermissions: readonly string[] | null | undefined,\n): boolean {\n if (!permissionList?.length) {\n return true;\n }\n\n if (!userPermissions?.length) {\n return false;\n }\n\n return permissionList.some((requiredPermission) => {\n return userPermissions.some((userPermission) => {\n return matchesPermission(requiredPermission, userPermission);\n });\n });\n}\n\nexport function deny(\n permissionList: readonly string[] | null | undefined,\n userPermissions: readonly string[] | null | undefined,\n): boolean {\n if (!permissionList?.length) {\n return false;\n }\n\n return !grant(permissionList, userPermissions);\n}\n"],"mappings":";AAAO,IAAM,aAAa;AAAA,EACxB,KAAK;AAAA,IACH,KAAK;AAAA,MACH,KAAK;AAAA,IACP;AAAA,EACF;AACF;AA8CO,SAAS,oBACX,OACsB;AACzB,SAAO,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,UAAU;AAC/C;AAEO,SAAS,qBACd,MACmB;AACnB,MAAI,CAAC,MAAM;AACT,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAA6B,CAAC;AACpC,QAAM,QAAQ,CAAC,UAAqC;AAClD,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,CAAC,cAAc,OAAO,UAAU,OAAO,WAAW,KAAK,IAC3D,MAAM,MAAM,GAAG;AACjB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,eAAW,eAAe,OAAO,OAAO,KAAK,GAAG;AAC9C,YAAM,WAAW;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,IAAI;AAEV,SAAO;AACT;AAEO,SAAS,oBAAoB,MAAwC;AAC1E,SAAO,qBAAqB,IAAI,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI;AAC7D;AAEO,SAAS,kBACd,oBACA,gBACS;AACT,QAAM,CAAC,qBAAqB,iBAAiB,gBAAgB,IAC3D,mBAAmB,MAAM,GAAG;AAC9B,QAAM,CAAC,iBAAiB,aAAa,YAAY,IAC/C,eAAe,MAAM,GAAG;AAE1B,UACG,wBAAwB,mBACvB,wBAAwB,SACxB,oBAAoB,WACrB,oBAAoB,eACnB,oBAAoB,SACpB,gBAAgB,WACjB,qBAAqB,gBACpB,qBAAqB,SACrB,iBAAiB;AAEvB;AAEO,SAAS,MACd,gBACA,iBACS;AACT,MAAI,CAAC,gBAAgB,QAAQ;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,iBAAiB,QAAQ;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,KAAK,CAAC,uBAAuB;AACjD,WAAO,gBAAgB,KAAK,CAAC,mBAAmB;AAC9C,aAAO,kBAAkB,oBAAoB,cAAc;AAAA,IAC7D,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,KACd,gBACA,iBACS;AACT,MAAI,CAAC,gBAAgB,QAAQ;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,MAAM,gBAAgB,eAAe;AAC/C;","names":[]}
@@ -1,9 +1,8 @@
1
- /** biome-ignore-all lint/suspicious/noConsole: <explanation> */
1
+ /** biome-ignore-all lint/suspicious/noConsole: logger package intentionally uses console */
2
2
  type LogMethod = (...args: unknown[]) => void;
3
3
  type TableMethod = (tabularData?: unknown, properties?: string[]) => void;
4
4
  declare class LoggerService {
5
- debugMode: boolean;
6
- constructor();
5
+ private shouldLog;
7
6
  get log(): LogMethod;
8
7
  get debug(): LogMethod;
9
8
  get info(): LogMethod;
@@ -1,6 +1,11 @@
1
1
  // src/utility/logger.ts
2
2
  var noop = () => void 0;
3
3
  var noopTable = () => void 0;
4
+ var DEBUG_KEY = "mesob:debug";
5
+ var isBrowserRuntime = () => {
6
+ const g = globalThis;
7
+ return typeof g.window !== "undefined" && typeof g.document !== "undefined";
8
+ };
4
9
  var getLocalStorage = () => {
5
10
  try {
6
11
  const storage = globalThis.localStorage;
@@ -13,42 +18,41 @@ var getLocalStorage = () => {
13
18
  }
14
19
  };
15
20
  var LoggerService = class {
16
- debugMode = false;
17
- constructor() {
21
+ shouldLog() {
22
+ if (!isBrowserRuntime()) {
23
+ return true;
24
+ }
18
25
  const storage = getLocalStorage();
19
- const envDebug = process.env.NODE_ENV === "development";
20
26
  if (!storage) {
21
- this.debugMode = envDebug;
22
- return;
27
+ return false;
23
28
  }
24
- const stored = storage.getItem("mesob:debug");
29
+ const stored = storage.getItem(DEBUG_KEY);
25
30
  if (!stored) {
26
- this.debugMode = envDebug;
27
- return;
31
+ return false;
28
32
  }
29
33
  try {
30
- this.debugMode = JSON.parse(stored);
34
+ return Boolean(JSON.parse(stored));
31
35
  } catch {
32
- this.debugMode = envDebug;
36
+ return false;
33
37
  }
34
38
  }
35
39
  get log() {
36
- return this.debugMode ? console.log.bind(console) : noop;
40
+ return this.shouldLog() ? console.log.bind(console) : noop;
37
41
  }
38
42
  get debug() {
39
- return this.debugMode ? console.debug.bind(console) : noop;
43
+ return this.shouldLog() ? console.debug.bind(console) : noop;
40
44
  }
41
45
  get info() {
42
- return this.debugMode ? console.info.bind(console) : noop;
46
+ return this.shouldLog() ? console.info.bind(console) : noop;
43
47
  }
44
48
  get warn() {
45
- return this.debugMode ? console.warn.bind(console) : noop;
49
+ return this.shouldLog() ? console.warn.bind(console) : noop;
46
50
  }
47
51
  get error() {
48
- return this.debugMode ? console.error.bind(console) : noop;
52
+ return this.shouldLog() ? console.error.bind(console) : noop;
49
53
  }
50
54
  get table() {
51
- return this.debugMode ? console.table.bind(console) : noopTable;
55
+ return this.shouldLog() ? console.table.bind(console) : noopTable;
52
56
  }
53
57
  };
54
58
  var logger = new LoggerService();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utility/logger.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: <explanation> */\n\ntype LogMethod = (...args: unknown[]) => void;\ntype TableMethod = (tabularData?: unknown, properties?: string[]) => void;\ntype LocalStorageLike = { getItem: (key: string) => string | null };\n\nconst noop: LogMethod = () => undefined;\nconst noopTable: TableMethod = () => undefined;\n\nconst getLocalStorage = (): LocalStorageLike | null => {\n try {\n const storage = (globalThis as { localStorage?: LocalStorageLike })\n .localStorage;\n\n if (!storage) {\n return null;\n }\n\n return storage;\n } catch {\n return null;\n }\n};\n\nclass LoggerService {\n debugMode = false;\n\n constructor() {\n const storage = getLocalStorage();\n const envDebug = process.env.NODE_ENV === 'development';\n\n if (!storage) {\n this.debugMode = envDebug;\n return;\n }\n\n const stored = storage.getItem('mesob:debug');\n if (!stored) {\n this.debugMode = envDebug;\n return;\n }\n\n try {\n this.debugMode = JSON.parse(stored);\n } catch {\n this.debugMode = envDebug;\n }\n }\n\n public get log(): LogMethod {\n return this.debugMode ? console.log.bind(console) : noop;\n }\n public get debug(): LogMethod {\n return this.debugMode ? console.debug.bind(console) : noop;\n }\n public get info(): LogMethod {\n return this.debugMode ? console.info.bind(console) : noop;\n }\n public get warn(): LogMethod {\n return this.debugMode ? console.warn.bind(console) : noop;\n }\n\n public get error(): LogMethod {\n return this.debugMode ? console.error.bind(console) : noop;\n }\n\n public get table(): TableMethod {\n return this.debugMode ? console.table.bind(console) : noopTable;\n }\n}\n\nconst logger = new LoggerService();\n\nexport default logger;\n"],"mappings":";AAMA,IAAM,OAAkB,MAAM;AAC9B,IAAM,YAAyB,MAAM;AAErC,IAAM,kBAAkB,MAA+B;AACrD,MAAI;AACF,UAAM,UAAW,WACd;AAEH,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,gBAAN,MAAoB;AAAA,EAClB,YAAY;AAAA,EAEZ,cAAc;AACZ,UAAM,UAAU,gBAAgB;AAChC,UAAM,WAAW,QAAQ,IAAI,aAAa;AAE1C,QAAI,CAAC,SAAS;AACZ,WAAK,YAAY;AACjB;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,QAAQ,aAAa;AAC5C,QAAI,CAAC,QAAQ;AACX,WAAK,YAAY;AACjB;AAAA,IACF;AAEA,QAAI;AACF,WAAK,YAAY,KAAK,MAAM,MAAM;AAAA,IACpC,QAAQ;AACN,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,IAAW,MAAiB;AAC1B,WAAO,KAAK,YAAY,QAAQ,IAAI,KAAK,OAAO,IAAI;AAAA,EACtD;AAAA,EACA,IAAW,QAAmB;AAC5B,WAAO,KAAK,YAAY,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EACxD;AAAA,EACA,IAAW,OAAkB;AAC3B,WAAO,KAAK,YAAY,QAAQ,KAAK,KAAK,OAAO,IAAI;AAAA,EACvD;AAAA,EACA,IAAW,OAAkB;AAC3B,WAAO,KAAK,YAAY,QAAQ,KAAK,KAAK,OAAO,IAAI;AAAA,EACvD;AAAA,EAEA,IAAW,QAAmB;AAC5B,WAAO,KAAK,YAAY,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EACxD;AAAA,EAEA,IAAW,QAAqB;AAC9B,WAAO,KAAK,YAAY,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EACxD;AACF;AAEA,IAAM,SAAS,IAAI,cAAc;AAEjC,IAAO,iBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/utility/logger.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: logger package intentionally uses console */\n\ntype LogMethod = (...args: unknown[]) => void;\ntype TableMethod = (tabularData?: unknown, properties?: string[]) => void;\ntype LocalStorageLike = { getItem: (key: string) => string | null };\n\nconst noop: LogMethod = () => undefined;\nconst noopTable: TableMethod = () => undefined;\nconst DEBUG_KEY = 'mesob:debug';\n\nconst isBrowserRuntime = (): boolean => {\n const g = globalThis as { window?: unknown; document?: unknown };\n return typeof g.window !== 'undefined' && typeof g.document !== 'undefined';\n};\n\nconst getLocalStorage = (): LocalStorageLike | null => {\n try {\n const storage = (globalThis as { localStorage?: LocalStorageLike })\n .localStorage;\n\n if (!storage) {\n return null;\n }\n\n return storage;\n } catch {\n return null;\n }\n};\n\nclass LoggerService {\n private shouldLog(): boolean {\n if (!isBrowserRuntime()) {\n return true;\n }\n\n const storage = getLocalStorage();\n\n if (!storage) {\n return false;\n }\n\n const stored = storage.getItem(DEBUG_KEY);\n if (!stored) {\n return false;\n }\n\n try {\n return Boolean(JSON.parse(stored));\n } catch {\n return false;\n }\n }\n\n public get log(): LogMethod {\n return this.shouldLog() ? console.log.bind(console) : noop;\n }\n public get debug(): LogMethod {\n return this.shouldLog() ? console.debug.bind(console) : noop;\n }\n public get info(): LogMethod {\n return this.shouldLog() ? console.info.bind(console) : noop;\n }\n public get warn(): LogMethod {\n return this.shouldLog() ? console.warn.bind(console) : noop;\n }\n\n public get error(): LogMethod {\n return this.shouldLog() ? console.error.bind(console) : noop;\n }\n\n public get table(): TableMethod {\n return this.shouldLog() ? console.table.bind(console) : noopTable;\n }\n}\n\nconst logger = new LoggerService();\n\nexport default logger;\n"],"mappings":";AAMA,IAAM,OAAkB,MAAM;AAC9B,IAAM,YAAyB,MAAM;AACrC,IAAM,YAAY;AAElB,IAAM,mBAAmB,MAAe;AACtC,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,WAAW,eAAe,OAAO,EAAE,aAAa;AAClE;AAEA,IAAM,kBAAkB,MAA+B;AACrD,MAAI;AACF,UAAM,UAAW,WACd;AAEH,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,gBAAN,MAAoB;AAAA,EACV,YAAqB;AAC3B,QAAI,CAAC,iBAAiB,GAAG;AACvB,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,gBAAgB;AAEhC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,QAAQ,QAAQ,SAAS;AACxC,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,QAAI;AACF,aAAO,QAAQ,KAAK,MAAM,MAAM,CAAC;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAW,MAAiB;AAC1B,WAAO,KAAK,UAAU,IAAI,QAAQ,IAAI,KAAK,OAAO,IAAI;AAAA,EACxD;AAAA,EACA,IAAW,QAAmB;AAC5B,WAAO,KAAK,UAAU,IAAI,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EAC1D;AAAA,EACA,IAAW,OAAkB;AAC3B,WAAO,KAAK,UAAU,IAAI,QAAQ,KAAK,KAAK,OAAO,IAAI;AAAA,EACzD;AAAA,EACA,IAAW,OAAkB;AAC3B,WAAO,KAAK,UAAU,IAAI,QAAQ,KAAK,KAAK,OAAO,IAAI;AAAA,EACzD;AAAA,EAEA,IAAW,QAAmB;AAC5B,WAAO,KAAK,UAAU,IAAI,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EAC1D;AAAA,EAEA,IAAW,QAAqB;AAC9B,WAAO,KAAK,UAAU,IAAI,QAAQ,MAAM,KAAK,OAAO,IAAI;AAAA,EAC1D;AACF;AAEA,IAAM,SAAS,IAAI,cAAc;AAEjC,IAAO,iBAAQ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mesob/common",
3
- "version": "0.3.5",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -22,6 +22,10 @@
22
22
  "types": "./dist/entity/*.d.ts",
23
23
  "default": "./dist/entity/*.js"
24
24
  },
25
+ "./permission": {
26
+ "types": "./dist/permission/index.d.ts",
27
+ "default": "./dist/permission/index.js"
28
+ },
25
29
  "./dayjs": {
26
30
  "types": "./dist/lib/dayjs/index.d.ts",
27
31
  "default": "./dist/lib/dayjs/index.js"