Skip to content

Commit 87e50d2

Browse files
authored
Merge pull request #8 from adobe-rnd/kv-confis
feat: use kv storage for configs
2 parents 07b9947 + 1acf8a0 commit 87e50d2

File tree

5 files changed

+42
-38
lines changed

5 files changed

+42
-38
lines changed

src/config.js

+7-26
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,6 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
/**
14-
* @type {Record<string, Record<string, Config>>}
15-
*/
16-
const TENANT_CONFIGS = {
17-
visualcomfort: {
18-
base: {
19-
apiKey: '59878b5d8af24fe9a354f523f5a0bb62',
20-
magentoEnvironmentId: '97034e45-43a5-48ab-91ab-c9b5a98623a8',
21-
magentoWebsiteCode: 'base',
22-
magentoStoreViewCode: 'default',
23-
coreEndpoint: 'https://www.visualcomfort.com/graphql',
24-
},
25-
'/us/p/{{urlkey}}/{{sku}}': {
26-
pageType: 'product',
27-
apiKey: '59878b5d8af24fe9a354f523f5a0bb62',
28-
magentoEnvironmentId: '97034e45-43a5-48ab-91ab-c9b5a98623a8',
29-
magentoWebsiteCode: 'base',
30-
magentoStoreViewCode: 'default',
31-
coreEndpoint: 'https://www.visualcomfort.com/graphql',
32-
},
33-
},
34-
};
35-
3613
/**
3714
* @param {string[]} patterns
3815
* @param {string} path
@@ -59,13 +36,17 @@ function extractPathParams(pattern, path) {
5936
* @param {Context} ctx
6037
* @param {string} tenant
6138
* @param {Partial<Config>} [overrides={}]
62-
* @returns {Config|null}
39+
* @returns {Promise<Config|null>}
6340
*/
64-
export function resolveConfig(ctx, tenant, overrides, configs = TENANT_CONFIGS) {
65-
const confMap = configs[tenant];
41+
export async function resolveConfig(ctx, tenant, overrides = {}) {
42+
const confMap = await ctx.env.CONFIGS.get(tenant, 'json');
6643
if (!confMap) {
6744
return null;
6845
}
46+
if (typeof confMap !== 'object') {
47+
ctx.log.warn('invalid config for tenant', tenant);
48+
return null;
49+
}
6950

7051
// order paths by preference
7152
const suffix = `/${ctx.url.pathname.split('/').slice(3).join('/')}`;

src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export default {
147147
}
148148

149149
const overrides = Object.fromEntries(ctx.url.searchParams.entries());
150-
const config = resolveConfig(ctx, tenant, overrides);
150+
const config = await resolveConfig(ctx, tenant, overrides);
151151
if (!config) {
152152
return errorResponse(404, 'config not found');
153153
}

src/types.d.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ExecutionContext } from "@cloudflare/workers-types/experimental";
1+
import type { ExecutionContext, KVNamespace } from "@cloudflare/workers-types/experimental";
22

33
declare global {
44
export interface Config {
@@ -14,12 +14,16 @@ declare global {
1414
export interface Env {
1515
VERSION: string;
1616
ENVIRONMENT: string;
17-
[key: string]: string;
17+
18+
// KV namespaces
19+
CONFIGS: KVNamespace<string>;
20+
21+
[key: string]: string | KVNamespace<string>;
1822
}
1923

2024
export interface Context extends ExecutionContext {
2125
url: URL;
22-
env: Record<string, string>;
26+
env: Env;
2327
log: Console;
2428
info: {
2529
method: string;

test/config.test.js

+23-8
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ import { resolveConfig } from '../src/config.js';
1515

1616
/**
1717
* @param {string} path
18+
* @param {Record<string, Config>} configMap
1819
* @returns {Context}
1920
*/
20-
const TEST_CONTEXT = (path) => ({
21-
env: {},
21+
const TEST_CONTEXT = (path, configMap) => ({
22+
env: {
23+
CONFIGS: {
24+
get: async (tenant) => configMap[tenant],
25+
},
26+
},
2227
log: console,
2328
url: new URL(`https://www.example.com/tenant/content${path}`),
2429
info: {
@@ -28,7 +33,7 @@ const TEST_CONTEXT = (path) => ({
2833
});
2934

3035
describe('config tests', () => {
31-
it('should extract path params', () => {
36+
it('should extract path params', async () => {
3237
const tenantConfigs = {
3338
'test-tenant': {
3439
base: {
@@ -40,15 +45,18 @@ describe('config tests', () => {
4045
},
4146
},
4247
};
43-
const config = resolveConfig(TEST_CONTEXT('/us/p/my-url-key/some-sku'), 'test-tenant', undefined, tenantConfigs);
48+
const config = await resolveConfig(
49+
TEST_CONTEXT('/us/p/my-url-key/some-sku', tenantConfigs),
50+
'test-tenant',
51+
);
4452
assert.deepStrictEqual(config, {
4553
apiKey: 'good',
4654
params: { urlkey: 'my-url-key', sku: 'some-sku' },
4755
pageType: 'product',
4856
});
4957
});
5058

51-
it('should allow wildcard path segments', () => {
59+
it('should allow wildcard path segments', async () => {
5260
const tenantConfigs = {
5361
'test-tenant': {
5462
base: {
@@ -60,15 +68,18 @@ describe('config tests', () => {
6068
},
6169
},
6270
};
63-
const config = resolveConfig(TEST_CONTEXT('/us/p/something-here/some-sku'), 'test-tenant', undefined, tenantConfigs);
71+
const config = await resolveConfig(
72+
TEST_CONTEXT('/us/p/something-here/some-sku', tenantConfigs),
73+
'test-tenant',
74+
);
6475
assert.deepStrictEqual(config, {
6576
apiKey: 'good',
6677
params: { sku: 'some-sku' },
6778
pageType: 'product',
6879
});
6980
});
7081

71-
it('should allow overrides', () => {
82+
it('should allow overrides', async () => {
7283
const tenantConfigs = {
7384
'test-tenant': {
7485
base: {
@@ -80,7 +91,11 @@ describe('config tests', () => {
8091
},
8192
},
8293
};
83-
const config = resolveConfig(TEST_CONTEXT('/us/p/some-sku'), 'test-tenant', { apiKey: 'good' }, tenantConfigs);
94+
const config = await resolveConfig(
95+
TEST_CONTEXT('/us/p/some-sku', tenantConfigs),
96+
'test-tenant',
97+
{ apiKey: 'good' },
98+
);
8499
assert.deepStrictEqual(config, {
85100
apiKey: 'good',
86101
params: { sku: 'some-sku' },

wrangler.toml

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ send_metrics = false
77

88
build = { command = "npm install && node build.js" }
99

10+
kv_namespaces = [
11+
{ binding = "CONFIGS", id = "bb91e12a65a8462282396f32e63406f1", preview_id = "bb91e12a65a8462282396f32e63406f1" }
12+
]
13+
1014
[vars]
1115
VERSION = "@@VERSION@@-dev"
1216
ENVIRONMENT = "dev"

0 commit comments

Comments
 (0)