@hamak/ui-remote-resource-impl 0.4.19

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 (41) hide show
  1. package/dist/es2015/index.js +33 -0
  2. package/dist/es2015/middleware/entity-middleware.js +209 -0
  3. package/dist/es2015/middleware/entity-sync-middleware.js +36 -0
  4. package/dist/es2015/middleware/resource-middleware.js +111 -0
  5. package/dist/es2015/middleware/sync-middleware.js +85 -0
  6. package/dist/es2015/plugin/resource-plugin-factory.js +151 -0
  7. package/dist/es2015/providers/mock-resource-provider.js +215 -0
  8. package/dist/es2015/providers/rest-resource-provider.js +140 -0
  9. package/dist/es2015/registry/entity-registry.js +50 -0
  10. package/dist/es2015/registry/resource-registry.js +68 -0
  11. package/dist/index.d.ts +18 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +16 -0
  14. package/dist/middleware/entity-middleware.d.ts +13 -0
  15. package/dist/middleware/entity-middleware.d.ts.map +1 -0
  16. package/dist/middleware/entity-middleware.js +221 -0
  17. package/dist/middleware/entity-sync-middleware.d.ts +7 -0
  18. package/dist/middleware/entity-sync-middleware.d.ts.map +1 -0
  19. package/dist/middleware/entity-sync-middleware.js +31 -0
  20. package/dist/middleware/resource-middleware.d.ts +13 -0
  21. package/dist/middleware/resource-middleware.d.ts.map +1 -0
  22. package/dist/middleware/resource-middleware.js +97 -0
  23. package/dist/middleware/sync-middleware.d.ts +12 -0
  24. package/dist/middleware/sync-middleware.d.ts.map +1 -0
  25. package/dist/middleware/sync-middleware.js +80 -0
  26. package/dist/plugin/resource-plugin-factory.d.ts +31 -0
  27. package/dist/plugin/resource-plugin-factory.d.ts.map +1 -0
  28. package/dist/plugin/resource-plugin-factory.js +131 -0
  29. package/dist/providers/mock-resource-provider.d.ts +147 -0
  30. package/dist/providers/mock-resource-provider.d.ts.map +1 -0
  31. package/dist/providers/mock-resource-provider.js +196 -0
  32. package/dist/providers/rest-resource-provider.d.ts +51 -0
  33. package/dist/providers/rest-resource-provider.d.ts.map +1 -0
  34. package/dist/providers/rest-resource-provider.js +117 -0
  35. package/dist/registry/entity-registry.d.ts +54 -0
  36. package/dist/registry/entity-registry.d.ts.map +1 -0
  37. package/dist/registry/entity-registry.js +46 -0
  38. package/dist/registry/resource-registry.d.ts +80 -0
  39. package/dist/registry/resource-registry.d.ts.map +1 -0
  40. package/dist/registry/resource-registry.js +64 -0
  41. package/package.json +57 -0
@@ -0,0 +1,147 @@
1
+ import type { IResourceProvider, ResourceCallParams, ResourceCallResult } from '@hamak/ui-remote-resource-spi';
2
+ import type { ResourceOperation } from '@hamak/ui-remote-resource-api';
3
+ /**
4
+ * Configuration for a single endpoint mock
5
+ */
6
+ export interface EndpointMockConfig {
7
+ /** Mock response data */
8
+ data?: any;
9
+ /** Mock metadata */
10
+ metadata?: any;
11
+ /** Simulate delay in ms */
12
+ delay?: number;
13
+ /** Simulate error */
14
+ error?: {
15
+ message: string;
16
+ code?: string;
17
+ details?: any;
18
+ };
19
+ /** Dynamic response generator */
20
+ responseGenerator?: (endpoint: string, params: ResourceCallParams, operation: ResourceOperation) => Promise<ResourceCallResult> | ResourceCallResult;
21
+ /** Callback invoked when this endpoint is called */
22
+ onCall?: (endpoint: string, params: ResourceCallParams, operation: ResourceOperation) => void;
23
+ }
24
+ /**
25
+ * Mock configuration map: endpoint pattern -> config
26
+ */
27
+ export type MockConfigMap = Record<string, EndpointMockConfig>;
28
+ /**
29
+ * Call history entry
30
+ */
31
+ export interface MockCallHistoryEntry {
32
+ timestamp: number;
33
+ endpoint: string;
34
+ params: ResourceCallParams;
35
+ operation: ResourceOperation;
36
+ result?: ResourceCallResult;
37
+ error?: any;
38
+ }
39
+ /**
40
+ * Mock provider configuration
41
+ */
42
+ export interface MockProviderConfig {
43
+ /** Predefined mocks for specific endpoints */
44
+ mocks?: MockConfigMap;
45
+ /** Default delay for all calls (can be overridden per endpoint) */
46
+ defaultDelay?: number;
47
+ /** Default response for unmocked endpoints */
48
+ defaultResponse?: any;
49
+ /** Whether to track call history */
50
+ trackHistory?: boolean;
51
+ /** Global error to simulate (overrides all endpoint configs) */
52
+ globalError?: {
53
+ message: string;
54
+ code?: string;
55
+ details?: any;
56
+ };
57
+ /** Callback for all calls */
58
+ onAnyCall?: (endpoint: string, params: ResourceCallParams, operation: ResourceOperation) => void;
59
+ }
60
+ /**
61
+ * Mock Resource Provider for testing
62
+ */
63
+ export declare class MockResourceProvider implements IResourceProvider {
64
+ readonly type = "mock";
65
+ private mocks;
66
+ private defaultDelay;
67
+ private defaultResponse;
68
+ private trackHistory;
69
+ private globalError?;
70
+ private onAnyCall?;
71
+ private callHistory;
72
+ constructor(config?: MockProviderConfig);
73
+ call<TData = any>(endpoint: string, params: ResourceCallParams, operation: ResourceOperation): Promise<ResourceCallResult<TData>>;
74
+ /**
75
+ * Find mock config for endpoint (supports pattern matching)
76
+ */
77
+ private findMockConfig;
78
+ /**
79
+ * Simple pattern matching for endpoints
80
+ */
81
+ private matchesPattern;
82
+ /**
83
+ * Generate response based on config
84
+ */
85
+ private generateResponse;
86
+ /**
87
+ * Create error object
88
+ */
89
+ private createError;
90
+ /**
91
+ * Sleep helper
92
+ */
93
+ private sleep;
94
+ /**
95
+ * Get call history
96
+ */
97
+ getCallHistory(): MockCallHistoryEntry[];
98
+ /**
99
+ * Get calls for specific endpoint
100
+ */
101
+ getCallsForEndpoint(endpoint: string): MockCallHistoryEntry[];
102
+ /**
103
+ * Get calls for specific operation
104
+ */
105
+ getCallsForOperation(operation: ResourceOperation): MockCallHistoryEntry[];
106
+ /**
107
+ * Clear call history
108
+ */
109
+ clearHistory(): void;
110
+ /**
111
+ * Get last call
112
+ */
113
+ getLastCall(): MockCallHistoryEntry | undefined;
114
+ /**
115
+ * Check if endpoint was called
116
+ */
117
+ wasEndpointCalled(endpoint: string, operation?: ResourceOperation): boolean;
118
+ /**
119
+ * Get call count for endpoint
120
+ */
121
+ getCallCount(endpoint?: string, operation?: ResourceOperation): number;
122
+ /**
123
+ * Add or update mock configuration
124
+ */
125
+ setMock(endpoint: string, config: EndpointMockConfig): void;
126
+ /**
127
+ * Remove mock configuration
128
+ */
129
+ removeMock(endpoint: string): void;
130
+ /**
131
+ * Set global error (all calls will fail)
132
+ */
133
+ setGlobalError(error?: {
134
+ message: string;
135
+ code?: string;
136
+ details?: any;
137
+ }): void;
138
+ /**
139
+ * Clear global error
140
+ */
141
+ clearGlobalError(): void;
142
+ /**
143
+ * Reset provider to initial state
144
+ */
145
+ reset(): void;
146
+ }
147
+ //# sourceMappingURL=mock-resource-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-resource-provider.d.ts","sourceRoot":"","sources":["../../src/providers/mock-resource-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,yBAAyB;IACzB,IAAI,CAAC,EAAE,GAAG,CAAC;IAEX,oBAAoB;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IAEf,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qBAAqB;IACrB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IAEF,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,CAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,iBAAiB,KACzB,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;IAEtD,oDAAoD;IACpD,MAAM,CAAC,EAAE,CACP,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,iBAAiB,KACzB,IAAI,CAAC;CACX;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,GAAG,CAAC;IAEtB,oCAAoC;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,gEAAgE;IAChE,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IAEF,6BAA6B;IAC7B,SAAS,CAAC,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,iBAAiB,KACzB,IAAI,CAAC;CACX;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IAC5D,QAAQ,CAAC,IAAI,UAAU;IAEvB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,WAAW,CAAC,CAAoD;IACxE,OAAO,CAAC,SAAS,CAAC,CAIR;IACV,OAAO,CAAC,WAAW,CAA8B;gBAErC,MAAM,GAAE,kBAAuB;IASrC,IAAI,CAAC,KAAK,GAAG,GAAG,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IA8DrC;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,OAAO,CAAC,KAAK;IAMb;;OAEG;IACH,cAAc,IAAI,oBAAoB,EAAE;IAIxC;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,EAAE;IAI7D;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,iBAAiB,GAAG,oBAAoB,EAAE;IAI1E;;OAEG;IACH,YAAY,IAAI,IAAI;IAIpB;;OAEG;IACH,WAAW,IAAI,oBAAoB,GAAG,SAAS;IAI/C;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,iBAAiB,GAAG,OAAO;IAO3E;;OAEG;IACH,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,iBAAiB,GAAG,MAAM;IAUtE;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAI3D;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,cAAc,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI;IAI/E;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Mock Resource Provider for testing
3
+ */
4
+ export class MockResourceProvider {
5
+ constructor(config = {}) {
6
+ this.type = 'mock';
7
+ this.callHistory = [];
8
+ this.mocks = config.mocks || {};
9
+ this.defaultDelay = config.defaultDelay || 0;
10
+ this.defaultResponse = config.defaultResponse || { message: 'Mock response' };
11
+ this.trackHistory = config.trackHistory !== false; // Default true
12
+ this.globalError = config.globalError;
13
+ this.onAnyCall = config.onAnyCall;
14
+ }
15
+ async call(endpoint, params, operation) {
16
+ // Invoke global callback
17
+ this.onAnyCall?.(endpoint, params, operation);
18
+ // Find matching mock config
19
+ const mockConfig = this.findMockConfig(endpoint);
20
+ // Determine delay
21
+ const delay = mockConfig?.delay ?? this.defaultDelay;
22
+ // Simulate delay
23
+ if (delay > 0) {
24
+ await this.sleep(delay);
25
+ }
26
+ // Record call start
27
+ const historyEntry = {
28
+ timestamp: Date.now(),
29
+ endpoint,
30
+ params,
31
+ operation
32
+ };
33
+ try {
34
+ // Check for global error
35
+ if (this.globalError) {
36
+ throw this.createError(this.globalError);
37
+ }
38
+ // Check for endpoint-specific error
39
+ if (mockConfig?.error) {
40
+ throw this.createError(mockConfig.error);
41
+ }
42
+ // Invoke endpoint callback
43
+ mockConfig?.onCall?.(endpoint, params, operation);
44
+ // Generate response
45
+ const result = await this.generateResponse(endpoint, params, operation, mockConfig);
46
+ // Record success
47
+ if (this.trackHistory) {
48
+ historyEntry.result = result;
49
+ this.callHistory.push(historyEntry);
50
+ }
51
+ return result;
52
+ }
53
+ catch (error) {
54
+ // Record error
55
+ if (this.trackHistory) {
56
+ historyEntry.error = error;
57
+ this.callHistory.push(historyEntry);
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ /**
63
+ * Find mock config for endpoint (supports pattern matching)
64
+ */
65
+ findMockConfig(endpoint) {
66
+ // Exact match
67
+ if (this.mocks[endpoint]) {
68
+ return this.mocks[endpoint];
69
+ }
70
+ // Pattern matching (e.g., "/api/users/:id" matches "/api/users/123")
71
+ for (const [pattern, config] of Object.entries(this.mocks)) {
72
+ if (this.matchesPattern(endpoint, pattern)) {
73
+ return config;
74
+ }
75
+ }
76
+ return undefined;
77
+ }
78
+ /**
79
+ * Simple pattern matching for endpoints
80
+ */
81
+ matchesPattern(endpoint, pattern) {
82
+ const patternRegex = pattern.replace(/:[^/]+/g, '[^/]+');
83
+ const regex = new RegExp(`^${patternRegex}$`);
84
+ return regex.test(endpoint);
85
+ }
86
+ /**
87
+ * Generate response based on config
88
+ */
89
+ async generateResponse(endpoint, params, operation, mockConfig) {
90
+ // Use custom response generator if provided
91
+ if (mockConfig?.responseGenerator) {
92
+ const result = await mockConfig.responseGenerator(endpoint, params, operation);
93
+ return result;
94
+ }
95
+ // Use configured data
96
+ const data = mockConfig?.data ?? this.defaultResponse;
97
+ const metadata = mockConfig?.metadata ?? {
98
+ status: 200,
99
+ headers: { 'content-type': 'application/json' }
100
+ };
101
+ return { data, metadata };
102
+ }
103
+ /**
104
+ * Create error object
105
+ */
106
+ createError(errorConfig) {
107
+ const error = new Error(errorConfig.message);
108
+ error.code = errorConfig.code;
109
+ error.details = errorConfig.details;
110
+ return error;
111
+ }
112
+ /**
113
+ * Sleep helper
114
+ */
115
+ sleep(ms) {
116
+ return new Promise((resolve) => setTimeout(resolve, ms));
117
+ }
118
+ // ========== Testing Utilities ==========
119
+ /**
120
+ * Get call history
121
+ */
122
+ getCallHistory() {
123
+ return [...this.callHistory];
124
+ }
125
+ /**
126
+ * Get calls for specific endpoint
127
+ */
128
+ getCallsForEndpoint(endpoint) {
129
+ return this.callHistory.filter((entry) => entry.endpoint === endpoint);
130
+ }
131
+ /**
132
+ * Get calls for specific operation
133
+ */
134
+ getCallsForOperation(operation) {
135
+ return this.callHistory.filter((entry) => entry.operation === operation);
136
+ }
137
+ /**
138
+ * Clear call history
139
+ */
140
+ clearHistory() {
141
+ this.callHistory = [];
142
+ }
143
+ /**
144
+ * Get last call
145
+ */
146
+ getLastCall() {
147
+ return this.callHistory[this.callHistory.length - 1];
148
+ }
149
+ /**
150
+ * Check if endpoint was called
151
+ */
152
+ wasEndpointCalled(endpoint, operation) {
153
+ return this.callHistory.some((entry) => entry.endpoint === endpoint && (!operation || entry.operation === operation));
154
+ }
155
+ /**
156
+ * Get call count for endpoint
157
+ */
158
+ getCallCount(endpoint, operation) {
159
+ if (!endpoint) {
160
+ return this.callHistory.length;
161
+ }
162
+ return this.callHistory.filter((entry) => entry.endpoint === endpoint && (!operation || entry.operation === operation)).length;
163
+ }
164
+ /**
165
+ * Add or update mock configuration
166
+ */
167
+ setMock(endpoint, config) {
168
+ this.mocks[endpoint] = config;
169
+ }
170
+ /**
171
+ * Remove mock configuration
172
+ */
173
+ removeMock(endpoint) {
174
+ delete this.mocks[endpoint];
175
+ }
176
+ /**
177
+ * Set global error (all calls will fail)
178
+ */
179
+ setGlobalError(error) {
180
+ this.globalError = error;
181
+ }
182
+ /**
183
+ * Clear global error
184
+ */
185
+ clearGlobalError() {
186
+ this.globalError = undefined;
187
+ }
188
+ /**
189
+ * Reset provider to initial state
190
+ */
191
+ reset() {
192
+ this.clearHistory();
193
+ this.clearGlobalError();
194
+ this.mocks = {};
195
+ }
196
+ }
@@ -0,0 +1,51 @@
1
+ import { type AxiosInstance } from 'axios';
2
+ import type { IResourceProvider, ResourceCallParams, ResourceCallResult } from '@hamak/ui-remote-resource-spi';
3
+ import type { ResourceOperation } from '@hamak/ui-remote-resource-api';
4
+ /**
5
+ * Configuration for REST resource provider
6
+ */
7
+ export interface RestProviderConfig {
8
+ /** Base URL for API requests */
9
+ baseUrl?: string;
10
+ /** Request timeout in milliseconds */
11
+ timeout?: number;
12
+ /** Default headers for all requests */
13
+ headers?: Record<string, string>;
14
+ /** Custom axios instance (if not provided, one will be created) */
15
+ axiosInstance?: AxiosInstance;
16
+ }
17
+ /**
18
+ * REST API resource provider using Axios
19
+ */
20
+ export declare class RestResourceProvider implements IResourceProvider {
21
+ readonly type = "rest";
22
+ private axios;
23
+ constructor(config?: RestProviderConfig);
24
+ /**
25
+ * Execute a resource call
26
+ */
27
+ call<TData = any>(endpoint: string, params: ResourceCallParams, operation: ResourceOperation): Promise<ResourceCallResult<TData>>;
28
+ /**
29
+ * Execute fetch operation (GET)
30
+ */
31
+ private executeFetch;
32
+ /**
33
+ * Execute create operation (POST)
34
+ */
35
+ private executeCreate;
36
+ /**
37
+ * Execute update operation (PUT)
38
+ */
39
+ private executeUpdate;
40
+ /**
41
+ * Execute delete operation (DELETE)
42
+ */
43
+ private executeDelete;
44
+ /**
45
+ * Build URL with path parameters
46
+ * Replaces :param placeholders with actual values
47
+ * Example: /users/:id + { id: "123" } → /users/123
48
+ */
49
+ private buildUrl;
50
+ }
51
+ //# sourceMappingURL=rest-resource-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-resource-provider.d.ts","sourceRoot":"","sources":["../../src/providers/rest-resource-provider.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,mEAAmE;IACnE,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IAC5D,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,KAAK,CAAgB;gBAEjB,MAAM,GAAE,kBAAuB;IAa3C;;OAEG;IACG,IAAI,CAAC,KAAK,GAAG,GAAG,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAerC;;OAEG;YACW,YAAY;IAmB1B;;OAEG;YACW,aAAa;IAkB3B;;OAEG;YACW,aAAa;IAmB3B;;OAEG;YACW,aAAa;IAmB3B;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CAUjB"}
@@ -0,0 +1,117 @@
1
+ import axios from 'axios';
2
+ /**
3
+ * REST API resource provider using Axios
4
+ */
5
+ export class RestResourceProvider {
6
+ constructor(config = {}) {
7
+ this.type = 'rest';
8
+ this.axios =
9
+ config.axiosInstance ||
10
+ axios.create({
11
+ baseURL: config.baseUrl,
12
+ timeout: config.timeout || 30000,
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ ...config.headers
16
+ }
17
+ });
18
+ }
19
+ /**
20
+ * Execute a resource call
21
+ */
22
+ async call(endpoint, params, operation) {
23
+ switch (operation) {
24
+ case 'fetch':
25
+ return this.executeFetch(endpoint, params);
26
+ case 'create':
27
+ return this.executeCreate(endpoint, params);
28
+ case 'update':
29
+ return this.executeUpdate(endpoint, params);
30
+ case 'delete':
31
+ return this.executeDelete(endpoint, params);
32
+ default:
33
+ throw new Error(`Unknown operation: ${operation}`);
34
+ }
35
+ }
36
+ /**
37
+ * Execute fetch operation (GET)
38
+ */
39
+ async executeFetch(endpoint, params) {
40
+ const url = this.buildUrl(endpoint, params.params);
41
+ const response = await this.axios.get(url, {
42
+ params: params.query,
43
+ headers: params.headers
44
+ });
45
+ return {
46
+ data: response.data,
47
+ metadata: {
48
+ status: response.status,
49
+ headers: response.headers
50
+ }
51
+ };
52
+ }
53
+ /**
54
+ * Execute create operation (POST)
55
+ */
56
+ async executeCreate(endpoint, params) {
57
+ const response = await this.axios.post(endpoint, params.body, {
58
+ params: params.query,
59
+ headers: params.headers
60
+ });
61
+ return {
62
+ data: response.data,
63
+ metadata: {
64
+ status: response.status,
65
+ headers: response.headers
66
+ }
67
+ };
68
+ }
69
+ /**
70
+ * Execute update operation (PUT)
71
+ */
72
+ async executeUpdate(endpoint, params) {
73
+ const url = this.buildUrl(endpoint, params.params);
74
+ const response = await this.axios.put(url, params.body, {
75
+ params: params.query,
76
+ headers: params.headers
77
+ });
78
+ return {
79
+ data: response.data,
80
+ metadata: {
81
+ status: response.status,
82
+ headers: response.headers
83
+ }
84
+ };
85
+ }
86
+ /**
87
+ * Execute delete operation (DELETE)
88
+ */
89
+ async executeDelete(endpoint, params) {
90
+ const url = this.buildUrl(endpoint, params.params);
91
+ const response = await this.axios.delete(url, {
92
+ params: params.query,
93
+ headers: params.headers
94
+ });
95
+ return {
96
+ data: response.data,
97
+ metadata: {
98
+ status: response.status,
99
+ headers: response.headers
100
+ }
101
+ };
102
+ }
103
+ /**
104
+ * Build URL with path parameters
105
+ * Replaces :param placeholders with actual values
106
+ * Example: /users/:id + { id: "123" } → /users/123
107
+ */
108
+ buildUrl(endpoint, params) {
109
+ if (!params)
110
+ return endpoint;
111
+ let url = endpoint;
112
+ Object.entries(params).forEach(([key, value]) => {
113
+ url = url.replace(`:${key}`, String(value));
114
+ });
115
+ return url;
116
+ }
117
+ }
@@ -0,0 +1,54 @@
1
+ import type { EntityDefinition } from '@hamak/ui-remote-resource-spi';
2
+ /**
3
+ * Internal entity registry interface with write operations
4
+ */
5
+ export interface IEntityRegistryInternal {
6
+ /**
7
+ * Register an entity definition
8
+ */
9
+ registerEntity(definition: EntityDefinition): void;
10
+ /**
11
+ * Unregister an entity definition
12
+ */
13
+ unregisterEntity(id: string): void;
14
+ /**
15
+ * Get entity definition by ID
16
+ */
17
+ getEntity(id: string): EntityDefinition | undefined;
18
+ /**
19
+ * Get all registered entities
20
+ */
21
+ getAllEntities(): EntityDefinition[];
22
+ /**
23
+ * Check if entity exists
24
+ */
25
+ hasEntity(id: string): boolean;
26
+ }
27
+ /**
28
+ * Entity registry implementation
29
+ * Manages entity definitions
30
+ */
31
+ export declare class EntityRegistry implements IEntityRegistryInternal {
32
+ private entities;
33
+ /**
34
+ * Register an entity definition
35
+ */
36
+ registerEntity(definition: EntityDefinition): void;
37
+ /**
38
+ * Unregister an entity definition
39
+ */
40
+ unregisterEntity(id: string): void;
41
+ /**
42
+ * Get entity definition by ID
43
+ */
44
+ getEntity(id: string): EntityDefinition | undefined;
45
+ /**
46
+ * Get all registered entities
47
+ */
48
+ getAllEntities(): EntityDefinition[];
49
+ /**
50
+ * Check if entity exists
51
+ */
52
+ hasEntity(id: string): boolean;
53
+ }
54
+ //# sourceMappingURL=entity-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-registry.d.ts","sourceRoot":"","sources":["../../src/registry/entity-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAEpD;;OAEG;IACH,cAAc,IAAI,gBAAgB,EAAE,CAAC;IAErC;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,cAAe,YAAW,uBAAuB;IAC5D,OAAO,CAAC,QAAQ,CAA4C;IAE5D;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAiBlD;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAInD;;OAEG;IACH,cAAc,IAAI,gBAAgB,EAAE;IAIpC;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAG/B"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Entity registry implementation
3
+ * Manages entity definitions
4
+ */
5
+ export class EntityRegistry {
6
+ constructor() {
7
+ this.entities = new Map();
8
+ }
9
+ /**
10
+ * Register an entity definition
11
+ */
12
+ registerEntity(definition) {
13
+ // Validate key schema
14
+ if (!definition.keySchema.fields || definition.keySchema.fields.length === 0) {
15
+ throw new Error(`Entity "${definition.id}" must have at least one key field in keySchema.fields`);
16
+ }
17
+ if (this.entities.has(definition.id)) {
18
+ console.warn(`Entity "${definition.id}" is already registered. Overwriting.`);
19
+ }
20
+ this.entities.set(definition.id, definition);
21
+ }
22
+ /**
23
+ * Unregister an entity definition
24
+ */
25
+ unregisterEntity(id) {
26
+ this.entities.delete(id);
27
+ }
28
+ /**
29
+ * Get entity definition by ID
30
+ */
31
+ getEntity(id) {
32
+ return this.entities.get(id);
33
+ }
34
+ /**
35
+ * Get all registered entities
36
+ */
37
+ getAllEntities() {
38
+ return Array.from(this.entities.values());
39
+ }
40
+ /**
41
+ * Check if entity exists
42
+ */
43
+ hasEntity(id) {
44
+ return this.entities.has(id);
45
+ }
46
+ }