@zerosls/clm-sdk 1.0.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.
Files changed (81) hide show
  1. package/.docs/publicacion-npm.md +111 -0
  2. package/.env.example +14 -0
  3. package/.gitlab-ci.yml +23 -0
  4. package/README.md +202 -0
  5. package/dist/config/config.d.ts +3 -0
  6. package/dist/config/config.js +21 -0
  7. package/dist/core/api-client.d.ts +27 -0
  8. package/dist/core/api-client.js +183 -0
  9. package/dist/core/api-error.d.ts +15 -0
  10. package/dist/core/api-error.js +46 -0
  11. package/dist/core/event-emitter.d.ts +11 -0
  12. package/dist/core/event-emitter.js +32 -0
  13. package/dist/index.d.ts +41 -0
  14. package/dist/index.js +59 -0
  15. package/dist/modules/legacy/areas/areas-api.d.ts +34 -0
  16. package/dist/modules/legacy/areas/areas-api.js +44 -0
  17. package/dist/modules/legacy/areas/types.d.ts +37 -0
  18. package/dist/modules/legacy/areas/types.js +1 -0
  19. package/dist/modules/legacy/classificationtypes/classificationtypes-api.d.ts +34 -0
  20. package/dist/modules/legacy/classificationtypes/classificationtypes-api.js +46 -0
  21. package/dist/modules/legacy/classificationtypes/types.d.ts +41 -0
  22. package/dist/modules/legacy/classificationtypes/types.js +1 -0
  23. package/dist/modules/v1/auth/auth-api.d.ts +17 -0
  24. package/dist/modules/v1/auth/auth-api.js +63 -0
  25. package/dist/modules/v1/auth/types.d.ts +18 -0
  26. package/dist/modules/v1/auth/types.js +1 -0
  27. package/dist/modules/v1/main/main-api.d.ts +11 -0
  28. package/dist/modules/v1/main/main-api.js +14 -0
  29. package/dist/modules/v1/main/types.d.ts +3 -0
  30. package/dist/modules/v1/main/types.js +1 -0
  31. package/dist/modules/v1/notifications/notification-api.d.ts +16 -0
  32. package/dist/modules/v1/notifications/notification-api.js +26 -0
  33. package/dist/modules/v1/notifications/types.d.ts +53 -0
  34. package/dist/modules/v1/notifications/types.js +1 -0
  35. package/dist/modules/v1/users/types.d.ts +64 -0
  36. package/dist/modules/v1/users/types.js +1 -0
  37. package/dist/modules/v1/users/users-api.d.ts +81 -0
  38. package/dist/modules/v1/users/users-api.js +113 -0
  39. package/dist/types/common.d.ts +18 -0
  40. package/dist/types/common.js +1 -0
  41. package/dist/types/sdk.d.ts +42 -0
  42. package/dist/types/sdk.js +11 -0
  43. package/dist/utils/cache.d.ts +10 -0
  44. package/dist/utils/cache.js +43 -0
  45. package/dist/utils/http.d.ts +5 -0
  46. package/dist/utils/http.js +56 -0
  47. package/package.json +38 -0
  48. package/src/config/config.ts +24 -0
  49. package/src/core/api-client.ts +272 -0
  50. package/src/core/api-error.ts +54 -0
  51. package/src/core/event-emitter.ts +43 -0
  52. package/src/index.ts +89 -0
  53. package/src/modules/legacy/areas/areas-api.ts +73 -0
  54. package/src/modules/legacy/areas/types.ts +49 -0
  55. package/src/modules/legacy/classificationtypes/classificationtypes-api.ts +80 -0
  56. package/src/modules/legacy/classificationtypes/types.ts +52 -0
  57. package/src/modules/v1/auth/auth-api.ts +75 -0
  58. package/src/modules/v1/auth/types.ts +20 -0
  59. package/src/modules/v1/main/main-api.ts +20 -0
  60. package/src/modules/v1/main/types.ts +3 -0
  61. package/src/modules/v1/notifications/notification-api.ts +55 -0
  62. package/src/modules/v1/notifications/types.ts +58 -0
  63. package/src/modules/v1/users/types.ts +83 -0
  64. package/src/modules/v1/users/users-api.ts +148 -0
  65. package/src/types/common.ts +22 -0
  66. package/src/types/sdk.ts +38 -0
  67. package/src/utils/cache.ts +58 -0
  68. package/src/utils/http.ts +77 -0
  69. package/tests/integration/legacy/auth-areas.test.ts +115 -0
  70. package/tests/integration/legacy/auth-classification-types.test.ts +80 -0
  71. package/tests/integration/v1/auth-logs.test.ts +145 -0
  72. package/tests/integration/v1/auth-users.test.ts +189 -0
  73. package/tests/modules/legacy/areas/areas-api.test.ts +232 -0
  74. package/tests/modules/legacy/classification-types/classification-types-api.test.ts +100 -0
  75. package/tests/modules/v1/auth/auth-api.test.ts +134 -0
  76. package/tests/modules/v1/users/users-api.test.ts +176 -0
  77. package/tests/setup.ts +12 -0
  78. package/tests/utils/test-utils.ts +453 -0
  79. package/tsconfig.json +16 -0
  80. package/tsconfig.test.json +13 -0
  81. package/vitest.config.ts +16 -0
@@ -0,0 +1,81 @@
1
+ import { ApiClient } from '../../../core/api-client';
2
+ import { RequestOptions } from '../../../types/common';
3
+ import { User, UsersResponse, UsersQuery, UserCreate, UserUpdate, UserCreatedResponse, UserUpdatedResponse, UserDeletedResponse, UserDeactivatedResponse } from './types';
4
+ export declare class UsersApi {
5
+ private apiClient;
6
+ private readonly CACHE_PREFIX;
7
+ constructor(apiClient: ApiClient);
8
+ /**
9
+ * Get all users with optional filters and pagination
10
+ *
11
+ * @param query - Query parameters for filtering and pagination
12
+ * @param options - Request options
13
+ * @returns Paginated list of users
14
+ */
15
+ getAll(query?: UsersQuery, options?: RequestOptions): Promise<UsersResponse>;
16
+ /**
17
+ * Get a specific user by ID
18
+ *
19
+ * @param id - User ID (UUID)
20
+ * @param showDeleted - Whether to include deleted users
21
+ * @param options - Request options
22
+ * @returns User data
23
+ */
24
+ getById(id: string, showDeleted?: boolean, options?: RequestOptions): Promise<User>;
25
+ /**
26
+ * Create a new user
27
+ *
28
+ * @param userData - User data for creation
29
+ * @param options - Request options
30
+ * @returns Created user response
31
+ */
32
+ create(userData: UserCreate, options?: RequestOptions): Promise<UserCreatedResponse>;
33
+ /**
34
+ * Update an existing user
35
+ *
36
+ * @param id - User ID (UUID)
37
+ * @param userData - Data to update
38
+ * @param options - Request options
39
+ * @returns Updated user response
40
+ */
41
+ update(id: string, userData: UserUpdate, options?: RequestOptions): Promise<UserUpdatedResponse>;
42
+ /**
43
+ * Permanently delete a user
44
+ *
45
+ * @param id - User ID (UUID)
46
+ * @param options - Request options
47
+ * @returns Delete confirmation response
48
+ */
49
+ delete(id: string, options?: RequestOptions): Promise<UserDeletedResponse>;
50
+ /**
51
+ * Deactivate a user (soft delete)
52
+ *
53
+ * @param id - User ID (UUID)
54
+ * @param options - Request options
55
+ * @returns Deactivated user response
56
+ */
57
+ deactivate(id: string, options?: RequestOptions): Promise<UserDeactivatedResponse>;
58
+ /**
59
+ * Search users by email or name
60
+ * Helper method that uses getAll with specific filters
61
+ *
62
+ * @param searchTerm - Term to search for in email or name
63
+ * @param options - Request options
64
+ * @returns Matching users
65
+ */
66
+ search(searchTerm: string, options?: RequestOptions): Promise<UsersResponse>;
67
+ /**
68
+ * Get users by role ID
69
+ * Helper method that uses getAll with role filter
70
+ *
71
+ * @param roleId - Role ID to filter by
72
+ * @param options - Request options
73
+ * @returns Users with the specified role
74
+ */
75
+ getByRole(roleId: number, options?: RequestOptions): Promise<UsersResponse>;
76
+ /**
77
+ * Clear cache for users
78
+ * Private method used internally after modifications
79
+ */
80
+ private clearCache;
81
+ }
@@ -0,0 +1,113 @@
1
+ export class UsersApi {
2
+ constructor(apiClient) {
3
+ this.CACHE_PREFIX = 'GET:/users';
4
+ this.apiClient = apiClient;
5
+ }
6
+ /**
7
+ * Get all users with optional filters and pagination
8
+ *
9
+ * @param query - Query parameters for filtering and pagination
10
+ * @param options - Request options
11
+ * @returns Paginated list of users
12
+ */
13
+ async getAll(query, options) {
14
+ const allUsers = this.apiClient.get('/users', query, options);
15
+ console.log(allUsers);
16
+ return allUsers;
17
+ }
18
+ /**
19
+ * Get a specific user by ID
20
+ *
21
+ * @param id - User ID (UUID)
22
+ * @param showDeleted - Whether to include deleted users
23
+ * @param options - Request options
24
+ * @returns User data
25
+ */
26
+ async getById(id, showDeleted = false, options) {
27
+ return this.apiClient.get(`/users/${id}`, { showDeleted }, options);
28
+ }
29
+ /**
30
+ * Create a new user
31
+ *
32
+ * @param userData - User data for creation
33
+ * @param options - Request options
34
+ * @returns Created user response
35
+ */
36
+ async create(userData, options) {
37
+ return this.apiClient.post('/users', userData, options);
38
+ }
39
+ /**
40
+ * Update an existing user
41
+ *
42
+ * @param id - User ID (UUID)
43
+ * @param userData - Data to update
44
+ * @param options - Request options
45
+ * @returns Updated user response
46
+ */
47
+ async update(id, userData, options) {
48
+ return this.apiClient.patch(`/users/${id}`, userData, options);
49
+ }
50
+ /**
51
+ * Permanently delete a user
52
+ *
53
+ * @param id - User ID (UUID)
54
+ * @param options - Request options
55
+ * @returns Delete confirmation response
56
+ */
57
+ async delete(id, options) {
58
+ return this.apiClient.delete(`/users/${id}`, undefined, options);
59
+ }
60
+ /**
61
+ * Deactivate a user (soft delete)
62
+ *
63
+ * @param id - User ID (UUID)
64
+ * @param options - Request options
65
+ * @returns Deactivated user response
66
+ */
67
+ async deactivate(id, options) {
68
+ return this.apiClient.patch(`/users/${id}/desactivate`, undefined, options);
69
+ }
70
+ /**
71
+ * Search users by email or name
72
+ * Helper method that uses getAll with specific filters
73
+ *
74
+ * @param searchTerm - Term to search for in email or name
75
+ * @param options - Request options
76
+ * @returns Matching users
77
+ */
78
+ async search(searchTerm, options) {
79
+ // Determine if searchTerm looks like an email
80
+ const isEmail = searchTerm.includes('@');
81
+ const query = isEmail
82
+ ? { email: searchTerm }
83
+ : { full_name: searchTerm };
84
+ return this.getAll(query, options);
85
+ }
86
+ /**
87
+ * Get users by role ID
88
+ * Helper method that uses getAll with role filter
89
+ *
90
+ * @param roleId - Role ID to filter by
91
+ * @param options - Request options
92
+ * @returns Users with the specified role
93
+ */
94
+ async getByRole(roleId, options) {
95
+ return this.getAll({ role_id: roleId }, options);
96
+ }
97
+ /**
98
+ * Clear cache for users
99
+ * Private method used internally after modifications
100
+ */
101
+ clearCache() {
102
+ try {
103
+ // @ts-ignore - This works because the SDK has a cache.clearByPrefix method
104
+ if (this.apiClient['cache'] && typeof this.apiClient['cache'].clearByPrefix === 'function') {
105
+ // @ts-ignore
106
+ this.apiClient['cache'].clearByPrefix(this.CACHE_PREFIX);
107
+ }
108
+ }
109
+ catch (error) {
110
+ console.error('Error clearing cache:', error);
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,18 @@
1
+ export interface PaginatedResponse<T> {
2
+ results: T[];
3
+ pagination: {
4
+ page: number;
5
+ limit: number;
6
+ totalPages: number;
7
+ totalItems: number;
8
+ };
9
+ }
10
+ export interface RequestOptions {
11
+ useCache?: boolean;
12
+ cacheTime?: number;
13
+ headers?: Record<string, string>;
14
+ }
15
+ export interface PaginationParams {
16
+ page?: number;
17
+ limit?: number;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ export interface SdkConfig {
2
+ baseUrl: string;
3
+ organization: string;
4
+ token?: string | null;
5
+ cache?: {
6
+ enabled?: boolean;
7
+ ttl?: number;
8
+ };
9
+ debug?: boolean;
10
+ }
11
+ export type SdkEventType = "tokenChanged" | "beforeRequest" | "afterRequest" | "requestError" | "authError";
12
+ export interface SdkEvents {
13
+ tokenChanged: string | null;
14
+ beforeRequest: {
15
+ url: string;
16
+ method: string;
17
+ data?: any;
18
+ };
19
+ afterRequest: {
20
+ url: string;
21
+ method: string;
22
+ response: any;
23
+ };
24
+ requestError: {
25
+ url: string;
26
+ method: string;
27
+ error: any;
28
+ };
29
+ authError: {
30
+ statusCode: number;
31
+ message: string;
32
+ };
33
+ }
34
+ export declare enum ErrorType {
35
+ NETWORK = "NETWORK",
36
+ AUTHENTICATION = "AUTHENTICATION",
37
+ AUTHORIZATION = "AUTHORIZATION",
38
+ NOT_FOUND = "NOT_FOUND",
39
+ VALIDATION = "VALIDATION",
40
+ SERVER = "SERVER",
41
+ UNKNOWN = "UNKNOWN"
42
+ }
@@ -0,0 +1,11 @@
1
+ // Tipos de errores HTTP
2
+ export var ErrorType;
3
+ (function (ErrorType) {
4
+ ErrorType["NETWORK"] = "NETWORK";
5
+ ErrorType["AUTHENTICATION"] = "AUTHENTICATION";
6
+ ErrorType["AUTHORIZATION"] = "AUTHORIZATION";
7
+ ErrorType["NOT_FOUND"] = "NOT_FOUND";
8
+ ErrorType["VALIDATION"] = "VALIDATION";
9
+ ErrorType["SERVER"] = "SERVER";
10
+ ErrorType["UNKNOWN"] = "UNKNOWN";
11
+ })(ErrorType || (ErrorType = {}));
@@ -0,0 +1,10 @@
1
+ export declare class Cache {
2
+ private store;
3
+ private defaultTtl;
4
+ constructor(defaultTtl?: number);
5
+ set<T>(key: string, data: T, ttl?: number): void;
6
+ get<T>(key: string): T | null;
7
+ delete(key: string): void;
8
+ clearByPrefix(prefix: string): void;
9
+ clear(): void;
10
+ }
@@ -0,0 +1,43 @@
1
+ export class Cache {
2
+ constructor(defaultTtl = 60000) {
3
+ this.store = new Map();
4
+ this.defaultTtl = defaultTtl;
5
+ }
6
+ // Guardar dato en caché
7
+ set(key, data, ttl) {
8
+ const expiry = ttl || this.defaultTtl;
9
+ this.store.set(key, {
10
+ data,
11
+ timestamp: Date.now(),
12
+ expiry
13
+ });
14
+ }
15
+ // Obtener dato desde caché
16
+ get(key) {
17
+ const item = this.store.get(key);
18
+ // Si no existe o está expirado, devolver null
19
+ if (!item || Date.now() > item.timestamp + item.expiry) {
20
+ if (item) {
21
+ this.store.delete(key); // Limpiar item expirado
22
+ }
23
+ return null;
24
+ }
25
+ return item.data;
26
+ }
27
+ // Eliminar dato específico
28
+ delete(key) {
29
+ this.store.delete(key);
30
+ }
31
+ // Limpiar caché por prefijo
32
+ clearByPrefix(prefix) {
33
+ for (const key of this.store.keys()) {
34
+ if (key.startsWith(prefix)) {
35
+ this.store.delete(key);
36
+ }
37
+ }
38
+ }
39
+ // Limpiar toda la caché
40
+ clear() {
41
+ this.store.clear();
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ export declare function buildUrl(baseUrl: string, endpoint: string, params?: Record<string, any>): string;
2
+ export declare function buildHeaders(token?: string | null, customHeaders?: Record<string, string>): Headers;
3
+ export declare function generateCacheKey(method: string, url: string, data?: any): string;
4
+ export declare function parseResponse<T>(response: Response): Promise<T>;
5
+ export declare function buildQueryParams(params: object | null): string;
@@ -0,0 +1,56 @@
1
+ // import { RequestOptions } from "../types/common";
2
+ // Construye URL con parámetros query
3
+ export function buildUrl(baseUrl, endpoint, params) {
4
+ const url = new URL(`${baseUrl}${endpoint}`);
5
+ if (params) {
6
+ Object.entries(params).forEach(([key, value]) => {
7
+ if (value !== undefined && value !== null) {
8
+ url.searchParams.append(key, String(value));
9
+ }
10
+ });
11
+ }
12
+ return url.toString();
13
+ }
14
+ // Construye cabeceras HTTP
15
+ export function buildHeaders(token, customHeaders) {
16
+ const headers = new Headers({
17
+ "Content-Type": "application/json",
18
+ Accept: "application/json",
19
+ ...customHeaders,
20
+ });
21
+ if (token && !headers.get("Authorization")) {
22
+ headers.append("Authorization", `Bearer ${token}`);
23
+ }
24
+ return headers;
25
+ }
26
+ // Genera una clave de caché única para cada petición
27
+ export function generateCacheKey(method, url, data) {
28
+ const dataString = data ? JSON.stringify(data) : "";
29
+ return `${method}:${url}:${dataString}`;
30
+ }
31
+ // Parse respuesta JSON con manejo de errores
32
+ export async function parseResponse(response) {
33
+ const responseText = await response.text();
34
+ try {
35
+ // Si no hay contenido, devolver objeto vacío
36
+ if (response.status === 204) {
37
+ return {};
38
+ }
39
+ // Intentar parsear como JSON
40
+ const data = JSON.parse(responseText);
41
+ return data;
42
+ }
43
+ catch (error) {
44
+ return responseText;
45
+ }
46
+ }
47
+ export function buildQueryParams(params) {
48
+ if (!params)
49
+ return "";
50
+ const queryParams = Object.entries(params)
51
+ .filter((line) => Boolean(line[1]))
52
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
53
+ if (queryParams.length === 0)
54
+ return "";
55
+ return "?" + queryParams.join("&");
56
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@zerosls/clm-sdk",
3
+ "version": "1.0.0",
4
+ "description": "SDK for ZeroCLM API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "vitest run",
10
+ "test:watch": "vitest",
11
+ "test:coverage": "vitest run --coverage",
12
+ "lint": "eslint src/**/*.ts",
13
+ "prepublish": "npm run build",
14
+ "prepare": "npm run build",
15
+ "dev": "tsc --watch --preserveWatchOutput",
16
+ "link-dev": "npm run build && npm link"
17
+ },
18
+ "keywords": [
19
+ "clm",
20
+ "api",
21
+ "sdk"
22
+ ],
23
+ "author": "devcervant",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "tslib": "^2.5.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^18.16.0",
30
+ "@typescript-eslint/eslint-plugin": "^5.59.1",
31
+ "@typescript-eslint/parser": "^5.59.1",
32
+ "@vitest/coverage-c8": "^0.32.0",
33
+ "eslint": "^8.39.0",
34
+ "jsdom": "^22.0.0",
35
+ "typescript": "^5.0.4",
36
+ "vitest": "^0.32.0"
37
+ }
38
+ }
@@ -0,0 +1,24 @@
1
+ import { SdkConfig } from "../types/sdk";
2
+
3
+ // Valores por defecto para la configuración
4
+ export const DEFAULT_CONFIG: Partial<SdkConfig> = {
5
+ baseUrl: "https://api.clm-app.com/api",
6
+ organization: "default-org",
7
+ cache: {
8
+ enabled: true,
9
+ ttl: 60000, // 1 minuto
10
+ },
11
+ debug: true,
12
+ };
13
+
14
+ // Función para combinar configuración del usuario con valores por defecto
15
+ export function mergeWithDefaultConfig(config: Partial<SdkConfig>): SdkConfig {
16
+ return {
17
+ ...DEFAULT_CONFIG,
18
+ ...config,
19
+ cache: {
20
+ ...DEFAULT_CONFIG.cache,
21
+ ...(config.cache || {}), // Usar un objeto vacío si config.cache es undefined
22
+ },
23
+ } as SdkConfig;
24
+ }