This repository has been archived by the owner on Mar 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): create command to generate CSV with course participants (#399
- Loading branch information
1 parent
9e1015a
commit b888236
Showing
14 changed files
with
273 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { isInt, isPositive } from 'class-validator'; | ||
import { Argument, Command } from 'commander'; | ||
|
||
import { parseToCsv } from '../shared/csv'; | ||
import { getUsersByRole } from '../shared/db'; | ||
import { createWelcomeCsv } from '../shared/files'; | ||
import { createLogger } from '../shared/logger'; | ||
import { userRoles, WelcomeCsvRow } from '../shared/models'; | ||
import { transformAndValidate } from '../shared/object'; | ||
|
||
const logger = createLogger('generate-welcome-csv'); | ||
|
||
export const generateWelcomeCsv = (program: Command) => { | ||
program | ||
.command('generate-welcome-csv') | ||
.description('Generates CSV file with names, emails and checklist URLs for all participants in the database') | ||
.addArgument(new Argument('<from-id>', 'Path to the CSV file')) | ||
.action(async (fromId?: string) => { | ||
const startFromId = Number(fromId); | ||
|
||
try { | ||
if (fromId && !(isPositive(startFromId) && isInt(startFromId))) { | ||
throw new Error('fromId parameter must be a positive integer'); | ||
} | ||
|
||
let participants = await getUsersByRole(userRoles.participant); | ||
|
||
if (startFromId) { | ||
participants = participants.filter((p) => p.id >= startFromId); | ||
} | ||
|
||
const welcomeCsvRows = await Promise.all(participants.map(transformAndValidate(WelcomeCsvRow))); | ||
|
||
logger.debug('Parsing welcome CSV objects to CSV format', welcomeCsvRows); | ||
|
||
const csv = parseToCsv(welcomeCsvRows); | ||
|
||
logger.debug('Creating welcome CSVfile', csv); | ||
|
||
await createWelcomeCsv(csv); | ||
} catch (ex) { | ||
logger.error(ex); | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export const asyncFilter = async <Item>( | ||
arr: Item[], | ||
predicate: (item: Item, index: number, arr: Item[]) => Promise<boolean>, | ||
) => { | ||
const results = await Promise.all(arr.map(predicate)); | ||
|
||
return arr.filter((_value, i) => results[i]); | ||
}; | ||
|
||
export const removeDuplicatesForProperty = <Item>(arr: Item[], property: keyof Item) => | ||
arr.filter((value, i, array) => array.findIndex((t) => t[property] === value[property]) === i); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { existsSync } from 'fs'; | ||
import { mkdir, writeFile } from 'fs/promises'; | ||
|
||
import { createLogger } from './logger'; | ||
|
||
const logger = createLogger('Files Utils'); | ||
|
||
const createOutputDir = async () => { | ||
if (!existsSync('output')) { | ||
await mkdir('output'); | ||
} | ||
}; | ||
|
||
export const createPasswordsList = () => { | ||
const passwords: Record<string, string> = {}; | ||
|
||
const add = ({ email, password }: { email: string; password: string }) => { | ||
logger.debug(`Adding password for email ${email}`); | ||
passwords[email] = password; | ||
}; | ||
|
||
const save = async () => { | ||
await createOutputDir(); | ||
|
||
const path = 'output/passwords.json'; | ||
|
||
logger.debug(`Saving passwords object to ${path}`); | ||
await writeFile(path, JSON.stringify(passwords), 'utf-8'); | ||
logger.debug('Passwords saved successfully'); | ||
}; | ||
|
||
return { add, save }; | ||
}; | ||
|
||
export const createWelcomeCsv = async (csv: string) => { | ||
await createOutputDir(); | ||
|
||
const path = 'output/welcome.csv'; | ||
|
||
logger.debug(`Saving welcome CSV to ${path}`); | ||
await writeFile(path, csv, 'utf-8'); | ||
logger.debug('Welcome CSV saved successfully'); | ||
}; |
Oops, something went wrong.