feat: git hook (#95)

This commit is contained in:
hiroki osame
2023-02-21 08:08:44 -05:00
committed by GitHub
parent 0d3f35c135
commit 0b80a0031e
7 changed files with 191 additions and 32 deletions

View File

@@ -2,32 +2,45 @@ import fs from 'fs/promises';
import path from 'path';
import os from 'os';
import ini from 'ini';
import { fileExists } from './fs.js';
const keyValidators = {
const parseAssert = (
name: string,
condition: any,
message: string,
) => {
if (!condition) {
throw new Error(`Invalid config property ${name}: ${message}`);
}
};
const configParsers = {
OPENAI_KEY(key: string) {
if (!key) {
return 'Cannot be empty';
}
parseAssert('OPENAI_KEY', key, 'Cannot be empty');
parseAssert('OPENAI_KEY', key.startsWith('sk-'), 'Must start with "sk-"');
parseAssert('OPENAI_KEY', key.length === 51, 'Must be 51 characters long');
if (!key.startsWith('sk-')) {
return 'Must start with "sk-"';
}
return key;
},
generate(key: string) {
parseAssert('generate', key, 'Cannot be empty');
parseAssert('generate', /^\d+$/.test(key), 'Must be an integer');
if (key.length !== 51) {
return 'Must be 51 characters long';
}
const parsed = Number(key);
parseAssert('generate', parsed > 0, 'Must be greater than 0');
parseAssert('generate', parsed <= 5, 'Must be less or equal to 5');
return parsed;
},
} as const;
type ValidKeys = keyof typeof keyValidators;
type ValidKeys = keyof typeof configParsers;
type ConfigType = {
[key in ValidKeys]?: string;
[key in ValidKeys]?: ReturnType<typeof configParsers[key]>;
};
const configPath = path.join(os.homedir(), '.aicommits');
const fileExists = (filePath: string) => fs.access(filePath).then(() => true, () => false);
export const getConfig = async (): Promise<ConfigType> => {
const configExists = await fileExists(configPath);
if (!configExists) {
@@ -35,7 +48,13 @@ export const getConfig = async (): Promise<ConfigType> => {
}
const configString = await fs.readFile(configPath, 'utf8');
return ini.parse(configString);
const config = ini.parse(configString);
for (const key of Object.keys(config)) {
const parsed = configParsers[key as ValidKeys](config[key]);
config[key as ValidKeys] = parsed;
}
return config;
};
const { hasOwnProperty } = Object.prototype;
@@ -47,16 +66,12 @@ export const setConfigs = async (
const config = await getConfig();
for (const [key, value] of keyValues) {
if (!hasOwn(keyValidators, key)) {
if (!hasOwn(configParsers, key)) {
throw new Error(`Invalid config property: ${key}`);
}
const isInvalid = keyValidators[key as ValidKeys](value);
if (isInvalid) {
throw new Error(`Invalid value for ${key}: ${isInvalid}`);
}
config[key as ValidKeys] = value;
const parsed = configParsers[key as ValidKeys](value);
config[key as ValidKeys] = parsed as any;
}
await fs.writeFile(configPath, ini.stringify(config), 'utf8');