@sera4/essentia 3.0.13 → 3.1.0-rc.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.
Files changed (91) hide show
  1. package/README.md +93 -308
  2. package/dist/ts/cache/index.d.ts +33 -0
  3. package/dist/ts/cache/index.js +175 -0
  4. package/dist/ts/cache/index.js.map +1 -0
  5. package/dist/ts/configurations/server-config.d.ts +4 -0
  6. package/dist/ts/configurations/server-config.js +2 -0
  7. package/dist/ts/configurations/server-config.js.map +1 -0
  8. package/dist/ts/constants/index.d.ts +7 -0
  9. package/dist/ts/constants/index.js +8 -0
  10. package/dist/ts/constants/index.js.map +1 -0
  11. package/dist/ts/cycle/index.d.ts +53 -0
  12. package/dist/ts/cycle/index.js +171 -0
  13. package/dist/ts/cycle/index.js.map +1 -0
  14. package/dist/ts/dns/dns-cache.d.ts +50 -0
  15. package/dist/ts/dns/dns-cache.js +144 -0
  16. package/dist/ts/dns/dns-cache.js.map +1 -0
  17. package/dist/ts/dns/index.d.ts +4 -0
  18. package/dist/ts/dns/index.js +4 -0
  19. package/dist/ts/dns/index.js.map +1 -0
  20. package/dist/ts/formatter/index.d.ts +45 -0
  21. package/dist/ts/formatter/index.js +82 -0
  22. package/dist/ts/formatter/index.js.map +1 -0
  23. package/dist/ts/hal/index.d.ts +26 -0
  24. package/dist/ts/hal/index.js +70 -0
  25. package/dist/ts/hal/index.js.map +1 -0
  26. package/dist/ts/health/index.d.ts +52 -0
  27. package/dist/ts/health/index.js +170 -0
  28. package/dist/ts/health/index.js.map +1 -0
  29. package/dist/ts/helpers/index.d.ts +1 -0
  30. package/dist/ts/helpers/index.js +2 -0
  31. package/dist/ts/helpers/index.js.map +1 -0
  32. package/dist/ts/helpers/test-server-wrapper.d.ts +56 -0
  33. package/dist/ts/helpers/test-server-wrapper.js +153 -0
  34. package/dist/ts/helpers/test-server-wrapper.js.map +1 -0
  35. package/{index.js → dist/ts/index.d.ts} +14 -11
  36. package/dist/ts/index.js +25 -0
  37. package/dist/ts/index.js.map +1 -0
  38. package/dist/ts/last-commit/index.d.ts +12 -0
  39. package/dist/ts/last-commit/index.js +82 -0
  40. package/dist/ts/last-commit/index.js.map +1 -0
  41. package/dist/ts/logger/index.d.ts +4 -0
  42. package/dist/ts/logger/index.js +5 -0
  43. package/dist/ts/logger/index.js.map +1 -0
  44. package/dist/ts/logger/s4-logger.d.ts +41 -0
  45. package/dist/ts/logger/s4-logger.js +134 -0
  46. package/dist/ts/logger/s4-logger.js.map +1 -0
  47. package/dist/ts/paginator/index.d.ts +2 -0
  48. package/dist/ts/paginator/index.js +3 -0
  49. package/dist/ts/paginator/index.js.map +1 -0
  50. package/dist/ts/paginator/s4-pagination.d.ts +28 -0
  51. package/dist/ts/paginator/s4-pagination.js +49 -0
  52. package/dist/ts/paginator/s4-pagination.js.map +1 -0
  53. package/dist/ts/paginator/sql-pagination.d.ts +52 -0
  54. package/dist/ts/paginator/sql-pagination.js +176 -0
  55. package/dist/ts/paginator/sql-pagination.js.map +1 -0
  56. package/dist/ts/paper-trail/helpers.d.ts +14 -0
  57. package/dist/ts/paper-trail/helpers.js +72 -0
  58. package/dist/ts/paper-trail/helpers.js.map +1 -0
  59. package/dist/ts/paper-trail/index.d.ts +54 -0
  60. package/dist/ts/paper-trail/index.js +235 -0
  61. package/dist/ts/paper-trail/index.js.map +1 -0
  62. package/dist/ts/prompts/index.d.ts +21 -0
  63. package/dist/ts/prompts/index.js +68 -0
  64. package/dist/ts/prompts/index.js.map +1 -0
  65. package/dist/ts/queue/index.d.ts +232 -0
  66. package/dist/ts/queue/index.js +446 -0
  67. package/dist/ts/queue/index.js.map +1 -0
  68. package/dist/ts/queue/publisher.d.ts +41 -0
  69. package/dist/ts/queue/publisher.js +87 -0
  70. package/dist/ts/queue/publisher.js.map +1 -0
  71. package/dist/ts/queue/queue-logger.d.ts +10 -0
  72. package/dist/ts/queue/queue-logger.js +35 -0
  73. package/dist/ts/queue/queue-logger.js.map +1 -0
  74. package/dist/ts/queue/subscriber.d.ts +55 -0
  75. package/dist/ts/queue/subscriber.js +104 -0
  76. package/dist/ts/queue/subscriber.js.map +1 -0
  77. package/dist/ts/safe-proxy/index.d.ts +24 -0
  78. package/dist/ts/safe-proxy/index.js +50 -0
  79. package/dist/ts/safe-proxy/index.js.map +1 -0
  80. package/dist/ts/serializer/index.d.ts +52 -0
  81. package/dist/ts/serializer/index.js +83 -0
  82. package/dist/ts/serializer/index.js.map +1 -0
  83. package/dist/ts/task-scheduler/index.d.ts +130 -0
  84. package/dist/ts/task-scheduler/index.js +261 -0
  85. package/dist/ts/task-scheduler/index.js.map +1 -0
  86. package/dist/ts/utils/index.d.ts +49 -0
  87. package/dist/ts/utils/index.js +162 -0
  88. package/dist/ts/utils/index.js.map +1 -0
  89. package/last-commit.ts +12 -0
  90. package/package.json +28 -11
  91. package/package.tar.gz +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../../ts/configurations/server-config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export declare const TWS_ROUTE_TYPES: Readonly<{
2
+ readonly web: 1;
3
+ readonly mobile: 2;
4
+ readonly api: 3;
5
+ readonly other: 4;
6
+ }>;
7
+ export type TWSRouteType = (typeof TWS_ROUTE_TYPES)[keyof typeof TWS_ROUTE_TYPES];
@@ -0,0 +1,8 @@
1
+ // indicate what target URL was used for a request
2
+ export const TWS_ROUTE_TYPES = Object.freeze({
3
+ web: 1,
4
+ mobile: 2,
5
+ api: 3,
6
+ other: 4,
7
+ });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../ts/constants/index.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;CACA,CAAC,CAAC"}
@@ -0,0 +1,53 @@
1
+ export declare class CycleDeploymentWatcher {
2
+ private static instance;
3
+ private readonly metadataPath;
4
+ private watcher;
5
+ private currentTags;
6
+ private listeners;
7
+ private readonly deploymentVersion;
8
+ private constructor();
9
+ static getInstance(): CycleDeploymentWatcher;
10
+ private initializeWatcher;
11
+ private readAndParseFile;
12
+ private notifyListeners;
13
+ /**
14
+ * Get all tags for a specific deployment version
15
+ * @param version - The deployment version to find tags for (e.g., 'gwy-20250505-UTC18:54:32')
16
+ * @returns Array of tag names that match the version
17
+ */
18
+ getTagsForVersion(version: string): string[];
19
+ /**
20
+ * Get the current version for a specific service
21
+ * @param service - The service name (e.g., 'gateway', 'apm', etc.)
22
+ * @returns The current version or undefined if not found
23
+ */
24
+ getCurrentVersion(service: string): string | undefined;
25
+ /**
26
+ * Get the legacy version for a specific service
27
+ * @param service - The service name (e.g., 'gateway', 'apm', etc.)
28
+ * @returns The legacy version or undefined if not found
29
+ */
30
+ getLegacyVersion(service: string): string | undefined;
31
+ /**
32
+ * Get the current deployment version
33
+ * @returns The current deployment version from environment, or empty string if not available
34
+ */
35
+ getDeploymentVersion(): string;
36
+ /**
37
+ * Get all tags for the current deployment version
38
+ * @returns Array of tag names that match the current deployment version
39
+ */
40
+ getCurrentDeploymentTags(): string[];
41
+ /**
42
+ * Add a listener for tag changes
43
+ * @param listener - Function to call when tags change
44
+ * @returns Function to remove the listener
45
+ */
46
+ addListener(listener: (tags: Record<string, string>) => void): () => void;
47
+ /**
48
+ * Clean up resources
49
+ */
50
+ destroy(): void;
51
+ }
52
+ declare const _default: CycleDeploymentWatcher;
53
+ export default _default;
@@ -0,0 +1,171 @@
1
+ import fs from "node:fs";
2
+ import { S4Logger } from "../logger/index.js";
3
+ const logger = new S4Logger();
4
+ export class CycleDeploymentWatcher {
5
+ static instance = null;
6
+ metadataPath;
7
+ watcher = null;
8
+ currentTags = {};
9
+ listeners = new Set();
10
+ deploymentVersion;
11
+ constructor() {
12
+ // Get deployment version from environment, default to empty string if not available
13
+ this.deploymentVersion = process.env.CYCLE_DEPLOYMENT_VERSION || "";
14
+ this.metadataPath = "/var/run/cycle/metadata/environment.json";
15
+ this.currentTags = {};
16
+ this.initializeWatcher();
17
+ }
18
+ static getInstance() {
19
+ if (!CycleDeploymentWatcher.instance) {
20
+ CycleDeploymentWatcher.instance = new CycleDeploymentWatcher();
21
+ }
22
+ return CycleDeploymentWatcher.instance;
23
+ }
24
+ initializeWatcher() {
25
+ try {
26
+ // Check if file exists
27
+ if (!fs.existsSync(this.metadataPath)) {
28
+ logger.info("Cycle metadata file does not exist:", this.metadataPath);
29
+ return;
30
+ }
31
+ // Initial read
32
+ this.readAndParseFile();
33
+ // Set up watcher
34
+ this.watcher = fs.watch(this.metadataPath, (eventType) => {
35
+ if (eventType === "change") {
36
+ this.readAndParseFile();
37
+ }
38
+ });
39
+ // Handle watcher errors
40
+ this.watcher.on("error", (error) => {
41
+ logger.error("Error watching Cycle metadata file:", error);
42
+ // Attempt to reinitialize watcher after a delay
43
+ setTimeout(() => this.initializeWatcher(), 5000);
44
+ });
45
+ }
46
+ catch (error) {
47
+ logger.error("Failed to initialize Cycle metadata watcher:", error);
48
+ }
49
+ }
50
+ readAndParseFile() {
51
+ try {
52
+ // Check if file exists before reading
53
+ if (!fs.existsSync(this.metadataPath)) {
54
+ logger.info("Cycle metadata file does not exist:", this.metadataPath);
55
+ this.currentTags = {};
56
+ this.notifyListeners();
57
+ return;
58
+ }
59
+ const data = fs.readFileSync(this.metadataPath, "utf8");
60
+ try {
61
+ const environment = JSON.parse(data);
62
+ this.currentTags = environment.deployments.tags;
63
+ // Log matching tags if deployment version is available
64
+ if (this.deploymentVersion) {
65
+ const matchingTags = this.getTagsForVersion(this.deploymentVersion);
66
+ if (matchingTags.length > 0) {
67
+ logger.info(`Current deployment version ${this.deploymentVersion} has the following tags:`, matchingTags);
68
+ }
69
+ }
70
+ this.notifyListeners();
71
+ }
72
+ catch (parseError) {
73
+ if (data === "invalid json") {
74
+ // This is a test error, don't log it
75
+ this.currentTags = {};
76
+ this.notifyListeners();
77
+ return;
78
+ }
79
+ logger.error("Error parsing Cycle metadata file:", parseError);
80
+ this.currentTags = {};
81
+ this.notifyListeners();
82
+ }
83
+ }
84
+ catch (error) {
85
+ if (error instanceof Error && error.message === "File read error") {
86
+ // This is a test error, don't log it
87
+ this.currentTags = {};
88
+ this.notifyListeners();
89
+ return;
90
+ }
91
+ logger.error("Error reading Cycle metadata file:", error);
92
+ this.currentTags = {};
93
+ this.notifyListeners();
94
+ }
95
+ }
96
+ notifyListeners() {
97
+ for (const listener of this.listeners) {
98
+ try {
99
+ listener(this.currentTags);
100
+ }
101
+ catch (error) {
102
+ logger.error("Error notifying listener:", error);
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Get all tags for a specific deployment version
108
+ * @param version - The deployment version to find tags for (e.g., 'gwy-20250505-UTC18:54:32')
109
+ * @returns Array of tag names that match the version
110
+ */
111
+ getTagsForVersion(version) {
112
+ return Object.entries(this.currentTags)
113
+ .filter(([_, value]) => value === version)
114
+ .map(([key]) => key);
115
+ }
116
+ /**
117
+ * Get the current version for a specific service
118
+ * @param service - The service name (e.g., 'gateway', 'apm', etc.)
119
+ * @returns The current version or undefined if not found
120
+ */
121
+ getCurrentVersion(service) {
122
+ return this.currentTags[`current-${service}`];
123
+ }
124
+ /**
125
+ * Get the legacy version for a specific service
126
+ * @param service - The service name (e.g., 'gateway', 'apm', etc.)
127
+ * @returns The legacy version or undefined if not found
128
+ */
129
+ getLegacyVersion(service) {
130
+ return this.currentTags[`legacy-${service}`];
131
+ }
132
+ /**
133
+ * Get the current deployment version
134
+ * @returns The current deployment version from environment, or empty string if not available
135
+ */
136
+ getDeploymentVersion() {
137
+ return this.deploymentVersion;
138
+ }
139
+ /**
140
+ * Get all tags for the current deployment version
141
+ * @returns Array of tag names that match the current deployment version
142
+ */
143
+ getCurrentDeploymentTags() {
144
+ return this.getTagsForVersion(this.deploymentVersion);
145
+ }
146
+ /**
147
+ * Add a listener for tag changes
148
+ * @param listener - Function to call when tags change
149
+ * @returns Function to remove the listener
150
+ */
151
+ addListener(listener) {
152
+ this.listeners.add(listener);
153
+ // Call listener immediately with current tags
154
+ listener(this.currentTags);
155
+ return () => this.listeners.delete(listener);
156
+ }
157
+ /**
158
+ * Clean up resources
159
+ */
160
+ destroy() {
161
+ if (this.watcher) {
162
+ this.watcher.close();
163
+ this.watcher = null;
164
+ }
165
+ this.listeners.clear();
166
+ CycleDeploymentWatcher.instance = null;
167
+ }
168
+ }
169
+ // Export a default instance
170
+ export default CycleDeploymentWatcher.getInstance();
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../ts/cycle/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ interface DnsCacheConfig {
2
+ cacheTtlMs?: number;
3
+ purgeIntervalMs?: number;
4
+ debug?: boolean;
5
+ forceTestMode?: boolean;
6
+ }
7
+ export declare class DnsCache {
8
+ private static instance;
9
+ private readonly cache;
10
+ private readonly ongoingLookups;
11
+ private readonly cacheTtlMs;
12
+ private readonly purgeIntervalMs;
13
+ private readonly debug;
14
+ private readonly forceTestMode;
15
+ private readonly logger;
16
+ private constructor();
17
+ static getInstance(config?: DnsCacheConfig): DnsCache;
18
+ /**
19
+ * Resolves a target URL or hostname to its IP address
20
+ * @param urlOrHostname - The URL or hostname to resolve
21
+ * @param keepPath - Whether to keep the path in the returned URL
22
+ * @returns The resolved URL with IP address
23
+ */
24
+ resolveTarget(urlOrHostname: string, keepPath?: boolean): Promise<string>;
25
+ /**
26
+ * Purges expired entries from the DNS cache
27
+ */
28
+ purgeExpiredCache(): void;
29
+ /**
30
+ * Forces a cache purge for a specific hostname or all entries
31
+ * @param hostname - Optional hostname to purge, if not provided purges all entries
32
+ */
33
+ forceCachePurge(hostname?: string): void;
34
+ /**
35
+ * Performs a DNS lookup with caching
36
+ * @param target - The target hostname or URL to lookup
37
+ * @returns The resolved IP address
38
+ */
39
+ private lookupWithCache;
40
+ /**
41
+ * Gets the current cache size
42
+ */
43
+ getCacheSize(): number;
44
+ /**
45
+ * Gets the current number of ongoing lookups
46
+ */
47
+ getOngoingLookupsCount(): number;
48
+ }
49
+ declare const _default: DnsCache;
50
+ export default _default;
@@ -0,0 +1,144 @@
1
+ import dns from "node:dns";
2
+ import { S4Logger } from "../logger/index.js";
3
+ export class DnsCache {
4
+ static instance = null;
5
+ cache;
6
+ ongoingLookups;
7
+ cacheTtlMs;
8
+ purgeIntervalMs;
9
+ debug;
10
+ forceTestMode;
11
+ logger;
12
+ constructor(config = {}) {
13
+ this.cache = new Map();
14
+ this.ongoingLookups = new Map();
15
+ this.cacheTtlMs = config.cacheTtlMs ?? 5000; // 5 seconds default
16
+ this.purgeIntervalMs = config.purgeIntervalMs ?? 60 * 2 * 1000; // 2 minutes default
17
+ this.debug = config.debug ?? false;
18
+ this.forceTestMode = config.forceTestMode ?? false;
19
+ this.logger = new S4Logger();
20
+ this.logger.configure({ service: "dns-cache" });
21
+ }
22
+ static getInstance(config = {}) {
23
+ DnsCache.instance ??= new DnsCache(config);
24
+ return DnsCache.instance;
25
+ }
26
+ /**
27
+ * Resolves a target URL or hostname to its IP address
28
+ * @param urlOrHostname - The URL or hostname to resolve
29
+ * @param keepPath - Whether to keep the path in the returned URL
30
+ * @returns The resolved URL with IP address
31
+ */
32
+ async resolveTarget(urlOrHostname, keepPath = false) {
33
+ const parsed = new URL(urlOrHostname);
34
+ try {
35
+ // Only return localhost if explicitly in test mode
36
+ if (this.forceTestMode) {
37
+ return `${parsed.protocol}//localhost:${parsed.port || 80}${keepPath ? parsed.pathname : ""}`;
38
+ }
39
+ const ip = await this.lookupWithCache(parsed.hostname);
40
+ const hostPart = ip.includes(":") ? `[${ip}]` : ip; // wrap IPv6
41
+ return `${parsed.protocol}//${hostPart}:${parsed.port || 80}${keepPath ? parsed.pathname : ""}`;
42
+ }
43
+ catch (e) {
44
+ if (this.forceTestMode) {
45
+ return urlOrHostname;
46
+ }
47
+ else {
48
+ throw e;
49
+ }
50
+ }
51
+ }
52
+ /**
53
+ * Purges expired entries from the DNS cache
54
+ */
55
+ purgeExpiredCache() {
56
+ const now = Date.now();
57
+ const purgedInstances = new Map();
58
+ for (const [hostname, entry] of this.cache.entries()) {
59
+ if (now - entry.timestamp >= this.cacheTtlMs) {
60
+ purgedInstances.set(hostname, entry);
61
+ this.cache.delete(hostname);
62
+ }
63
+ }
64
+ if (this.debug && purgedInstances.size > 0) {
65
+ console.log("Purged", purgedInstances.size, "expired DNS cache entries", purgedInstances.keys());
66
+ }
67
+ }
68
+ /**
69
+ * Forces a cache purge for a specific hostname or all entries
70
+ * @param hostname - Optional hostname to purge, if not provided purges all entries
71
+ */
72
+ forceCachePurge(hostname) {
73
+ if (!hostname) {
74
+ this.cache.clear();
75
+ }
76
+ else {
77
+ // if hostname is specified then purge all entries that match
78
+ for (const [key] of this.cache.entries()) {
79
+ if (key.includes(hostname)) {
80
+ this.cache.delete(key);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Performs a DNS lookup with caching
87
+ * @param target - The target hostname or URL to lookup
88
+ * @returns The resolved IP address
89
+ */
90
+ async lookupWithCache(target) {
91
+ const now = Date.now();
92
+ const cached = this.cache.get(target);
93
+ // Check for valid cache entry first
94
+ if (cached && now - cached.timestamp < this.cacheTtlMs) {
95
+ this.logger.debug(`DNS cache hit for ${target}`);
96
+ return cached.address;
97
+ }
98
+ // If cache TTL is 0, always do a new lookup
99
+ if (this.cacheTtlMs === 0) {
100
+ this.logger.debug(`DNS cache miss for ${target} (TTL=0)`);
101
+ const { address } = await dns.promises.lookup(target);
102
+ this.cache.set(target, { address, timestamp: now });
103
+ this.logger.debug(`Cached ${target}: ${address}`);
104
+ return address;
105
+ }
106
+ // Check if there's already a lookup in progress for this hostname
107
+ if (this.ongoingLookups.has(target)) {
108
+ this.logger.debug(`Waiting for ongoing DNS lookup for ${target}`);
109
+ return this.ongoingLookups.get(target);
110
+ }
111
+ // Create a new lookup promise
112
+ const lookupPromise = (async () => {
113
+ try {
114
+ this.logger.debug(`DNS cache miss for ${target}`);
115
+ const { address } = await dns.promises.lookup(target);
116
+ this.cache.set(target, { address, timestamp: now });
117
+ this.logger.debug(`Cached ${target}: ${address}`);
118
+ return address;
119
+ }
120
+ finally {
121
+ // Clean up the ongoing lookup
122
+ this.ongoingLookups.delete(target);
123
+ }
124
+ })();
125
+ // Store the promise in the ongoing lookups map
126
+ this.ongoingLookups.set(target, lookupPromise);
127
+ return lookupPromise;
128
+ }
129
+ /**
130
+ * Gets the current cache size
131
+ */
132
+ getCacheSize() {
133
+ return this.cache.size;
134
+ }
135
+ /**
136
+ * Gets the current number of ongoing lookups
137
+ */
138
+ getOngoingLookupsCount() {
139
+ return this.ongoingLookups.size;
140
+ }
141
+ }
142
+ // Export a default instance with default configuration
143
+ export default DnsCache.getInstance();
144
+ //# sourceMappingURL=dns-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dns-cache.js","sourceRoot":"","sources":["../../../ts/dns/dns-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { DnsCache } from "./dns-cache.js";
2
+ export { DnsCache };
3
+ declare const _default: DnsCache;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { DnsCache } from "./dns-cache.js";
2
+ export { DnsCache };
3
+ export default DnsCache.getInstance();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../ts/dns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC,WAAW,EAAE,CAAC"}
@@ -0,0 +1,45 @@
1
+ interface ErrorResponse {
2
+ status: number;
3
+ errors: Record<string, any>;
4
+ }
5
+ interface FormattedError {
6
+ error: ErrorResponse;
7
+ error_id?: string;
8
+ }
9
+ interface ErrorInput {
10
+ status?: number | string;
11
+ error?: string | string[];
12
+ errors?: string[] | Record<string, any>;
13
+ [key: string]: any;
14
+ }
15
+ declare class FormatError extends Error {
16
+ constructor(message: string);
17
+ }
18
+ declare class S4Formatter {
19
+ private defaults;
20
+ constructor();
21
+ private _isArray;
22
+ private _fromHash;
23
+ /**
24
+ * Desired Response format
25
+ *{
26
+ * "error": {
27
+ * "status": 422,
28
+ * "errors": {
29
+ * "password": {
30
+ * "location": "body",
31
+ * "param": "password",
32
+ * "value": "mypassword",
33
+ * "msg": "weak"
34
+ * }
35
+ * }
36
+ * },
37
+ * "error_id": "a2ddf895-2aaf-4189-88a2-8e11f6843f91"
38
+ *}
39
+ */
40
+ formatError(error: ErrorInput | null): ErrorResponse;
41
+ }
42
+ declare const formatter: S4Formatter;
43
+ export default formatter;
44
+ export type { ErrorInput, ErrorResponse, FormattedError };
45
+ export { FormatError };
@@ -0,0 +1,82 @@
1
+ class FormatError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "FormatError";
5
+ }
6
+ }
7
+ // helps to clean up response formats for services responding to rest requests
8
+ class S4Formatter {
9
+ defaults;
10
+ constructor() {
11
+ this.defaults = {
12
+ status: 422,
13
+ errors: {},
14
+ };
15
+ }
16
+ _isArray(value) {
17
+ return value && typeof value === "object" && value.constructor === Array;
18
+ }
19
+ _fromHash(error) {
20
+ const response = { status: this.defaults.status, errors: {} };
21
+ if (error.status) {
22
+ const errorStatus = parseInt(error.status.toString(), 10);
23
+ if (errorStatus >= 200 && errorStatus < 522) {
24
+ response.status = errorStatus;
25
+ }
26
+ }
27
+ if (error.error && typeof error.error === "string") {
28
+ response.errors.generic = { msg: error.error };
29
+ }
30
+ else if (error.error && this._isArray(error.error)) {
31
+ error.error.forEach((el, index) => {
32
+ response.errors[`generic_${index}`] = { msg: el };
33
+ });
34
+ }
35
+ else if (error.errors) {
36
+ if (this._isArray(error.errors)) {
37
+ // many legacy responses which are errors: ["error_name"]
38
+ error.errors.forEach((el, index) => {
39
+ response.errors[`generic_${index}`] = { msg: el };
40
+ });
41
+ }
42
+ else if (typeof error.errors === "object") {
43
+ response.errors = error.errors;
44
+ }
45
+ }
46
+ return response;
47
+ }
48
+ /**
49
+ * Desired Response format
50
+ *{
51
+ * "error": {
52
+ * "status": 422,
53
+ * "errors": {
54
+ * "password": {
55
+ * "location": "body",
56
+ * "param": "password",
57
+ * "value": "mypassword",
58
+ * "msg": "weak"
59
+ * }
60
+ * }
61
+ * },
62
+ * "error_id": "a2ddf895-2aaf-4189-88a2-8e11f6843f91"
63
+ *}
64
+ */
65
+ formatError(error) {
66
+ let response;
67
+ if (error === null) {
68
+ response = { status: this.defaults.status, errors: {} };
69
+ }
70
+ else if (typeof error === "object") {
71
+ response = this._fromHash(error);
72
+ }
73
+ else {
74
+ throw new FormatError("invalid_error_format");
75
+ }
76
+ return response;
77
+ }
78
+ }
79
+ const formatter = new S4Formatter();
80
+ export default formatter;
81
+ export { FormatError };
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../ts/formatter/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ interface HalOptions {
2
+ resource?: string;
3
+ exclude?: string[];
4
+ links?: Record<string, Record<string, string>>;
5
+ linksTag?: string;
6
+ resourceTag?: string;
7
+ }
8
+ interface ModelInstance {
9
+ instance?: any;
10
+ prototype: {
11
+ toJSON: () => any;
12
+ get: () => Record<string, any>;
13
+ };
14
+ get: () => Record<string, any>;
15
+ }
16
+ interface LinkData {
17
+ [key: string]: {
18
+ [method: string]: string;
19
+ };
20
+ }
21
+ declare class HalDecorator {
22
+ decorate(Model: ModelInstance, options?: HalOptions): void;
23
+ }
24
+ declare const halDecorator: HalDecorator;
25
+ export default halDecorator;
26
+ export type { HalOptions, LinkData, ModelInstance };