@culturefy/shared 1.0.66 → 1.0.67
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.
- package/build/cjs/enums/secretKeys.enum.js +1 -0
- package/build/cjs/enums/secretKeys.enum.js.map +1 -1
- package/build/cjs/utils/cache.js +49 -21
- package/build/cjs/utils/cache.js.map +1 -1
- package/build/esm/enums/secretKeys.enum.js +1 -0
- package/build/esm/enums/secretKeys.enum.js.map +1 -1
- package/build/esm/utils/cache.js +49 -21
- package/build/esm/utils/cache.js.map +1 -1
- package/build/src/enums/secretKeys.enum.d.ts +2 -1
- package/build/src/enums/secretKeys.enum.js +1 -0
- package/build/src/enums/secretKeys.enum.js.map +1 -1
- package/build/src/utils/cache.d.ts +1 -1
- package/build/src/utils/cache.js +55 -23
- package/build/src/utils/cache.js.map +1 -1
- package/package.json +1 -1
|
@@ -45,6 +45,7 @@ let AzureSecretKeysEnum = exports.AzureSecretKeysEnum = /*#__PURE__*/function (A
|
|
|
45
45
|
AzureSecretKeysEnum["REDIS_HOST"] = "REDIS-HOST";
|
|
46
46
|
AzureSecretKeysEnum["REDIS_KEY"] = "REDIS-KEY";
|
|
47
47
|
AzureSecretKeysEnum["REDIS_URL"] = "REDIS-URL";
|
|
48
|
+
AzureSecretKeysEnum["REDIS_PORT"] = "REDIS-PORT";
|
|
48
49
|
return AzureSecretKeysEnum;
|
|
49
50
|
}({}); // AUTH-SERVICE-AUTHENTICATION-URL
|
|
50
51
|
// https://culturefy-auth-staging.azurewebsites.net/api/verify
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum","exports"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n DB_CONNECTING_STRING_PAYMENT = \"DB-CONNECTION-STRING-PAYMENT\",\n DB_CONNECTING_STRING_CORE = \"DB-CONNECTION-STRING-CORE\",\n DB_CONNECTING_STRING_BILLING = \"DB-CONNECTION-STRING-BILLING\",\n DB_CONNECTING_STRING_STAGING = \"DB-CONNECTION-STRING-STAGING\",\n DB_CONNECTING_STRING_BNT_DEV = \"DB-CONNECTION-STRING-BNT-DEV\",\n DB_CONNECTION_STRING_TENANT_BRIDGE = \"DB-CONNECTION-STRING-TENANT-BRIDGE\",\n SERVICE_BUS_CONNECTION_STRING = \"servicebus-connection-string\",\n STRIPE_CUSTOMER_SYNC_WEBHOOK_SECRET = \"stripe-customer-sync-webhook-secret-key\",\n STRIPE_INVOICE_SYNC_WEBHOOK_SECRET = \"stripe-invoice-sync-webhook-secret-key\",\n STRIPE_PRODUCT_SYNC_WEBHOOK_SECRET = \"stripe-product-sync-webhook-secret-key\",\n STRIPE_PRICE_SYNC_WEBHOOK_SECRET = \"stripe-price-sync-webhook-secret-key\",\n STRIPE_SECRET_KEY = \"Stripe-secret-key\",\n STRIPE_WEBHOOK_CUSTOMER_CREATED_SECRET_KEY = \"Stripe-Webhook-Customer-Created-Secret-Key\",\n STRIPE_SUBSCRIPTION_SYNC_WEBHOOK_SECRET = \"stripe-subscription-sync-webhook-secret-key\",\n FIREBASE_SERVICE_ACCOUNTS_VARIABLE = \"firebase_service_accounts_variable\",\n HMS_ACCESS_KEY=\"MEETING-HMS-ACCESS-KEY-APP-SECRET\",\n MEETING_ROOM_APP_SECRET=\"MEETING-ROOM-APP-SECRET\",\n BASE_DB_CLUSTER_CONNECTING_STRING_CHAT = \"BASE-DB-CLUSTER-CONNECTING-STRING-CHAT\",\n AUTH_SERVICE_AUTHENTICATION_URL = \"AUTH-SERVICE-AUTHENTICATION-URL\",\n GCP_PROJECT_ID=\"gcp-project-id\",\n PUBSUB_SERVICE_ACCOUNT_KEYS=\"pubsub-service-account-keys\",\n VAPI_TOKEN = \"vapi-token\",\n GITHUB_TOKEN = \"GITHUB-TOKEN\",\n GITHUB_WORKFLOW_URL = \"GITHUB-WORKFLOW-URL\",\n DB_CONNECTION_STRING_ENCRYPTION_KEY = \"DB-CONNECTION-STRING-ENCRYPTION-KEY\",\n\n REDIS_HOST=\"REDIS-HOST\",\n REDIS_KEY=\"REDIS-KEY\",\n REDIS_URL = \"REDIS-URL\"\n}\n\n// AUTH-SERVICE-AUTHENTICATION-URL\n// https://culturefy-auth-staging.azurewebsites.net/api/verify\n\n// REFRESH-SESSION-URL"],"mappings":";;;;AAAA;AAAA,IACYA,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAI4C;EAJ/DA,mBAAmB;EAKwC;EAL3DA,mBAAmB;EAMoC;EANvDA,mBAAmB;EAOY;EAP/BA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA,
|
|
1
|
+
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum","exports"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n DB_CONNECTING_STRING_PAYMENT = \"DB-CONNECTION-STRING-PAYMENT\",\n DB_CONNECTING_STRING_CORE = \"DB-CONNECTION-STRING-CORE\",\n DB_CONNECTING_STRING_BILLING = \"DB-CONNECTION-STRING-BILLING\",\n DB_CONNECTING_STRING_STAGING = \"DB-CONNECTION-STRING-STAGING\",\n DB_CONNECTING_STRING_BNT_DEV = \"DB-CONNECTION-STRING-BNT-DEV\",\n DB_CONNECTION_STRING_TENANT_BRIDGE = \"DB-CONNECTION-STRING-TENANT-BRIDGE\",\n SERVICE_BUS_CONNECTION_STRING = \"servicebus-connection-string\",\n STRIPE_CUSTOMER_SYNC_WEBHOOK_SECRET = \"stripe-customer-sync-webhook-secret-key\",\n STRIPE_INVOICE_SYNC_WEBHOOK_SECRET = \"stripe-invoice-sync-webhook-secret-key\",\n STRIPE_PRODUCT_SYNC_WEBHOOK_SECRET = \"stripe-product-sync-webhook-secret-key\",\n STRIPE_PRICE_SYNC_WEBHOOK_SECRET = \"stripe-price-sync-webhook-secret-key\",\n STRIPE_SECRET_KEY = \"Stripe-secret-key\",\n STRIPE_WEBHOOK_CUSTOMER_CREATED_SECRET_KEY = \"Stripe-Webhook-Customer-Created-Secret-Key\",\n STRIPE_SUBSCRIPTION_SYNC_WEBHOOK_SECRET = \"stripe-subscription-sync-webhook-secret-key\",\n FIREBASE_SERVICE_ACCOUNTS_VARIABLE = \"firebase_service_accounts_variable\",\n HMS_ACCESS_KEY=\"MEETING-HMS-ACCESS-KEY-APP-SECRET\",\n MEETING_ROOM_APP_SECRET=\"MEETING-ROOM-APP-SECRET\",\n BASE_DB_CLUSTER_CONNECTING_STRING_CHAT = \"BASE-DB-CLUSTER-CONNECTING-STRING-CHAT\",\n AUTH_SERVICE_AUTHENTICATION_URL = \"AUTH-SERVICE-AUTHENTICATION-URL\",\n GCP_PROJECT_ID=\"gcp-project-id\",\n PUBSUB_SERVICE_ACCOUNT_KEYS=\"pubsub-service-account-keys\",\n VAPI_TOKEN = \"vapi-token\",\n GITHUB_TOKEN = \"GITHUB-TOKEN\",\n GITHUB_WORKFLOW_URL = \"GITHUB-WORKFLOW-URL\",\n DB_CONNECTION_STRING_ENCRYPTION_KEY = \"DB-CONNECTION-STRING-ENCRYPTION-KEY\",\n\n REDIS_HOST=\"REDIS-HOST\",\n REDIS_KEY=\"REDIS-KEY\",\n REDIS_URL = \"REDIS-URL\",\n REDIS_PORT = \"REDIS-PORT\"\n}\n\n// AUTH-SERVICE-AUTHENTICATION-URL\n// https://culturefy-auth-staging.azurewebsites.net/api/verify\n\n// REFRESH-SESSION-URL"],"mappings":";;;;AAAA;AAAA,IACYA,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAI4C;EAJ/DA,mBAAmB;EAKwC;EAL3DA,mBAAmB;EAMoC;EANvDA,mBAAmB;EAOY;EAP/BA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA,OA0C/B;AACA;AAEA","ignoreList":[]}
|
package/build/cjs/utils/cache.js
CHANGED
|
@@ -3,33 +3,61 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.getRedisClient = exports.createCache = exports.Cacheable = void 0;
|
|
5
5
|
var _ioredis = _interopRequireDefault(require("ioredis"));
|
|
6
|
+
var _enums = require("../enums");
|
|
7
|
+
var _secrets = require("./secrets");
|
|
6
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
9
|
let redis = null;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return redisUrl;
|
|
10
|
+
let redisOptionsCache = null;
|
|
11
|
+
let redisOptionsPromise = null;
|
|
12
|
+
const resolveRedisConfig = async ctx => {
|
|
13
|
+
const vaultName = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
14
|
+
if (!vaultName) {
|
|
15
|
+
throw new Error("AZURE_KEY_VAULT_NAME is required to fetch Redis secrets");
|
|
15
16
|
}
|
|
16
|
-
if (
|
|
17
|
+
if (!ctx) {
|
|
18
|
+
throw new Error("InvocationContext is required to fetch Redis secrets");
|
|
19
|
+
}
|
|
20
|
+
const [redisHost, redisKey, redisPortSecret] = await Promise.all([(0, _secrets.getAzureVaultSecretByKey)(ctx, vaultName, _enums.AzureSecretKeysEnum.REDIS_HOST), (0, _secrets.getAzureVaultSecretByKey)(ctx, vaultName, _enums.AzureSecretKeysEnum.REDIS_KEY), (0, _secrets.getAzureVaultSecretByKey)(ctx, vaultName, _enums.AzureSecretKeysEnum.REDIS_PORT)]);
|
|
21
|
+
const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;
|
|
22
|
+
if (!redisHost || !redisKey) {
|
|
23
|
+
throw new Error("Redis configuration missing in Key Vault");
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
host: redisHost,
|
|
27
|
+
key: redisKey,
|
|
28
|
+
port: redisPort
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const buildRedisOptions = async ctx => {
|
|
32
|
+
if (redisOptionsCache) return redisOptionsCache;
|
|
33
|
+
if (redisOptionsPromise) return redisOptionsPromise;
|
|
34
|
+
redisOptionsPromise = (async () => {
|
|
35
|
+
const {
|
|
36
|
+
host,
|
|
37
|
+
key,
|
|
38
|
+
port
|
|
39
|
+
} = await resolveRedisConfig(ctx);
|
|
17
40
|
return {
|
|
18
|
-
host
|
|
19
|
-
port
|
|
20
|
-
password:
|
|
41
|
+
host,
|
|
42
|
+
port,
|
|
43
|
+
password: key,
|
|
21
44
|
tls: {
|
|
22
|
-
servername:
|
|
45
|
+
servername: host
|
|
23
46
|
},
|
|
24
47
|
maxRetriesPerRequest: 3,
|
|
25
48
|
enableReadyCheck: false
|
|
26
49
|
};
|
|
27
|
-
}
|
|
28
|
-
|
|
50
|
+
})().then(options => {
|
|
51
|
+
redisOptionsCache = options;
|
|
52
|
+
return options;
|
|
53
|
+
}).finally(() => {
|
|
54
|
+
redisOptionsPromise = null;
|
|
55
|
+
});
|
|
56
|
+
return redisOptionsPromise;
|
|
29
57
|
};
|
|
30
|
-
const getRedisClient = ctx => {
|
|
58
|
+
const getRedisClient = async ctx => {
|
|
31
59
|
if (redis) return redis;
|
|
32
|
-
const options = buildRedisOptions();
|
|
60
|
+
const options = await buildRedisOptions(ctx);
|
|
33
61
|
redis = new _ioredis.default(options);
|
|
34
62
|
redis.on("error", err => ctx == null || ctx.error == null ? void 0 : ctx.error("Redis error", err));
|
|
35
63
|
redis.on("connect", () => ctx == null || ctx.info == null ? void 0 : ctx.info("Redis connected"));
|
|
@@ -41,7 +69,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
41
69
|
return {
|
|
42
70
|
key: (...parts) => buildKey(namespace, parts),
|
|
43
71
|
get: async (ctx, ...parts) => {
|
|
44
|
-
const client = getRedisClient(ctx);
|
|
72
|
+
const client = await getRedisClient(ctx);
|
|
45
73
|
try {
|
|
46
74
|
return await client.get(buildKey(namespace, parts));
|
|
47
75
|
} catch (error) {
|
|
@@ -50,7 +78,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
50
78
|
}
|
|
51
79
|
},
|
|
52
80
|
set: async (ctx, value, ...parts) => {
|
|
53
|
-
const client = getRedisClient(ctx);
|
|
81
|
+
const client = await getRedisClient(ctx);
|
|
54
82
|
try {
|
|
55
83
|
await client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
56
84
|
} catch (error) {
|
|
@@ -59,7 +87,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
59
87
|
},
|
|
60
88
|
getOrSet: async (ctx, parts, fetcher) => {
|
|
61
89
|
const cached = await (async () => {
|
|
62
|
-
const client = getRedisClient(ctx);
|
|
90
|
+
const client = await getRedisClient(ctx);
|
|
63
91
|
try {
|
|
64
92
|
return await client.get(buildKey(namespace, parts));
|
|
65
93
|
} catch (error) {
|
|
@@ -70,7 +98,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
70
98
|
if (cached) return cached;
|
|
71
99
|
const value = await fetcher();
|
|
72
100
|
await (async () => {
|
|
73
|
-
const client = getRedisClient(ctx);
|
|
101
|
+
const client = await getRedisClient(ctx);
|
|
74
102
|
try {
|
|
75
103
|
await client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
76
104
|
} catch (error) {
|
|
@@ -80,7 +108,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
80
108
|
return value;
|
|
81
109
|
},
|
|
82
110
|
delete: async (ctx, ...parts) => {
|
|
83
|
-
const client = getRedisClient(ctx);
|
|
111
|
+
const client = await getRedisClient(ctx);
|
|
84
112
|
try {
|
|
85
113
|
await client.del(buildKey(namespace, parts));
|
|
86
114
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","names":["_ioredis","_interopRequireDefault","require","e","__esModule","default","redis","buildRedisOptions","redisUrl","process","env","REDIS_URL","redisHost","REDIS_HOST","redisKey","REDIS_KEY","redisPort","REDIS_PORT","Number","host","port","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","Error","getRedisClient","ctx","options","Redis","on","err","error","info","exports","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","key","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\n\nlet redis: Redis | null = null;\n\nconst buildRedisOptions = (): RedisOptions | string => {\n const redisUrl = process.env.REDIS_URL;\n const redisHost =\n process.env.REDIS_HOST || \"redis-shared-dev-01.redis.cache.windows.net\";\n const redisKey =\n process.env.REDIS_KEY || \"ipno36YDLwvUDydaFsulBbKPFaOQK2P7IAzCaLjKf7U=\";\n const redisPort = process.env.REDIS_PORT ? Number(process.env.REDIS_PORT) : 6380;\n\n if (redisUrl) {\n return redisUrl;\n }\n\n if (redisHost && redisKey) {\n return {\n host: redisHost,\n port: redisPort,\n password: redisKey,\n tls: { servername: redisHost },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n }\n\n throw new Error(\n \"Redis configuration missing: set REDIS_URL or REDIS_HOST/REDIS_KEY\",\n );\n};\n\nexport const getRedisClient = (ctx?: InvocationContext): Redis => {\n if (redis) return redis;\n\n const options = buildRedisOptions();\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => ctx?.info?.(\"Redis connected\"));\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"cache.js","names":["_ioredis","_interopRequireDefault","require","_enums","_secrets","e","__esModule","default","redis","redisOptionsCache","redisOptionsPromise","resolveRedisConfig","ctx","vaultName","process","env","AZURE_KEY_VAULT_NAME","Error","redisHost","redisKey","redisPortSecret","Promise","all","getAzureVaultSecretByKey","AzureSecretKeysEnum","REDIS_HOST","REDIS_KEY","REDIS_PORT","redisPort","Number","host","key","port","buildRedisOptions","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","then","options","finally","getRedisClient","Redis","on","err","error","info","exports","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { getAzureVaultSecretByKey } from \"./secrets\";\n\nlet redis: Redis | null = null;\nlet redisOptionsCache: RedisOptions | string | null = null;\nlet redisOptionsPromise: Promise<RedisOptions | string> | null = null;\n\ntype RedisConfig = {\n host: string;\n key: string;\n port: number;\n};\n\nconst resolveRedisConfig = async (\n ctx?: InvocationContext,\n): Promise<RedisConfig> => {\n const vaultName = process.env.AZURE_KEY_VAULT_NAME || \"\";\n if (!vaultName) {\n throw new Error(\"AZURE_KEY_VAULT_NAME is required to fetch Redis secrets\");\n }\n if (!ctx) {\n throw new Error(\"InvocationContext is required to fetch Redis secrets\");\n }\n\n const [redisHost, redisKey, redisPortSecret] = await Promise.all([\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_HOST),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_KEY),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_PORT),\n ]);\n\n const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;\n\n if (!redisHost || !redisKey) {\n throw new Error(\"Redis configuration missing in Key Vault\");\n }\n\n return {\n host: redisHost,\n key: redisKey,\n port: redisPort,\n };\n};\n\nconst buildRedisOptions = async (\n ctx?: InvocationContext,\n): Promise<RedisOptions | string> => {\n if (redisOptionsCache) return redisOptionsCache;\n if (redisOptionsPromise) return redisOptionsPromise;\n\n redisOptionsPromise = (async () => {\n const { host, key, port } = await resolveRedisConfig(ctx);\n\n return {\n host,\n port,\n password: key,\n tls: { servername: host },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n })()\n .then((options) => {\n redisOptionsCache = options;\n return options;\n })\n .finally(() => {\n redisOptionsPromise = null;\n });\n\n return redisOptionsPromise;\n};\n\nexport const getRedisClient = async (ctx?: InvocationContext): Promise<Redis> => {\n if (redis) return redis;\n\n const options = await buildRedisOptions(ctx);\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => ctx?.info?.(\"Redis connected\"));\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -41,6 +41,7 @@ export let AzureSecretKeysEnum = /*#__PURE__*/function (AzureSecretKeysEnum) {
|
|
|
41
41
|
AzureSecretKeysEnum["REDIS_HOST"] = "REDIS-HOST";
|
|
42
42
|
AzureSecretKeysEnum["REDIS_KEY"] = "REDIS-KEY";
|
|
43
43
|
AzureSecretKeysEnum["REDIS_URL"] = "REDIS-URL";
|
|
44
|
+
AzureSecretKeysEnum["REDIS_PORT"] = "REDIS-PORT";
|
|
44
45
|
return AzureSecretKeysEnum;
|
|
45
46
|
}({});
|
|
46
47
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n DB_CONNECTING_STRING_PAYMENT = \"DB-CONNECTION-STRING-PAYMENT\",\n DB_CONNECTING_STRING_CORE = \"DB-CONNECTION-STRING-CORE\",\n DB_CONNECTING_STRING_BILLING = \"DB-CONNECTION-STRING-BILLING\",\n DB_CONNECTING_STRING_STAGING = \"DB-CONNECTION-STRING-STAGING\",\n DB_CONNECTING_STRING_BNT_DEV = \"DB-CONNECTION-STRING-BNT-DEV\",\n DB_CONNECTION_STRING_TENANT_BRIDGE = \"DB-CONNECTION-STRING-TENANT-BRIDGE\",\n SERVICE_BUS_CONNECTION_STRING = \"servicebus-connection-string\",\n STRIPE_CUSTOMER_SYNC_WEBHOOK_SECRET = \"stripe-customer-sync-webhook-secret-key\",\n STRIPE_INVOICE_SYNC_WEBHOOK_SECRET = \"stripe-invoice-sync-webhook-secret-key\",\n STRIPE_PRODUCT_SYNC_WEBHOOK_SECRET = \"stripe-product-sync-webhook-secret-key\",\n STRIPE_PRICE_SYNC_WEBHOOK_SECRET = \"stripe-price-sync-webhook-secret-key\",\n STRIPE_SECRET_KEY = \"Stripe-secret-key\",\n STRIPE_WEBHOOK_CUSTOMER_CREATED_SECRET_KEY = \"Stripe-Webhook-Customer-Created-Secret-Key\",\n STRIPE_SUBSCRIPTION_SYNC_WEBHOOK_SECRET = \"stripe-subscription-sync-webhook-secret-key\",\n FIREBASE_SERVICE_ACCOUNTS_VARIABLE = \"firebase_service_accounts_variable\",\n HMS_ACCESS_KEY=\"MEETING-HMS-ACCESS-KEY-APP-SECRET\",\n MEETING_ROOM_APP_SECRET=\"MEETING-ROOM-APP-SECRET\",\n BASE_DB_CLUSTER_CONNECTING_STRING_CHAT = \"BASE-DB-CLUSTER-CONNECTING-STRING-CHAT\",\n AUTH_SERVICE_AUTHENTICATION_URL = \"AUTH-SERVICE-AUTHENTICATION-URL\",\n GCP_PROJECT_ID=\"gcp-project-id\",\n PUBSUB_SERVICE_ACCOUNT_KEYS=\"pubsub-service-account-keys\",\n VAPI_TOKEN = \"vapi-token\",\n GITHUB_TOKEN = \"GITHUB-TOKEN\",\n GITHUB_WORKFLOW_URL = \"GITHUB-WORKFLOW-URL\",\n DB_CONNECTION_STRING_ENCRYPTION_KEY = \"DB-CONNECTION-STRING-ENCRYPTION-KEY\",\n\n REDIS_HOST=\"REDIS-HOST\",\n REDIS_KEY=\"REDIS-KEY\",\n REDIS_URL = \"REDIS-URL\"\n}\n\n// AUTH-SERVICE-AUTHENTICATION-URL\n// https://culturefy-auth-staging.azurewebsites.net/api/verify\n\n// REFRESH-SESSION-URL"],"mappings":"AAAA;AACA,WAAYA,mBAAmB,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAI4C;EAJ/DA,mBAAmB;EAKwC;EAL3DA,mBAAmB;EAMoC;EANvDA,mBAAmB;EAOY;EAP/BA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA;;
|
|
1
|
+
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n DB_CONNECTING_STRING_PAYMENT = \"DB-CONNECTION-STRING-PAYMENT\",\n DB_CONNECTING_STRING_CORE = \"DB-CONNECTION-STRING-CORE\",\n DB_CONNECTING_STRING_BILLING = \"DB-CONNECTION-STRING-BILLING\",\n DB_CONNECTING_STRING_STAGING = \"DB-CONNECTION-STRING-STAGING\",\n DB_CONNECTING_STRING_BNT_DEV = \"DB-CONNECTION-STRING-BNT-DEV\",\n DB_CONNECTION_STRING_TENANT_BRIDGE = \"DB-CONNECTION-STRING-TENANT-BRIDGE\",\n SERVICE_BUS_CONNECTION_STRING = \"servicebus-connection-string\",\n STRIPE_CUSTOMER_SYNC_WEBHOOK_SECRET = \"stripe-customer-sync-webhook-secret-key\",\n STRIPE_INVOICE_SYNC_WEBHOOK_SECRET = \"stripe-invoice-sync-webhook-secret-key\",\n STRIPE_PRODUCT_SYNC_WEBHOOK_SECRET = \"stripe-product-sync-webhook-secret-key\",\n STRIPE_PRICE_SYNC_WEBHOOK_SECRET = \"stripe-price-sync-webhook-secret-key\",\n STRIPE_SECRET_KEY = \"Stripe-secret-key\",\n STRIPE_WEBHOOK_CUSTOMER_CREATED_SECRET_KEY = \"Stripe-Webhook-Customer-Created-Secret-Key\",\n STRIPE_SUBSCRIPTION_SYNC_WEBHOOK_SECRET = \"stripe-subscription-sync-webhook-secret-key\",\n FIREBASE_SERVICE_ACCOUNTS_VARIABLE = \"firebase_service_accounts_variable\",\n HMS_ACCESS_KEY=\"MEETING-HMS-ACCESS-KEY-APP-SECRET\",\n MEETING_ROOM_APP_SECRET=\"MEETING-ROOM-APP-SECRET\",\n BASE_DB_CLUSTER_CONNECTING_STRING_CHAT = \"BASE-DB-CLUSTER-CONNECTING-STRING-CHAT\",\n AUTH_SERVICE_AUTHENTICATION_URL = \"AUTH-SERVICE-AUTHENTICATION-URL\",\n GCP_PROJECT_ID=\"gcp-project-id\",\n PUBSUB_SERVICE_ACCOUNT_KEYS=\"pubsub-service-account-keys\",\n VAPI_TOKEN = \"vapi-token\",\n GITHUB_TOKEN = \"GITHUB-TOKEN\",\n GITHUB_WORKFLOW_URL = \"GITHUB-WORKFLOW-URL\",\n DB_CONNECTION_STRING_ENCRYPTION_KEY = \"DB-CONNECTION-STRING-ENCRYPTION-KEY\",\n\n REDIS_HOST=\"REDIS-HOST\",\n REDIS_KEY=\"REDIS-KEY\",\n REDIS_URL = \"REDIS-URL\",\n REDIS_PORT = \"REDIS-PORT\"\n}\n\n// AUTH-SERVICE-AUTHENTICATION-URL\n// https://culturefy-auth-staging.azurewebsites.net/api/verify\n\n// REFRESH-SESSION-URL"],"mappings":"AAAA;AACA,WAAYA,mBAAmB,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAI4C;EAJ/DA,mBAAmB;EAKwC;EAL3DA,mBAAmB;EAMoC;EANvDA,mBAAmB;EAOY;EAP/BA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA;;AA0C/B;AACA;;AAEA","ignoreList":[]}
|
package/build/esm/utils/cache.js
CHANGED
|
@@ -1,30 +1,58 @@
|
|
|
1
1
|
import Redis from "ioredis";
|
|
2
|
+
import { AzureSecretKeysEnum } from "../enums";
|
|
3
|
+
import { getAzureVaultSecretByKey } from "./secrets";
|
|
2
4
|
let redis = null;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return redisUrl;
|
|
5
|
+
let redisOptionsCache = null;
|
|
6
|
+
let redisOptionsPromise = null;
|
|
7
|
+
const resolveRedisConfig = async ctx => {
|
|
8
|
+
const vaultName = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
9
|
+
if (!vaultName) {
|
|
10
|
+
throw new Error("AZURE_KEY_VAULT_NAME is required to fetch Redis secrets");
|
|
10
11
|
}
|
|
11
|
-
if (
|
|
12
|
+
if (!ctx) {
|
|
13
|
+
throw new Error("InvocationContext is required to fetch Redis secrets");
|
|
14
|
+
}
|
|
15
|
+
const [redisHost, redisKey, redisPortSecret] = await Promise.all([getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_HOST), getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_KEY), getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_PORT)]);
|
|
16
|
+
const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;
|
|
17
|
+
if (!redisHost || !redisKey) {
|
|
18
|
+
throw new Error("Redis configuration missing in Key Vault");
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
host: redisHost,
|
|
22
|
+
key: redisKey,
|
|
23
|
+
port: redisPort
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const buildRedisOptions = async ctx => {
|
|
27
|
+
if (redisOptionsCache) return redisOptionsCache;
|
|
28
|
+
if (redisOptionsPromise) return redisOptionsPromise;
|
|
29
|
+
redisOptionsPromise = (async () => {
|
|
30
|
+
const {
|
|
31
|
+
host,
|
|
32
|
+
key,
|
|
33
|
+
port
|
|
34
|
+
} = await resolveRedisConfig(ctx);
|
|
12
35
|
return {
|
|
13
|
-
host
|
|
14
|
-
port
|
|
15
|
-
password:
|
|
36
|
+
host,
|
|
37
|
+
port,
|
|
38
|
+
password: key,
|
|
16
39
|
tls: {
|
|
17
|
-
servername:
|
|
40
|
+
servername: host
|
|
18
41
|
},
|
|
19
42
|
maxRetriesPerRequest: 3,
|
|
20
43
|
enableReadyCheck: false
|
|
21
44
|
};
|
|
22
|
-
}
|
|
23
|
-
|
|
45
|
+
})().then(options => {
|
|
46
|
+
redisOptionsCache = options;
|
|
47
|
+
return options;
|
|
48
|
+
}).finally(() => {
|
|
49
|
+
redisOptionsPromise = null;
|
|
50
|
+
});
|
|
51
|
+
return redisOptionsPromise;
|
|
24
52
|
};
|
|
25
|
-
export const getRedisClient = ctx => {
|
|
53
|
+
export const getRedisClient = async ctx => {
|
|
26
54
|
if (redis) return redis;
|
|
27
|
-
const options = buildRedisOptions();
|
|
55
|
+
const options = await buildRedisOptions(ctx);
|
|
28
56
|
redis = new Redis(options);
|
|
29
57
|
redis.on("error", err => ctx == null || ctx.error == null ? void 0 : ctx.error("Redis error", err));
|
|
30
58
|
redis.on("connect", () => ctx == null || ctx.info == null ? void 0 : ctx.info("Redis connected"));
|
|
@@ -35,7 +63,7 @@ export const createCache = (namespace, ttlSeconds) => {
|
|
|
35
63
|
return {
|
|
36
64
|
key: (...parts) => buildKey(namespace, parts),
|
|
37
65
|
get: async (ctx, ...parts) => {
|
|
38
|
-
const client = getRedisClient(ctx);
|
|
66
|
+
const client = await getRedisClient(ctx);
|
|
39
67
|
try {
|
|
40
68
|
return await client.get(buildKey(namespace, parts));
|
|
41
69
|
} catch (error) {
|
|
@@ -44,7 +72,7 @@ export const createCache = (namespace, ttlSeconds) => {
|
|
|
44
72
|
}
|
|
45
73
|
},
|
|
46
74
|
set: async (ctx, value, ...parts) => {
|
|
47
|
-
const client = getRedisClient(ctx);
|
|
75
|
+
const client = await getRedisClient(ctx);
|
|
48
76
|
try {
|
|
49
77
|
await client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
50
78
|
} catch (error) {
|
|
@@ -53,7 +81,7 @@ export const createCache = (namespace, ttlSeconds) => {
|
|
|
53
81
|
},
|
|
54
82
|
getOrSet: async (ctx, parts, fetcher) => {
|
|
55
83
|
const cached = await (async () => {
|
|
56
|
-
const client = getRedisClient(ctx);
|
|
84
|
+
const client = await getRedisClient(ctx);
|
|
57
85
|
try {
|
|
58
86
|
return await client.get(buildKey(namespace, parts));
|
|
59
87
|
} catch (error) {
|
|
@@ -64,7 +92,7 @@ export const createCache = (namespace, ttlSeconds) => {
|
|
|
64
92
|
if (cached) return cached;
|
|
65
93
|
const value = await fetcher();
|
|
66
94
|
await (async () => {
|
|
67
|
-
const client = getRedisClient(ctx);
|
|
95
|
+
const client = await getRedisClient(ctx);
|
|
68
96
|
try {
|
|
69
97
|
await client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
70
98
|
} catch (error) {
|
|
@@ -74,7 +102,7 @@ export const createCache = (namespace, ttlSeconds) => {
|
|
|
74
102
|
return value;
|
|
75
103
|
},
|
|
76
104
|
delete: async (ctx, ...parts) => {
|
|
77
|
-
const client = getRedisClient(ctx);
|
|
105
|
+
const client = await getRedisClient(ctx);
|
|
78
106
|
try {
|
|
79
107
|
await client.del(buildKey(namespace, parts));
|
|
80
108
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","names":["Redis","redis","buildRedisOptions","redisUrl","process","env","REDIS_URL","redisHost","REDIS_HOST","redisKey","REDIS_KEY","redisPort","REDIS_PORT","Number","host","port","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","Error","getRedisClient","ctx","options","on","err","error","info","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","key","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\n\nlet redis: Redis | null = null;\n\nconst buildRedisOptions = (): RedisOptions | string => {\n const redisUrl = process.env.REDIS_URL;\n const redisHost =\n process.env.REDIS_HOST || \"redis-shared-dev-01.redis.cache.windows.net\";\n const redisKey =\n process.env.REDIS_KEY || \"ipno36YDLwvUDydaFsulBbKPFaOQK2P7IAzCaLjKf7U=\";\n const redisPort = process.env.REDIS_PORT ? Number(process.env.REDIS_PORT) : 6380;\n\n if (redisUrl) {\n return redisUrl;\n }\n\n if (redisHost && redisKey) {\n return {\n host: redisHost,\n port: redisPort,\n password: redisKey,\n tls: { servername: redisHost },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n }\n\n throw new Error(\n \"Redis configuration missing: set REDIS_URL or REDIS_HOST/REDIS_KEY\",\n );\n};\n\nexport const getRedisClient = (ctx?: InvocationContext): Redis => {\n if (redis) return redis;\n\n const options = buildRedisOptions();\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => ctx?.info?.(\"Redis connected\"));\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"cache.js","names":["Redis","AzureSecretKeysEnum","getAzureVaultSecretByKey","redis","redisOptionsCache","redisOptionsPromise","resolveRedisConfig","ctx","vaultName","process","env","AZURE_KEY_VAULT_NAME","Error","redisHost","redisKey","redisPortSecret","Promise","all","REDIS_HOST","REDIS_KEY","REDIS_PORT","redisPort","Number","host","key","port","buildRedisOptions","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","then","options","finally","getRedisClient","on","err","error","info","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { getAzureVaultSecretByKey } from \"./secrets\";\n\nlet redis: Redis | null = null;\nlet redisOptionsCache: RedisOptions | string | null = null;\nlet redisOptionsPromise: Promise<RedisOptions | string> | null = null;\n\ntype RedisConfig = {\n host: string;\n key: string;\n port: number;\n};\n\nconst resolveRedisConfig = async (\n ctx?: InvocationContext,\n): Promise<RedisConfig> => {\n const vaultName = process.env.AZURE_KEY_VAULT_NAME || \"\";\n if (!vaultName) {\n throw new Error(\"AZURE_KEY_VAULT_NAME is required to fetch Redis secrets\");\n }\n if (!ctx) {\n throw new Error(\"InvocationContext is required to fetch Redis secrets\");\n }\n\n const [redisHost, redisKey, redisPortSecret] = await Promise.all([\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_HOST),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_KEY),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_PORT),\n ]);\n\n const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;\n\n if (!redisHost || !redisKey) {\n throw new Error(\"Redis configuration missing in Key Vault\");\n }\n\n return {\n host: redisHost,\n key: redisKey,\n port: redisPort,\n };\n};\n\nconst buildRedisOptions = async (\n ctx?: InvocationContext,\n): Promise<RedisOptions | string> => {\n if (redisOptionsCache) return redisOptionsCache;\n if (redisOptionsPromise) return redisOptionsPromise;\n\n redisOptionsPromise = (async () => {\n const { host, key, port } = await resolveRedisConfig(ctx);\n\n return {\n host,\n port,\n password: key,\n tls: { servername: host },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n })()\n .then((options) => {\n redisOptionsCache = options;\n return options;\n })\n .finally(() => {\n redisOptionsPromise = null;\n });\n\n return redisOptionsPromise;\n};\n\nexport const getRedisClient = async (ctx?: InvocationContext): Promise<Redis> => {\n if (redis) return redis;\n\n const options = await buildRedisOptions(ctx);\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => ctx?.info?.(\"Redis connected\"));\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -35,5 +35,6 @@ export declare enum AzureSecretKeysEnum {
|
|
|
35
35
|
DB_CONNECTION_STRING_ENCRYPTION_KEY = "DB-CONNECTION-STRING-ENCRYPTION-KEY",
|
|
36
36
|
REDIS_HOST = "REDIS-HOST",
|
|
37
37
|
REDIS_KEY = "REDIS-KEY",
|
|
38
|
-
REDIS_URL = "REDIS-URL"
|
|
38
|
+
REDIS_URL = "REDIS-URL",
|
|
39
|
+
REDIS_PORT = "REDIS-PORT"
|
|
39
40
|
}
|
|
@@ -41,6 +41,7 @@ var AzureSecretKeysEnum;
|
|
|
41
41
|
AzureSecretKeysEnum["REDIS_HOST"] = "REDIS-HOST";
|
|
42
42
|
AzureSecretKeysEnum["REDIS_KEY"] = "REDIS-KEY";
|
|
43
43
|
AzureSecretKeysEnum["REDIS_URL"] = "REDIS-URL";
|
|
44
|
+
AzureSecretKeysEnum["REDIS_PORT"] = "REDIS-PORT";
|
|
44
45
|
})(AzureSecretKeysEnum || (exports.AzureSecretKeysEnum = AzureSecretKeysEnum = {}));
|
|
45
46
|
// AUTH-SERVICE-AUTHENTICATION-URL
|
|
46
47
|
// https://culturefy-auth-staging.azurewebsites.net/api/verify
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretKeys.enum.js","sourceRoot":"","sources":["../../../src/enums/secretKeys.enum.ts"],"names":[],"mappings":";;;AAAA,uBAAuB;AACvB,IAAY,
|
|
1
|
+
{"version":3,"file":"secretKeys.enum.js","sourceRoot":"","sources":["../../../src/enums/secretKeys.enum.ts"],"names":[],"mappings":";;;AAAA,uBAAuB;AACvB,IAAY,mBAwCX;AAxCD,WAAY,mBAAmB;IAC7B,oFAA6D,CAAA;IAC7D,4EAAqD,CAAA;IACrD,8DAAuC,CAAA;IACvC,8FAAuE,CAAA;IACvE,0FAAmE,CAAA;IACnE,sFAA+D,CAAA;IAC/D,8DAAuC,CAAA;IACvC,8EAAuD,CAAA;IACvD,8EAAuD,CAAA;IACvD,oFAA6D,CAAA;IAC7D,8EAAuD,CAAA;IACvD,oFAA6D,CAAA;IAC7D,oFAA8D,CAAA;IAC9D,oFAA6D,CAAA;IAC7D,gGAAyE,CAAA;IACzE,qFAA8D,CAAA;IAC9D,sGAA+E,CAAA;IAC/E,oGAA6E,CAAA;IAC7E,oGAA6E,CAAA;IAC7E,gGAAyE,CAAA;IACzE,8DAAuC,CAAA;IACvC,gHAAyF,CAAA;IACzF,8GAAuF,CAAA;IACvF,gGAAyE,CAAA;IACzE,2EAAkD,CAAA;IAClD,0EAAiD,CAAA;IACjD,wGAAiF,CAAA;IACjF,0FAAmE,CAAA;IACnE,wDAA+B,CAAA;IAC/B,kFAAyD,CAAA;IACzD,gDAAyB,CAAA;IACzB,oDAA6B,CAAA;IAC7B,kEAA2C,CAAA;IAC3C,kGAA2E,CAAA;IAE3E,gDAAuB,CAAA;IACvB,8CAAqB,CAAA;IACrB,8CAAuB,CAAA;IACvB,gDAAyB,CAAA;AAC3B,CAAC,EAxCW,mBAAmB,mCAAnB,mBAAmB,QAwC9B;AAED,kCAAkC;AAClC,8DAA8D;AAE9D,sBAAsB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Redis from "ioredis";
|
|
2
2
|
import { InvocationContext } from "@azure/functions";
|
|
3
|
-
export declare const getRedisClient: (ctx?: InvocationContext) => Redis
|
|
3
|
+
export declare const getRedisClient: (ctx?: InvocationContext) => Promise<Redis>;
|
|
4
4
|
export declare const createCache: (namespace: string, ttlSeconds: number) => {
|
|
5
5
|
key: (...parts: Array<string | number | undefined>) => string;
|
|
6
6
|
get: (ctx: InvocationContext | undefined, ...parts: Array<string | number | undefined>) => Promise<string | null>;
|
package/build/src/utils/cache.js
CHANGED
|
@@ -3,36 +3,68 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Cacheable = exports.createCache = exports.getRedisClient = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const ioredis_1 = tslib_1.__importDefault(require("ioredis"));
|
|
6
|
+
const enums_1 = require("../enums");
|
|
7
|
+
const secrets_1 = require("./secrets");
|
|
6
8
|
let redis = null;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return redisUrl;
|
|
9
|
+
let redisOptionsCache = null;
|
|
10
|
+
let redisOptionsPromise = null;
|
|
11
|
+
const resolveRedisConfig = (ctx) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
12
|
+
const vaultName = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
13
|
+
if (!vaultName) {
|
|
14
|
+
throw new Error("AZURE_KEY_VAULT_NAME is required to fetch Redis secrets");
|
|
14
15
|
}
|
|
15
|
-
if (
|
|
16
|
+
if (!ctx) {
|
|
17
|
+
throw new Error("InvocationContext is required to fetch Redis secrets");
|
|
18
|
+
}
|
|
19
|
+
const [redisHost, redisKey, redisPortSecret] = yield Promise.all([
|
|
20
|
+
(0, secrets_1.getAzureVaultSecretByKey)(ctx, vaultName, enums_1.AzureSecretKeysEnum.REDIS_HOST),
|
|
21
|
+
(0, secrets_1.getAzureVaultSecretByKey)(ctx, vaultName, enums_1.AzureSecretKeysEnum.REDIS_KEY),
|
|
22
|
+
(0, secrets_1.getAzureVaultSecretByKey)(ctx, vaultName, enums_1.AzureSecretKeysEnum.REDIS_PORT),
|
|
23
|
+
]);
|
|
24
|
+
const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;
|
|
25
|
+
if (!redisHost || !redisKey) {
|
|
26
|
+
throw new Error("Redis configuration missing in Key Vault");
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
host: redisHost,
|
|
30
|
+
key: redisKey,
|
|
31
|
+
port: redisPort,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
const buildRedisOptions = (ctx) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
if (redisOptionsCache)
|
|
36
|
+
return redisOptionsCache;
|
|
37
|
+
if (redisOptionsPromise)
|
|
38
|
+
return redisOptionsPromise;
|
|
39
|
+
redisOptionsPromise = (() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
const { host, key, port } = yield resolveRedisConfig(ctx);
|
|
16
41
|
return {
|
|
17
|
-
host
|
|
18
|
-
port
|
|
19
|
-
password:
|
|
20
|
-
tls: { servername:
|
|
42
|
+
host,
|
|
43
|
+
port,
|
|
44
|
+
password: key,
|
|
45
|
+
tls: { servername: host },
|
|
21
46
|
maxRetriesPerRequest: 3,
|
|
22
47
|
enableReadyCheck: false,
|
|
23
48
|
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
49
|
+
}))()
|
|
50
|
+
.then((options) => {
|
|
51
|
+
redisOptionsCache = options;
|
|
52
|
+
return options;
|
|
53
|
+
})
|
|
54
|
+
.finally(() => {
|
|
55
|
+
redisOptionsPromise = null;
|
|
56
|
+
});
|
|
57
|
+
return redisOptionsPromise;
|
|
58
|
+
});
|
|
59
|
+
const getRedisClient = (ctx) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
28
60
|
if (redis)
|
|
29
61
|
return redis;
|
|
30
|
-
const options = buildRedisOptions();
|
|
62
|
+
const options = yield buildRedisOptions(ctx);
|
|
31
63
|
redis = new ioredis_1.default(options);
|
|
32
64
|
redis.on("error", (err) => { var _a; return (_a = ctx === null || ctx === void 0 ? void 0 : ctx.error) === null || _a === void 0 ? void 0 : _a.call(ctx, "Redis error", err); });
|
|
33
65
|
redis.on("connect", () => { var _a; return (_a = ctx === null || ctx === void 0 ? void 0 : ctx.info) === null || _a === void 0 ? void 0 : _a.call(ctx, "Redis connected"); });
|
|
34
66
|
return redis;
|
|
35
|
-
};
|
|
67
|
+
});
|
|
36
68
|
exports.getRedisClient = getRedisClient;
|
|
37
69
|
const buildKey = (namespace, parts) => [namespace, ...parts.map((part) => part !== null && part !== void 0 ? part : "_")].join(":");
|
|
38
70
|
const createCache = (namespace, ttlSeconds) => {
|
|
@@ -40,7 +72,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
40
72
|
key: (...parts) => buildKey(namespace, parts),
|
|
41
73
|
get: (ctx, ...parts) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
42
74
|
var _a;
|
|
43
|
-
const client = (0, exports.getRedisClient)(ctx);
|
|
75
|
+
const client = yield (0, exports.getRedisClient)(ctx);
|
|
44
76
|
try {
|
|
45
77
|
return yield client.get(buildKey(namespace, parts));
|
|
46
78
|
}
|
|
@@ -51,7 +83,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
51
83
|
}),
|
|
52
84
|
set: (ctx, value, ...parts) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
53
85
|
var _a;
|
|
54
|
-
const client = (0, exports.getRedisClient)(ctx);
|
|
86
|
+
const client = yield (0, exports.getRedisClient)(ctx);
|
|
55
87
|
try {
|
|
56
88
|
yield client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
57
89
|
}
|
|
@@ -62,7 +94,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
62
94
|
getOrSet: (ctx, parts, fetcher) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
63
95
|
const cached = yield (() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
64
96
|
var _a;
|
|
65
|
-
const client = (0, exports.getRedisClient)(ctx);
|
|
97
|
+
const client = yield (0, exports.getRedisClient)(ctx);
|
|
66
98
|
try {
|
|
67
99
|
return yield client.get(buildKey(namespace, parts));
|
|
68
100
|
}
|
|
@@ -76,7 +108,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
76
108
|
const value = yield fetcher();
|
|
77
109
|
yield (() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
78
110
|
var _a;
|
|
79
|
-
const client = (0, exports.getRedisClient)(ctx);
|
|
111
|
+
const client = yield (0, exports.getRedisClient)(ctx);
|
|
80
112
|
try {
|
|
81
113
|
yield client.set(buildKey(namespace, parts), value, "EX", ttlSeconds);
|
|
82
114
|
}
|
|
@@ -88,7 +120,7 @@ const createCache = (namespace, ttlSeconds) => {
|
|
|
88
120
|
}),
|
|
89
121
|
delete: (ctx, ...parts) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
90
122
|
var _a;
|
|
91
|
-
const client = (0, exports.getRedisClient)(ctx);
|
|
123
|
+
const client = yield (0, exports.getRedisClient)(ctx);
|
|
92
124
|
try {
|
|
93
125
|
yield client.del(buildKey(namespace, parts));
|
|
94
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/utils/cache.ts"],"names":[],"mappings":";;;;AAAA,8DAA8C;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/utils/cache.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED