Skip to content

Commit

Permalink
Added command to generate or print sample config file
Browse files Browse the repository at this point in the history
  • Loading branch information
oskardudycz committed Sep 12, 2024
1 parent b42076b commit 1440797
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 14 deletions.
4 changes: 3 additions & 1 deletion src/packages/pongo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"test:int:watch": "glob -c \"node --import tsx --test --watch\" **/*.int.spec.ts",
"test:e2e:watch": "glob -c \"node --import tsx --test --watch\" **/*.e2e.spec.ts",
"cli:sql:print": "tsx src/cli.ts migrate sql --collection users",
"cli:migrate:dryRun": "tsx src/cli.ts migrate run --config src/e2e/cli-config.ts -cs postgresql://postgres:postgres@localhost:5432/postgres "
"cli:migrate:dryRun": "tsx src/cli.ts migrate run --config src/e2e/cli-config.ts -cs postgresql://postgres:postgres@localhost:5432/postgres",
"cli:config:print": "tsx src/cli.ts config sample --print",
"cli:config:generate": "tsx src/cli.ts config sample --generate --file ./pongoConfig.ts "
},
"repository": {
"type": "git",
Expand Down
3 changes: 2 additions & 1 deletion src/packages/pongo/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#!/usr/bin/env node
import { Command } from 'commander';
import { migrateCommand } from './commandLine';
import { configCommand, migrateCommand } from './commandLine';

const program = new Command();

program.name('pongo').description('CLI tool for Pongo');

program.addCommand(configCommand);
program.addCommand(migrateCommand);

program.parse(process.argv);
Expand Down
Empty file.
122 changes: 114 additions & 8 deletions src/packages/pongo/src/commandLine/configFile.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
import { Command } from 'commander';
import fs from 'node:fs';
import { objectEntries, type PongoSchemaConfig } from '../core';
import {
toDbSchemaMetadata,
type PongoDbSchemaMetadata,
} from '../core/typing/schema';

const sampleConfig = `import { pongoSchema } from '@event-driven-io/pongo';
const formatTypeName = (input: string): string => {
if (input.length === 0) {
return input;
}

let formatted = input.charAt(0).toUpperCase() + input.slice(1);

if (formatted.endsWith('s')) {
formatted = formatted.slice(0, -1);
}

return formatted;
};

type User = { name: string };
const sampleConfig = (collectionNames: string[] = ['users']) => {
const types = collectionNames
.map(
(name) =>
`type ${formatTypeName(name)} = { name: string, description: string, date: Date }`,
)
.join('\n');

const collections = collectionNames
.map(
(name) =>
` ${name}: pongoSchema.collection<${formatTypeName(name)}>('${name}'),`,
)
.join('\n');

return `import { pongoSchema } from '@event-driven-io/pongo';
${types}
export default {
schema: pongoSchema.client({
database: pongoSchema.db({
users: pongoSchema.collection<User>('users'),
${collections}
}),
}),
};`;
};

const missingDefaultExport = `Error: Config should contain default export, e.g.\n\n${sampleConfig}`;
const missingSchema = `Error: Config should contain schema property, e.g.\n\n${sampleConfig}`;
const missingDbs = `Error: Config should have at least a single database defined, e.g.\n\n${sampleConfig}`;
const missingDefaultDb = `Error: Config should have a default database defined (without name or or with default database name), e.g.\n\n${sampleConfig}`;
const missingCollections = `Error: Database should have defined at least one collection, e.g.\n\n${sampleConfig}`;
const missingDefaultExport = `Error: Config should contain default export, e.g.\n\n${sampleConfig()}`;
const missingSchema = `Error: Config should contain schema property, e.g.\n\n${sampleConfig()}`;
const missingDbs = `Error: Config should have at least a single database defined, e.g.\n\n${sampleConfig()}`;
const missingDefaultDb = `Error: Config should have a default database defined (without name or or with default database name), e.g.\n\n${sampleConfig()}`;
const missingCollections = `Error: Database should have defined at least one collection, e.g.\n\n${sampleConfig()}`;

export const loadConfigFile = async (
configPath: string,
Expand All @@ -46,6 +78,20 @@ export const loadConfigFile = async (
}
};

export const generateConfigFile = (
configPath: string,
collectionNames: string[],
): void => {
try {
fs.writeFileSync(configPath, sampleConfig(collectionNames), 'utf8');
console.log(`Configuration file stored at: ${configPath}`);
} catch (error) {
console.error(`Error: Couldn't store config file: ${configPath}!`);
console.error(error);
process.exit(1);
}
};

export const parseDefaultDbSchema = (
imported: Partial<{ default: PongoSchemaConfig }>,
): PongoDbSchemaMetadata | string => {
Expand Down Expand Up @@ -81,3 +127,63 @@ export const parseDefaultDbSchema = (

return toDbSchemaMetadata(defaultDb);
};

type SampleConfigOptions =
| {
collection: string[];
print?: boolean;
}
| {
collection: string[];
generate?: boolean;
file?: string;
};

export const configCommand = new Command('config').description(
'Manage Pongo configuration',
);

const sampleConfigCommand = configCommand
.command('sample')
.description('Generate or print sample configuration')
.option(
'-col, --collection <name>',
'Specify the collection name',
(value: string, previous: string[]) => {
// Accumulate collection names into an array (explicitly typing `previous` as `string[]`)
return previous.concat([value]);
},
[] as string[],
)
.option(
'-f, --file <path>',
'Path to configuration file with collection list',
)
.option('-g, --generate', 'Generate sample config file')
.option('-p, --print', 'Print sample config file')
.action((options: SampleConfigOptions) => {
const collectionNames =
options.collection.length > 0 ? options.collection : ['users'];

if (!('print' in options) && !('generate' in options)) {
console.error(
'Error: Please provide either:\n--print param to print sample config or\n--generate to generate sample config file',
);
process.exit(1);
}

if ('print' in options) {
console.log(`${sampleConfig(collectionNames)}`);
} else if ('generate' in options) {
if (!options.file) {
console.error(
'Error: You need to provide a config file through a --file',
);
process.exit(1);
}

generateConfigFile(options.file, collectionNames);
}
});

sampleConfigCommand.command('generate');
5 changes: 1 addition & 4 deletions src/packages/pongo/src/commandLine/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ migrateCommand
},
[] as string[],
)
.option(
'-f, --config <path>',
'Path to configuration file with collection list',
)
.option('-f, --config <path>', 'Path to configuration file with Pongo config')
.option('-dr, --dryRun', 'Perform dry run without commiting changes', false)
.action(async (options: MigrateRunOptions) => {
const { collection, dryRun } = options;
Expand Down

0 comments on commit 1440797

Please sign in to comment.