New data structures for handling configuration load
This commit is contained in:
@@ -2,8 +2,8 @@
|
|||||||
"stores": [
|
"stores": [
|
||||||
{
|
{
|
||||||
"name": "kroger",
|
"name": "kroger",
|
||||||
"base_url": "https://shockrah.xyz",
|
"base_url": "https://api-ce.kroger.com/v1/",
|
||||||
"roducts": []
|
"products": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import fsPromises from 'fs/promises';
|
import fsPromises from 'fs/promises'
|
||||||
|
|
||||||
interface Product {
|
interface Product {
|
||||||
name: string,
|
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
|
* Here we control what stores and what products we are going to query
|
||||||
* from the configuration since the collector is basically just a oneshot
|
* from the configuration since the collector is basically just a oneshot
|
||||||
* tool
|
* tool
|
||||||
*/
|
*/
|
||||||
export interface Config {
|
export interface ContentConfig {
|
||||||
stores: Array<Store>
|
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
|
* 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('stores' in data) {
|
||||||
if(!(data['stores'] instanceof Array)) {
|
if(!(data['stores'] instanceof Array)) {
|
||||||
console.error('stores is not an array!')
|
console.error('stores is not an array!')
|
||||||
return false
|
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:
|
// TODO: i don't like this check but it's fine for now :thinking:
|
||||||
const keys = Object.keys(store);
|
const keys = Object.keys(store);
|
||||||
return keys.includes('name') && keys.includes('base_url') && keys.includes('products')
|
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
|
* Handling the loading and generation of the Configuration that we'll use
|
||||||
* during the run of data fetching.
|
* 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 {
|
try {
|
||||||
const file = await fsPromises.readFile(path);
|
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;
|
return valid(config) ? config : null;
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
|
// TODO: fix this catch block to be more explicit
|
||||||
|
console.error('bro')
|
||||||
return null;
|
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