node-server-engine 1.12.4 → 1.14.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.
|
@@ -10,6 +10,43 @@ var _EngineError = require("../EngineError");
|
|
|
10
10
|
var _LifecycleController = require("../LifecycleController");
|
|
11
11
|
var _utils = require("../../utils");
|
|
12
12
|
const namespace = 'engine:PubSub';
|
|
13
|
+
const RETRYABLE_ERROR_CODES = new Set([4, 8, 10, 13, 14]); // DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED, ABORTED, INTERNAL, UNAVAILABLE
|
|
14
|
+
const resolvedProjectId = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT || process.env.GCP_PROJECT_ID;
|
|
15
|
+
function isRetryableInitError(error) {
|
|
16
|
+
const err = error;
|
|
17
|
+
const message = (err?.message ?? '').toLowerCase();
|
|
18
|
+
const code = typeof err?.code === 'string' ? Number.parseInt(err.code, 10) : err?.code;
|
|
19
|
+
return typeof code === 'number' && RETRYABLE_ERROR_CODES.has(code) || message.includes('deadline exceeded') || message.includes('timed out') || message.includes('timeout') || message.includes('unavailable') || message.includes('resource exhausted');
|
|
20
|
+
}
|
|
21
|
+
async function withRetry(operationName, fn) {
|
|
22
|
+
const maxAttempts = Math.max(1, Number.parseInt(process.env.PUBSUB_INIT_MAX_ATTEMPTS ?? '4', 10));
|
|
23
|
+
const baseDelayMs = Math.max(100, Number.parseInt(process.env.PUBSUB_INIT_RETRY_BASE_DELAY_MS ?? '1000', 10));
|
|
24
|
+
const maxDelayMs = Math.max(baseDelayMs, Number.parseInt(process.env.PUBSUB_INIT_RETRY_MAX_DELAY_MS ?? '10000', 10));
|
|
25
|
+
let lastError;
|
|
26
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
27
|
+
try {
|
|
28
|
+
return await fn();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
lastError = error;
|
|
31
|
+
if (!isRetryableInitError(error) || attempt === maxAttempts) {
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
const delayMs = Math.min(baseDelayMs * 2 ** (attempt - 1), maxDelayMs);
|
|
35
|
+
(0, _utils.reportError)({
|
|
36
|
+
namespace,
|
|
37
|
+
message: `Retrying Pub/Sub init operation '${operationName}'`,
|
|
38
|
+
error: {
|
|
39
|
+
attempt,
|
|
40
|
+
maxAttempts,
|
|
41
|
+
delayMs,
|
|
42
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw lastError instanceof Error ? lastError : new Error(`Pub/Sub init operation '${operationName}' failed after retries`);
|
|
49
|
+
}
|
|
13
50
|
|
|
14
51
|
/**
|
|
15
52
|
* Associative containing all the subscriptions sorted by topic registered for publishing
|
|
@@ -20,7 +57,9 @@ const subscriptions = {};
|
|
|
20
57
|
* Associative containing all the topics registered for publishing
|
|
21
58
|
*/
|
|
22
59
|
const topics = {};
|
|
23
|
-
const pubSubClient = new _pubsub.PubSub(
|
|
60
|
+
const pubSubClient = new _pubsub.PubSub(resolvedProjectId ? {
|
|
61
|
+
projectId: resolvedProjectId
|
|
62
|
+
} : undefined);
|
|
24
63
|
|
|
25
64
|
/**
|
|
26
65
|
* This is a singleton service who's role is to manage pub/sub connections
|
|
@@ -36,28 +75,42 @@ const PubSub = exports.PubSub = {
|
|
|
36
75
|
namespace,
|
|
37
76
|
message: `Initializing Pub/Sub`
|
|
38
77
|
});
|
|
78
|
+
if (!resolvedProjectId) {
|
|
79
|
+
(0, _utils.reportDebug)({
|
|
80
|
+
namespace,
|
|
81
|
+
message: 'Pub/Sub projectId not set in env, relying on ADC auto-detection'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const skipValidation = process.env.PUBSUB_SKIP_VALIDATION?.toLowerCase() === 'true';
|
|
39
85
|
// Check that all topics/permissions exist, and that we have permission on them
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
86
|
+
if (!skipValidation) {
|
|
87
|
+
await Promise.all([
|
|
88
|
+
// Test that all topics actually exist and that we have permissions
|
|
89
|
+
...Object.values(topics).map(async topic => {
|
|
90
|
+
const [exists] = await withRetry(`topic.exists:${topic.name}`, async () => topic.exists());
|
|
91
|
+
if (!exists) throw new _EngineError.EngineError(`Topic ${topic.name} does not exist`);
|
|
92
|
+
// Test permission ton publish to topic
|
|
93
|
+
const [permissions] = await withRetry(`topic.permissions:${topic.name}`, async () => topic.iam.testPermissions(['pubsub.topics.publish']));
|
|
94
|
+
const hasPermissions = Object.values(permissions).every(success => success);
|
|
95
|
+
if (!hasPermissions) throw new _EngineError.EngineError(`Instance does not have appropriate permissions to publish to topic ${topic.name}`);
|
|
96
|
+
}),
|
|
97
|
+
// Test that all subscriptions actually exist and that we have permissions
|
|
98
|
+
...Object.values(subscriptions).map(async ({
|
|
99
|
+
subscription
|
|
100
|
+
}) => {
|
|
101
|
+
const [exists] = await withRetry(`subscription.exists:${subscription.name}`, async () => subscription.exists());
|
|
102
|
+
if (!exists) throw new _EngineError.EngineError(`Subscription ${subscription.name} does not exist`);
|
|
103
|
+
// Test permission ton consume subscription
|
|
104
|
+
const [permissions] = await withRetry(`subscription.permissions:${subscription.name}`, async () => subscription.iam.testPermissions(['pubsub.subscriptions.consume']));
|
|
105
|
+
const hasPermissions = Object.values(permissions).every(success => success);
|
|
106
|
+
if (!hasPermissions) throw new _EngineError.EngineError(`Instance does not have appropriate permissions to subscribe to subscription ${subscription.name}`);
|
|
107
|
+
})]);
|
|
108
|
+
} else {
|
|
109
|
+
(0, _utils.reportDebug)({
|
|
110
|
+
namespace,
|
|
111
|
+
message: 'Skipping Pub/Sub existence and permission validation (PUBSUB_SKIP_VALIDATION=true)'
|
|
112
|
+
});
|
|
113
|
+
}
|
|
61
114
|
|
|
62
115
|
// Register handlers on the subscriptions to activate them
|
|
63
116
|
for (const {
|
|
@@ -70,6 +123,13 @@ const PubSub = exports.PubSub = {
|
|
|
70
123
|
(0, _utils.reportError)(error);
|
|
71
124
|
});
|
|
72
125
|
});
|
|
126
|
+
subscription.on('error', error => {
|
|
127
|
+
(0, _utils.reportError)({
|
|
128
|
+
namespace,
|
|
129
|
+
message: `Pub/Sub subscription stream error on '${subscription.name}'`,
|
|
130
|
+
error
|
|
131
|
+
});
|
|
132
|
+
});
|
|
73
133
|
}
|
|
74
134
|
_LifecycleController.LifecycleController.register(PubSub);
|
|
75
135
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PubSub.js","names":["_pubsub","require","_handleMessage","_EngineError","_LifecycleController","_utils","namespace","subscriptions","topics","pubSubClient","PubsubClient","PubSub","exports","init","reportDebug","message","Promise","all","Object","values","map","topic","exists","EngineError","name","permissions","iam","testPermissions","hasPermissions","every","success","subscription","handlers","isDebezium","on","handleMessage","catch","error","reportError","LifecycleController","register","shutdown","flush","close","keys","forEach","addPublisher","options","topicArray","Array","join","data","includes","enableOpenTelemetryTracing","messageOrdering","enableMessageOrdering","batching","maxMessages","maxBytes","maxMilliseconds","undefined","gaxOpts","retry","retryCodes","backoffSettings","initialRetryDelayMillis","initialDelayMillis","maxRetryDelayMillis","maxDelayMillis","retryDelayMultiplier","delayMultiplier","initialRpcTimeoutMillis","maxRpcTimeoutMillis","rpcTimeoutMultiplier","totalTimeoutMillis","addSubscriber","handler","first","flowControl","ackDeadline","handlersCount","length","allowExcessMessages","push","unshift","publish","attributes","orderingKey","publishMessage","json"],"sources":["../../../src/entities/PubSub/PubSub.ts"],"sourcesContent":["import {\n Attributes,\n PubSub as PubsubClient,\n Message\n} from '@google-cloud/pubsub';\nimport { handleMessage } from './handleMessage';\nimport {\n PubSubTopicsMap,\n PubSubSubscriptionsMap,\n PubSubAddSubscriberOptions,\n PubSubMessageHandler,\n PubSubPublisherOptions\n} from './PubSub.types';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { reportDebug, reportError } from 'utils';\n\nconst namespace = 'engine:PubSub';\n\n/**\n * Associative containing all the subscriptions sorted by topic registered for publishing\n */\nconst subscriptions: PubSubSubscriptionsMap = {};\n\n/**\n * Associative containing all the topics registered for publishing\n */\nconst topics: PubSubTopicsMap = {};\n\nconst pubSubClient = new PubsubClient();\n\n/**\n * This is a singleton service who's role is to manage pub/sub connections\n * It is the preferred way to interact with Pub/Sub as it manages the underlying subscription and handler objects\n * It avoids potential subscription splitting on an instance\n */\nexport const PubSub = {\n /**\n * Initialize the registered publishers and subscribers\n */\n async init(): Promise<void> {\n reportDebug({ namespace, message: `Initializing Pub/Sub` });\n // Check that all topics/permissions exist, and that we have permission on them\n await Promise.all([\n // Test that all topics actually exist and that we have permissions\n ...Object.values(topics).map(async (topic) => {\n const [exists] = await topic.exists();\n if (!exists)\n throw new EngineError(`Topic ${topic.name} does not exist`);\n // Test permission ton publish to topic\n const [permissions] = await topic.iam.testPermissions([\n 'pubsub.topics.publish'\n ]);\n const hasPermissions = Object.values(permissions).every(\n (success) => success\n );\n if (!hasPermissions)\n throw new EngineError(\n `Instance does not have appropriate permissions to publish to topic ${topic.name}`\n );\n }),\n // Test that all subscriptions actually exist and that we have permissions\n ...Object.values(subscriptions).map(async ({ subscription }) => {\n const [exists] = await subscription.exists();\n if (!exists)\n throw new EngineError(\n `Subscription ${subscription.name} does not exist`\n );\n // Test permission ton consume subscription\n const [permissions] = await subscription.iam.testPermissions([\n 'pubsub.subscriptions.consume'\n ]);\n const hasPermissions = Object.values(permissions).every(\n (success) => success\n );\n if (!hasPermissions)\n throw new EngineError(\n `Instance does not have appropriate permissions to subscribe to subscription ${subscription.name}`\n );\n })\n ]);\n\n // Register handlers on the subscriptions to activate them\n for (const { subscription, handlers, isDebezium } of Object.values(\n subscriptions\n )) {\n subscription.on('message', (message) => {\n handleMessage(\n message as Message,\n subscription,\n handlers,\n isDebezium\n ).catch((error) => {\n reportError(error);\n });\n });\n }\n\n LifecycleController.register(PubSub);\n },\n\n /**\n * Shutdown the registered publishers and subscribers\n */\n async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Pub/Sub` });\n // Flush all pending messages and shut down connections\n await Promise.all([\n ...Object.values(topics).map(async (topic) => topic.flush()),\n ...Object.values(subscriptions).map(async ({ subscription }) =>\n subscription.close()\n )\n ]);\n // Delete the stored topics/subscriptions\n Object.keys(topics).forEach((topic) => delete topics[topic]);\n Object.keys(subscriptions).forEach(\n (subscription) => delete subscriptions[subscription]\n );\n // Close the client\n await pubSubClient.close();\n },\n\n /**\n * Creates a publisher if it does not exist yet\n * @param topic - Topic name or array of topic names\n * @param options - Publisher configuration options\n */\n addPublisher(\n topic: string | Array<string>,\n options?: PubSubPublisherOptions\n ): void {\n const topicArray = topic instanceof Array ? topic : [topic];\n reportDebug({\n namespace,\n message: `Registering publisher for topics '${topicArray.join(\"', '\")}'`,\n data: options\n });\n // Register a new topic if it does not exist yet\n for (const topic of topicArray) {\n if (!Object.keys(topics).includes(topic)) {\n topics[topic] = pubSubClient.topic(topic, {\n enableOpenTelemetryTracing: true,\n messageOrdering: options?.enableMessageOrdering ?? false,\n batching: options?.batching\n ? {\n maxMessages: options.batching.maxMessages ?? 100,\n maxBytes: options.batching.maxBytes ?? 1024 * 1024, // 1MB\n maxMilliseconds: options.batching.maxMilliseconds ?? 100\n }\n : undefined,\n gaxOpts: options?.retry\n ? {\n retry: {\n retryCodes: [10, 14], // ABORTED, UNAVAILABLE\n backoffSettings: {\n initialRetryDelayMillis:\n options.retry.initialDelayMillis ?? 100,\n maxRetryDelayMillis: options.retry.maxDelayMillis ?? 60000,\n retryDelayMultiplier: options.retry.delayMultiplier ?? 1.3,\n initialRpcTimeoutMillis: 60000,\n maxRpcTimeoutMillis: 600000,\n rpcTimeoutMultiplier: 1.0,\n totalTimeoutMillis: 600000\n }\n }\n }\n : undefined\n });\n }\n }\n },\n\n /**\n * Add message handlers to a subscription\n * @param subscription - Name of the Pub/Sub subscription\n * @param handler - Function or list of functions to set as message handlers\n * @param options - Indicates that the additional options need to handle on Subscriber\n */\n addSubscriber<T>(\n subscription: string,\n handler: PubSubMessageHandler<T> | Array<PubSubMessageHandler<T>>,\n options: PubSubAddSubscriberOptions = {}\n ): void {\n const handlers = handler instanceof Array ? handler : [handler];\n const isDebezium = options?.isDebezium ?? false;\n const first = options?.first ?? false;\n const flowControl = options?.flowControl;\n const ackDeadline = options?.ackDeadline;\n\n reportDebug({\n namespace,\n message: `Registering subscriber for subscription '${subscription}'`,\n data: {\n first,\n handlersCount: handlers.length,\n isDebezium,\n flowControl\n }\n });\n if (!Object.keys(subscriptions).includes(subscription)) {\n subscriptions[subscription] = {\n subscription: pubSubClient.subscription(subscription, {\n enableOpenTelemetryTracing: true,\n flowControl: flowControl\n ? {\n maxMessages: flowControl.maxMessages ?? 1000,\n maxBytes: flowControl.maxBytes ?? 100 * 1024 * 1024, // 100MB\n allowExcessMessages: flowControl.allowExcessMessages ?? true\n }\n : {\n maxMessages: 1000,\n maxBytes: 100 * 1024 * 1024,\n allowExcessMessages: true\n },\n ackDeadline: ackDeadline ?? 60\n }),\n handlers: []\n };\n }\n\n if (isDebezium) subscriptions[subscription].isDebezium = true;\n\n if (first) subscriptions[subscription].handlers.push(...handlers);\n else subscriptions[subscription].handlers.unshift(...handlers);\n },\n\n /**\n * Send a message to a Pub/Sub topic\n * @param topic - Name of the topic\n * @param message - Content of the message, must be an object that can be JSON stringified\n * @param attributes - Attributes for this message, can be used to filter messages on the subscription\n * @param orderingKey - Enforce order guarantee of messages sent with the same key\n */\n async publish(\n topic: string,\n message: unknown,\n attributes?: Attributes,\n orderingKey?: string\n ): Promise<void> {\n if (!topics[topic])\n throw new EngineError(`No publisher was registered for topic '${topic}'`);\n reportDebug({\n namespace,\n message: `Sending message to topic '${topic}'`,\n data: { message, attributes, orderingKey }\n });\n await topics[topic].publishMessage({\n json: message,\n attributes,\n orderingKey\n });\n }\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"PubSub.js","names":["_pubsub","require","_handleMessage","_EngineError","_LifecycleController","_utils","namespace","RETRYABLE_ERROR_CODES","Set","resolvedProjectId","process","env","GOOGLE_CLOUD_PROJECT","GCLOUD_PROJECT","GCP_PROJECT_ID","isRetryableInitError","error","err","message","toLowerCase","code","Number","parseInt","has","includes","withRetry","operationName","fn","maxAttempts","Math","max","PUBSUB_INIT_MAX_ATTEMPTS","baseDelayMs","PUBSUB_INIT_RETRY_BASE_DELAY_MS","maxDelayMs","PUBSUB_INIT_RETRY_MAX_DELAY_MS","lastError","attempt","delayMs","min","reportError","reason","Error","String","Promise","resolve","setTimeout","subscriptions","topics","pubSubClient","PubsubClient","projectId","undefined","PubSub","exports","init","reportDebug","skipValidation","PUBSUB_SKIP_VALIDATION","all","Object","values","map","topic","exists","name","EngineError","permissions","iam","testPermissions","hasPermissions","every","success","subscription","handlers","isDebezium","on","handleMessage","catch","LifecycleController","register","shutdown","flush","close","keys","forEach","addPublisher","options","topicArray","Array","join","data","enableOpenTelemetryTracing","messageOrdering","enableMessageOrdering","batching","maxMessages","maxBytes","maxMilliseconds","gaxOpts","retry","retryCodes","backoffSettings","initialRetryDelayMillis","initialDelayMillis","maxRetryDelayMillis","maxDelayMillis","retryDelayMultiplier","delayMultiplier","initialRpcTimeoutMillis","maxRpcTimeoutMillis","rpcTimeoutMultiplier","totalTimeoutMillis","addSubscriber","handler","first","flowControl","ackDeadline","handlersCount","length","allowExcessMessages","push","unshift","publish","attributes","orderingKey","publishMessage","json"],"sources":["../../../src/entities/PubSub/PubSub.ts"],"sourcesContent":["import {\n Attributes,\n PubSub as PubsubClient,\n Message\n} from '@google-cloud/pubsub';\nimport { handleMessage } from './handleMessage';\nimport {\n PubSubTopicsMap,\n PubSubSubscriptionsMap,\n PubSubAddSubscriberOptions,\n PubSubMessageHandler,\n PubSubPublisherOptions\n} from './PubSub.types';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { reportDebug, reportError } from 'utils';\n\nconst namespace = 'engine:PubSub';\nconst RETRYABLE_ERROR_CODES = new Set([4, 8, 10, 13, 14]); // DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED, ABORTED, INTERNAL, UNAVAILABLE\nconst resolvedProjectId =\n process.env.GOOGLE_CLOUD_PROJECT ||\n process.env.GCLOUD_PROJECT ||\n process.env.GCP_PROJECT_ID;\n\nfunction isRetryableInitError(error: unknown): boolean {\n const err = error as { code?: number | string; message?: string } | undefined;\n const message = (err?.message ?? '').toLowerCase();\n const code =\n typeof err?.code === 'string' ? Number.parseInt(err.code, 10) : err?.code;\n return (\n (typeof code === 'number' && RETRYABLE_ERROR_CODES.has(code)) ||\n message.includes('deadline exceeded') ||\n message.includes('timed out') ||\n message.includes('timeout') ||\n message.includes('unavailable') ||\n message.includes('resource exhausted')\n );\n}\n\nasync function withRetry<T>(\n operationName: string,\n fn: () => Promise<T>\n): Promise<T> {\n const maxAttempts = Math.max(\n 1,\n Number.parseInt(process.env.PUBSUB_INIT_MAX_ATTEMPTS ?? '4', 10)\n );\n const baseDelayMs = Math.max(\n 100,\n Number.parseInt(process.env.PUBSUB_INIT_RETRY_BASE_DELAY_MS ?? '1000', 10)\n );\n const maxDelayMs = Math.max(\n baseDelayMs,\n Number.parseInt(process.env.PUBSUB_INIT_RETRY_MAX_DELAY_MS ?? '10000', 10)\n );\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (!isRetryableInitError(error) || attempt === maxAttempts) {\n throw error;\n }\n const delayMs = Math.min(baseDelayMs * 2 ** (attempt - 1), maxDelayMs);\n reportError({\n namespace,\n message: `Retrying Pub/Sub init operation '${operationName}'`,\n error: {\n attempt,\n maxAttempts,\n delayMs,\n reason: error instanceof Error ? error.message : String(error)\n }\n });\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n throw lastError instanceof Error\n ? lastError\n : new Error(\n `Pub/Sub init operation '${operationName}' failed after retries`\n );\n}\n\n/**\n * Associative containing all the subscriptions sorted by topic registered for publishing\n */\nconst subscriptions: PubSubSubscriptionsMap = {};\n\n/**\n * Associative containing all the topics registered for publishing\n */\nconst topics: PubSubTopicsMap = {};\n\nconst pubSubClient = new PubsubClient(\n resolvedProjectId ? { projectId: resolvedProjectId } : undefined\n);\n\n/**\n * This is a singleton service who's role is to manage pub/sub connections\n * It is the preferred way to interact with Pub/Sub as it manages the underlying subscription and handler objects\n * It avoids potential subscription splitting on an instance\n */\nexport const PubSub = {\n /**\n * Initialize the registered publishers and subscribers\n */\n async init(): Promise<void> {\n reportDebug({ namespace, message: `Initializing Pub/Sub` });\n if (!resolvedProjectId) {\n reportDebug({\n namespace,\n message:\n 'Pub/Sub projectId not set in env, relying on ADC auto-detection'\n });\n }\n const skipValidation =\n process.env.PUBSUB_SKIP_VALIDATION?.toLowerCase() === 'true';\n // Check that all topics/permissions exist, and that we have permission on them\n if (!skipValidation) {\n await Promise.all([\n // Test that all topics actually exist and that we have permissions\n ...Object.values(topics).map(async (topic) => {\n const [exists] = await withRetry(\n `topic.exists:${topic.name}`,\n async () => topic.exists()\n );\n if (!exists)\n throw new EngineError(`Topic ${topic.name} does not exist`);\n // Test permission ton publish to topic\n const [permissions] = await withRetry(\n `topic.permissions:${topic.name}`,\n async () => topic.iam.testPermissions(['pubsub.topics.publish'])\n );\n const hasPermissions = Object.values(permissions).every(\n (success) => success\n );\n if (!hasPermissions)\n throw new EngineError(\n `Instance does not have appropriate permissions to publish to topic ${topic.name}`\n );\n }),\n // Test that all subscriptions actually exist and that we have permissions\n ...Object.values(subscriptions).map(async ({ subscription }) => {\n const [exists] = await withRetry(\n `subscription.exists:${subscription.name}`,\n async () => subscription.exists()\n );\n if (!exists)\n throw new EngineError(\n `Subscription ${subscription.name} does not exist`\n );\n // Test permission ton consume subscription\n const [permissions] = await withRetry(\n `subscription.permissions:${subscription.name}`,\n async () =>\n subscription.iam.testPermissions(['pubsub.subscriptions.consume'])\n );\n const hasPermissions = Object.values(permissions).every(\n (success) => success\n );\n if (!hasPermissions)\n throw new EngineError(\n `Instance does not have appropriate permissions to subscribe to subscription ${subscription.name}`\n );\n })\n ]);\n } else {\n reportDebug({\n namespace,\n message:\n 'Skipping Pub/Sub existence and permission validation (PUBSUB_SKIP_VALIDATION=true)'\n });\n }\n\n // Register handlers on the subscriptions to activate them\n for (const { subscription, handlers, isDebezium } of Object.values(\n subscriptions\n )) {\n subscription.on('message', (message) => {\n handleMessage(\n message as Message,\n subscription,\n handlers,\n isDebezium\n ).catch((error) => {\n reportError(error);\n });\n });\n subscription.on('error', (error) => {\n reportError({\n namespace,\n message: `Pub/Sub subscription stream error on '${subscription.name}'`,\n error\n });\n });\n }\n\n LifecycleController.register(PubSub);\n },\n\n /**\n * Shutdown the registered publishers and subscribers\n */\n async shutdown(): Promise<void> {\n reportDebug({ namespace, message: `Shutting down Pub/Sub` });\n // Flush all pending messages and shut down connections\n await Promise.all([\n ...Object.values(topics).map(async (topic) => topic.flush()),\n ...Object.values(subscriptions).map(async ({ subscription }) =>\n subscription.close()\n )\n ]);\n // Delete the stored topics/subscriptions\n Object.keys(topics).forEach((topic) => delete topics[topic]);\n Object.keys(subscriptions).forEach(\n (subscription) => delete subscriptions[subscription]\n );\n // Close the client\n await pubSubClient.close();\n },\n\n /**\n * Creates a publisher if it does not exist yet\n * @param topic - Topic name or array of topic names\n * @param options - Publisher configuration options\n */\n addPublisher(\n topic: string | Array<string>,\n options?: PubSubPublisherOptions\n ): void {\n const topicArray = topic instanceof Array ? topic : [topic];\n reportDebug({\n namespace,\n message: `Registering publisher for topics '${topicArray.join(\"', '\")}'`,\n data: options\n });\n // Register a new topic if it does not exist yet\n for (const topic of topicArray) {\n if (!Object.keys(topics).includes(topic)) {\n topics[topic] = pubSubClient.topic(topic, {\n enableOpenTelemetryTracing: true,\n messageOrdering: options?.enableMessageOrdering ?? false,\n batching: options?.batching\n ? {\n maxMessages: options.batching.maxMessages ?? 100,\n maxBytes: options.batching.maxBytes ?? 1024 * 1024, // 1MB\n maxMilliseconds: options.batching.maxMilliseconds ?? 100\n }\n : undefined,\n gaxOpts: options?.retry\n ? {\n retry: {\n retryCodes: [10, 14], // ABORTED, UNAVAILABLE\n backoffSettings: {\n initialRetryDelayMillis:\n options.retry.initialDelayMillis ?? 100,\n maxRetryDelayMillis: options.retry.maxDelayMillis ?? 60000,\n retryDelayMultiplier: options.retry.delayMultiplier ?? 1.3,\n initialRpcTimeoutMillis: 60000,\n maxRpcTimeoutMillis: 600000,\n rpcTimeoutMultiplier: 1.0,\n totalTimeoutMillis: 600000\n }\n }\n }\n : undefined\n });\n }\n }\n },\n\n /**\n * Add message handlers to a subscription\n * @param subscription - Name of the Pub/Sub subscription\n * @param handler - Function or list of functions to set as message handlers\n * @param options - Indicates that the additional options need to handle on Subscriber\n */\n addSubscriber<T>(\n subscription: string,\n handler: PubSubMessageHandler<T> | Array<PubSubMessageHandler<T>>,\n options: PubSubAddSubscriberOptions = {}\n ): void {\n const handlers = handler instanceof Array ? handler : [handler];\n const isDebezium = options?.isDebezium ?? false;\n const first = options?.first ?? false;\n const flowControl = options?.flowControl;\n const ackDeadline = options?.ackDeadline;\n\n reportDebug({\n namespace,\n message: `Registering subscriber for subscription '${subscription}'`,\n data: {\n first,\n handlersCount: handlers.length,\n isDebezium,\n flowControl\n }\n });\n if (!Object.keys(subscriptions).includes(subscription)) {\n subscriptions[subscription] = {\n subscription: pubSubClient.subscription(subscription, {\n enableOpenTelemetryTracing: true,\n flowControl: flowControl\n ? {\n maxMessages: flowControl.maxMessages ?? 1000,\n maxBytes: flowControl.maxBytes ?? 100 * 1024 * 1024, // 100MB\n allowExcessMessages: flowControl.allowExcessMessages ?? true\n }\n : {\n maxMessages: 1000,\n maxBytes: 100 * 1024 * 1024,\n allowExcessMessages: true\n },\n ackDeadline: ackDeadline ?? 60\n }),\n handlers: []\n };\n }\n\n if (isDebezium) subscriptions[subscription].isDebezium = true;\n\n if (first) subscriptions[subscription].handlers.push(...handlers);\n else subscriptions[subscription].handlers.unshift(...handlers);\n },\n\n /**\n * Send a message to a Pub/Sub topic\n * @param topic - Name of the topic\n * @param message - Content of the message, must be an object that can be JSON stringified\n * @param attributes - Attributes for this message, can be used to filter messages on the subscription\n * @param orderingKey - Enforce order guarantee of messages sent with the same key\n */\n async publish(\n topic: string,\n message: unknown,\n attributes?: Attributes,\n orderingKey?: string\n ): Promise<void> {\n if (!topics[topic])\n throw new EngineError(`No publisher was registered for topic '${topic}'`);\n reportDebug({\n namespace,\n message: `Sending message to topic '${topic}'`,\n data: { message, attributes, orderingKey }\n });\n await topics[topic].publishMessage({\n json: message,\n attributes,\n orderingKey\n });\n }\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,6 +9,7 @@ exports.createSequelizeClient = createSequelizeClient;
|
|
|
9
9
|
exports.init = init;
|
|
10
10
|
exports.sequelizeClient = exports.sequelize = void 0;
|
|
11
11
|
exports.shutdown = shutdown;
|
|
12
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
13
|
var _sequelizeTypescript = require("sequelize-typescript");
|
|
13
14
|
var _Sequelize = _interopRequireDefault(require("./Sequelize.config"));
|
|
14
15
|
var _Sequelize2 = require("./Sequelize.validate");
|
|
@@ -52,7 +53,8 @@ async function init() {
|
|
|
52
53
|
user: process.env.SQL_USER,
|
|
53
54
|
port: process.env.SQL_PORT,
|
|
54
55
|
dialect: process.env.SQL_TYPE || 'postgres',
|
|
55
|
-
isUnixSocket: process.env.SQL_HOST?.startsWith('/')
|
|
56
|
+
isUnixSocket: process.env.SQL_HOST?.startsWith('/'),
|
|
57
|
+
sqlStorage: (process.env.SQL_TYPE ?? '').toLowerCase() === 'sqlite' ? process.env.SQL_STORAGE || _path.default.join(process.cwd(), 'database.sqlite') : undefined
|
|
56
58
|
}
|
|
57
59
|
});
|
|
58
60
|
exports.sequelizeClient = sequelizeClient = createSequelizeClient();
|
|
@@ -153,6 +155,24 @@ function createSequelizeClient() {
|
|
|
153
155
|
});
|
|
154
156
|
}
|
|
155
157
|
|
|
158
|
+
// File-based SQLite for local / offline dev (no SQL_HOST / live server)
|
|
159
|
+
const sqlType = (process.env.SQL_TYPE ?? '').toLowerCase();
|
|
160
|
+
if (sqlType === 'sqlite') {
|
|
161
|
+
const storage = process.env.SQL_STORAGE && process.env.SQL_STORAGE.trim().length > 0 ? process.env.SQL_STORAGE.trim() : _path.default.join(process.cwd(), 'database.sqlite');
|
|
162
|
+
(0, _report.reportInfo)({
|
|
163
|
+
message: 'Creating Sequelize client (SQLite file)',
|
|
164
|
+
data: {
|
|
165
|
+
storage,
|
|
166
|
+
dialect: 'sqlite'
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return new _sequelizeTypescript.Sequelize({
|
|
170
|
+
dialect: 'sqlite',
|
|
171
|
+
storage,
|
|
172
|
+
logging: process.env.SQL_LOGGING === 'true' ? console.log : false
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
156
176
|
// Throw an error if there is no host initial
|
|
157
177
|
(0, _Sequelize2.validateSequelizeEnvironment)();
|
|
158
178
|
(0, _report.reportInfo)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sequelize.js","names":["_sequelizeTypescript","require","_Sequelize","_interopRequireDefault","_Sequelize2","_EngineError","_LifecycleController","_report","sequelizeClient","exports","sequelize","Proxy","get","target","property","init","shutdown","addModels","EngineError","message","reportInfo","data","host","process","env","SQL_HOST","database","SQL_DB","user","SQL_USER","port","SQL_PORT","dialect","SQL_TYPE","isUnixSocket","startsWith","createSequelizeClient","NODE_ENV","authenticate","getDialect","err","reportError","error","Error","String","stack","undefined","LifecycleController","register","close","console","models","addHook","result","convertToPlain","instance","modelInstance","toJSON","plain","Object","keys","forEach","key","Array","isArray","sync","Sequelize","storage","logging","validateSequelizeEnvironment","username","dbConfig","poolMax","pool","max","poolMin","min","SQL_PASSWORD"],"sources":["../../../src/entities/Sequelize/Sequelize.ts"],"sourcesContent":["import { Sequelize, ModelCtor } from 'sequelize-typescript';\nimport dbConfig from './Sequelize.config';\nimport { Sequelize as SequelizeInterface } from './Sequelize.types';\nimport { validateSequelizeEnvironment } from './Sequelize.validate';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { reportInfo, reportError } from 'utils/report';\n\nexport let sequelizeClient: undefined | Sequelize;\n\n/**\n * We use a proxy to extend the Sequelize behavior and allow initialization of the client only when needed while keeping the same interface\n */\nexport const sequelize = new Proxy<SequelizeInterface>(\n // Due to how we do the proxying, we are forced to ignore ts-errors, we could never create an object that respects the interface properly\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n {},\n {\n get: function (target, property): unknown {\n if (property === 'init') return init;\n if (property === 'shutdown') return shutdown;\n if (property === 'addModels') return addModels;\n // Create the sequelize client if it does not exist\n if (!sequelizeClient)\n throw new EngineError({\n message: 'Sequelize client was not initialized'\n });\n // Call the function on the sequelize client\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return sequelizeClient[property] as unknown;\n }\n }\n);\n\n/** On init create client and connect */\nexport async function init(): Promise<void> {\n // Ignore if already initialized\n if (sequelizeClient) return;\n \n reportInfo({\n message: 'Initializing Sequelize client',\n data: {\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n user: process.env.SQL_USER,\n port: process.env.SQL_PORT,\n dialect: process.env.SQL_TYPE || 'postgres',\n isUnixSocket: process.env.SQL_HOST?.startsWith('/')\n }\n });\n \n sequelizeClient = createSequelizeClient();\n \n // In test environment, authentication happens automatically with SQLite\n // For other environments, authenticate and log the result\n if (process.env.NODE_ENV !== 'test') {\n reportInfo({\n message: 'Starting database authentication'\n });\n\n try {\n await sequelizeClient.authenticate();\n reportInfo({ \n message: 'Connected to database successfully',\n data: {\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n dialect: sequelizeClient?.getDialect()\n }\n });\n } catch (err) {\n reportError({\n message: 'Failed to connect to database',\n data: {\n error: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n user: process.env.SQL_USER,\n port: process.env.SQL_PORT\n }\n });\n if (err instanceof Error) {\n reportError(err);\n }\n throw err;\n }\n }\n \n LifecycleController.register(sequelize);\n}\n\n/** On shutdown close connection and clear client */\nexport async function shutdown(): Promise<void> {\n if (sequelizeClient) {\n try {\n // For SQLite, just close the client (closing connection manager first causes SQLITE_MISUSE)\n // For other dialects, sequelize.close() handles everything properly\n await sequelizeClient.close();\n } catch (error) {\n // Ignore errors during shutdown\n if (process.env.NODE_ENV !== 'test') {\n console.error('Error closing sequelize client:', error);\n }\n }\n }\n sequelizeClient = undefined;\n}\n\nexport function addModels(models: Array<ModelCtor>): void {\n if (!sequelizeClient)\n throw new EngineError({\n message: 'Sequelize client was not initialized'\n });\n sequelizeClient.addModels(models);\n \n // Override toJSON behavior globally to ensure consistency between dev and prod\n // In dev (ts-node), property access works directly on instances\n // In prod (compiled), we need explicit serialization\n // This hook intercepts all afterFind results and converts them to plain objects\n sequelizeClient.addHook('afterFind', (result) => {\n if (!result) return;\n \n const convertToPlain = (instance: unknown) => {\n if (!instance || typeof instance !== 'object') return instance;\n const modelInstance = instance as { toJSON?: () => Record<string, unknown> } & Record<string, unknown>;\n if (!modelInstance.toJSON) return instance;\n const plain = modelInstance.toJSON();\n // Copy the plain object properties back to the instance\n // This makes property access work without .toJSON() in compiled code\n Object.keys(plain).forEach(key => {\n modelInstance[key] = plain[key];\n });\n };\n \n if (Array.isArray(result)) {\n result.forEach(convertToPlain);\n } else {\n convertToPlain(result);\n }\n });\n \n sequelizeClient.sync();\n}\n\n/** Create Sequelize client */\nexport function createSequelizeClient(): Sequelize {\n // Use in-memory SQLite for test environment to avoid real database connections\n if (process.env.NODE_ENV === 'test') {\n return new Sequelize({\n dialect: 'sqlite',\n storage: ':memory:',\n logging: false\n });\n }\n \n // Throw an error if there is no host initial\n validateSequelizeEnvironment();\n \n reportInfo({\n message: 'Creating Sequelize client with config',\n data: {\n database: process.env.SQL_DB,\n username: process.env.SQL_USER,\n host: process.env.SQL_HOST,\n port: dbConfig.port,\n dialect: dbConfig.dialect,\n isUnixSocket: process.env.SQL_HOST?.startsWith('/'),\n poolMax: dbConfig.pool?.max,\n poolMin: dbConfig.pool?.min\n }\n });\n \n return new Sequelize(\n process.env.SQL_DB as string,\n process.env.SQL_USER as string,\n process.env.SQL_PASSWORD as string,\n dbConfig\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Sequelize.js","names":["_path","_interopRequireDefault","require","_sequelizeTypescript","_Sequelize","_Sequelize2","_EngineError","_LifecycleController","_report","sequelizeClient","exports","sequelize","Proxy","get","target","property","init","shutdown","addModels","EngineError","message","reportInfo","data","host","process","env","SQL_HOST","database","SQL_DB","user","SQL_USER","port","SQL_PORT","dialect","SQL_TYPE","isUnixSocket","startsWith","sqlStorage","toLowerCase","SQL_STORAGE","path","join","cwd","undefined","createSequelizeClient","NODE_ENV","authenticate","getDialect","err","reportError","error","Error","String","stack","LifecycleController","register","close","console","models","addHook","result","convertToPlain","instance","modelInstance","toJSON","plain","Object","keys","forEach","key","Array","isArray","sync","Sequelize","storage","logging","sqlType","trim","length","SQL_LOGGING","log","validateSequelizeEnvironment","username","dbConfig","poolMax","pool","max","poolMin","min","SQL_PASSWORD"],"sources":["../../../src/entities/Sequelize/Sequelize.ts"],"sourcesContent":["import path from 'path';\nimport { Sequelize, ModelCtor } from 'sequelize-typescript';\nimport dbConfig from './Sequelize.config';\nimport { Sequelize as SequelizeInterface } from './Sequelize.types';\nimport { validateSequelizeEnvironment } from './Sequelize.validate';\nimport { EngineError } from 'entities/EngineError';\nimport { LifecycleController } from 'entities/LifecycleController';\nimport { reportInfo, reportError } from 'utils/report';\n\nexport let sequelizeClient: undefined | Sequelize;\n\n/**\n * We use a proxy to extend the Sequelize behavior and allow initialization of the client only when needed while keeping the same interface\n */\nexport const sequelize = new Proxy<SequelizeInterface>(\n // Due to how we do the proxying, we are forced to ignore ts-errors, we could never create an object that respects the interface properly\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n {},\n {\n get: function (target, property): unknown {\n if (property === 'init') return init;\n if (property === 'shutdown') return shutdown;\n if (property === 'addModels') return addModels;\n // Create the sequelize client if it does not exist\n if (!sequelizeClient)\n throw new EngineError({\n message: 'Sequelize client was not initialized'\n });\n // Call the function on the sequelize client\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return sequelizeClient[property] as unknown;\n }\n }\n);\n\n/** On init create client and connect */\nexport async function init(): Promise<void> {\n // Ignore if already initialized\n if (sequelizeClient) return;\n \n reportInfo({\n message: 'Initializing Sequelize client',\n data: {\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n user: process.env.SQL_USER,\n port: process.env.SQL_PORT,\n dialect: process.env.SQL_TYPE || 'postgres',\n isUnixSocket: process.env.SQL_HOST?.startsWith('/'),\n sqlStorage:\n (process.env.SQL_TYPE ?? '').toLowerCase() === 'sqlite'\n ? process.env.SQL_STORAGE || path.join(process.cwd(), 'database.sqlite')\n : undefined\n }\n });\n \n sequelizeClient = createSequelizeClient();\n \n // In test environment, authentication happens automatically with SQLite\n // For other environments, authenticate and log the result\n if (process.env.NODE_ENV !== 'test') {\n reportInfo({\n message: 'Starting database authentication'\n });\n\n try {\n await sequelizeClient.authenticate();\n reportInfo({ \n message: 'Connected to database successfully',\n data: {\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n dialect: sequelizeClient?.getDialect()\n }\n });\n } catch (err) {\n reportError({\n message: 'Failed to connect to database',\n data: {\n error: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n host: process.env.SQL_HOST,\n database: process.env.SQL_DB,\n user: process.env.SQL_USER,\n port: process.env.SQL_PORT\n }\n });\n if (err instanceof Error) {\n reportError(err);\n }\n throw err;\n }\n }\n \n LifecycleController.register(sequelize);\n}\n\n/** On shutdown close connection and clear client */\nexport async function shutdown(): Promise<void> {\n if (sequelizeClient) {\n try {\n // For SQLite, just close the client (closing connection manager first causes SQLITE_MISUSE)\n // For other dialects, sequelize.close() handles everything properly\n await sequelizeClient.close();\n } catch (error) {\n // Ignore errors during shutdown\n if (process.env.NODE_ENV !== 'test') {\n console.error('Error closing sequelize client:', error);\n }\n }\n }\n sequelizeClient = undefined;\n}\n\nexport function addModels(models: Array<ModelCtor>): void {\n if (!sequelizeClient)\n throw new EngineError({\n message: 'Sequelize client was not initialized'\n });\n sequelizeClient.addModels(models);\n \n // Override toJSON behavior globally to ensure consistency between dev and prod\n // In dev (ts-node), property access works directly on instances\n // In prod (compiled), we need explicit serialization\n // This hook intercepts all afterFind results and converts them to plain objects\n sequelizeClient.addHook('afterFind', (result) => {\n if (!result) return;\n \n const convertToPlain = (instance: unknown) => {\n if (!instance || typeof instance !== 'object') return instance;\n const modelInstance = instance as { toJSON?: () => Record<string, unknown> } & Record<string, unknown>;\n if (!modelInstance.toJSON) return instance;\n const plain = modelInstance.toJSON();\n // Copy the plain object properties back to the instance\n // This makes property access work without .toJSON() in compiled code\n Object.keys(plain).forEach(key => {\n modelInstance[key] = plain[key];\n });\n };\n \n if (Array.isArray(result)) {\n result.forEach(convertToPlain);\n } else {\n convertToPlain(result);\n }\n });\n \n sequelizeClient.sync();\n}\n\n/** Create Sequelize client */\nexport function createSequelizeClient(): Sequelize {\n // Use in-memory SQLite for test environment to avoid real database connections\n if (process.env.NODE_ENV === 'test') {\n return new Sequelize({\n dialect: 'sqlite',\n storage: ':memory:',\n logging: false\n });\n }\n\n // File-based SQLite for local / offline dev (no SQL_HOST / live server)\n const sqlType = (process.env.SQL_TYPE ?? '').toLowerCase();\n if (sqlType === 'sqlite') {\n const storage =\n process.env.SQL_STORAGE && process.env.SQL_STORAGE.trim().length > 0\n ? process.env.SQL_STORAGE.trim()\n : path.join(process.cwd(), 'database.sqlite');\n reportInfo({\n message: 'Creating Sequelize client (SQLite file)',\n data: { storage, dialect: 'sqlite' }\n });\n return new Sequelize({\n dialect: 'sqlite',\n storage,\n logging: process.env.SQL_LOGGING === 'true' ? console.log : false\n });\n }\n\n // Throw an error if there is no host initial\n validateSequelizeEnvironment();\n \n reportInfo({\n message: 'Creating Sequelize client with config',\n data: {\n database: process.env.SQL_DB,\n username: process.env.SQL_USER,\n host: process.env.SQL_HOST,\n port: dbConfig.port,\n dialect: dbConfig.dialect,\n isUnixSocket: process.env.SQL_HOST?.startsWith('/'),\n poolMax: dbConfig.pool?.max,\n poolMin: dbConfig.pool?.min\n }\n });\n \n return new Sequelize(\n process.env.SQL_DB as string,\n process.env.SQL_USER as string,\n process.env.SQL_PASSWORD as string,\n dbConfig\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-server-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|