Skip to content

Commit

Permalink
feat: serve /config.json (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
tripodsan authored Apr 18, 2024
1 parent f6b4aa2 commit f01f9ce
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 18 deletions.
42 changes: 28 additions & 14 deletions src/json-pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ async function fetchJsonContent(state, req, res) {
owner, repo, ref, contentBusId, partition, s3Loader, log, info,
} = state;
const { path } = state.info;
state.content.sourceBus = 'content';
let ret = await s3Loader.getObject('helix-content-bus', `${contentBusId}/${partition}${path}`);

// if not found, fall back to code bus
if (ret.status === 404) {
state.content.sourceBus = 'code';
ret = await s3Loader.getObject('helix-code-bus', `${owner}/${repo}/${ref}${path}`);
}

Expand All @@ -76,15 +78,23 @@ async function fetchJsonContent(state, req, res) {

updateLastModified(state, res, extractLastModified(ret.headers));
} else {
state.content.sourceBus = 'content';
res.status = ret.status === 404 ? 404 : 502;
res.error = `failed to load ${state.info.resourcePath}: ${ret.status}`;
}
}

async function computeSurrogateKeys(path, contentBusId) {
async function computeSurrogateKeys(state) {
const keys = [];
keys.push(`${contentBusId}${path}`.replace(/\//g, '_')); // TODO: remove
keys.push(await computeSurrogateKey(`${contentBusId}${path}`));
const pathKey = state.content?.sourceBus === 'code'
? `${state.ref}--${state.repo}--${state.owner}${state.info.path}`
: `${state.contentBusId}${state.info.path}`;

if (state.info.path === '/config.json') {
keys.push(await computeSurrogateKey(`${state.site}--${state.org}_config.json`));
}
keys.push(pathKey.replace(/\//g, '_')); // TODO: remove
keys.push(await computeSurrogateKey(pathKey));
return keys;
}

Expand Down Expand Up @@ -142,23 +152,27 @@ export async function jsonPipe(state, req) {

await authenticate(state, req, res);

if (res.error) {
if (res.status === 404 && state.info.path === '/config.json' && state.config.public) {
// special handling for public config
res.status = 200;
res.body = JSON.stringify(state.config.public, null, 2);
} else if (res.error) {
if (res.status < 400) {
return res;
}
throw new PipelineStatusError(res.status, res.error);
} else {
// filter data
jsonFilter(state, res, {
limit: limit ? Number.parseInt(limit, 10) : undefined,
offset: offset ? Number.parseInt(offset, 10) : undefined,
sheet,
raw: limit === undefined && offset === undefined && sheet === undefined,
});
}

// filter data
jsonFilter(state, res, {
limit: limit ? Number.parseInt(limit, 10) : undefined,
offset: offset ? Number.parseInt(offset, 10) : undefined,
sheet,
raw: limit === undefined && offset === undefined && sheet === undefined,
});

// set surrogate keys
const keys = await computeSurrogateKeys(state.info.path, state.contentBusId);
const keys = await computeSurrogateKeys(state);
res.headers.set('x-surrogate-key', keys.join(' '));

await setCustomResponseHeaders(state, req, res);
Expand All @@ -175,7 +189,7 @@ export async function jsonPipe(state, req) {
await setCustomResponseHeaders(state, req, res);
}
if (res.status === 404) {
const keys = await computeSurrogateKeys(state.info.path, state.contentBusId);
const keys = await computeSurrogateKeys(state);
res.headers.set('x-surrogate-key', keys.join(' '));
}
return res;
Expand Down
43 changes: 39 additions & 4 deletions test/json-pipe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ describe('JSON Pipe Test', () => {
);
});

function createDefaultState(config = DEFAULT_CONFIG) {
function createDefaultState(config = DEFAULT_CONFIG, path = '/en/index.json') {
return new PipelineState({
path: '/en/index.json',
path,
org: 'org',
site: 'site',
ref: 'ref',
Expand Down Expand Up @@ -163,6 +163,41 @@ describe('JSON Pipe Test', () => {
});
});

it('sends 404 for missing /config.json', async () => {
const state = createDefaultState(DEFAULT_CONFIG, '/config.json');
const resp = await jsonPipe(state, new PipelineRequest('https://json-filter.com/?limit=10&offset=5'));
assert.strictEqual(resp.status, 404);
assert.deepStrictEqual(Object.fromEntries(resp.headers.entries()), {
'x-error': 'failed to load /config.json: 404',
'x-surrogate-key': 'U_NW4adJU7Qazf-I foobar_config.json kz8SoCaNqfp4ohQo',
});
});

it('sends public config for /config.json', async () => {
const config = {
...DEFAULT_CONFIG,
public: {
test: 'property',
colors: ['a', 'b', 'c'],
},
};
const state = createDefaultState(config, '/config.json');
const resp = await jsonPipe(state, new PipelineRequest('https://json-filter.com/?limit=10&offset=5'));
assert.strictEqual(resp.status, 200);
assert.deepStrictEqual(Object.fromEntries(resp.headers.entries()), {
'content-type': 'application/json',
'x-surrogate-key': 'U_NW4adJU7Qazf-I foobar_config.json kz8SoCaNqfp4ohQo',
});
assert.deepStrictEqual(await resp.json(), {
colors: [
'a',
'b',
'c',
],
test: 'property',
});
});

it('fetches correct content with folder mapping', async () => {
const state = createDefaultState(CONFIG_WITH_FOLDER);
state.info = getPathInfo('/super/mapped/index.json');
Expand Down Expand Up @@ -343,7 +378,7 @@ describe('JSON Pipe Test', () => {
assert.deepStrictEqual(Object.fromEntries(resp.headers.entries()), {
'content-type': 'application/json',
'last-modified': 'Wed, 12 Oct 2009 17:50:00 GMT',
'x-surrogate-key': 'foobar_en_index.json Atrz_qDg26DmSe9a',
'x-surrogate-key': 'ref--repo--owner_en_index.json SIMSxecp2CJXqGYs',
});
});

Expand Down Expand Up @@ -378,7 +413,7 @@ describe('JSON Pipe Test', () => {
assert.deepStrictEqual(Object.fromEntries(resp.headers.entries()), {
'content-type': 'application/json',
'last-modified': 'Wed, 12 Oct 2009 17:50:00 GMT',
'x-surrogate-key': 'foobar_en_index.json Atrz_qDg26DmSe9a',
'x-surrogate-key': 'ref--repo--owner_en_index.json SIMSxecp2CJXqGYs',
});
});

Expand Down

0 comments on commit f01f9ce

Please sign in to comment.