New data structures for handling configuration load
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
"stores": [
|
||||
{
|
||||
"name": "kroger",
|
||||
"base_url": "https://shockrah.xyz",
|
||||
"roducts": []
|
||||
"base_url": "https://api-ce.kroger.com/v1/",
|
||||
"products": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fsPromises from 'fs/promises';
|
||||
import fsPromises from 'fs/promises'
|
||||
|
||||
interface Product {
|
||||
name: string,
|
||||
@@ -14,25 +14,59 @@ export interface Store {
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: ConentConfig defines what content we actually want; it has
|
||||
* almost nothing to do with key definitions and is meant to be fully public.
|
||||
*
|
||||
* Here we control what stores and what products we are going to query
|
||||
* from the configuration since the collector is basically just a oneshot
|
||||
* tool
|
||||
*/
|
||||
export interface Config {
|
||||
export interface ContentConfig {
|
||||
stores: Array<Store>
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up the API keys that we pull in from the environment
|
||||
* WARN: this should never mix wth the Config type to keep things
|
||||
* from leaking out into a plaintext file. Config's are considered to be
|
||||
* expendable and public facing and as such can be committed ( for my
|
||||
* purposes )
|
||||
*/
|
||||
export interface Keys {
|
||||
kroger_id: string|undefined
|
||||
kroger_secret: string|undefined
|
||||
}
|
||||
|
||||
/*
|
||||
* Environment variable names to look out for for key values
|
||||
*/
|
||||
export const EnvVars = {
|
||||
kroger_id: 'KROGER_CLIENT_ID',
|
||||
kroger_secret: 'KROGER_SECRET'
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the values from the env const
|
||||
*
|
||||
*/
|
||||
export function LoadKeys() : Keys {
|
||||
return {
|
||||
kroger_id: process.env.KROGER_CLIENT_ID,
|
||||
kroger_secret: process.env.KROGER_SECRET,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling the validation of our configuration
|
||||
*
|
||||
*/
|
||||
function valid(data: any) : data is Config {
|
||||
function valid(data: any) : data is ContentConfig {
|
||||
if('stores' in data) {
|
||||
if(!(data['stores'] instanceof Array)) {
|
||||
console.error('stores is not an array!')
|
||||
return false
|
||||
}
|
||||
for(const store in data['stores']) {
|
||||
for(const store of data['stores']) {
|
||||
// TODO: i don't like this check but it's fine for now :thinking:
|
||||
const keys = Object.keys(store);
|
||||
return keys.includes('name') && keys.includes('base_url') && keys.includes('products')
|
||||
@@ -46,13 +80,14 @@ function valid(data: any) : data is Config {
|
||||
* Handling the loading and generation of the Configuration that we'll use
|
||||
* during the run of data fetching.
|
||||
*/
|
||||
export async function LoadConfig(path: string) : Promise<Config|null> {
|
||||
export async function LoadConfig(path: string) : Promise<ContentConfig|null> {
|
||||
try {
|
||||
const file = await fsPromises.readFile(path);
|
||||
const config: Config = JSON.parse(file.toString())
|
||||
const config: ContentConfig = JSON.parse(file.toString())
|
||||
return valid(config) ? config : null;
|
||||
|
||||
} catch {
|
||||
// TODO: fix this catch block to be more explicit
|
||||
console.error('bro')
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
15
collector/scraper/src/data/error.ts
Normal file
15
collector/scraper/src/data/error.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export class EnvVarError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
this.name = 'EnvVarError'
|
||||
this.message = message
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfigurationError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
this.name = 'CollectorConfigurationError'
|
||||
this.message = message
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user