Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove env from paths #29

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/catalog/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
* governing permissions and limitations under the License.
*/

/* eslint-disable no-await-in-loop */

import { errorResponse } from '../utils/http.js';
import { fetchProduct } from '../utils/r2.js';

Expand Down
2 changes: 1 addition & 1 deletion src/catalog/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default async function catalogHandler(ctx, config, request) {
}

if (pathSegments.length < catalogIndex + 4) {
return errorResponse(400, 'Invalid URL structure: Expected format: /{org}/{site}/{env}/catalog/{store}/{storeView}/product/{sku}');
return errorResponse(400, 'Invalid URL structure: Expected format: /{org}/{site}/catalog/{store}/{storeView}/product/{sku}');
}

const [storeCode, storeViewCode, subRoute, sku] = pathSegments.slice(catalogIndex + 1);
Expand Down
2 changes: 1 addition & 1 deletion src/catalog/lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export async function handleProductLookupRequest(ctx, config) {
return new Response(undefined, {
status: 301,
headers: {
Location: `${ctx.url.origin}/${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/product/${sku}`,
Location: `${ctx.url.origin}/${config.org}/${config.site}/catalog/${config.storeCode}/${config.storeViewCode}/product/${sku}`,
},
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/catalog/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export async function handleProductSaveRequest(ctx, config, request) {
}
}

const { base: _ = undefined, ...otherPatterns } = config.confEnvMap[config.env] ?? {};
const { base: _ = undefined, ...otherPatterns } = config.confMap;
const matchedPathPatterns = Object.entries(otherPatterns)
.reduce((acc, [pattern, matchConf]) => {
// find only configs that match the provided store & view codes
Expand Down
23 changes: 5 additions & 18 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,40 +48,28 @@ function extractPathParams(pattern, path) {
* @returns {Promise<Config|null>} - A promise that resolves to the configuration.
*/
export async function resolveConfig(ctx, overrides = {}) {
const [_, org, site, env, route] = ctx.url.pathname.split('/');
const [_, org, site, route] = ctx.url.pathname.split('/');
if (!org) {
throw errorWithResponse(404, 'missing org');
}
if (!site) {
throw errorWithResponse(404, 'missing site');
}
if (!env) {
throw errorWithResponse(404, 'missing env');
}
if (!route) {
throw errorWithResponse(404, 'missing route');
}

const siteKey = `${org}--${site}`;

/**
* @type {ConfigEnvMap}
* @type {ConfigMap}
*/
const confEnvMap = await ctx.env.CONFIGS.get(siteKey, 'json');
if (!confEnvMap) {
return null;
}
if (typeof confEnvMap !== 'object') {
ctx.log.warn('invalid config for ', siteKey);
return null;
}

const confMap = confEnvMap[env];
const confMap = await ctx.env.CONFIGS.get(siteKey, 'json');
if (!confMap) {
return null;
}
if (typeof confMap !== 'object') {
ctx.log.warn('invalid config for ', siteKey, env);
ctx.log.warn('invalid config for ', siteKey);
return null;
}

Expand Down Expand Up @@ -112,10 +100,9 @@ export async function resolveConfig(ctx, overrides = {}) {
headers: confMap.base?.headers ?? {},
params: {},
}),
confEnvMap,
confMap,
org,
site,
env,
route,
...overrides,
};
Expand Down
8 changes: 1 addition & 7 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ declare global {
*/
export type ConfigMap = Record<string, Config>;

/**
* { env => { pathPattern => Config } }
*/
export type ConfigEnvMap = Record<string, ConfigMap>;

/**
* Resolved config object
*/
Expand All @@ -23,14 +18,13 @@ declare global {
apiKey: string;
magentoEnvironmentId: string;
magentoWebsiteCode: string;
env: string;
storeViewCode: string;
storeCode: string;
coreEndpoint: string;
catalogSource: string
catalogEndpoint?: string;
sku?: string;
confEnvMap: ConfigEnvMap;
confMap: ConfigMap;
params: Record<string, string>;
headers: Record<string, string>;
}
Expand Down
12 changes: 6 additions & 6 deletions src/utils/r2.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { errorWithResponse } from './http.js';
*/
export async function fetchProduct(ctx, config, sku) {
const { log } = ctx;
const key = `${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/products/${sku}.json`;
const key = `${config.org}/${config.site}/${config.storeCode}/${config.storeViewCode}/products/${sku}.json`;
log.debug('Fetching product from R2:', key);
const object = await ctx.env.CATALOG_BUCKET.get(key);

Expand Down Expand Up @@ -55,7 +55,7 @@ export async function saveProducts(ctx, config, products) {
try {
const { name, urlKey } = product;
const { sku } = config;
const key = `${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/products/${sku}.json`;
const key = `${config.org}/${config.site}/${config.storeCode}/${config.storeViewCode}/products/${sku}.json`;
const body = JSON.stringify(product);
const customMetadata = { sku, name, urlKey };

Expand All @@ -65,7 +65,7 @@ export async function saveProducts(ctx, config, products) {
});

if (urlKey) {
const metadataKey = `${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/urlkeys/${urlKey}`;
const metadataKey = `${config.org}/${config.site}/${config.storeCode}/${config.storeViewCode}/urlkeys/${urlKey}`;
const metadataPromise = ctx.env.CATALOG_BUCKET.put(metadataKey, '', {
httpMetadata: { contentType: 'application/octet-stream' },
customMetadata,
Expand Down Expand Up @@ -98,7 +98,7 @@ export async function saveProducts(ctx, config, products) {
*/
export async function lookupSku(ctx, config, urlKey) {
// Make a HEAD request to retrieve the SKU from metadata based on the URL key
const urlKeyPath = `${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/urlkeys/${urlKey}`;
const urlKeyPath = `${config.org}/${config.site}/${config.storeCode}/${config.storeViewCode}/urlkeys/${urlKey}`;
const headResponse = await ctx.env.CATALOG_BUCKET.head(urlKeyPath);

if (!headResponse || !headResponse.customMetadata?.sku) {
Expand All @@ -118,7 +118,7 @@ export async function lookupSku(ctx, config, urlKey) {
export async function listAllProducts(ctx, config) {
const bucket = ctx.env.CATALOG_BUCKET;

const listResponse = await bucket.list({ prefix: `${config.org}/${config.site}/${config.env}/${config.storeCode}/${config.storeViewCode}/products/` });
const listResponse = await bucket.list({ prefix: `${config.org}/${config.site}/${config.storeCode}/${config.storeViewCode}/products/` });
const files = listResponse.objects;

const batchSize = 50; // Define the batch size
Expand Down Expand Up @@ -152,7 +152,7 @@ export async function listAllProducts(ctx, config) {
return {
...customMetadata,
links: {
product: `${ctx.url.origin}/${config.org}/${config.site}/${config.env}/catalog/${config.storeCode}/${config.storeViewCode}/product/${sku}`,
product: `${ctx.url.origin}/${config.org}/${config.site}/catalog/${config.storeCode}/${config.storeViewCode}/product/${sku}`,
},
};
} else {
Expand Down
12 changes: 6 additions & 6 deletions test/catalog/handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('catalogHandler Tests', () => {
it('should return 400 when URL structure is incorrect', async () => {
const ctx = {
info: { method: 'GET' },
url: { pathname: '/org/site/env/catalog/store/view' },
url: { pathname: '/org/site/catalog/store/view' },
};
const config = {};
const request = {};
Expand All @@ -87,13 +87,13 @@ describe('catalogHandler Tests', () => {
const response = await catalogHandler(ctx, config, request);

assert.equal(response.status, 400);
assert(errorResponseStub.calledWith(400, 'Invalid URL structure: Expected format: /{org}/{site}/{env}/catalog/{store}/{storeView}/product/{sku}'));
assert(errorResponseStub.calledWith(400, 'Invalid URL structure: Expected format: /{org}/{site}/catalog/{store}/{storeView}/product/{sku}'));
});

it('should call handleProductLookupRequest when method is GET and subRoute is "lookup"', async () => {
const ctx = {
info: { method: 'GET' },
url: { pathname: '/org/site/env/catalog/store/view/lookup/sku' },
url: { pathname: '/org/site/catalog/store/view/lookup/sku' },
};
const config = {};
const request = {};
Expand All @@ -110,7 +110,7 @@ describe('catalogHandler Tests', () => {
it('should return 405 if subRoute is "lookup" but method is not GET', async () => {
const ctx = {
info: { method: 'PUT' },
url: { pathname: '/org/site/env/catalog/store/view/lookup/sku' },
url: { pathname: '/org/site/catalog/store/view/lookup/sku' },
};
const config = {};
const request = {};
Expand All @@ -127,7 +127,7 @@ describe('catalogHandler Tests', () => {
it('should call handleProductSaveRequest when method is PUT and subRoute is not "lookup"', async () => {
const ctx = {
info: { method: 'PUT' },
url: { pathname: '/org/site/stage/catalog/store/view/product/sku' },
url: { pathname: '/org/site/catalog/store/view/product/sku' },
};
const config = {};
const request = {};
Expand All @@ -144,7 +144,7 @@ describe('catalogHandler Tests', () => {
it('should call handleProductFetchRequest when method is GET and subRoute is not "lookup"', async () => {
const ctx = {
info: { method: 'GET' },
url: { pathname: '/org/site/stage/catalog/store/view/product/sku' },
url: { pathname: '/org/site/catalog/store/view/product/sku' },
};
const config = {};
const request = {};
Expand Down
3 changes: 1 addition & 2 deletions test/catalog/lookup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ describe('handleProductLookupRequest Tests', () => {
const config = {
org: 'test-org',
site: 'test-site',
env: 'test-env',
storeCode: 'test-store-code',
storeViewCode: 'test-store-view-code',
};
Expand All @@ -60,7 +59,7 @@ describe('handleProductLookupRequest Tests', () => {

const response = await handleProductLookupRequest(ctx, config);

assert.equal(response.headers.get('Location'), 'https://test-origin/test-org/test-site/test-env/test-store-code/test-store-view-code/product/1234');
assert.equal(response.headers.get('Location'), 'https://test-origin/test-org/test-site/catalog/test-store-code/test-store-view-code/product/1234');
assert.equal(response.status, 301);

assert(lookupSkuStub.calledOnceWith(ctx, config, 'some-url-key'));
Expand Down
24 changes: 7 additions & 17 deletions test/catalog/update.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,10 @@ describe('Product Save Tests', () => {
it('should return 201 when product is successfully saved and paths are purged', async () => {
const config = {
sku: '1234',
confEnvMap: {
test: {
'/path/to/{{sku}}': { env: 'test' },
'/path/to/{{urlkey}}/{{sku}}': { env: 'test' },
},
confMap: {
'/path/to/{{sku}}': {},
'/path/to/{{urlkey}}/{{sku}}': {},
},
env: 'test',
};
const ctx = { log: { error: sinon.stub() } };
const request = { json: sinon.stub().resolves({ sku: '1234', urlKey: 'product-url-key' }) };
Expand All @@ -99,13 +96,9 @@ describe('Product Save Tests', () => {
it('should return 404 when no matching path patterns found', async () => {
const config = {
sku: '1234',
confEnvMap: {
prod: {
base: { },
'/path/to/{{sku}}': { env: 'other-env' },
},
confMap: {
base: {},
},
env: 'dev',
};
const ctx = { log: { error: sinon.stub() } };
const request = { json: sinon.stub().resolves({ sku: '1234' }) };
Expand All @@ -121,12 +114,9 @@ describe('Product Save Tests', () => {
it('should return error when purging fails', async () => {
const config = {
sku: '1234',
confEnvMap: {
test: {
'/path/to/{{sku}}': { env: 'test' },
},
confMap: {
'/path/to/{{sku}}': {},
},
env: 'test',
};
const ctx = { log: console };
const request = { json: sinon.stub().resolves({ sku: '1234', urlKey: 'product-url-key' }) };
Expand Down
Loading